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

📄 error.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Call-backs for C++ error reporting.   This code is non-reentrant.   Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.   This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  */#include "config.h"#include "tree.h"#include "cp-tree.h"#include "obstack.h"#include <ctype.h>typedef char* cp_printer ();#define A args_as_string#define C code_as_string#define D decl_as_string#define E expr_as_string#define L language_as_string#define O op_as_string#define P parm_as_string#define T type_as_string#define V cv_as_string#define _ (cp_printer *) 0cp_printer * cp_printers[256] ={ /*0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x00 */  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x10 */  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x20 */  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x30 */  _, A, _, C, D, E, _, _, _, _, _, _, L, _, _, O, /* 0x40 */  P, _, _, _, T, _, V, _, _, _, _, _, _, _, _, _, /* 0x50 */  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x60 */  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x70 */};#undef C#undef D#undef E#undef L#undef O#undef P#undef T#undef V#undef _#define obstack_chunk_alloc xmalloc#define obstack_chunk_free free/* Obstack where we build text strings for overloading, etc.  */static struct obstack scratch_obstack;static char *scratch_firstobj;# define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)# define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))# define OB_PUTC2(C1,C2)	\  (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))# define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))# define OB_PUTID(ID)  \  (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID),	\		 IDENTIFIER_LENGTH (ID)))# define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))# define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))# define OB_PUTI(CST) do { sprintf (digit_buffer, "%d", (CST)); \			   OB_PUTCP (digit_buffer); } while (0)# define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N));# define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t)))static void dump_type (), dump_decl (), dump_function_decl ();static void dump_expr (), dump_unary_op (), dump_binary_op ();static void dump_aggr_type (), dump_type_prefix (), dump_type_suffix ();static void dump_function_name ();voidinit_error (){  gcc_obstack_init (&scratch_obstack);  scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);}enum pad { none, before, after };static voiddump_readonly_or_volatile (t, p)     tree t;     enum pad p;{  if (TYPE_READONLY (t) || TYPE_VOLATILE (t))    {      if (p == before) OB_PUTC (' ');      if (TYPE_READONLY (t))	OB_PUTS ("const");      if (TYPE_READONLY (t) && TYPE_VOLATILE (t))	OB_PUTC (' ');      if (TYPE_VOLATILE (t))	OB_PUTS ("volatile");      if (p == after) OB_PUTC (' ');    }}/* This must be large enough to hold any printed integer or floating-point   value.  */static char digit_buffer[128];/* Dump into the obstack a human-readable equivalent of TYPE. */static voiddump_type (t, v)     tree t;     int v;			/* verbose? */{  if (t == NULL_TREE)    return;    if (TYPE_PTRMEMFUNC_P (t))    goto offset_type;  switch (TREE_CODE (t))    {    case ERROR_MARK:      OB_PUTS ("{error}");      break;    case UNKNOWN_TYPE:      OB_PUTS ("{unknown type}");      break;    case TREE_LIST:      /* i.e. function taking no arguments */      if (t != void_list_node)	{	  dump_type (TREE_VALUE (t), v);	  /* Can this happen other than for default arguments? */	  if (TREE_PURPOSE (t) && v)	    {	      OB_PUTS (" = ");	      dump_expr (TREE_PURPOSE (t));	    }	  if (TREE_CHAIN (t))	    {	      if (TREE_CHAIN (t) != void_list_node)		{		  OB_PUTC2 (',', ' ');		  dump_type (TREE_CHAIN (t), v);		}	    }	  else OB_PUTS (" ...");	}      break;    case IDENTIFIER_NODE:      OB_PUTID (t);      break;    case TREE_VEC:      dump_type (BINFO_TYPE (t), v);      break;    case RECORD_TYPE:    case UNION_TYPE:    case ENUMERAL_TYPE:      if (TYPE_LANG_SPECIFIC (t)	  && (IS_SIGNATURE_POINTER (t) || IS_SIGNATURE_REFERENCE (t)))	{	  if (TYPE_READONLY (t) | TYPE_VOLATILE (t))	    dump_readonly_or_volatile (t);	  dump_type (SIGNATURE_TYPE (t), v);	  if (IS_SIGNATURE_POINTER (t))	    OB_PUTC ('*');	  else	    OB_PUTC ('&');	}      else	dump_aggr_type (t, v);      break;    case TYPE_DECL:      dump_decl (t, v);      break;    case INTEGER_TYPE:      if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))	OB_PUTS ("unsigned ");      else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t))	OB_PUTS ("signed ");      /* fall through.  */    case REAL_TYPE:    case VOID_TYPE:    case BOOLEAN_TYPE:      dump_readonly_or_volatile (t, after);      OB_PUTID (TYPE_IDENTIFIER (t));      break;    case TEMPLATE_TYPE_PARM:      OB_PUTID (TYPE_IDENTIFIER (t));      break;    case UNINSTANTIATED_P_TYPE:      OB_PUTID (DECL_NAME (UPT_TEMPLATE (t)));      OB_PUTS ("<...>");      break;      /* This is not always necessary for pointers and such, but doing this	 reduces code size.  */    case ARRAY_TYPE:    case POINTER_TYPE:    case REFERENCE_TYPE:    case OFFSET_TYPE:    offset_type:    case FUNCTION_TYPE:    case METHOD_TYPE:      dump_type_prefix (t, v);      dump_type_suffix (t, v);      break;    default:      sorry ("`%s' not supported by dump_type",	     tree_code_name[(int) TREE_CODE (t)]);    }}static char *aggr_variety (t)     tree t;{  if (TREE_CODE (t) == ENUMERAL_TYPE)    return "enum";  else if (TREE_CODE (t) == UNION_TYPE)    return "union";  else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))    return "class";  else if (TYPE_LANG_SPECIFIC (t) && IS_SIGNATURE (t))    return "signature";  else    return "struct";}/* Print out a class declaration, in the form `class foo'. */static voiddump_aggr_type (t, v)     tree t;     int v;			/* verbose? */{  tree name;  char *variety = aggr_variety (t);  dump_readonly_or_volatile (t, after);  if (v > 0)    {      OB_PUTCP (variety);      OB_PUTC (' ');    }    name = TYPE_NAME (t);  if (name && DECL_CONTEXT (name))    {      /* FUNCTION_DECL or RECORD_TYPE */      dump_decl (DECL_CONTEXT (name), 0);      OB_PUTC2 (':', ':');    }  /* kludge around weird behavior on g++.brendan/line1.C */  if (name && TREE_CODE (name) != IDENTIFIER_NODE)    name = DECL_NAME (name);  if (name == 0 || ANON_AGGRNAME_P (name))    {      OB_PUTS ("{anonymous");      if (!v)	{	  OB_PUTC (' ');	  OB_PUTCP (variety);	}      OB_PUTC ('}');    }  else    OB_PUTID (name);}/* Dump into the obstack the initial part of the output for a given type.   This is necessary when dealing with things like functions returning   functions.  Examples:   return type of `int (* fee ())()': pointer -> function -> int.  Both   pointer (and reference and offset) and function (and member) types must   deal with prefix and suffix.   Arrays must also do this for DECL nodes, like int a[], and for things like   int *[]&.  */static voiddump_type_prefix (t, v)     tree t;     int v;			/* verbosity */{  if (TYPE_PTRMEMFUNC_P (t))    {      t = TYPE_PTRMEMFUNC_FN_TYPE (t);      goto offset_type;    }    switch (TREE_CODE (t))    {    case POINTER_TYPE:      {	tree sub = TREE_TYPE (t);		dump_type_prefix (sub, v);	/* A tree for a member pointer looks like pointer to offset,	   so let the OFFSET_TYPE case handle it.  */	if (TREE_CODE (sub) != OFFSET_TYPE)	  {	    switch (TREE_CODE (sub))	      {		/* We don't want int ( *)() */	      case FUNCTION_TYPE:	      case METHOD_TYPE:		break;			      case ARRAY_TYPE:		OB_PUTC2 (' ', '(');		break;	      case POINTER_TYPE:		/* We don't want "char * *" */		if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))		  break;		/* But we do want "char *const *" */			      default:		OB_PUTC (' ');	      }	    OB_PUTC ('*');	    dump_readonly_or_volatile (t, none);	  }      }      break;    case REFERENCE_TYPE:      {	tree sub = TREE_TYPE (t);	dump_type_prefix (sub, v);	switch (TREE_CODE (sub))	  {	  case ARRAY_TYPE:	    OB_PUTC2 (' ', '(');	    break;	  case POINTER_TYPE:	    /* We don't want "char * &" */	    if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))	      break;	    /* But we do want "char *const &" */	  default:	    OB_PUTC (' ');	  }      }      OB_PUTC ('&');      dump_readonly_or_volatile (t, none);      break;    case OFFSET_TYPE:    offset_type:      dump_type_prefix (TREE_TYPE (t), v);      if (TREE_CODE (t) == OFFSET_TYPE)	/* pmfs deal with this in d_t_p */	{	  OB_PUTC (' ');	  dump_type (TYPE_OFFSET_BASETYPE (t), 0);	  OB_PUTC2 (':', ':');	}      OB_PUTC ('*');      dump_readonly_or_volatile (t, none);      break;      /* Can only be reached through function pointer -- this would not be         correct if FUNCTION_DECLs used it.  */    case FUNCTION_TYPE:      dump_type_prefix (TREE_TYPE (t), v);      OB_PUTC2 (' ', '(');      break;    case METHOD_TYPE:      dump_type_prefix (TREE_TYPE (t), v);      OB_PUTC2 (' ', '(');      dump_aggr_type (TYPE_METHOD_BASETYPE (t), 0);      OB_PUTC2 (':', ':');      break;    case ARRAY_TYPE:      dump_type_prefix (TREE_TYPE (t), v);      break;    case ENUMERAL_TYPE:    case ERROR_MARK:    case IDENTIFIER_NODE:    case INTEGER_TYPE:    case BOOLEAN_TYPE:    case REAL_TYPE:    case RECORD_TYPE:    case TEMPLATE_TYPE_PARM:    case TREE_LIST:    case TYPE_DECL:    case TREE_VEC:    case UNINSTANTIATED_P_TYPE:    case UNION_TYPE:    case UNKNOWN_TYPE:    case VOID_TYPE:      dump_type (t, v);      break;          default:      sorry ("`%s' not supported by dump_type_prefix",	     tree_code_name[(int) TREE_CODE (t)]);    }}static voiddump_type_suffix (t, v)     tree t;     int v;			/* verbose? */{  if (TYPE_PTRMEMFUNC_P (t))    t = TYPE_PTRMEMFUNC_FN_TYPE (t);  switch (TREE_CODE (t))    {    case POINTER_TYPE:    case REFERENCE_TYPE:    case OFFSET_TYPE:      if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)	OB_PUTC (')');      dump_type_suffix (TREE_TYPE (t), v);      break;      /* Can only be reached through function pointer */    case FUNCTION_TYPE:    case METHOD_TYPE:      {	tree arg;	OB_PUTC2 (')', '(');	arg = TYPE_ARG_TYPES (t);	if (TREE_CODE (t) == METHOD_TYPE)	  arg = TREE_CHAIN (arg);	if (arg)	  dump_type (arg, v);	else	  OB_PUTS ("...");	OB_PUTC (')');	if (TREE_CODE (t) == METHOD_TYPE)	  dump_readonly_or_volatile	    (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before);	dump_type_suffix (TREE_TYPE (t), v);	break;      }    case ARRAY_TYPE:      OB_PUTC ('[');      if (TYPE_DOMAIN (t))	OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);      OB_PUTC (']');      dump_type_suffix (TREE_TYPE (t), v);      break;          case ENUMERAL_TYPE:    case ERROR_MARK:    case IDENTIFIER_NODE:    case INTEGER_TYPE:    case BOOLEAN_TYPE:    case REAL_TYPE:    case RECORD_TYPE:    case TEMPLATE_TYPE_PARM:    case TREE_LIST:    case TYPE_DECL:

⌨️ 快捷键说明

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