diff options
Diffstat (limited to 'contrib/gcc/cp/error.c')
| -rw-r--r-- | contrib/gcc/cp/error.c | 816 | 
1 files changed, 648 insertions, 168 deletions
diff --git a/contrib/gcc/cp/error.c b/contrib/gcc/cp/error.c index 4eb196e3add5..bb21bcb5021c 100644 --- a/contrib/gcc/cp/error.c +++ b/contrib/gcc/cp/error.c @@ -1,6 +1,6 @@  /* Call-backs for C++ error reporting.     This code is non-reentrant. -   Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +   Copyright (C) 1993, 94-97, 1998 Free Software Foundation, Inc.     This file is part of GNU CC. @@ -20,10 +20,11 @@ the Free Software Foundation, 59 Temple Place - Suite 330,  Boston, MA 02111-1307, USA.  */  #include "config.h" +#include "system.h"  #include "tree.h"  #include "cp-tree.h"  #include "obstack.h" -#include <ctype.h> +#include "toplev.h"  typedef char* cp_printer (); @@ -34,21 +35,22 @@ typedef char* cp_printer ();  #define L language_as_string  #define O op_as_string  #define P parm_as_string +#define Q assop_as_string  #define T type_as_string  #define V cv_as_string -#define _ (cp_printer *) 0 +#define o (cp_printer *) 0  cp_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 */ +  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x00 */ +  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x10 */ +  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x20 */ +  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x30 */ +  o, A, o, C, D, E, o, o, o, o, o, o, L, o, o, O, /* 0x40 */ +  P, Q, o, o, T, o, V, o, o, o, o, o, o, o, o, o, /* 0x50 */ +  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x60 */ +  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x70 */  };  #undef C  #undef D @@ -56,9 +58,10 @@ cp_printer * cp_printers[256] =  #undef L  #undef O  #undef P +#undef Q  #undef T  #undef V -#undef _ +#undef o  #define obstack_chunk_alloc xmalloc  #define obstack_chunk_free free @@ -77,16 +80,32 @@ static char *scratch_firstobj;  		 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)); \ +# define OB_PUTI(CST) do { sprintf (digit_buffer, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(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 (); +enum pad { none, before, after }; + +static void dump_type PROTO((tree, int)); +static void dump_type_real PROTO((tree, int, int)); +static void dump_simple_decl PROTO((tree, tree, int)); +static void dump_decl PROTO((tree, int)); +static void dump_function_decl PROTO((tree, int)); +static void dump_expr PROTO((tree, int)); +static void dump_unary_op PROTO((char *, tree, int)); +static void dump_binary_op PROTO((char *, tree)); +static void dump_aggr_type PROTO((tree, int, int)); +static void dump_type_prefix PROTO((tree, int, int)); +static void dump_type_suffix PROTO((tree, int, int)); +static void dump_function_name PROTO((tree)); +static void dump_expr_list PROTO((tree)); +static void dump_global_iord PROTO((tree)); +static void dump_readonly_or_volatile PROTO((tree, enum pad)); +static void dump_char PROTO((int)); +static char *aggr_variety PROTO((tree)); +static tree ident_fndecl PROTO((tree));  void  init_error () @@ -95,8 +114,6 @@ init_error ()    scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);  } -enum pad { none, before, after }; -  static void  dump_readonly_or_volatile (t, p)       tree t; @@ -119,11 +136,13 @@ dump_readonly_or_volatile (t, p)     value.  */  static char digit_buffer[128]; -/* Dump into the obstack a human-readable equivalent of TYPE. */ +/* Dump into the obstack a human-readable equivalent of TYPE.  */ +  static void -dump_type (t, v) +dump_type_real (t, v, canonical_name)       tree t;       int v;			/* verbose? */ +     int canonical_name;  {    if (t == NULL_TREE)      return; @@ -145,19 +164,19 @@ dump_type (t, v)        /* i.e. function taking no arguments */        if (t != void_list_node)  	{ -	  dump_type (TREE_VALUE (t), v); +	  dump_type_real (TREE_VALUE (t), v, canonical_name);  	  /* Can this happen other than for default arguments? */  	  if (TREE_PURPOSE (t) && v)  	    {  	      OB_PUTS (" = "); -	      dump_expr (TREE_PURPOSE (t)); +	      dump_expr (TREE_PURPOSE (t), 0);  	    }  	  if (TREE_CHAIN (t))  	    {  	      if (TREE_CHAIN (t) != void_list_node)  		{  		  OB_PUTC2 (',', ' '); -		  dump_type (TREE_CHAIN (t), v); +		  dump_type_real (TREE_CHAIN (t), v, canonical_name);  		}  	    }  	  else OB_PUTS (" ..."); @@ -169,7 +188,7 @@ dump_type (t, v)        break;      case TREE_VEC: -      dump_type (BINFO_TYPE (t), v); +      dump_type_real (BINFO_TYPE (t), v, canonical_name);        break;      case RECORD_TYPE: @@ -179,21 +198,27 @@ dump_type (t, v)  	  && (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); +	    dump_readonly_or_volatile (t, after); +	  dump_type_real (SIGNATURE_TYPE (t), v, canonical_name);  	  if (IS_SIGNATURE_POINTER (t))  	    OB_PUTC ('*');  	  else  	    OB_PUTC ('&');  	}        else -	dump_aggr_type (t, v); +	dump_aggr_type (t, v, canonical_name);        break;      case TYPE_DECL: +    case TEMPLATE_DECL:        dump_decl (t, v);        break; +    case COMPLEX_TYPE: +      OB_PUTS ("complex "); +      dump_type_real (TREE_TYPE (t), v, canonical_name); +      break; +      case INTEGER_TYPE:        if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))  	OB_PUTS ("unsigned "); @@ -204,17 +229,56 @@ dump_type (t, v)      case REAL_TYPE:      case VOID_TYPE:      case BOOLEAN_TYPE: -      dump_readonly_or_volatile (t, after); -      OB_PUTID (TYPE_IDENTIFIER (t)); +      { +	tree type; +	dump_readonly_or_volatile (t, after); +	type = canonical_name ? TYPE_MAIN_VARIANT (t) : t; +	if (TYPE_NAME (type) && TYPE_IDENTIFIER (type)) +	  OB_PUTID (TYPE_IDENTIFIER (type)); +	else +	  /* Types like intQI_type_node and friends have no names. +	     These don't come up in user error messages, but it's nice +	     to be able to print them from the debugger.  */ +	  OB_PUTS ("{anonymous}"); +      }        break; -    case TEMPLATE_TYPE_PARM: -      OB_PUTID (TYPE_IDENTIFIER (t)); +    case TEMPLATE_TEMPLATE_PARM: +      if (!CLASSTYPE_TEMPLATE_INFO (t)) +	{ +	  /* For parameters inside template signature. */ +	  if (TYPE_IDENTIFIER (t)) +	    OB_PUTID (TYPE_IDENTIFIER (t)); +	  else +	    OB_PUTS ("{anonymous template template parm}"); +	} +      else +	{ +	  int i; +	  tree args = CLASSTYPE_TI_ARGS (t); +	  OB_PUTID (TYPE_IDENTIFIER (t)); +	  OB_PUTC ('<'); +	  for (i = 0; i < TREE_VEC_LENGTH (args); i++) +	    { +	      tree arg = TREE_VEC_ELT (args, i); +	      if (TREE_CODE_CLASS (TREE_CODE (arg)) == 't' +		  || TREE_CODE (arg) == TEMPLATE_DECL) +	        dump_type_real (arg, 0, canonical_name); +	      else +	        dump_expr (arg, 0); +	      if (i < TREE_VEC_LENGTH (args)-1) +	        OB_PUTC2 (',', ' '); +	    } +	  OB_PUTC ('>'); +	}        break; -    case UNINSTANTIATED_P_TYPE: -      OB_PUTID (DECL_NAME (UPT_TEMPLATE (t))); -      OB_PUTS ("<...>"); +    case TEMPLATE_TYPE_PARM: +      dump_readonly_or_volatile (t, after); +      if (TYPE_IDENTIFIER (t)) +	OB_PUTID (TYPE_IDENTIFIER (t)); +      else +	OB_PUTS ("{anonymous template type parm}");        break;        /* This is not always necessary for pointers and such, but doing this @@ -226,8 +290,15 @@ dump_type (t, v)      offset_type:      case FUNCTION_TYPE:      case METHOD_TYPE: -      dump_type_prefix (t, v); -      dump_type_suffix (t, v); +      dump_type_prefix (t, v, canonical_name); +      dump_type_suffix (t, v, canonical_name); +      break; + +    case TYPENAME_TYPE: +      OB_PUTS ("typename "); +      dump_type_real (TYPE_CONTEXT (t), 0, canonical_name); +      OB_PUTS ("::"); +      OB_PUTID (TYPE_IDENTIFIER (t));        break;      default: @@ -252,12 +323,22 @@ aggr_variety (t)      return "struct";  } -/* Print out a class declaration, in the form `class foo'. */  static void -dump_aggr_type (t, v) +dump_type (t, v)       tree t;       int v;			/* verbose? */  { +  dump_type_real (t, v, 0); +} + +/* Print out a class declaration, in the form `class foo'.  */ + +static void +dump_aggr_type (t, v, canonical_name) +     tree t; +     int v;			/* verbose? */ +     int canonical_name; +{    tree name;    char *variety = aggr_variety (t); @@ -269,9 +350,9 @@ dump_aggr_type (t, v)        OB_PUTC (' ');      } -  name = TYPE_NAME (t); +  name = TYPE_NAME (canonical_name ? TYPE_MAIN_VARIANT (t) : t); -  if (name && DECL_CONTEXT (name)) +  if (name && DECL_CONTEXT (name) && DECL_CONTEXT (name) != global_namespace)      {        /* FUNCTION_DECL or RECORD_TYPE */        dump_decl (DECL_CONTEXT (name), 0); @@ -308,9 +389,10 @@ dump_aggr_type (t, v)     int *[]&.  */  static void -dump_type_prefix (t, v) +dump_type_prefix (t, v, canonical_name)       tree t;       int v;			/* verbosity */ +     int canonical_name;  {    if (TYPE_PTRMEMFUNC_P (t))      { @@ -324,7 +406,7 @@ dump_type_prefix (t, v)        {  	tree sub = TREE_TYPE (t); -	dump_type_prefix (sub, v); +	dump_type_prefix (sub, v, canonical_name);  	/* 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) @@ -358,7 +440,7 @@ dump_type_prefix (t, v)      case REFERENCE_TYPE:        {  	tree sub = TREE_TYPE (t); -	dump_type_prefix (sub, v); +	dump_type_prefix (sub, v, canonical_name);  	switch (TREE_CODE (sub))  	  { @@ -382,11 +464,11 @@ dump_type_prefix (t, v)      case OFFSET_TYPE:      offset_type: -      dump_type_prefix (TREE_TYPE (t), v); +      dump_type_prefix (TREE_TYPE (t), v, canonical_name);        if (TREE_CODE (t) == OFFSET_TYPE)	/* pmfs deal with this in d_t_p */  	{  	  OB_PUTC (' '); -	  dump_type (TYPE_OFFSET_BASETYPE (t), 0); +	  dump_type_real (TYPE_OFFSET_BASETYPE (t), 0, canonical_name);  	  OB_PUTC2 (':', ':');  	}        OB_PUTC ('*'); @@ -396,19 +478,19 @@ dump_type_prefix (t, v)        /* 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); +      dump_type_prefix (TREE_TYPE (t), v, canonical_name);        OB_PUTC2 (' ', '(');        break;      case METHOD_TYPE: -      dump_type_prefix (TREE_TYPE (t), v); +      dump_type_prefix (TREE_TYPE (t), v, canonical_name);        OB_PUTC2 (' ', '('); -      dump_aggr_type (TYPE_METHOD_BASETYPE (t), 0); +      dump_aggr_type (TYPE_METHOD_BASETYPE (t), 0, canonical_name);        OB_PUTC2 (':', ':');        break;      case ARRAY_TYPE: -      dump_type_prefix (TREE_TYPE (t), v); +      dump_type_prefix (TREE_TYPE (t), v, canonical_name);        break;      case ENUMERAL_TYPE: @@ -419,14 +501,16 @@ dump_type_prefix (t, v)      case REAL_TYPE:      case RECORD_TYPE:      case TEMPLATE_TYPE_PARM: +    case TEMPLATE_TEMPLATE_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); +    case TYPENAME_TYPE: +    case COMPLEX_TYPE: +      dump_type_real (t, v, canonical_name);        break;      default: @@ -436,9 +520,10 @@ dump_type_prefix (t, v)  }  static void -dump_type_suffix (t, v) +dump_type_suffix (t, v, canonical_name)       tree t;       int v;			/* verbose? */ +     int canonical_name;  {    if (TYPE_PTRMEMFUNC_P (t))      t = TYPE_PTRMEMFUNC_FN_TYPE (t); @@ -450,7 +535,7 @@ dump_type_suffix (t, v)      case OFFSET_TYPE:        if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)  	OB_PUTC (')'); -      dump_type_suffix (TREE_TYPE (t), v); +      dump_type_suffix (TREE_TYPE (t), v, canonical_name);        break;        /* Can only be reached through function pointer */ @@ -471,16 +556,25 @@ dump_type_suffix (t, v)  	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); +	dump_type_suffix (TREE_TYPE (t), v, canonical_name);  	break;        }      case ARRAY_TYPE:        OB_PUTC ('[');        if (TYPE_DOMAIN (t)) -	OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1); +	{ +	  if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST) +	    OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1); +	  else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR) +	    dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 0); +	  else +	    dump_expr (fold (build_binary_op +			     (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)), +			      integer_one_node, 1)), 0); +	}        OB_PUTC (']'); -      dump_type_suffix (TREE_TYPE (t), v); +      dump_type_suffix (TREE_TYPE (t), v, canonical_name);        break;      case ENUMERAL_TYPE: @@ -491,13 +585,15 @@ dump_type_suffix (t, v)      case REAL_TYPE:      case RECORD_TYPE:      case TEMPLATE_TYPE_PARM: +    case TEMPLATE_TEMPLATE_PARM:      case TREE_LIST:      case TYPE_DECL:      case TREE_VEC: -    case UNINSTANTIATED_P_TYPE:      case UNION_TYPE:      case UNKNOWN_TYPE:      case VOID_TYPE: +    case TYPENAME_TYPE: +    case COMPLEX_TYPE:        break;      default: @@ -508,7 +604,8 @@ dump_type_suffix (t, v)  /* Return a function declaration which corresponds to the IDENTIFIER_NODE     argument.  */ -tree + +static tree  ident_fndecl (t)       tree t;  { @@ -538,9 +635,9 @@ ident_fndecl (t)  #endif  #define GLOBAL_IORD_P(NODE) \ -  !strncmp(IDENTIFIER_POINTER(NODE),GLOBAL_THING,sizeof(GLOBAL_THING)-1) +  ! strncmp (IDENTIFIER_POINTER(NODE), GLOBAL_THING, sizeof (GLOBAL_THING) - 1) -void +static void  dump_global_iord (t)       tree t;  { @@ -560,6 +657,31 @@ dump_global_iord (t)  }  static void +dump_simple_decl (t, type, v) +     tree t; +     tree type; +     int v; +{ +  if (v > 0) +    { +      dump_type_prefix (type, v, 0); +      OB_PUTC (' '); +      dump_readonly_or_volatile (t, after); +    } +  if (DECL_CLASS_SCOPE_P (t)) +    { +      dump_type (DECL_CONTEXT (t), 0); +      OB_PUTC2 (':', ':'); +    } +  if (DECL_NAME (t)) +    dump_decl (DECL_NAME (t), v); +  else +    OB_PUTS ("{anon}"); +  if (v > 0) +    dump_type_suffix (type, v, 0); +} + +static void  dump_decl (t, v)       tree t;       int v;			/* verbosity */ @@ -576,18 +698,20 @@ dump_decl (t, v)      case TYPE_DECL:        {  	/* Don't say 'typedef class A' */ -	tree type = TREE_TYPE (t); -        if (((IS_AGGR_TYPE (type) && ! TYPE_PTRMEMFUNC_P (type)) -	     || TREE_CODE (type) == ENUMERAL_TYPE) -	    && type == TYPE_MAIN_VARIANT (type)) +        if (DECL_ARTIFICIAL (t))  	  { -	    dump_type (type, v); +	    if (v > 0 && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) +	      /* Say `class T' not just `T'. */ +	      OB_PUTS ("class "); + +	    dump_type (TREE_TYPE (t), v);  	    break;  	  }        }        if (v > 0)  	OB_PUTS ("typedef "); -      goto general; +      dump_simple_decl (t, DECL_ORIGINAL_TYPE (t)  +			? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), v);        break;      case VAR_DECL: @@ -600,32 +724,24 @@ dump_decl (t, v)        /* else fall through */      case FIELD_DECL:      case PARM_DECL: -    general: -      if (v > 0) -	{ -	  dump_type_prefix (TREE_TYPE (t), v); -	  OB_PUTC (' '); -	  dump_readonly_or_volatile (t, after); -	} -      /* DECL_CLASS_CONTEXT isn't being set in some cases.  Hmm...  */ -      if (DECL_CONTEXT (t) -	  && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't') -	{ -	  dump_type (DECL_CONTEXT (t), 0); -	  OB_PUTC2 (':', ':'); -	} -      if (DECL_NAME (t)) -	dump_decl (DECL_NAME (t), v); -      else -	OB_PUTS ("{anon}"); -      if (v > 0) -	dump_type_suffix (TREE_TYPE (t), v); +      dump_simple_decl (t, TREE_TYPE (t), v);        break;      case NAMESPACE_DECL: +      if (DECL_CONTEXT (t) != global_namespace) +	{ +	  dump_decl (DECL_CONTEXT (t), v); +	  OB_PUTC2 (':',':'); +	}        OB_PUTID (DECL_NAME (t));        break; +    case SCOPE_REF: +      dump_decl (TREE_OPERAND (t, 0), 0); +      OB_PUTS ("::"); +      dump_decl (TREE_OPERAND (t, 1), 0); +      break;       +      case ARRAY_REF:        dump_decl (TREE_OPERAND (t, 0), v);        OB_PUTC ('['); @@ -646,7 +762,7 @@ dump_decl (t, v)        break;        /* These special cases are duplicated here so that other functions -	 can feed identifiers to cp_error and get them demangled properly. */ +	 can feed identifiers to cp_error and get them demangled properly.  */      case IDENTIFIER_NODE:        { tree f;  	if (DESTRUCTOR_NAME_P (t) @@ -677,45 +793,64 @@ dump_decl (t, v)      case FUNCTION_DECL:        if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t)))  	dump_global_iord (DECL_ASSEMBLER_NAME (t)); +      else if (! DECL_LANG_SPECIFIC (t)) +	OB_PUTS ("{internal}");        else  	dump_function_decl (t, v);        break;      case TEMPLATE_DECL:        { -	tree args = DECL_TEMPLATE_PARMS (t); -	int i, len = args ? TREE_VEC_LENGTH (args) : 0; -	OB_PUTS ("template <"); -	for (i = 0; i < len; i++) +	tree orig_args = DECL_TEMPLATE_PARMS (t); +	tree args; +	int i;  +	for (args = orig_args = nreverse (orig_args);  +	     args; +	     args = TREE_CHAIN (args))  	  { -	    tree arg = TREE_VEC_ELT (args, i); -	    tree defval = TREE_PURPOSE (arg); -	    arg = TREE_VALUE (arg); -	    if (TREE_CODE (arg) == TYPE_DECL) -	      { -		OB_PUTS ("class "); -		OB_PUTID (DECL_NAME (arg)); -	      } -	    else -	      dump_decl (arg, 1); +	    int len = TREE_VEC_LENGTH (TREE_VALUE (args)); -	    if (defval) +	    OB_PUTS ("template <"); +	    for (i = 0; i < len; i++)  	      { -		OB_PUTS (" = "); -		dump_decl (defval, 1); -	      } +		tree arg = TREE_VEC_ELT (TREE_VALUE (args), i); +		tree defval = TREE_PURPOSE (arg); +		arg = TREE_VALUE (arg); +		if (TREE_CODE (arg) == TYPE_DECL) +		  { +		    if (DECL_NAME (arg)) +		      { +			OB_PUTS ("class "); +			OB_PUTID (DECL_NAME (arg)); +		      } +		    else +		      OB_PUTS ("class"); +		  } +		else +		  dump_decl (arg, 1); +		 +		if (defval) +		  { +		    OB_PUTS (" = "); +		    if (TREE_CODE (arg) == TYPE_DECL +			|| TREE_CODE (arg) == TEMPLATE_DECL) +		      dump_type (defval, 1); +		    else +		      dump_expr (defval, 1); +		  } -	    OB_PUTC2 (',', ' '); +		OB_PUTC2 (',', ' '); +	      } +	    if (len != 0) +	      OB_UNPUT (2); +	    OB_PUTC2 ('>', ' ');  	  } -	if (len != 0) -	  OB_UNPUT (2); -	OB_PUTC2 ('>', ' '); +	nreverse(orig_args); -	if (DECL_TEMPLATE_IS_CLASS (t)) -	  { -	    OB_PUTS ("class "); -	    OB_PUTID (DECL_NAME (t)); -	  } +	if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) +	  dump_type (TREE_TYPE (t), v); +	else if (TREE_TYPE (t) == NULL_TREE) +	   my_friendly_abort (353);  	else switch (NEXT_CODE (t))  	  {  	  case METHOD_TYPE: @@ -724,20 +859,60 @@ dump_decl (t, v)  	    break;  	  default: -	    my_friendly_abort (353); +	    /* This case can occur with some illegal code.  */ +	    dump_type (TREE_TYPE (t), v); +	  } +      } +      break; + +    case TEMPLATE_ID_EXPR: +      { +	tree args; +	tree name = TREE_OPERAND (t, 0); +	if (is_overloaded_fn (name)) +	  name = DECL_NAME (get_first_fn (name)); +	dump_decl (name, v); +	OB_PUTC ('<'); +	for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args)) +	  { +	    if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (args))) == 't' +		|| TREE_CODE (TREE_VALUE (args)) == TEMPLATE_DECL) +	      dump_type (TREE_VALUE (args), 0); +	    else +	      dump_expr (TREE_VALUE (args), 0); +	    if (TREE_CHAIN (args)) +	      OB_PUTC2 (',', ' ');  	  } +	OB_PUTC ('>');        }        break; +    case LOOKUP_EXPR: +      dump_decl (TREE_OPERAND (t, 0), v); +      break; +      case LABEL_DECL:        OB_PUTID (DECL_NAME (t));        break;      case CONST_DECL: -      if (NEXT_CODE (t) == ENUMERAL_TYPE) -	goto general; -      else +      if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE) +	  || (DECL_INITIAL (t) && +	      TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX)) +	dump_simple_decl (t, TREE_TYPE (t), v); +      else if (DECL_NAME (t)) +	dump_decl (DECL_NAME (t), v); +      else if (DECL_INITIAL (t))  	dump_expr (DECL_INITIAL (t), 0); +      else +	OB_PUTS ("enumerator"); +      break; + +    case USING_DECL: +      OB_PUTS ("using "); +      dump_type (DECL_INITIAL (t), 0); +      OB_PUTS ("::"); +      OB_PUTID (DECL_NAME (t));        break;      default: @@ -755,11 +930,18 @@ dump_function_decl (t, v)       tree t;       int v;  { -  tree name = DECL_ASSEMBLER_NAME (t); -  tree fntype = TREE_TYPE (t); -  tree parmtypes = TYPE_ARG_TYPES (fntype); +  tree name; +  tree fntype; +  tree parmtypes;    tree cname = NULL_TREE; +  if (TREE_CODE (t) == TEMPLATE_DECL) +    t = DECL_TEMPLATE_RESULT (t); + +  name = DECL_ASSEMBLER_NAME (t); +  fntype = TREE_TYPE (t); +  parmtypes = TYPE_ARG_TYPES (fntype); +    /* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT.  */    if (DECL_CONTEXT (t))      cname = DECL_CLASS_CONTEXT (t); @@ -778,7 +960,7 @@ dump_function_decl (t, v)  	  && ! DECL_CONSTRUCTOR_P (t)  	  && ! DESTRUCTOR_NAME_P (name))  	{ -	  dump_type_prefix (TREE_TYPE (fntype), 1); +	  dump_type_prefix (TREE_TYPE (fntype), 1, 0);  	  OB_PUTC (' ');  	}      } @@ -809,7 +991,7 @@ dump_function_decl (t, v)    OB_PUTC (')');    if (v && ! IDENTIFIER_TYPENAME_P (name)) -    dump_type_suffix (TREE_TYPE (fntype), 1); +    dump_type_suffix (TREE_TYPE (fntype), 1, 0);    if (TREE_CODE (fntype) == METHOD_TYPE)      { @@ -825,6 +1007,7 @@ dump_function_decl (t, v)  /* Handle the function name for a FUNCTION_DECL node, grokking operators     and destructors properly.  */ +  static void  dump_function_name (t)       tree t; @@ -858,11 +1041,98 @@ dump_function_name (t)      }    else      dump_decl (name, 0); + +  if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t)) +    { +      tree args = DECL_TEMPLATE_INFO (t) ? DECL_TI_ARGS (t) : NULL_TREE;  + +      if (args != NULL_TREE +	  && DECL_CONTEXT (t) != NULL_TREE +	  && uses_template_parms (DECL_CONTEXT (t)) +	  /* This next clause checks that there is only one level of +	     template arguments.  In that case, they are the +	     arguments for the class context.  */ +	  && (TREE_CODE (args) == TREE_LIST +	      || (TREE_CODE (args) == TREE_VEC  +		  && TREE_VEC_ELT (args, 0) != NULL_TREE +		  && TREE_CODE (TREE_VEC_ELT (args, 0)) != TREE_VEC))) +	/* We have something like this: +	    +	   template <class T> struct S { void f(); }; +	    +	   and we are printing S<int>::f().  This is a template +	   instantiation, but we don't print anything after the f.  */ +	; +      else +	{ +	  OB_PUTC ('<'); + +	  /* Be careful only to print things when we have them, so as not +	     to crash producing error messages.  */ +	  if (args) +	    { +	      if (TREE_CODE (args) == TREE_LIST) +		{ +		  tree arg; +		  int need_comma = 0; + +		  for (arg = args; arg; arg = TREE_CHAIN (arg)) +		    { +		      tree a = TREE_VALUE (arg); + +		      if (need_comma) +			OB_PUTS (", "); + +		      if (a) +			{ +			  if (TREE_CODE_CLASS (TREE_CODE (a)) == 't' +			      || TREE_CODE (a) == TEMPLATE_DECL) +			    dump_type (a, 0); +			  else +			    dump_expr (a, 0); +			} +		   +		      need_comma = 1; +		    } +		} +	      else if (TREE_CODE (args) == TREE_VEC) +		{ +		  int i; +		  int need_comma = 0; + +		  if (TREE_VEC_LENGTH (args) > 0 +		      && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) +		    args = TREE_VEC_ELT (args,  +					 TREE_VEC_LENGTH (args) - 1); + +		  for (i = 0; i < TREE_VEC_LENGTH (args); i++) +		    { +		      tree a = TREE_VEC_ELT (args, i); + +		      if (need_comma) +			OB_PUTS (", "); + +		      if (a) +			{ +			  if (TREE_CODE_CLASS (TREE_CODE (a)) == 't' +			      || TREE_CODE (a) == TEMPLATE_DECL) +			    dump_type (a, 0); +			  else +			    dump_expr (a, 0); +			} +		   +		      need_comma = 1; +		    } +		} +	    } +	  OB_PUTC ('>'); +	} +    }  }  static void  dump_char (c) -     char c; +     int c;  {    switch (c)      { @@ -897,7 +1167,7 @@ dump_char (c)        OB_PUTS ("\\\"");        break;      default: -      if (isprint (c)) +      if (ISPRINT (c))  	OB_PUTC (c);        else  	{ @@ -908,6 +1178,7 @@ dump_char (c)  }  /* Print out a list of initializers (subr of dump_expr) */ +  static void  dump_expr_list (l)       tree l; @@ -922,6 +1193,7 @@ dump_expr_list (l)  }  /* Print out an expression */ +  static void  dump_expr (t, nop)       tree t; @@ -934,6 +1206,8 @@ dump_expr (t, nop)      case FIELD_DECL:      case CONST_DECL:      case FUNCTION_DECL: +    case TEMPLATE_DECL: +    case NAMESPACE_DECL:        dump_decl (t, -1);        break; @@ -950,12 +1224,12 @@ dump_expr (t, nop)  	  }  	else if (type == boolean_type_node)  	  { -	    if (t == boolean_false_node) +	    if (t == boolean_false_node +		|| (TREE_INT_CST_LOW (t) == 0 +		    && TREE_INT_CST_HIGH (t) == 0))  	      OB_PUTS ("false");  	    else if (t == boolean_true_node)  	      OB_PUTS ("true"); -	    else -	      my_friendly_abort (366);  	  }  	else if (type == char_type_node)  	  { @@ -995,7 +1269,7 @@ dump_expr (t, nop)  #else        {  	unsigned char *p = (unsigned char *) &TREE_REAL_CST (t); -	int i; +	size_t i;  	strcpy (digit_buffer, "0x");  	for (i = 0; i < sizeof TREE_REAL_CST (t); i++)  	  sprintf (digit_buffer + 2 + 2*i, "%02x", *p++); @@ -1044,10 +1318,11 @@ dump_expr (t, nop)  	}        break; -    case NEW_EXPR: +    case AGGR_INIT_EXPR:        OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));        OB_PUTC ('('); -      dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1))); +      if (TREE_OPERAND (t, 1)) +	dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));        OB_PUTC (')');        break; @@ -1059,7 +1334,7 @@ dump_expr (t, nop)  	if (TREE_CODE (fn) == ADDR_EXPR)  	  fn = TREE_OPERAND (fn, 0); -	if (NEXT_CODE (fn) == METHOD_TYPE) +	if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)  	  {  	    tree ob = TREE_VALUE (args);  	    if (TREE_CODE (ob) == ADDR_EXPR) @@ -1076,16 +1351,37 @@ dump_expr (t, nop)  	    args = TREE_CHAIN (args);  	  }  	dump_expr (fn, 0); -	OB_PUTC('('); +	OB_PUTC ('(');  	dump_expr_list (args);  	OB_PUTC (')');        }        break; -    case WITH_CLEANUP_EXPR: -      /* Note that this only works for G++ cleanups.  If somebody -	 builds a general cleanup, there's no way to represent it.  */ -      dump_expr (TREE_OPERAND (t, 0), 0); +    case NEW_EXPR: +      { +	tree type = TREE_OPERAND (t, 1); +	if (NEW_EXPR_USE_GLOBAL (t)) +	  OB_PUTS ("::"); +	OB_PUTS ("new "); +	if (TREE_OPERAND (t, 0)) +	  { +	    OB_PUTC ('('); +	    dump_expr_list (TREE_OPERAND (t, 0)); +	    OB_PUTS (") "); +	  } +	if (TREE_CODE (type) == ARRAY_REF) +	  type = build_cplus_array_type +	    (TREE_OPERAND (type, 0), +	     build_index_type (size_binop (MINUS_EXPR, TREE_OPERAND (type, 1), +					   integer_one_node))); +	dump_type (type, 0); +	if (TREE_OPERAND (t, 2)) +	  { +	    OB_PUTC ('('); +	    dump_expr_list (TREE_OPERAND (t, 2)); +	    OB_PUTC (')'); +	  } +      }        break;      case TARGET_EXPR: @@ -1188,7 +1484,8 @@ dump_expr (t, nop)  	}        else  	{ -	  if (NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE) +	  if (TREE_OPERAND (t,0) != NULL_TREE +	      && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)  	    dump_expr (TREE_OPERAND (t, 0), nop);  	  else  	    dump_unary_op ("*", t, nop); @@ -1215,7 +1512,7 @@ dump_expr (t, nop)        /* FIXME: This is a KLUDGE workaround for a parsing problem.  There  	 should be another level of INDIRECT_REF so that I don't have to do  	 this.  */ -      if (NEXT_CODE (t) == POINTER_TYPE) +      if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)  	{  	  tree next = TREE_TYPE (TREE_TYPE (t)); @@ -1240,8 +1537,46 @@ dump_expr (t, nop)        break;      case CONSTRUCTOR: +      if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) +	{ +	  tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0); + +	  if (integer_all_onesp (idx)) +	    { +	      tree pfn = PFN_FROM_PTRMEMFUNC (t); +	      dump_expr (pfn, 0); +	      break; +	    } +	  if (TREE_CODE (idx) == INTEGER_CST +	      && TREE_INT_CST_HIGH (idx) == 0) +	    { +	      tree virtuals; +	      unsigned HOST_WIDE_INT n; + +	      t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t))); +	      t = TYPE_METHOD_BASETYPE (t); +	      virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t))); +	       +	      n = TREE_INT_CST_LOW (idx); + +	      /* Map vtable index back one, to allow for the null pointer to +		 member.  */ +	      --n; + +	      while (n > 0 && virtuals) +		{ +		  --n; +		  virtuals = TREE_CHAIN (virtuals); +		} +	      if (virtuals) +		{ +		  dump_expr (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0); +		  break; +		} +	    } +	}        OB_PUTC ('{'); -      dump_expr_list (CONSTRUCTOR_ELTS (t), 0); +      dump_expr_list (CONSTRUCTOR_ELTS (t));        OB_PUTC ('}');        break; @@ -1255,12 +1590,82 @@ dump_expr (t, nop)  	  dump_expr (TREE_OPERAND (t, 1), 0);  	else  	  { -	    sorry ("operand of OFFSET_REF not understood"); -	    goto error; +	    dump_expr (TREE_OPERAND (t, 0), 0); +	    OB_PUTS (" .* "); +	    dump_expr (TREE_OPERAND (t, 1), 0);  	  }  	break;        } +    case TEMPLATE_PARM_INDEX: +      dump_decl (TEMPLATE_PARM_DECL (t), -1); +      break; + +    case IDENTIFIER_NODE: +      OB_PUTID (t); +      break; + +    case SCOPE_REF: +      dump_type (TREE_OPERAND (t, 0), 0); +      OB_PUTS ("::"); +      dump_expr (TREE_OPERAND (t, 1), 0); +      break; + +    case CAST_EXPR: +      if (TREE_OPERAND (t, 0) == NULL_TREE +	  || TREE_CHAIN (TREE_OPERAND (t, 0))) +	{ +	  dump_type (TREE_TYPE (t), 0); +	  OB_PUTC ('('); +	  dump_expr_list (TREE_OPERAND (t, 0)); +	  OB_PUTC (')'); +	} +      else +	{ +	  OB_PUTC ('('); +	  dump_type (TREE_TYPE (t), 0); +	  OB_PUTC (')'); +	  OB_PUTC ('('); +	  dump_expr_list (TREE_OPERAND (t, 0)); +	  OB_PUTC (')'); +	} +      break; + +    case LOOKUP_EXPR: +      OB_PUTID (TREE_OPERAND (t, 0)); +      break; + +    case ARROW_EXPR: +      dump_expr (TREE_OPERAND (t, 0), nop); +      OB_PUTS ("->"); +      break; + +    case SIZEOF_EXPR: +    case ALIGNOF_EXPR: +      if (TREE_CODE (t) == SIZEOF_EXPR) +	OB_PUTS ("sizeof ("); +      else  +	{ +	  my_friendly_assert (TREE_CODE (t) == ALIGNOF_EXPR, 0); +	  OB_PUTS ("__alignof__ ("); +	} +      if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't') +	dump_type (TREE_OPERAND (t, 0), 0); +      else +	dump_unary_op ("*", t, 0); +      OB_PUTC (')'); +      break; + +    case DEFAULT_ARG: +      OB_PUTS ("{unparsed}"); +      break; + +    case TRY_CATCH_EXPR: +    case WITH_CLEANUP_EXPR: +    case CLEANUP_POINT_EXPR: +      dump_expr (TREE_OPERAND (t, 0), nop); +      break; +      case TREE_LIST:        if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)  	{ @@ -1278,7 +1683,6 @@ dump_expr (t, nop)        /* fall through to ERROR_MARK...  */      case ERROR_MARK: -    error:        OB_PUTCP ("{error}");        break;      } @@ -1311,34 +1715,47 @@ dump_unary_op (opstring, t, nop)  }  char * -fndecl_as_string (cname, fndecl, print_ret_type_p) -     tree cname, fndecl; +fndecl_as_string (fndecl, print_ret_type_p) +     tree fndecl;       int print_ret_type_p;  {    return decl_as_string (fndecl, print_ret_type_p);  } -/* Same, but handtype a _TYPE. +/* Same, but handle a _TYPE.     Called from convert_to_reference, mangle_class_name_for_template, -   build_unary_op, and GNU_xref_decl.  */ +   build_unary_op, and GNU_xref_decl.  If CANONICAL_NAME is non-zero, +   when describing a typedef, we use the name of the type described, +   rather than the name of the typedef.  */ +  char * -type_as_string (typ, v) +type_as_string_real (typ, v, canonical_name)       tree typ;       int v; +     int canonical_name;  {    OB_INIT (); -  dump_type (typ, v); +  dump_type_real (typ, v, canonical_name);    OB_FINISH ();    return (char *)obstack_base (&scratch_obstack);  } + +char * +type_as_string (typ, v) +     tree typ; +     int v; +{ +  return type_as_string_real (typ, v, 0); +} +  char *  expr_as_string (decl, v)       tree decl; -     int v; +     int v ATTRIBUTE_UNUSED;  {    OB_INIT (); @@ -1351,6 +1768,7 @@ expr_as_string (decl, v)  /* A cross between type_as_string and fndecl_as_string.     Only called from substitute_nice_name.  */ +  char *  decl_as_string (decl, v)       tree decl; @@ -1365,14 +1783,48 @@ decl_as_string (decl, v)    return (char *)obstack_base (&scratch_obstack);  } +/* Generate the three forms of printable names for lang_printable_name.  */ + +char * +lang_decl_name (decl, v) +     tree decl; +     int v; +{ +  if (v >= 2) +    return decl_as_string (decl, 1); + +  OB_INIT (); + +  if (v == 1 && DECL_CLASS_SCOPE_P (decl)) +    { +      tree cname; +      if (TREE_CODE (decl) == FUNCTION_DECL) +	cname = DECL_CLASS_CONTEXT (decl); +      else +	cname = DECL_CONTEXT (decl); +      dump_type (cname, 0); +      OB_PUTC2 (':', ':'); +    } + +  if (TREE_CODE (decl) == FUNCTION_DECL) +    dump_function_name (decl); +  else +    dump_decl (DECL_NAME (decl), 0); + +  OB_FINISH (); + +  return (char *)obstack_base (&scratch_obstack); +} +   +  char *  cp_file_of (t)       tree t;  { -  if (TREE_CODE (t) == PARM_DECL) +  if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))      return DECL_SOURCE_FILE (DECL_CONTEXT (t));    else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') -    return DECL_SOURCE_FILE (TYPE_NAME (t)); +    return DECL_SOURCE_FILE (TYPE_MAIN_DECL (t));    else      return DECL_SOURCE_FILE (t);  } @@ -1382,18 +1834,13 @@ cp_line_of (t)       tree t;  {    int line = 0; -  if (TREE_CODE (t) == PARM_DECL) +  if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))      line = DECL_SOURCE_LINE (DECL_CONTEXT (t));    if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t))      t = TREE_TYPE (t);    if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') -    { -      if (IS_AGGR_TYPE (t)) -	line = CLASSTYPE_SOURCE_LINE (t); -      else -	line = DECL_SOURCE_LINE (TYPE_NAME (t)); -    } +    line = DECL_SOURCE_LINE (TYPE_MAIN_DECL (t));    else      line = DECL_SOURCE_LINE (t); @@ -1406,7 +1853,7 @@ cp_line_of (t)  char *  code_as_string (c, v)       enum tree_code c; -     int v; +     int v ATTRIBUTE_UNUSED;  {    return tree_code_name [c];  } @@ -1414,7 +1861,7 @@ code_as_string (c, v)  char *  language_as_string (c, v)       enum languages c; -     int v; +     int v ATTRIBUTE_UNUSED;  {    switch (c)      { @@ -1424,6 +1871,9 @@ language_as_string (c, v)      case lang_cplusplus:        return "C++"; +    case lang_java: +      return "Java"; +      default:        my_friendly_abort (355);        return 0; @@ -1431,9 +1881,11 @@ language_as_string (c, v)  }  /* Return the proper printed version of a parameter to a C++ function.  */ +  char *  parm_as_string (p, v) -     int p, v; +     int p; +     int v ATTRIBUTE_UNUSED;  {    if (p < 0)      return "`this'"; @@ -1445,7 +1897,7 @@ parm_as_string (p, v)  char *  op_as_string (p, v)       enum tree_code p; -     int v; +     int v ATTRIBUTE_UNUSED;  {    static char buf[] = "operator                "; @@ -1457,20 +1909,48 @@ op_as_string (p, v)  }  char * +assop_as_string (p, v) +     enum tree_code p; +     int v ATTRIBUTE_UNUSED; +{ +  static char buf[] = "operator                "; + +  if (p == 0) +    return "{unknown}"; +   +  strcpy (buf + 9, assignop_tab [p]); +  return buf; +} + +char *  args_as_string (p, v)       tree p;       int v;  {    if (p == NULL_TREE) -    return "..."; +    return ""; + +  if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (p))) == 't') +    return type_as_string (p, v); -  return type_as_string (p, v); +  OB_INIT (); +  for (; p; p = TREE_CHAIN (p)) +    { +      if (TREE_VALUE (p) == null_node) +	OB_PUTS ("NULL"); +      else +	dump_type (error_type (TREE_VALUE (p)), v); +      if (TREE_CHAIN (p)) +	OB_PUTS (", "); +    } +  OB_FINISH (); +  return (char *)obstack_base (&scratch_obstack);  }  char *  cv_as_string (p, v)       tree p; -     int v; +     int v ATTRIBUTE_UNUSED;  {    OB_INIT ();  | 
