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 (); |
