118334Speter/* Call-backs for C++ error reporting. 218334Speter This code is non-reentrant. 3132718Skan Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 4169689Skan 2003, 2004, 2005 Free Software Foundation, Inc. 5132718Skan This file is part of GCC. 618334Speter 7132718SkanGCC is free software; you can redistribute it and/or modify 818334Speterit under the terms of the GNU General Public License as published by 918334Speterthe Free Software Foundation; either version 2, or (at your option) 1018334Speterany later version. 1118334Speter 12132718SkanGCC is distributed in the hope that it will be useful, 1318334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of 1418334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1518334SpeterGNU General Public License for more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 18132718Skanalong with GCC; see the file COPYING. If not, write to 19169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor, 20169689SkanBoston, MA 02110-1301, USA. */ 2118334Speter 2218334Speter#include "config.h" 2350397Sobrien#include "system.h" 24132718Skan#include "coretypes.h" 25132718Skan#include "tm.h" 2618334Speter#include "tree.h" 2718334Speter#include "cp-tree.h" 2890075Sobrien#include "real.h" 2950397Sobrien#include "toplev.h" 3090075Sobrien#include "flags.h" 3190075Sobrien#include "diagnostic.h" 32117395Skan#include "langhooks-def.h" 33132718Skan#include "cxx-pretty-print.h" 3418334Speter 35169689Skan#define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',') 3618334Speter 3790075Sobrien/* The global buffer where we dump everything. It is there only for 3890075Sobrien transitional purpose. It is expected, in the near future, to be 3990075Sobrien completely removed. */ 40132718Skanstatic cxx_pretty_printer scratch_pretty_printer; 41132718Skan#define cxx_pp (&scratch_pretty_printer) 4218334Speter 4390075Sobrien# define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T))) 4418334Speter 45132718Skanstatic const char *args_to_string (tree, int); 46132718Skanstatic const char *assop_to_string (enum tree_code); 47132718Skanstatic const char *code_to_string (enum tree_code); 48132718Skanstatic const char *cv_to_string (tree, int); 49132718Skanstatic const char *decl_to_string (tree, int); 50132718Skanstatic const char *expr_to_string (tree); 51132718Skanstatic const char *fndecl_to_string (tree, int); 52132718Skanstatic const char *op_to_string (enum tree_code); 53132718Skanstatic const char *parm_to_string (int); 54132718Skanstatic const char *type_to_string (tree, int); 5552284Sobrien 56132718Skanstatic void dump_type (tree, int); 57132718Skanstatic void dump_typename (tree, int); 58132718Skanstatic void dump_simple_decl (tree, tree, int); 59132718Skanstatic void dump_decl (tree, int); 60132718Skanstatic void dump_template_decl (tree, int); 61132718Skanstatic void dump_function_decl (tree, int); 62132718Skanstatic void dump_expr (tree, int); 63132718Skanstatic void dump_unary_op (const char *, tree, int); 64132718Skanstatic void dump_binary_op (const char *, tree, int); 65132718Skanstatic void dump_aggr_type (tree, int); 66169689Skanstatic void dump_type_prefix (tree, int); 67132718Skanstatic void dump_type_suffix (tree, int); 68132718Skanstatic void dump_function_name (tree, int); 69132718Skanstatic void dump_expr_list (tree, int); 70132718Skanstatic void dump_global_iord (tree); 71132718Skanstatic void dump_parameters (tree, int); 72132718Skanstatic void dump_exception_spec (tree, int); 73132718Skanstatic void dump_template_argument (tree, int); 74132718Skanstatic void dump_template_argument_list (tree, int); 75132718Skanstatic void dump_template_parameter (tree, int); 76132718Skanstatic void dump_template_bindings (tree, tree); 77132718Skanstatic void dump_scope (tree, int); 78132718Skanstatic void dump_template_parms (tree, int, int); 7918334Speter 80132718Skanstatic const char *function_category (tree); 81132718Skanstatic void maybe_print_instantiation_context (diagnostic_context *); 82132718Skanstatic void print_instantiation_full_context (diagnostic_context *); 83132718Skanstatic void print_instantiation_partial_context (diagnostic_context *, 84169689Skan tree, location_t); 85132718Skanstatic void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *); 86132718Skanstatic void cp_diagnostic_finalizer (diagnostic_context *, diagnostic_info *); 87132718Skanstatic void cp_print_error_function (diagnostic_context *, diagnostic_info *); 8818334Speter 89169689Skanstatic bool cp_printer (pretty_printer *, text_info *, const char *, 90169689Skan int, bool, bool, bool); 91132718Skanstatic location_t location_of (tree); 9250397Sobrien 9318334Spetervoid 94132718Skaninit_error (void) 9518334Speter{ 9690075Sobrien diagnostic_starter (global_dc) = cp_diagnostic_starter; 9790075Sobrien diagnostic_finalizer (global_dc) = cp_diagnostic_finalizer; 9890075Sobrien diagnostic_format_decoder (global_dc) = cp_printer; 9990075Sobrien 100132718Skan pp_construct (pp_base (cxx_pp), NULL, 0); 101132718Skan pp_cxx_pretty_printer_init (cxx_pp); 10218334Speter} 10318334Speter 10490075Sobrien/* Dump a scope, if deemed necessary. */ 10552284Sobrien 10690075Sobrienstatic void 107132718Skandump_scope (tree scope, int flags) 10852284Sobrien{ 10990075Sobrien int f = ~TFF_RETURN_TYPE & (flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF)); 11052284Sobrien 11190075Sobrien if (scope == NULL_TREE) 11290075Sobrien return; 11390075Sobrien 11490075Sobrien if (TREE_CODE (scope) == NAMESPACE_DECL) 11590075Sobrien { 11690075Sobrien if (scope != global_namespace) 117169689Skan { 118169689Skan dump_decl (scope, f); 119169689Skan pp_cxx_colon_colon (cxx_pp); 120169689Skan } 12190075Sobrien } 12290075Sobrien else if (AGGREGATE_TYPE_P (scope)) 12390075Sobrien { 12490075Sobrien dump_type (scope, f); 125169689Skan pp_cxx_colon_colon (cxx_pp); 12690075Sobrien } 12790075Sobrien else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL) 12890075Sobrien { 12990075Sobrien dump_function_decl (scope, f); 130169689Skan pp_cxx_colon_colon (cxx_pp); 13190075Sobrien } 13252284Sobrien} 13352284Sobrien 13490075Sobrien/* Dump the template ARGument under control of FLAGS. */ 13552284Sobrien 13690075Sobrienstatic void 137132718Skandump_template_argument (tree arg, int flags) 13890075Sobrien{ 13990075Sobrien if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL) 14090075Sobrien dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM); 14190075Sobrien else 14290075Sobrien dump_expr (arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM); 14390075Sobrien} 14452284Sobrien 14590075Sobrien/* Dump a template-argument-list ARGS (always a TREE_VEC) under control 14690075Sobrien of FLAGS. */ 14752284Sobrien 14890075Sobrienstatic void 149132718Skandump_template_argument_list (tree args, int flags) 15090075Sobrien{ 15190075Sobrien int n = TREE_VEC_LENGTH (args); 15290075Sobrien int need_comma = 0; 15390075Sobrien int i; 15452284Sobrien 15590075Sobrien for (i = 0; i< n; ++i) 15690075Sobrien { 15790075Sobrien if (need_comma) 158169689Skan pp_separate_with_comma (cxx_pp); 15990075Sobrien dump_template_argument (TREE_VEC_ELT (args, i), flags); 16090075Sobrien need_comma = 1; 16190075Sobrien } 16290075Sobrien} 16352284Sobrien 16490075Sobrien/* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS. */ 16590075Sobrien 16690075Sobrienstatic void 167132718Skandump_template_parameter (tree parm, int flags) 16890075Sobrien{ 169169689Skan tree p; 170169689Skan tree a; 17190075Sobrien 172169689Skan if (parm == error_mark_node) 173169689Skan return; 174169689Skan 175169689Skan p = TREE_VALUE (parm); 176169689Skan a = TREE_PURPOSE (parm); 177169689Skan 17890075Sobrien if (TREE_CODE (p) == TYPE_DECL) 17990075Sobrien { 18090075Sobrien if (flags & TFF_DECL_SPECIFIERS) 181169689Skan { 182169689Skan pp_cxx_identifier (cxx_pp, "class"); 183169689Skan if (DECL_NAME (p)) 184169689Skan pp_cxx_tree_identifier (cxx_pp, DECL_NAME (p)); 185169689Skan } 18690075Sobrien else if (DECL_NAME (p)) 187169689Skan pp_cxx_tree_identifier (cxx_pp, DECL_NAME (p)); 18890075Sobrien else 189169689Skan pp_cxx_canonical_template_parameter (cxx_pp, TREE_TYPE (p)); 19090075Sobrien } 19190075Sobrien else 19290075Sobrien dump_decl (p, flags | TFF_DECL_SPECIFIERS); 19390075Sobrien 19490075Sobrien if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE) 19590075Sobrien { 196169689Skan pp_cxx_whitespace (cxx_pp); 197169689Skan pp_equal (cxx_pp); 198169689Skan pp_cxx_whitespace (cxx_pp); 19990075Sobrien if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL) 200169689Skan dump_type (a, flags & ~TFF_CHASE_TYPEDEF); 20190075Sobrien else 202169689Skan dump_expr (a, flags | TFF_EXPR_IN_PARENS); 20390075Sobrien } 20490075Sobrien} 20590075Sobrien 20690075Sobrien/* Dump, under control of FLAGS, a template-parameter-list binding. 20790075Sobrien PARMS is a TREE_LIST of TREE_VEC of TREE_LIST and ARGS is a 20890075Sobrien TREE_VEC. */ 20990075Sobrien 21090075Sobrienstatic void 211132718Skandump_template_bindings (tree parms, tree args) 21290075Sobrien{ 21390075Sobrien int need_comma = 0; 21490075Sobrien 21590075Sobrien while (parms) 21690075Sobrien { 21790075Sobrien tree p = TREE_VALUE (parms); 21890075Sobrien int lvl = TMPL_PARMS_DEPTH (parms); 21990075Sobrien int arg_idx = 0; 22090075Sobrien int i; 22190075Sobrien 22290075Sobrien for (i = 0; i < TREE_VEC_LENGTH (p); ++i) 22390075Sobrien { 22490075Sobrien tree arg = NULL_TREE; 22590075Sobrien 22690075Sobrien /* Don't crash if we had an invalid argument list. */ 22790075Sobrien if (TMPL_ARGS_DEPTH (args) >= lvl) 22890075Sobrien { 22990075Sobrien tree lvl_args = TMPL_ARGS_LEVEL (args, lvl); 23090075Sobrien if (NUM_TMPL_ARGS (lvl_args) > arg_idx) 23190075Sobrien arg = TREE_VEC_ELT (lvl_args, arg_idx); 23290075Sobrien } 23390075Sobrien 23490075Sobrien if (need_comma) 235132718Skan pp_separate_with_comma (cxx_pp); 23690075Sobrien dump_template_parameter (TREE_VEC_ELT (p, i), TFF_PLAIN_IDENTIFIER); 237169689Skan pp_cxx_whitespace (cxx_pp); 238169689Skan pp_equal (cxx_pp); 239169689Skan pp_cxx_whitespace (cxx_pp); 24090075Sobrien if (arg) 24190075Sobrien dump_template_argument (arg, TFF_PLAIN_IDENTIFIER); 24290075Sobrien else 243132718Skan pp_identifier (cxx_pp, "<missing>"); 24490075Sobrien 24590075Sobrien ++arg_idx; 24690075Sobrien need_comma = 1; 24752284Sobrien } 24890075Sobrien 24990075Sobrien parms = TREE_CHAIN (parms); 25018334Speter } 25118334Speter} 25218334Speter 253117395Skan/* Dump a human-readable equivalent of TYPE. FLAGS controls the 254117395Skan format. */ 25518334Speter 25618334Speterstatic void 257132718Skandump_type (tree t, int flags) 25818334Speter{ 25918334Speter if (t == NULL_TREE) 26018334Speter return; 26190075Sobrien 26218334Speter if (TYPE_PTRMEMFUNC_P (t)) 26318334Speter goto offset_type; 26418334Speter 26518334Speter switch (TREE_CODE (t)) 26618334Speter { 26718334Speter case UNKNOWN_TYPE: 268169689Skan pp_identifier (cxx_pp, "<unresolved overloaded function type>"); 26918334Speter break; 27018334Speter 27118334Speter case TREE_LIST: 27252284Sobrien /* A list of function parms. */ 27390075Sobrien dump_parameters (t, flags); 27418334Speter break; 27518334Speter 27618334Speter case IDENTIFIER_NODE: 277169689Skan pp_cxx_tree_identifier (cxx_pp, t); 27818334Speter break; 27918334Speter 280169689Skan case TREE_BINFO: 28190075Sobrien dump_type (BINFO_TYPE (t), flags); 28218334Speter break; 28318334Speter 28418334Speter case RECORD_TYPE: 28518334Speter case UNION_TYPE: 28618334Speter case ENUMERAL_TYPE: 28790075Sobrien dump_aggr_type (t, flags); 28818334Speter break; 28918334Speter 29018334Speter case TYPE_DECL: 29190075Sobrien if (flags & TFF_CHASE_TYPEDEF) 292169689Skan { 293169689Skan dump_type (DECL_ORIGINAL_TYPE (t) 294169689Skan ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags); 295169689Skan break; 296169689Skan } 297132718Skan /* Else fall through. */ 29890075Sobrien 29950397Sobrien case TEMPLATE_DECL: 30052284Sobrien case NAMESPACE_DECL: 30190075Sobrien dump_decl (t, flags & ~TFF_DECL_SPECIFIERS); 30218334Speter break; 30318334Speter 30418334Speter case INTEGER_TYPE: 30518334Speter case REAL_TYPE: 30618334Speter case VOID_TYPE: 30718334Speter case BOOLEAN_TYPE: 308132718Skan case COMPLEX_TYPE: 309132718Skan case VECTOR_TYPE: 310132718Skan pp_type_specifier_seq (cxx_pp, t); 31118334Speter break; 31218334Speter 31350397Sobrien case TEMPLATE_TEMPLATE_PARM: 314117395Skan /* For parameters inside template signature. */ 31590075Sobrien if (TYPE_IDENTIFIER (t)) 316169689Skan pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); 31750397Sobrien else 318169689Skan pp_cxx_canonical_template_parameter (cxx_pp, t); 31918334Speter break; 32018334Speter 32190075Sobrien case BOUND_TEMPLATE_TEMPLATE_PARM: 32290075Sobrien { 32390075Sobrien tree args = TYPE_TI_ARGS (t); 324169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, t); 325169689Skan pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); 326169689Skan pp_cxx_begin_template_argument_list (cxx_pp); 327169689Skan dump_template_argument_list (args, flags); 328169689Skan pp_cxx_end_template_argument_list (cxx_pp); 32990075Sobrien } 33090075Sobrien break; 33190075Sobrien 33250397Sobrien case TEMPLATE_TYPE_PARM: 333169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, t); 33450397Sobrien if (TYPE_IDENTIFIER (t)) 335169689Skan pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); 33650397Sobrien else 337169689Skan pp_cxx_canonical_template_parameter 338169689Skan (cxx_pp, TEMPLATE_TYPE_PARM_INDEX (t)); 33918334Speter break; 34018334Speter 34118334Speter /* This is not always necessary for pointers and such, but doing this 34218334Speter reduces code size. */ 34318334Speter case ARRAY_TYPE: 34418334Speter case POINTER_TYPE: 34518334Speter case REFERENCE_TYPE: 34618334Speter case OFFSET_TYPE: 34718334Speter offset_type: 34818334Speter case FUNCTION_TYPE: 34918334Speter case METHOD_TYPE: 35090075Sobrien { 35190075Sobrien dump_type_prefix (t, flags); 35290075Sobrien dump_type_suffix (t, flags); 35318334Speter break; 35490075Sobrien } 35550397Sobrien case TYPENAME_TYPE: 356169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, t); 357169689Skan pp_cxx_identifier (cxx_pp, 358169689Skan TYPENAME_IS_ENUM_P (t) ? "enum" 359169689Skan : TYPENAME_IS_CLASS_P (t) ? "class" 360169689Skan : "typename"); 36190075Sobrien dump_typename (t, flags); 36250397Sobrien break; 36350397Sobrien 36490075Sobrien case UNBOUND_CLASS_TEMPLATE: 36590075Sobrien dump_type (TYPE_CONTEXT (t), flags); 366169689Skan pp_cxx_colon_colon (cxx_pp); 367169689Skan pp_cxx_identifier (cxx_pp, "template"); 36890075Sobrien dump_type (DECL_NAME (TYPE_NAME (t)), flags); 36990075Sobrien break; 37090075Sobrien 37152284Sobrien case TYPEOF_TYPE: 372169689Skan pp_cxx_identifier (cxx_pp, "__typeof__"); 373169689Skan pp_cxx_whitespace (cxx_pp); 374169689Skan pp_cxx_left_paren (cxx_pp); 375169689Skan dump_expr (TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS); 376169689Skan pp_cxx_right_paren (cxx_pp); 37752284Sobrien break; 37852284Sobrien 37918334Speter default: 380132718Skan pp_unsupported_tree (cxx_pp, t); 381117395Skan /* Fall through to error. */ 38290075Sobrien 38390075Sobrien case ERROR_MARK: 384132718Skan pp_identifier (cxx_pp, "<type error>"); 38590075Sobrien break; 38618334Speter } 38718334Speter} 38818334Speter 38990075Sobrien/* Dump a TYPENAME_TYPE. We need to notice when the context is itself 39090075Sobrien a TYPENAME_TYPE. */ 39190075Sobrien 39290075Sobrienstatic void 393132718Skandump_typename (tree t, int flags) 39418334Speter{ 39590075Sobrien tree ctx = TYPE_CONTEXT (t); 39690075Sobrien 39790075Sobrien if (TREE_CODE (ctx) == TYPENAME_TYPE) 39890075Sobrien dump_typename (ctx, flags); 39990075Sobrien else 40090075Sobrien dump_type (ctx, flags & ~TFF_CLASS_KEY_OR_ENUM); 401169689Skan pp_cxx_colon_colon (cxx_pp); 40290075Sobrien dump_decl (TYPENAME_TYPE_FULLNAME (t), flags); 40390075Sobrien} 40490075Sobrien 40590075Sobrien/* Return the name of the supplied aggregate, or enumeral type. */ 40690075Sobrien 407169689Skanconst char * 408169689Skanclass_key_or_enum_as_string (tree t) 40990075Sobrien{ 41018334Speter if (TREE_CODE (t) == ENUMERAL_TYPE) 41118334Speter return "enum"; 41218334Speter else if (TREE_CODE (t) == UNION_TYPE) 41318334Speter return "union"; 41418334Speter else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t)) 41518334Speter return "class"; 41618334Speter else 41718334Speter return "struct"; 41818334Speter} 41918334Speter 42090075Sobrien/* Print out a class declaration T under the control of FLAGS, 42190075Sobrien in the form `class foo'. */ 42250397Sobrien 42350397Sobrienstatic void 424132718Skandump_aggr_type (tree t, int flags) 42550397Sobrien{ 42618334Speter tree name; 427169689Skan const char *variety = class_key_or_enum_as_string (t); 42890075Sobrien int typdef = 0; 42990075Sobrien int tmplate = 0; 43018334Speter 431169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, t); 43218334Speter 43390075Sobrien if (flags & TFF_CLASS_KEY_OR_ENUM) 434169689Skan pp_cxx_identifier (cxx_pp, variety); 43518334Speter 43690075Sobrien if (flags & TFF_CHASE_TYPEDEF) 43790075Sobrien t = TYPE_MAIN_VARIANT (t); 43890075Sobrien 43990075Sobrien name = TYPE_NAME (t); 44090075Sobrien 44190075Sobrien if (name) 44218334Speter { 44390075Sobrien typdef = !DECL_ARTIFICIAL (name); 44490075Sobrien tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE 445169689Skan && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t) 446169689Skan && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL 447169689Skan || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))); 44890075Sobrien dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE); 44990075Sobrien if (tmplate) 450169689Skan { 451169689Skan /* Because the template names are mangled, we have to locate 452169689Skan the most general template, and use that name. */ 453169689Skan tree tpl = CLASSTYPE_TI_TEMPLATE (t); 45490075Sobrien 455169689Skan while (DECL_TEMPLATE_INFO (tpl)) 456169689Skan tpl = DECL_TI_TEMPLATE (tpl); 457169689Skan name = tpl; 458169689Skan } 45990075Sobrien name = DECL_NAME (name); 46018334Speter } 46118334Speter 46218334Speter if (name == 0 || ANON_AGGRNAME_P (name)) 46318334Speter { 46490075Sobrien if (flags & TFF_CLASS_KEY_OR_ENUM) 465169689Skan pp_identifier (cxx_pp, "<anonymous>"); 46690075Sobrien else 467169689Skan pp_printf (pp_base (cxx_pp), "<anonymous %s>", variety); 46818334Speter } 46918334Speter else 470169689Skan pp_cxx_tree_identifier (cxx_pp, name); 47190075Sobrien if (tmplate) 47290075Sobrien dump_template_parms (TYPE_TEMPLATE_INFO (t), 473169689Skan !CLASSTYPE_USE_TEMPLATE (t), 474169689Skan flags & ~TFF_TEMPLATE_HEADER); 47518334Speter} 47618334Speter 47718334Speter/* Dump into the obstack the initial part of the output for a given type. 47818334Speter This is necessary when dealing with things like functions returning 47918334Speter functions. Examples: 48018334Speter 48118334Speter return type of `int (* fee ())()': pointer -> function -> int. Both 48218334Speter pointer (and reference and offset) and function (and member) types must 48318334Speter deal with prefix and suffix. 48418334Speter 48518334Speter Arrays must also do this for DECL nodes, like int a[], and for things like 486169689Skan int *[]&. */ 48718334Speter 488169689Skanstatic void 489132718Skandump_type_prefix (tree t, int flags) 49018334Speter{ 49118334Speter if (TYPE_PTRMEMFUNC_P (t)) 49218334Speter { 49318334Speter t = TYPE_PTRMEMFUNC_FN_TYPE (t); 49418334Speter goto offset_type; 49518334Speter } 49690075Sobrien 49718334Speter switch (TREE_CODE (t)) 49818334Speter { 49918334Speter case POINTER_TYPE: 50052284Sobrien case REFERENCE_TYPE: 50118334Speter { 50218334Speter tree sub = TREE_TYPE (t); 50390075Sobrien 504169689Skan dump_type_prefix (sub, flags); 505132718Skan if (TREE_CODE (sub) == ARRAY_TYPE) 50618334Speter { 507169689Skan pp_cxx_whitespace (cxx_pp); 508169689Skan pp_cxx_left_paren (cxx_pp); 50918334Speter } 510132718Skan pp_character (cxx_pp, "&*"[TREE_CODE (t) == POINTER_TYPE]); 511169689Skan pp_base (cxx_pp)->padding = pp_before; 512169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, t); 51318334Speter } 51418334Speter break; 51518334Speter 51618334Speter case OFFSET_TYPE: 51718334Speter offset_type: 518169689Skan dump_type_prefix (TREE_TYPE (t), flags); 51918334Speter if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */ 52018334Speter { 521169689Skan pp_maybe_space (cxx_pp); 522169689Skan if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) 523169689Skan pp_cxx_left_paren (cxx_pp); 52490075Sobrien dump_type (TYPE_OFFSET_BASETYPE (t), flags); 525169689Skan pp_cxx_colon_colon (cxx_pp); 52618334Speter } 527169689Skan pp_cxx_star (cxx_pp); 528169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, t); 529169689Skan pp_base (cxx_pp)->padding = pp_before; 53018334Speter break; 53118334Speter 53218334Speter /* Can only be reached through function pointer -- this would not be 533169689Skan correct if FUNCTION_DECLs used it. */ 53418334Speter case FUNCTION_TYPE: 535169689Skan dump_type_prefix (TREE_TYPE (t), flags); 536169689Skan pp_maybe_space (cxx_pp); 537169689Skan pp_cxx_left_paren (cxx_pp); 53818334Speter break; 53918334Speter 54018334Speter case METHOD_TYPE: 541169689Skan dump_type_prefix (TREE_TYPE (t), flags); 542169689Skan pp_maybe_space (cxx_pp); 543169689Skan pp_cxx_left_paren (cxx_pp); 54490075Sobrien dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags); 545169689Skan pp_cxx_colon_colon (cxx_pp); 54618334Speter break; 54718334Speter 54818334Speter case ARRAY_TYPE: 549169689Skan dump_type_prefix (TREE_TYPE (t), flags); 55018334Speter break; 55118334Speter 55218334Speter case ENUMERAL_TYPE: 55318334Speter case IDENTIFIER_NODE: 55418334Speter case INTEGER_TYPE: 55518334Speter case BOOLEAN_TYPE: 55618334Speter case REAL_TYPE: 55718334Speter case RECORD_TYPE: 55818334Speter case TEMPLATE_TYPE_PARM: 55950397Sobrien case TEMPLATE_TEMPLATE_PARM: 56090075Sobrien case BOUND_TEMPLATE_TEMPLATE_PARM: 56118334Speter case TREE_LIST: 56218334Speter case TYPE_DECL: 56318334Speter case TREE_VEC: 56418334Speter case UNION_TYPE: 56518334Speter case UNKNOWN_TYPE: 56618334Speter case VOID_TYPE: 56750397Sobrien case TYPENAME_TYPE: 56850397Sobrien case COMPLEX_TYPE: 56990075Sobrien case VECTOR_TYPE: 570117395Skan case TYPEOF_TYPE: 57190075Sobrien dump_type (t, flags); 572169689Skan pp_base (cxx_pp)->padding = pp_before; 57318334Speter break; 57490075Sobrien 57518334Speter default: 576132718Skan pp_unsupported_tree (cxx_pp, t); 57790075Sobrien /* fall through. */ 57890075Sobrien case ERROR_MARK: 579132718Skan pp_identifier (cxx_pp, "<typeprefixerror>"); 58090075Sobrien break; 58118334Speter } 58218334Speter} 58318334Speter 58490075Sobrien/* Dump the suffix of type T, under control of FLAGS. This is the part 58590075Sobrien which appears after the identifier (or function parms). */ 58690075Sobrien 58718334Speterstatic void 588132718Skandump_type_suffix (tree t, int flags) 58918334Speter{ 59018334Speter if (TYPE_PTRMEMFUNC_P (t)) 59118334Speter t = TYPE_PTRMEMFUNC_FN_TYPE (t); 59218334Speter 59318334Speter switch (TREE_CODE (t)) 59418334Speter { 59518334Speter case POINTER_TYPE: 59618334Speter case REFERENCE_TYPE: 59718334Speter case OFFSET_TYPE: 59818334Speter if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) 599169689Skan pp_cxx_right_paren (cxx_pp); 60090075Sobrien dump_type_suffix (TREE_TYPE (t), flags); 60118334Speter break; 60218334Speter 603132718Skan /* Can only be reached through function pointer. */ 60418334Speter case FUNCTION_TYPE: 60518334Speter case METHOD_TYPE: 60618334Speter { 60718334Speter tree arg; 608169689Skan pp_cxx_right_paren (cxx_pp); 60918334Speter arg = TYPE_ARG_TYPES (t); 61018334Speter if (TREE_CODE (t) == METHOD_TYPE) 61118334Speter arg = TREE_CHAIN (arg); 61218334Speter 61352284Sobrien /* Function pointers don't have default args. Not in standard C++, 61452284Sobrien anyway; they may in g++, but we'll just pretend otherwise. */ 61590075Sobrien dump_parameters (arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS); 61652284Sobrien 61718334Speter if (TREE_CODE (t) == METHOD_TYPE) 618169689Skan pp_cxx_cv_qualifier_seq 619169689Skan (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t)))); 620169689Skan else 621169689Skan pp_cxx_cv_qualifier_seq(cxx_pp, t); 62290075Sobrien dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags); 62390075Sobrien dump_type_suffix (TREE_TYPE (t), flags); 62418334Speter break; 62518334Speter } 62618334Speter 62718334Speter case ARRAY_TYPE: 628169689Skan pp_maybe_space (cxx_pp); 629169689Skan pp_cxx_left_bracket (cxx_pp); 63018334Speter if (TYPE_DOMAIN (t)) 63150397Sobrien { 63290075Sobrien if (host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0)) 633132718Skan pp_wide_integer 634169689Skan (cxx_pp, tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0) + 1); 63550397Sobrien else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR) 63690075Sobrien dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 637169689Skan flags & ~TFF_EXPR_IN_PARENS); 63850397Sobrien else 63990075Sobrien dump_expr (fold (cp_build_binary_op 64050397Sobrien (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 64190075Sobrien integer_one_node)), 642169689Skan flags & ~TFF_EXPR_IN_PARENS); 64350397Sobrien } 644169689Skan pp_cxx_right_bracket (cxx_pp); 64590075Sobrien dump_type_suffix (TREE_TYPE (t), flags); 64618334Speter break; 64790075Sobrien 64818334Speter case ENUMERAL_TYPE: 64918334Speter case IDENTIFIER_NODE: 65018334Speter case INTEGER_TYPE: 65118334Speter case BOOLEAN_TYPE: 65218334Speter case REAL_TYPE: 65318334Speter case RECORD_TYPE: 65418334Speter case TEMPLATE_TYPE_PARM: 65550397Sobrien case TEMPLATE_TEMPLATE_PARM: 65690075Sobrien case BOUND_TEMPLATE_TEMPLATE_PARM: 65718334Speter case TREE_LIST: 65818334Speter case TYPE_DECL: 65918334Speter case TREE_VEC: 66018334Speter case UNION_TYPE: 66118334Speter case UNKNOWN_TYPE: 66218334Speter case VOID_TYPE: 66350397Sobrien case TYPENAME_TYPE: 66450397Sobrien case COMPLEX_TYPE: 66590075Sobrien case VECTOR_TYPE: 666117395Skan case TYPEOF_TYPE: 66718334Speter break; 66818334Speter 66918334Speter default: 670132718Skan pp_unsupported_tree (cxx_pp, t); 67190075Sobrien case ERROR_MARK: 67290075Sobrien /* Don't mark it here, we should have already done in 673169689Skan dump_type_prefix. */ 67490075Sobrien break; 67518334Speter } 67618334Speter} 67718334Speter 67850397Sobrienstatic void 679132718Skandump_global_iord (tree t) 68018334Speter{ 68190075Sobrien const char *p = NULL; 68218334Speter 68390075Sobrien if (DECL_GLOBAL_CTOR_P (t)) 68490075Sobrien p = "initializers"; 68590075Sobrien else if (DECL_GLOBAL_DTOR_P (t)) 68690075Sobrien p = "destructors"; 68718334Speter else 688169689Skan gcc_unreachable (); 68990075Sobrien 690132718Skan pp_printf (pp_base (cxx_pp), "(static %s for %s)", p, input_filename); 69118334Speter} 69218334Speter 69318334Speterstatic void 694132718Skandump_simple_decl (tree t, tree type, int flags) 69550397Sobrien{ 69690075Sobrien if (flags & TFF_DECL_SPECIFIERS) 69750397Sobrien { 698169689Skan dump_type_prefix (type, flags); 699169689Skan pp_maybe_space (cxx_pp); 70050397Sobrien } 70190075Sobrien if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX) 70290075Sobrien dump_scope (CP_DECL_CONTEXT (t), flags); 70350397Sobrien if (DECL_NAME (t)) 70490075Sobrien dump_decl (DECL_NAME (t), flags); 70550397Sobrien else 706132718Skan pp_identifier (cxx_pp, "<anonymous>"); 70790075Sobrien if (flags & TFF_DECL_SPECIFIERS) 70890075Sobrien dump_type_suffix (type, flags); 70950397Sobrien} 71050397Sobrien 71190075Sobrien/* Dump a human readable string for the decl T under control of FLAGS. */ 71290075Sobrien 71350397Sobrienstatic void 714132718Skandump_decl (tree t, int flags) 71518334Speter{ 71618334Speter if (t == NULL_TREE) 71718334Speter return; 71818334Speter 71918334Speter switch (TREE_CODE (t)) 72018334Speter { 72118334Speter case TYPE_DECL: 722169689Skan /* Don't say 'typedef class A' */ 723169689Skan if (DECL_ARTIFICIAL (t)) 724169689Skan { 725169689Skan if ((flags & TFF_DECL_SPECIFIERS) 726169689Skan && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) 727169689Skan /* Say `class T' not just `T'. */ 728169689Skan pp_cxx_identifier (cxx_pp, "class"); 72950397Sobrien 730169689Skan dump_type (TREE_TYPE (t), flags); 731169689Skan break; 732169689Skan } 73390075Sobrien if (flags & TFF_DECL_SPECIFIERS) 734169689Skan pp_cxx_identifier (cxx_pp, "typedef"); 73590075Sobrien dump_simple_decl (t, DECL_ORIGINAL_TYPE (t) 73690075Sobrien ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), 737169689Skan flags); 73818334Speter break; 73990075Sobrien 74018334Speter case VAR_DECL: 74118334Speter if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t))) 74218334Speter { 743132718Skan pp_string (cxx_pp, "vtable for "); 744169689Skan gcc_assert (TYPE_P (DECL_CONTEXT (t))); 74590075Sobrien dump_type (DECL_CONTEXT (t), flags); 74618334Speter break; 74718334Speter } 748132718Skan /* Else fall through. */ 74918334Speter case FIELD_DECL: 75018334Speter case PARM_DECL: 75190075Sobrien dump_simple_decl (t, TREE_TYPE (t), flags); 75218334Speter break; 75318334Speter 75490075Sobrien case RESULT_DECL: 755132718Skan pp_string (cxx_pp, "<return value> "); 75690075Sobrien dump_simple_decl (t, TREE_TYPE (t), flags); 75790075Sobrien break; 75890075Sobrien 75918334Speter case NAMESPACE_DECL: 760132718Skan if (flags & TFF_DECL_SPECIFIERS) 761169689Skan pp_cxx_declaration (cxx_pp, t); 76252284Sobrien else 763169689Skan { 764169689Skan dump_scope (CP_DECL_CONTEXT (t), flags); 765169689Skan if (DECL_NAME (t) == NULL_TREE) 766169689Skan pp_identifier (cxx_pp, "<unnamed>"); 767169689Skan else 768169689Skan pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t)); 769169689Skan } 77018334Speter break; 77118334Speter 77250397Sobrien case SCOPE_REF: 773146895Skan pp_expression (cxx_pp, t); 77490075Sobrien break; 77550397Sobrien 77618334Speter case ARRAY_REF: 77790075Sobrien dump_decl (TREE_OPERAND (t, 0), flags); 778169689Skan pp_cxx_left_bracket (cxx_pp); 77990075Sobrien dump_decl (TREE_OPERAND (t, 1), flags); 780169689Skan pp_cxx_right_bracket (cxx_pp); 78118334Speter break; 78218334Speter 78390075Sobrien /* So that we can do dump_decl on an aggr type. */ 78418334Speter case RECORD_TYPE: 78518334Speter case UNION_TYPE: 78618334Speter case ENUMERAL_TYPE: 78790075Sobrien dump_type (t, flags); 78818334Speter break; 78918334Speter 790132718Skan case BIT_NOT_EXPR: 791132718Skan /* This is a pseudo destructor call which has not been folded into 792169689Skan a PSEUDO_DTOR_EXPR yet. */ 793169689Skan pp_cxx_complement (cxx_pp); 794132718Skan dump_type (TREE_OPERAND (t, 0), flags); 795132718Skan break; 796132718Skan 79718334Speter case TYPE_EXPR: 798169689Skan gcc_unreachable (); 79918334Speter break; 80018334Speter 80118334Speter /* These special cases are duplicated here so that other functions 80290075Sobrien can feed identifiers to error and get them demangled properly. */ 80318334Speter case IDENTIFIER_NODE: 80490075Sobrien if (IDENTIFIER_TYPENAME_P (t)) 80590075Sobrien { 806169689Skan pp_cxx_identifier (cxx_pp, "operator"); 80790075Sobrien /* Not exactly IDENTIFIER_TYPE_VALUE. */ 80890075Sobrien dump_type (TREE_TYPE (t), flags); 80990075Sobrien break; 81090075Sobrien } 81190075Sobrien else 812169689Skan pp_cxx_tree_identifier (cxx_pp, t); 81318334Speter break; 81418334Speter 81552284Sobrien case OVERLOAD: 816110611Skan if (OVL_CHAIN (t)) 817110611Skan { 818110611Skan t = OVL_CURRENT (t); 819110611Skan if (DECL_CLASS_SCOPE_P (t)) 820110611Skan { 821110611Skan dump_type (DECL_CONTEXT (t), flags); 822169689Skan pp_cxx_colon_colon (cxx_pp); 823110611Skan } 824110611Skan else if (DECL_CONTEXT (t)) 825110611Skan { 826110611Skan dump_decl (DECL_CONTEXT (t), flags); 827169689Skan pp_cxx_colon_colon (cxx_pp); 828110611Skan } 829110611Skan dump_decl (DECL_NAME (t), flags); 830110611Skan break; 831110611Skan } 832169689Skan 833110611Skan /* If there's only one function, just treat it like an ordinary 834110611Skan FUNCTION_DECL. */ 83552284Sobrien t = OVL_CURRENT (t); 83652284Sobrien /* Fall through. */ 83752284Sobrien 83818334Speter case FUNCTION_DECL: 839169689Skan if (! DECL_LANG_SPECIFIC (t)) 840169689Skan pp_identifier (cxx_pp, "<built-in>"); 841169689Skan else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t)) 84290075Sobrien dump_global_iord (t); 84318334Speter else 844169689Skan dump_function_decl (t, flags); 84518334Speter break; 84618334Speter 84718334Speter case TEMPLATE_DECL: 84890075Sobrien dump_template_decl (t, flags); 84918334Speter break; 85018334Speter 85150397Sobrien case TEMPLATE_ID_EXPR: 85250397Sobrien { 85350397Sobrien tree name = TREE_OPERAND (t, 0); 854169689Skan 85550397Sobrien if (is_overloaded_fn (name)) 85650397Sobrien name = DECL_NAME (get_first_fn (name)); 85790075Sobrien dump_decl (name, flags); 858169689Skan pp_cxx_begin_template_argument_list (cxx_pp); 859132718Skan if (TREE_OPERAND (t, 1)) 860132718Skan dump_template_argument_list (TREE_OPERAND (t, 1), flags); 861169689Skan pp_cxx_end_template_argument_list (cxx_pp); 86250397Sobrien } 86350397Sobrien break; 86450397Sobrien 86518334Speter case LABEL_DECL: 866169689Skan pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t)); 86718334Speter break; 86818334Speter 86918334Speter case CONST_DECL: 87050397Sobrien if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE) 87150397Sobrien || (DECL_INITIAL (t) && 87250397Sobrien TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX)) 87390075Sobrien dump_simple_decl (t, TREE_TYPE (t), flags); 87450397Sobrien else if (DECL_NAME (t)) 87590075Sobrien dump_decl (DECL_NAME (t), flags); 87650397Sobrien else if (DECL_INITIAL (t)) 87790075Sobrien dump_expr (DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS); 87818334Speter else 879132718Skan pp_identifier (cxx_pp, "<enumerator>"); 88018334Speter break; 88118334Speter 88250397Sobrien case USING_DECL: 883169689Skan pp_cxx_identifier (cxx_pp, "using"); 884169689Skan dump_type (USING_DECL_SCOPE (t), flags); 885169689Skan pp_cxx_colon_colon (cxx_pp); 886117395Skan dump_decl (DECL_NAME (t), flags); 88750397Sobrien break; 88850397Sobrien 889117395Skan case BASELINK: 890117395Skan dump_decl (BASELINK_FUNCTIONS (t), flags); 891117395Skan break; 892117395Skan 893132718Skan case NON_DEPENDENT_EXPR: 894132718Skan dump_expr (t, flags); 895132718Skan break; 896132718Skan 897132718Skan case TEMPLATE_TYPE_PARM: 898132718Skan if (flags & TFF_DECL_SPECIFIERS) 899169689Skan pp_cxx_declaration (cxx_pp, t); 900132718Skan else 901169689Skan pp_type_id (cxx_pp, t); 902132718Skan break; 903132718Skan 904220150Smm case UNBOUND_CLASS_TEMPLATE: 905220150Smm dump_type (t, flags); 906220150Smm break; 907220150Smm 90818334Speter default: 909132718Skan pp_unsupported_tree (cxx_pp, t); 910169689Skan /* Fall through to error. */ 91190075Sobrien 91290075Sobrien case ERROR_MARK: 913132718Skan pp_identifier (cxx_pp, "<declaration error>"); 91490075Sobrien break; 91518334Speter } 91618334Speter} 91718334Speter 91890075Sobrien/* Dump a template declaration T under control of FLAGS. This means the 91990075Sobrien 'template <...> leaders plus the 'class X' or 'void fn(...)' part. */ 92090075Sobrien 92190075Sobrienstatic void 922132718Skandump_template_decl (tree t, int flags) 92390075Sobrien{ 92490075Sobrien tree orig_parms = DECL_TEMPLATE_PARMS (t); 92590075Sobrien tree parms; 92690075Sobrien int i; 92790075Sobrien 92890075Sobrien if (flags & TFF_TEMPLATE_HEADER) 92990075Sobrien { 93090075Sobrien for (parms = orig_parms = nreverse (orig_parms); 931169689Skan parms; 932169689Skan parms = TREE_CHAIN (parms)) 933169689Skan { 93490075Sobrien tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms); 935169689Skan int len = TREE_VEC_LENGTH (inner_parms); 93690075Sobrien 937169689Skan pp_cxx_identifier (cxx_pp, "template"); 938169689Skan pp_cxx_begin_template_argument_list (cxx_pp); 93990075Sobrien 94090075Sobrien /* If we've shown the template prefix, we'd better show the 94190075Sobrien parameters' and decl's type too. */ 94290075Sobrien flags |= TFF_DECL_SPECIFIERS; 94390075Sobrien 944169689Skan for (i = 0; i < len; i++) 945169689Skan { 946169689Skan if (i) 947169689Skan pp_separate_with_comma (cxx_pp); 948169689Skan dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags); 949169689Skan } 950169689Skan pp_cxx_end_template_argument_list (cxx_pp); 951169689Skan pp_cxx_whitespace (cxx_pp); 952169689Skan } 95390075Sobrien nreverse(orig_parms); 95490075Sobrien 95590075Sobrien if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) 956117395Skan /* Say `template<arg> class TT' not just `template<arg> TT'. */ 957169689Skan pp_cxx_identifier (cxx_pp, "class"); 95890075Sobrien } 95990075Sobrien 96090075Sobrien if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) 96190075Sobrien dump_type (TREE_TYPE (t), 962169689Skan ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME 963169689Skan | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0))); 96490075Sobrien else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL) 96590075Sobrien dump_decl (DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME); 96690075Sobrien else 96790075Sobrien { 968169689Skan gcc_assert (TREE_TYPE (t)); 969169689Skan switch (NEXT_CODE (t)) 970169689Skan { 971169689Skan case METHOD_TYPE: 972169689Skan case FUNCTION_TYPE: 973169689Skan dump_function_decl (t, flags | TFF_TEMPLATE_NAME); 974169689Skan break; 975169689Skan default: 976169689Skan /* This case can occur with some invalid code. */ 977169689Skan dump_type (TREE_TYPE (t), 978169689Skan (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME 979169689Skan | (flags & TFF_DECL_SPECIFIERS 980169689Skan ? TFF_CLASS_KEY_OR_ENUM : 0)); 981169689Skan } 98290075Sobrien } 98390075Sobrien} 98490075Sobrien 98552284Sobrien/* Pretty print a function decl. There are several ways we want to print a 98690075Sobrien function declaration. The TFF_ bits in FLAGS tells us how to behave. 98790075Sobrien As error can only apply the '#' flag once to give 0 and 1 for V, there 988117395Skan is %D which doesn't print the throw specs, and %F which does. */ 98918334Speter 99018334Speterstatic void 991132718Skandump_function_decl (tree t, int flags) 99218334Speter{ 99350397Sobrien tree fntype; 99450397Sobrien tree parmtypes; 99518334Speter tree cname = NULL_TREE; 99690075Sobrien tree template_args = NULL_TREE; 99790075Sobrien tree template_parms = NULL_TREE; 99890075Sobrien int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS; 99918334Speter 100050397Sobrien if (TREE_CODE (t) == TEMPLATE_DECL) 100150397Sobrien t = DECL_TEMPLATE_RESULT (t); 100250397Sobrien 100390075Sobrien /* Pretty print template instantiations only. */ 100490075Sobrien if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t)) 100590075Sobrien { 100690075Sobrien tree tmpl; 100790075Sobrien 100890075Sobrien template_args = DECL_TI_ARGS (t); 100990075Sobrien tmpl = most_general_template (t); 101090075Sobrien if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL) 101190075Sobrien { 101290075Sobrien template_parms = DECL_TEMPLATE_PARMS (tmpl); 101390075Sobrien t = tmpl; 101490075Sobrien } 101590075Sobrien } 101690075Sobrien 101750397Sobrien fntype = TREE_TYPE (t); 101890075Sobrien parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t); 101950397Sobrien 102052284Sobrien if (DECL_CLASS_SCOPE_P (t)) 102190075Sobrien cname = DECL_CONTEXT (t); 1022132718Skan /* This is for partially instantiated template methods. */ 102318334Speter else if (TREE_CODE (fntype) == METHOD_TYPE) 102418334Speter cname = TREE_TYPE (TREE_VALUE (parmtypes)); 102518334Speter 102690075Sobrien if (!(flags & TFF_DECL_SPECIFIERS)) 102790075Sobrien /* OK */; 102890075Sobrien else if (DECL_STATIC_FUNCTION_P (t)) 1029169689Skan pp_cxx_identifier (cxx_pp, "static"); 103090075Sobrien else if (DECL_VIRTUAL_P (t)) 1031169689Skan pp_cxx_identifier (cxx_pp, "virtual"); 103290075Sobrien 103390075Sobrien /* Print the return type? */ 103490075Sobrien if (show_return) 103590075Sobrien show_return = !DECL_CONV_FN_P (t) && !DECL_CONSTRUCTOR_P (t) 1036169689Skan && !DECL_DESTRUCTOR_P (t); 103790075Sobrien if (show_return) 1038169689Skan dump_type_prefix (TREE_TYPE (fntype), flags); 103918334Speter 104052284Sobrien /* Print the function name. */ 104118334Speter if (cname) 104218334Speter { 104390075Sobrien dump_type (cname, flags); 1044169689Skan pp_cxx_colon_colon (cxx_pp); 104518334Speter } 104690075Sobrien else 104790075Sobrien dump_scope (CP_DECL_CONTEXT (t), flags); 104890075Sobrien 104990075Sobrien dump_function_name (t, flags); 105090075Sobrien 1051132718Skan if (!(flags & TFF_NO_FUNCTION_ARGUMENTS)) 105252284Sobrien { 105390075Sobrien dump_parameters (parmtypes, flags); 105418334Speter 105590075Sobrien if (TREE_CODE (fntype) == METHOD_TYPE) 1056169689Skan { 1057169689Skan pp_base (cxx_pp)->padding = pp_before; 1058169689Skan pp_cxx_cv_qualifier_seq 1059169689Skan (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype)))); 1060169689Skan } 106118334Speter 106290075Sobrien if (flags & TFF_EXCEPTION_SPECIFICATION) 1063169689Skan { 1064169689Skan pp_base (cxx_pp)->padding = pp_before; 1065169689Skan dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags); 1066169689Skan } 106718334Speter 106890075Sobrien if (show_return) 106990075Sobrien dump_type_suffix (TREE_TYPE (fntype), flags); 107090075Sobrien } 107118334Speter 107290075Sobrien /* If T is a template instantiation, dump the parameter binding. */ 107390075Sobrien if (template_parms != NULL_TREE && template_args != NULL_TREE) 107418334Speter { 1075169689Skan pp_cxx_whitespace (cxx_pp); 1076169689Skan pp_cxx_left_bracket (cxx_pp); 1077169689Skan pp_cxx_identifier (cxx_pp, "with"); 1078169689Skan pp_cxx_whitespace (cxx_pp); 107990075Sobrien dump_template_bindings (template_parms, template_args); 1080169689Skan pp_cxx_right_bracket (cxx_pp); 108118334Speter } 108218334Speter} 108318334Speter 108490075Sobrien/* Print a parameter list. If this is for a member function, the 108590075Sobrien member object ptr (and any other hidden args) should have 1086117395Skan already been removed. */ 108752284Sobrien 108852284Sobrienstatic void 1089132718Skandump_parameters (tree parmtypes, int flags) 109052284Sobrien{ 109152284Sobrien int first; 109252284Sobrien 1093169689Skan pp_cxx_left_paren (cxx_pp); 109490075Sobrien 109552284Sobrien for (first = 1; parmtypes != void_list_node; 109652284Sobrien parmtypes = TREE_CHAIN (parmtypes)) 109752284Sobrien { 109852284Sobrien if (!first) 1099169689Skan pp_separate_with_comma (cxx_pp); 110052284Sobrien first = 0; 110152284Sobrien if (!parmtypes) 1102169689Skan { 1103169689Skan pp_cxx_identifier (cxx_pp, "..."); 1104169689Skan break; 1105169689Skan } 110690075Sobrien dump_type (TREE_VALUE (parmtypes), flags); 110790075Sobrien 110890075Sobrien if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes)) 1109169689Skan { 1110169689Skan pp_cxx_whitespace (cxx_pp); 1111169689Skan pp_equal (cxx_pp); 1112169689Skan pp_cxx_whitespace (cxx_pp); 1113169689Skan dump_expr (TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS); 1114169689Skan } 111552284Sobrien } 111652284Sobrien 1117169689Skan pp_cxx_right_paren (cxx_pp); 111852284Sobrien} 111952284Sobrien 1120117395Skan/* Print an exception specification. T is the exception specification. */ 112152284Sobrien 112252284Sobrienstatic void 1123132718Skandump_exception_spec (tree t, int flags) 112452284Sobrien{ 112552284Sobrien if (t) 112652284Sobrien { 1127169689Skan pp_cxx_identifier (cxx_pp, "throw"); 1128169689Skan pp_cxx_whitespace (cxx_pp); 1129169689Skan pp_cxx_left_paren (cxx_pp); 113052284Sobrien if (TREE_VALUE (t) != NULL_TREE) 1131169689Skan while (1) 1132169689Skan { 1133169689Skan dump_type (TREE_VALUE (t), flags); 1134169689Skan t = TREE_CHAIN (t); 1135169689Skan if (!t) 1136169689Skan break; 1137169689Skan pp_separate_with_comma (cxx_pp); 1138169689Skan } 1139169689Skan pp_cxx_right_paren (cxx_pp); 114052284Sobrien } 114152284Sobrien} 114252284Sobrien 114318334Speter/* Handle the function name for a FUNCTION_DECL node, grokking operators 114418334Speter and destructors properly. */ 114550397Sobrien 114618334Speterstatic void 1147132718Skandump_function_name (tree t, int flags) 114818334Speter{ 114918334Speter tree name = DECL_NAME (t); 115018334Speter 1151169689Skan /* We can get here with a decl that was synthesized by language- 1152169689Skan independent machinery (e.g. coverage.c) in which case it won't 1153169689Skan have a lang_specific structure attached and DECL_CONSTRUCTOR_P 1154169689Skan will crash. In this case it is safe just to print out the 1155169689Skan literal name. */ 1156169689Skan if (!DECL_LANG_SPECIFIC (t)) 1157169689Skan { 1158169689Skan pp_cxx_tree_identifier (cxx_pp, name); 1159169689Skan return; 1160169689Skan } 1161169689Skan 1162117395Skan if (TREE_CODE (t) == TEMPLATE_DECL) 1163117395Skan t = DECL_TEMPLATE_RESULT (t); 1164117395Skan 116590075Sobrien /* Don't let the user see __comp_ctor et al. */ 116690075Sobrien if (DECL_CONSTRUCTOR_P (t) 116790075Sobrien || DECL_DESTRUCTOR_P (t)) 116890075Sobrien name = constructor_name (DECL_CONTEXT (t)); 116990075Sobrien 117052284Sobrien if (DECL_DESTRUCTOR_P (t)) 117118334Speter { 1172169689Skan pp_cxx_complement (cxx_pp); 117390075Sobrien dump_decl (name, TFF_PLAIN_IDENTIFIER); 117418334Speter } 117552284Sobrien else if (DECL_CONV_FN_P (t)) 117618334Speter { 117718334Speter /* This cannot use the hack that the operator's return 117818334Speter type is stashed off of its name because it may be 117918334Speter used for error reporting. In the case of conflicting 118018334Speter declarations, both will have the same name, yet 118118334Speter the types will be different, hence the TREE_TYPE field 118218334Speter of the first name will be clobbered by the second. */ 1183169689Skan pp_cxx_identifier (cxx_pp, "operator"); 118490075Sobrien dump_type (TREE_TYPE (TREE_TYPE (t)), flags); 118518334Speter } 118618334Speter else if (IDENTIFIER_OPNAME_P (name)) 1187169689Skan pp_cxx_tree_identifier (cxx_pp, name); 118818334Speter else 118990075Sobrien dump_decl (name, flags); 119050397Sobrien 1191169689Skan if (DECL_TEMPLATE_INFO (t) 119290075Sobrien && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t) 1193169689Skan && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL 119452284Sobrien || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))) 119590075Sobrien dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags); 119690075Sobrien} 119790075Sobrien 119890075Sobrien/* Dump the template parameters from the template info INFO under control of 119990075Sobrien FLAGS. PRIMARY indicates whether this is a primary template decl, or 120090075Sobrien specialization (partial or complete). For partial specializations we show 120190075Sobrien the specialized parameter values. For a primary template we show no 120290075Sobrien decoration. */ 120390075Sobrien 120490075Sobrienstatic void 1205132718Skandump_template_parms (tree info, int primary, int flags) 120690075Sobrien{ 120790075Sobrien tree args = info ? TI_ARGS (info) : NULL_TREE; 120890075Sobrien 120990075Sobrien if (primary && flags & TFF_TEMPLATE_NAME) 121090075Sobrien return; 121190075Sobrien flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME); 1212169689Skan pp_cxx_begin_template_argument_list (cxx_pp); 121390075Sobrien 121490075Sobrien /* Be careful only to print things when we have them, so as not 121590075Sobrien to crash producing error messages. */ 121690075Sobrien if (args && !primary) 121750397Sobrien { 1218132718Skan int len, ix; 121950397Sobrien 1220132718Skan if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) 1221132718Skan args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1); 1222169689Skan 1223132718Skan len = TREE_VEC_LENGTH (args); 1224132718Skan 1225132718Skan for (ix = 0; ix != len; ix++) 1226169689Skan { 1227169689Skan tree arg = TREE_VEC_ELT (args, ix); 122890075Sobrien 1229169689Skan if (ix) 1230169689Skan pp_separate_with_comma (cxx_pp); 1231169689Skan 1232169689Skan if (!arg) 1233169689Skan pp_identifier (cxx_pp, "<template parameter error>"); 1234169689Skan else 1235169689Skan dump_template_argument (arg, flags); 1236169689Skan } 123750397Sobrien } 123890075Sobrien else if (primary) 123990075Sobrien { 124090075Sobrien tree tpl = TI_TEMPLATE (info); 124190075Sobrien tree parms = DECL_TEMPLATE_PARMS (tpl); 124290075Sobrien int len, ix; 124390075Sobrien 124490075Sobrien parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE; 124590075Sobrien len = parms ? TREE_VEC_LENGTH (parms) : 0; 124690075Sobrien 124790075Sobrien for (ix = 0; ix != len; ix++) 1248169689Skan { 1249169689Skan tree parm; 125090075Sobrien 1251169689Skan if (TREE_VEC_ELT (parms, ix) == error_mark_node) 1252169689Skan { 1253169689Skan pp_identifier (cxx_pp, "<template parameter error>"); 1254169689Skan continue; 1255169689Skan } 125690075Sobrien 1257169689Skan parm = TREE_VALUE (TREE_VEC_ELT (parms, ix)); 1258169689Skan 1259169689Skan if (ix) 1260169689Skan pp_separate_with_comma (cxx_pp); 1261169689Skan 1262169689Skan dump_decl (parm, flags & ~TFF_DECL_SPECIFIERS); 1263169689Skan } 126490075Sobrien } 1265169689Skan pp_cxx_end_template_argument_list (cxx_pp); 126618334Speter} 126718334Speter 1268132718Skan/* Print out a list of initializers (subr of dump_expr). */ 126918334Speter 127018334Speterstatic void 1271132718Skandump_expr_list (tree l, int flags) 127218334Speter{ 127318334Speter while (l) 127418334Speter { 127590075Sobrien dump_expr (TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS); 127618334Speter l = TREE_CHAIN (l); 127790075Sobrien if (l) 1278132718Skan pp_separate_with_comma (cxx_pp); 127918334Speter } 128018334Speter} 128118334Speter 1282169689Skan/* Print out a vector of initializers (subr of dump_expr). */ 1283169689Skan 1284169689Skanstatic void 1285169689Skandump_expr_init_vec (VEC(constructor_elt,gc) *v, int flags) 1286169689Skan{ 1287169689Skan unsigned HOST_WIDE_INT idx; 1288169689Skan tree value; 1289169689Skan 1290169689Skan FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value) 1291169689Skan { 1292169689Skan dump_expr (value, flags | TFF_EXPR_IN_PARENS); 1293169689Skan if (idx != VEC_length (constructor_elt, v) - 1) 1294169689Skan pp_separate_with_comma (cxx_pp); 1295169689Skan } 1296169689Skan} 1297169689Skan 1298169689Skan 1299169689Skan/* We've gotten an indirect REFERENCE (an OBJ_TYPE_REF) to a virtual 1300169689Skan function. Resolve it to a close relative -- in the sense of static 1301169689Skan type -- variant being overridden. That is close to what was written in 1302169689Skan the source code. Subroutine of dump_expr. */ 1303169689Skan 1304169689Skanstatic tree 1305169689Skanresolve_virtual_fun_from_obj_type_ref (tree ref) 1306169689Skan{ 1307169689Skan tree obj_type = TREE_TYPE (OBJ_TYPE_REF_OBJECT (ref)); 1308220150Smm HOST_WIDE_INT index = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1); 1309169689Skan tree fun = BINFO_VIRTUALS (TYPE_BINFO (TREE_TYPE (obj_type))); 1310220150Smm while (index) 1311220150Smm { 1312169689Skan fun = TREE_CHAIN (fun); 1313220150Smm index -= (TARGET_VTABLE_USES_DESCRIPTORS 1314220150Smm ? TARGET_VTABLE_USES_DESCRIPTORS : 1); 1315220150Smm } 1316169689Skan 1317169689Skan return BV_FN (fun); 1318169689Skan} 1319169689Skan 1320117395Skan/* Print out an expression E under control of FLAGS. */ 132150397Sobrien 132218334Speterstatic void 1323132718Skandump_expr (tree t, int flags) 132418334Speter{ 1325117395Skan if (t == 0) 1326117395Skan return; 1327169689Skan 132818334Speter switch (TREE_CODE (t)) 132918334Speter { 133018334Speter case VAR_DECL: 133118334Speter case PARM_DECL: 133218334Speter case FIELD_DECL: 133318334Speter case CONST_DECL: 133418334Speter case FUNCTION_DECL: 133550397Sobrien case TEMPLATE_DECL: 133650397Sobrien case NAMESPACE_DECL: 1337161651Skan case LABEL_DECL: 133890075Sobrien case OVERLOAD: 1339132718Skan case IDENTIFIER_NODE: 1340132718Skan dump_decl (t, (flags & ~TFF_DECL_SPECIFIERS) | TFF_NO_FUNCTION_ARGUMENTS); 134118334Speter break; 134218334Speter 134318334Speter case INTEGER_CST: 1344169689Skan case REAL_CST: 1345132718Skan case STRING_CST: 1346169689Skan pp_constant (cxx_pp, t); 134718334Speter break; 134818334Speter 1349132718Skan case THROW_EXPR: 1350169689Skan pp_cxx_identifier (cxx_pp, "throw"); 1351132718Skan dump_expr (TREE_OPERAND (t, 0), flags); 135218334Speter break; 135318334Speter 135452284Sobrien case PTRMEM_CST: 1355132718Skan pp_ampersand (cxx_pp); 135690075Sobrien dump_type (PTRMEM_CST_CLASS (t), flags); 1357169689Skan pp_cxx_colon_colon (cxx_pp); 1358169689Skan pp_cxx_tree_identifier (cxx_pp, DECL_NAME (PTRMEM_CST_MEMBER (t))); 135952284Sobrien break; 136052284Sobrien 136118334Speter case COMPOUND_EXPR: 1362169689Skan pp_cxx_left_paren (cxx_pp); 136390075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1364132718Skan pp_separate_with_comma (cxx_pp); 136590075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 1366169689Skan pp_cxx_right_paren (cxx_pp); 136718334Speter break; 136818334Speter 136918334Speter case COND_EXPR: 1370169689Skan pp_cxx_left_paren (cxx_pp); 137190075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1372132718Skan pp_string (cxx_pp, " ? "); 137390075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 1374132718Skan pp_string (cxx_pp, " : "); 137590075Sobrien dump_expr (TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS); 1376169689Skan pp_cxx_right_paren (cxx_pp); 137718334Speter break; 137818334Speter 137918334Speter case SAVE_EXPR: 138018334Speter if (TREE_HAS_CONSTRUCTOR (t)) 138118334Speter { 1382169689Skan pp_cxx_identifier (cxx_pp, "new"); 1383169689Skan pp_cxx_whitespace (cxx_pp); 138490075Sobrien dump_type (TREE_TYPE (TREE_TYPE (t)), flags); 138518334Speter } 138618334Speter else 1387169689Skan dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 138818334Speter break; 138918334Speter 139050397Sobrien case AGGR_INIT_EXPR: 139190075Sobrien { 139290075Sobrien tree fn = NULL_TREE; 139390075Sobrien 139490075Sobrien if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR) 139590075Sobrien fn = TREE_OPERAND (TREE_OPERAND (t, 0), 0); 139690075Sobrien 139790075Sobrien if (fn && TREE_CODE (fn) == FUNCTION_DECL) 139890075Sobrien { 139990075Sobrien if (DECL_CONSTRUCTOR_P (fn)) 1400169689Skan dump_type (DECL_CONTEXT (fn), flags); 140190075Sobrien else 140290075Sobrien dump_decl (fn, 0); 140390075Sobrien } 140490075Sobrien else 140590075Sobrien dump_expr (TREE_OPERAND (t, 0), 0); 140690075Sobrien } 1407169689Skan pp_cxx_left_paren (cxx_pp); 140850397Sobrien if (TREE_OPERAND (t, 1)) 140990075Sobrien dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags); 1410169689Skan pp_cxx_right_paren (cxx_pp); 141118334Speter break; 141218334Speter 141318334Speter case CALL_EXPR: 141418334Speter { 141518334Speter tree fn = TREE_OPERAND (t, 0); 141618334Speter tree args = TREE_OPERAND (t, 1); 141790075Sobrien 141818334Speter if (TREE_CODE (fn) == ADDR_EXPR) 141918334Speter fn = TREE_OPERAND (fn, 0); 142018334Speter 1421169689Skan /* Nobody is interested in seeing the guts of vcalls. */ 1422169689Skan if (TREE_CODE (fn) == OBJ_TYPE_REF) 1423169689Skan fn = resolve_virtual_fun_from_obj_type_ref (fn); 1424169689Skan 142550397Sobrien if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE) 142618334Speter { 142718334Speter tree ob = TREE_VALUE (args); 142818334Speter if (TREE_CODE (ob) == ADDR_EXPR) 142918334Speter { 143090075Sobrien dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS); 1431220150Smm pp_cxx_dot (cxx_pp); 143218334Speter } 143318334Speter else if (TREE_CODE (ob) != PARM_DECL 143418334Speter || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) 143518334Speter { 143690075Sobrien dump_expr (ob, flags | TFF_EXPR_IN_PARENS); 1437220150Smm pp_cxx_arrow (cxx_pp); 143818334Speter } 143918334Speter args = TREE_CHAIN (args); 144018334Speter } 144190075Sobrien dump_expr (fn, flags | TFF_EXPR_IN_PARENS); 1442169689Skan pp_cxx_left_paren (cxx_pp); 144390075Sobrien dump_expr_list (args, flags); 1444169689Skan pp_cxx_right_paren (cxx_pp); 144518334Speter } 144618334Speter break; 144718334Speter 144850397Sobrien case NEW_EXPR: 144950397Sobrien { 145050397Sobrien tree type = TREE_OPERAND (t, 1); 1451117395Skan tree init = TREE_OPERAND (t, 2); 145250397Sobrien if (NEW_EXPR_USE_GLOBAL (t)) 1453169689Skan pp_cxx_colon_colon (cxx_pp); 1454169689Skan pp_cxx_identifier (cxx_pp, "new"); 145550397Sobrien if (TREE_OPERAND (t, 0)) 145650397Sobrien { 1457169689Skan pp_cxx_left_paren (cxx_pp); 145890075Sobrien dump_expr_list (TREE_OPERAND (t, 0), flags); 1459169689Skan pp_cxx_right_paren (cxx_pp); 1460169689Skan pp_cxx_whitespace (cxx_pp); 146150397Sobrien } 146250397Sobrien if (TREE_CODE (type) == ARRAY_REF) 146350397Sobrien type = build_cplus_array_type 146450397Sobrien (TREE_OPERAND (type, 0), 1465169689Skan build_index_type (fold_build2 (MINUS_EXPR, integer_type_node, 146690075Sobrien TREE_OPERAND (type, 1), 1467169689Skan integer_one_node))); 146890075Sobrien dump_type (type, flags); 1469117395Skan if (init) 147050397Sobrien { 1471169689Skan pp_cxx_left_paren (cxx_pp); 1472117395Skan if (TREE_CODE (init) == TREE_LIST) 1473117395Skan dump_expr_list (init, flags); 1474117395Skan else if (init == void_zero_node) 1475117395Skan /* This representation indicates an empty initializer, 1476117395Skan e.g.: "new int()". */ 1477117395Skan ; 1478117395Skan else 1479117395Skan dump_expr (init, flags); 1480169689Skan pp_cxx_right_paren (cxx_pp); 148150397Sobrien } 148250397Sobrien } 148318334Speter break; 148418334Speter 148518334Speter case TARGET_EXPR: 148618334Speter /* Note that this only works for G++ target exprs. If somebody 148718334Speter builds a general TARGET_EXPR, there's no way to represent that 148818334Speter it initializes anything other that the parameter slot for the 148918334Speter default argument. Note we may have cleared out the first 149018334Speter operand in expand_expr, so don't go killing ourselves. */ 149118334Speter if (TREE_OPERAND (t, 1)) 149290075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 149318334Speter break; 149418334Speter 149590075Sobrien case INIT_EXPR: 149618334Speter case MODIFY_EXPR: 149718334Speter case PLUS_EXPR: 149818334Speter case MINUS_EXPR: 149918334Speter case MULT_EXPR: 150018334Speter case TRUNC_DIV_EXPR: 150118334Speter case TRUNC_MOD_EXPR: 150218334Speter case MIN_EXPR: 150318334Speter case MAX_EXPR: 150418334Speter case LSHIFT_EXPR: 150518334Speter case RSHIFT_EXPR: 150618334Speter case BIT_IOR_EXPR: 150718334Speter case BIT_XOR_EXPR: 150818334Speter case BIT_AND_EXPR: 150918334Speter case TRUTH_ANDIF_EXPR: 151018334Speter case TRUTH_ORIF_EXPR: 151118334Speter case LT_EXPR: 151218334Speter case LE_EXPR: 151318334Speter case GT_EXPR: 151418334Speter case GE_EXPR: 151518334Speter case EQ_EXPR: 151618334Speter case NE_EXPR: 151790075Sobrien case EXACT_DIV_EXPR: 151890075Sobrien dump_binary_op (operator_name_info[(int) TREE_CODE (t)].name, t, flags); 151918334Speter break; 152018334Speter 152118334Speter case CEIL_DIV_EXPR: 152218334Speter case FLOOR_DIV_EXPR: 152318334Speter case ROUND_DIV_EXPR: 1524146895Skan case RDIV_EXPR: 152590075Sobrien dump_binary_op ("/", t, flags); 152618334Speter break; 152718334Speter 152818334Speter case CEIL_MOD_EXPR: 152918334Speter case FLOOR_MOD_EXPR: 153018334Speter case ROUND_MOD_EXPR: 153190075Sobrien dump_binary_op ("%", t, flags); 153218334Speter break; 153318334Speter 153418334Speter case COMPONENT_REF: 153518334Speter { 153618334Speter tree ob = TREE_OPERAND (t, 0); 153718334Speter if (TREE_CODE (ob) == INDIRECT_REF) 153818334Speter { 153918334Speter ob = TREE_OPERAND (ob, 0); 154018334Speter if (TREE_CODE (ob) != PARM_DECL 1541169689Skan || (DECL_NAME (ob) 1542169689Skan && strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))) 154318334Speter { 154490075Sobrien dump_expr (ob, flags | TFF_EXPR_IN_PARENS); 1545169689Skan pp_cxx_arrow (cxx_pp); 154618334Speter } 154718334Speter } 154818334Speter else 154918334Speter { 155090075Sobrien dump_expr (ob, flags | TFF_EXPR_IN_PARENS); 1551169689Skan pp_cxx_dot (cxx_pp); 155218334Speter } 155390075Sobrien dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS); 155418334Speter } 155518334Speter break; 155618334Speter 155718334Speter case ARRAY_REF: 155890075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1559169689Skan pp_cxx_left_bracket (cxx_pp); 156090075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 1561169689Skan pp_cxx_right_bracket (cxx_pp); 156218334Speter break; 156318334Speter 1564169689Skan case UNARY_PLUS_EXPR: 1565169689Skan dump_unary_op ("+", t, flags); 156618334Speter break; 156718334Speter 156818334Speter case ADDR_EXPR: 156918334Speter if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL 157090075Sobrien || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST 157190075Sobrien /* An ADDR_EXPR can have reference type. In that case, we 157290075Sobrien shouldn't print the `&' doing so indicates to the user 157390075Sobrien that the expression has pointer type. */ 157490075Sobrien || (TREE_TYPE (t) 157590075Sobrien && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)) 157690075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1577161651Skan else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL) 1578161651Skan dump_unary_op ("&&", t, flags); 157918334Speter else 158090075Sobrien dump_unary_op ("&", t, flags); 158118334Speter break; 158218334Speter 158318334Speter case INDIRECT_REF: 158418334Speter if (TREE_HAS_CONSTRUCTOR (t)) 158518334Speter { 158618334Speter t = TREE_OPERAND (t, 0); 1587169689Skan gcc_assert (TREE_CODE (t) == CALL_EXPR); 158890075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1589169689Skan pp_cxx_left_paren (cxx_pp); 159090075Sobrien dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags); 1591169689Skan pp_cxx_right_paren (cxx_pp); 159218334Speter } 159318334Speter else 159418334Speter { 159550397Sobrien if (TREE_OPERAND (t,0) != NULL_TREE 159652284Sobrien && TREE_TYPE (TREE_OPERAND (t, 0)) 159750397Sobrien && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE) 159890075Sobrien dump_expr (TREE_OPERAND (t, 0), flags); 159918334Speter else 160090075Sobrien dump_unary_op ("*", t, flags); 160118334Speter } 160218334Speter break; 160318334Speter 160418334Speter case NEGATE_EXPR: 160518334Speter case BIT_NOT_EXPR: 160618334Speter case TRUTH_NOT_EXPR: 160718334Speter case PREDECREMENT_EXPR: 160818334Speter case PREINCREMENT_EXPR: 160990075Sobrien dump_unary_op (operator_name_info [(int)TREE_CODE (t)].name, t, flags); 161018334Speter break; 161118334Speter 161218334Speter case POSTDECREMENT_EXPR: 161318334Speter case POSTINCREMENT_EXPR: 1614169689Skan pp_cxx_left_paren (cxx_pp); 161590075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1616169689Skan pp_cxx_identifier (cxx_pp, operator_name_info[(int)TREE_CODE (t)].name); 1617169689Skan pp_cxx_right_paren (cxx_pp); 161818334Speter break; 161918334Speter 162018334Speter case NON_LVALUE_EXPR: 162118334Speter /* FIXME: This is a KLUDGE workaround for a parsing problem. There 162218334Speter should be another level of INDIRECT_REF so that I don't have to do 162318334Speter this. */ 162450397Sobrien if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE) 162518334Speter { 162618334Speter tree next = TREE_TYPE (TREE_TYPE (t)); 162718334Speter 162818334Speter while (TREE_CODE (next) == POINTER_TYPE) 162918334Speter next = TREE_TYPE (next); 163090075Sobrien 163118334Speter if (TREE_CODE (next) == FUNCTION_TYPE) 163218334Speter { 163390075Sobrien if (flags & TFF_EXPR_IN_PARENS) 1634169689Skan pp_cxx_left_paren (cxx_pp); 1635169689Skan pp_cxx_star (cxx_pp); 163690075Sobrien dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); 163790075Sobrien if (flags & TFF_EXPR_IN_PARENS) 1638169689Skan pp_cxx_right_paren (cxx_pp); 163918334Speter break; 164018334Speter } 1641132718Skan /* Else fall through. */ 164218334Speter } 164390075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 164418334Speter break; 164518334Speter 164618334Speter case NOP_EXPR: 1647169689Skan case CONVERT_EXPR: 1648132718Skan { 1649132718Skan tree op = TREE_OPERAND (t, 0); 1650169689Skan 1651132718Skan if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t))) 1652132718Skan { 1653132718Skan /* It is a cast, but we cannot tell whether it is a 1654132718Skan reinterpret or static cast. Use the C style notation. */ 1655132718Skan if (flags & TFF_EXPR_IN_PARENS) 1656169689Skan pp_cxx_left_paren (cxx_pp); 1657169689Skan pp_cxx_left_paren (cxx_pp); 1658132718Skan dump_type (TREE_TYPE (t), flags); 1659169689Skan pp_cxx_right_paren (cxx_pp); 1660132718Skan dump_expr (op, flags | TFF_EXPR_IN_PARENS); 1661132718Skan if (flags & TFF_EXPR_IN_PARENS) 1662169689Skan pp_cxx_right_paren (cxx_pp); 1663132718Skan } 1664132718Skan else 1665132718Skan dump_expr (op, flags); 1666132718Skan break; 1667132718Skan } 166890075Sobrien 166918334Speter case CONSTRUCTOR: 167050397Sobrien if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) 167150397Sobrien { 1672117395Skan tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier); 167350397Sobrien 167490075Sobrien if (integer_zerop (idx)) 167550397Sobrien { 167652284Sobrien /* A NULL pointer-to-member constant. */ 1677169689Skan pp_cxx_left_paren (cxx_pp); 1678169689Skan pp_cxx_left_paren (cxx_pp); 167990075Sobrien dump_type (TREE_TYPE (t), flags); 1680169689Skan pp_cxx_right_paren (cxx_pp); 1681169689Skan pp_character (cxx_pp, '0'); 1682169689Skan pp_cxx_right_paren (cxx_pp); 168352284Sobrien break; 168452284Sobrien } 168590075Sobrien else if (host_integerp (idx, 0)) 168652284Sobrien { 168750397Sobrien tree virtuals; 168850397Sobrien unsigned HOST_WIDE_INT n; 168950397Sobrien 169050397Sobrien t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t))); 169150397Sobrien t = TYPE_METHOD_BASETYPE (t); 1692169689Skan virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t))); 169350397Sobrien 169490075Sobrien n = tree_low_cst (idx, 0); 169590075Sobrien 169650397Sobrien /* Map vtable index back one, to allow for the null pointer to 169750397Sobrien member. */ 169850397Sobrien --n; 169950397Sobrien 170050397Sobrien while (n > 0 && virtuals) 170150397Sobrien { 170250397Sobrien --n; 170350397Sobrien virtuals = TREE_CHAIN (virtuals); 170450397Sobrien } 170550397Sobrien if (virtuals) 170650397Sobrien { 170790075Sobrien dump_expr (BV_FN (virtuals), 1708169689Skan flags | TFF_EXPR_IN_PARENS); 170950397Sobrien break; 171050397Sobrien } 171150397Sobrien } 171250397Sobrien } 1713169689Skan if (TREE_TYPE (t) && EMPTY_CONSTRUCTOR_P (t)) 1714132718Skan { 1715132718Skan dump_type (TREE_TYPE (t), 0); 1716169689Skan pp_cxx_left_paren (cxx_pp); 1717169689Skan pp_cxx_right_paren (cxx_pp); 1718132718Skan } 1719117395Skan else 1720132718Skan { 1721169689Skan pp_cxx_left_brace (cxx_pp); 1722169689Skan dump_expr_init_vec (CONSTRUCTOR_ELTS (t), flags); 1723169689Skan pp_cxx_right_brace (cxx_pp); 1724132718Skan } 1725169689Skan 172618334Speter break; 172718334Speter 172818334Speter case OFFSET_REF: 172918334Speter { 173018334Speter tree ob = TREE_OPERAND (t, 0); 173152284Sobrien if (is_dummy_object (ob)) 173252284Sobrien { 173352284Sobrien t = TREE_OPERAND (t, 1); 173452284Sobrien if (TREE_CODE (t) == FUNCTION_DECL) 173552284Sobrien /* A::f */ 173690075Sobrien dump_expr (t, flags | TFF_EXPR_IN_PARENS); 173752284Sobrien else if (BASELINK_P (t)) 1738169689Skan dump_expr (OVL_CURRENT (BASELINK_FUNCTIONS (t)), 1739117395Skan flags | TFF_EXPR_IN_PARENS); 174052284Sobrien else 174190075Sobrien dump_decl (t, flags); 174252284Sobrien } 174318334Speter else 174418334Speter { 174552284Sobrien if (TREE_CODE (ob) == INDIRECT_REF) 174652284Sobrien { 174790075Sobrien dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS); 1748169689Skan pp_cxx_arrow (cxx_pp); 1749169689Skan pp_cxx_star (cxx_pp); 175052284Sobrien } 175152284Sobrien else 175252284Sobrien { 175390075Sobrien dump_expr (ob, flags | TFF_EXPR_IN_PARENS); 1754169689Skan pp_cxx_dot (cxx_pp); 1755169689Skan pp_cxx_star (cxx_pp); 175652284Sobrien } 175790075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 175818334Speter } 175918334Speter break; 176018334Speter } 176118334Speter 176250397Sobrien case TEMPLATE_PARM_INDEX: 176390075Sobrien dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS); 176450397Sobrien break; 176550397Sobrien 176650397Sobrien case SCOPE_REF: 1767146895Skan pp_expression (cxx_pp, t); 176850397Sobrien break; 176950397Sobrien 177050397Sobrien case CAST_EXPR: 177150397Sobrien if (TREE_OPERAND (t, 0) == NULL_TREE 177250397Sobrien || TREE_CHAIN (TREE_OPERAND (t, 0))) 177350397Sobrien { 177490075Sobrien dump_type (TREE_TYPE (t), flags); 1775169689Skan pp_cxx_left_paren (cxx_pp); 177690075Sobrien dump_expr_list (TREE_OPERAND (t, 0), flags); 1777169689Skan pp_cxx_right_paren (cxx_pp); 177850397Sobrien } 177950397Sobrien else 178050397Sobrien { 1781169689Skan pp_cxx_left_paren (cxx_pp); 178290075Sobrien dump_type (TREE_TYPE (t), flags); 1783169689Skan pp_cxx_right_paren (cxx_pp); 1784169689Skan pp_cxx_left_paren (cxx_pp); 178590075Sobrien dump_expr_list (TREE_OPERAND (t, 0), flags); 1786169689Skan pp_cxx_right_paren (cxx_pp); 178750397Sobrien } 178850397Sobrien break; 178950397Sobrien 179090075Sobrien case STATIC_CAST_EXPR: 1791169689Skan pp_cxx_identifier (cxx_pp, "static_cast"); 179290075Sobrien goto cast; 179390075Sobrien case REINTERPRET_CAST_EXPR: 1794169689Skan pp_cxx_identifier (cxx_pp, "reinterpret_cast"); 179590075Sobrien goto cast; 179690075Sobrien case CONST_CAST_EXPR: 1797169689Skan pp_cxx_identifier (cxx_pp, "const_cast"); 179890075Sobrien goto cast; 179990075Sobrien case DYNAMIC_CAST_EXPR: 1800169689Skan pp_cxx_identifier (cxx_pp, "dynamic_cast"); 180190075Sobrien cast: 1802169689Skan pp_cxx_begin_template_argument_list (cxx_pp); 180390075Sobrien dump_type (TREE_TYPE (t), flags); 1804169689Skan pp_cxx_end_template_argument_list (cxx_pp); 1805169689Skan pp_cxx_left_paren (cxx_pp); 180690075Sobrien dump_expr (TREE_OPERAND (t, 0), flags); 1807169689Skan pp_cxx_right_paren (cxx_pp); 180890075Sobrien break; 180990075Sobrien 181050397Sobrien case ARROW_EXPR: 181190075Sobrien dump_expr (TREE_OPERAND (t, 0), flags); 1812169689Skan pp_cxx_arrow (cxx_pp); 181350397Sobrien break; 181450397Sobrien 181550397Sobrien case SIZEOF_EXPR: 181650397Sobrien case ALIGNOF_EXPR: 181750397Sobrien if (TREE_CODE (t) == SIZEOF_EXPR) 1818169689Skan pp_cxx_identifier (cxx_pp, "sizeof"); 181990075Sobrien else 182050397Sobrien { 1821169689Skan gcc_assert (TREE_CODE (t) == ALIGNOF_EXPR); 1822169689Skan pp_cxx_identifier (cxx_pp, "__alignof__"); 182350397Sobrien } 1824169689Skan pp_cxx_whitespace (cxx_pp); 1825169689Skan pp_cxx_left_paren (cxx_pp); 182690075Sobrien if (TYPE_P (TREE_OPERAND (t, 0))) 182790075Sobrien dump_type (TREE_OPERAND (t, 0), flags); 182850397Sobrien else 1829169689Skan dump_expr (TREE_OPERAND (t, 0), flags); 1830169689Skan pp_cxx_right_paren (cxx_pp); 183150397Sobrien break; 183250397Sobrien 1833132718Skan case REALPART_EXPR: 1834132718Skan case IMAGPART_EXPR: 1835169689Skan pp_cxx_identifier (cxx_pp, operator_name_info[TREE_CODE (t)].name); 1836169689Skan pp_cxx_whitespace (cxx_pp); 1837132718Skan dump_expr (TREE_OPERAND (t, 0), flags); 1838132718Skan break; 1839132718Skan 184050397Sobrien case DEFAULT_ARG: 1841132718Skan pp_identifier (cxx_pp, "<unparsed>"); 184250397Sobrien break; 184350397Sobrien 184450397Sobrien case TRY_CATCH_EXPR: 184550397Sobrien case WITH_CLEANUP_EXPR: 184650397Sobrien case CLEANUP_POINT_EXPR: 184790075Sobrien dump_expr (TREE_OPERAND (t, 0), flags); 184850397Sobrien break; 184950397Sobrien 185090075Sobrien case PSEUDO_DTOR_EXPR: 185190075Sobrien dump_expr (TREE_OPERAND (t, 2), flags); 1852169689Skan pp_cxx_dot (cxx_pp); 185390075Sobrien dump_type (TREE_OPERAND (t, 0), flags); 1854169689Skan pp_cxx_colon_colon (cxx_pp); 1855169689Skan pp_cxx_complement (cxx_pp); 185690075Sobrien dump_type (TREE_OPERAND (t, 1), flags); 185790075Sobrien break; 185890075Sobrien 185952284Sobrien case TEMPLATE_ID_EXPR: 186090075Sobrien dump_decl (t, flags); 186152284Sobrien break; 186252284Sobrien 1863169689Skan case BIND_EXPR: 186490075Sobrien case STMT_EXPR: 1865169689Skan case STATEMENT_LIST: 186690075Sobrien /* We don't yet have a way of dumping statements in a 186790075Sobrien human-readable format. */ 1868132718Skan pp_string (cxx_pp, "({...})"); 186990075Sobrien break; 187090075Sobrien 187190075Sobrien case LOOP_EXPR: 1872132718Skan pp_string (cxx_pp, "while (1) { "); 187390075Sobrien dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); 1874169689Skan pp_cxx_right_brace (cxx_pp); 187590075Sobrien break; 187690075Sobrien 187790075Sobrien case EXIT_EXPR: 1878132718Skan pp_string (cxx_pp, "if ("); 187990075Sobrien dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); 1880132718Skan pp_string (cxx_pp, ") break; "); 188190075Sobrien break; 188290075Sobrien 1883117395Skan case BASELINK: 1884132718Skan dump_expr (get_first_fn (t), flags & ~TFF_EXPR_IN_PARENS); 1885117395Skan break; 1886117395Skan 1887132718Skan case EMPTY_CLASS_EXPR: 1888132718Skan dump_type (TREE_TYPE (t), flags); 1889169689Skan pp_cxx_left_paren (cxx_pp); 1890169689Skan pp_cxx_right_paren (cxx_pp); 1891132718Skan break; 189218334Speter 1893132718Skan case NON_DEPENDENT_EXPR: 1894132718Skan dump_expr (TREE_OPERAND (t, 0), flags); 1895132718Skan break; 1896132718Skan 189718334Speter /* This list is incomplete, but should suffice for now. 189818334Speter It is very important that `sorry' does not call 189918334Speter `report_error_function'. That could cause an infinite loop. */ 190018334Speter default: 1901132718Skan pp_unsupported_tree (cxx_pp, t); 190218334Speter /* fall through to ERROR_MARK... */ 190318334Speter case ERROR_MARK: 1904132718Skan pp_identifier (cxx_pp, "<expression error>"); 190518334Speter break; 190618334Speter } 190718334Speter} 190818334Speter 190918334Speterstatic void 1910132718Skandump_binary_op (const char *opstring, tree t, int flags) 191118334Speter{ 1912169689Skan pp_cxx_left_paren (cxx_pp); 191390075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1914169689Skan pp_cxx_whitespace (cxx_pp); 191590075Sobrien if (opstring) 1916169689Skan pp_cxx_identifier (cxx_pp, opstring); 191790075Sobrien else 1918132718Skan pp_identifier (cxx_pp, "<unknown operator>"); 1919169689Skan pp_cxx_whitespace (cxx_pp); 192090075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 1921169689Skan pp_cxx_right_paren (cxx_pp); 192218334Speter} 192318334Speter 192418334Speterstatic void 1925132718Skandump_unary_op (const char *opstring, tree t, int flags) 192618334Speter{ 192790075Sobrien if (flags & TFF_EXPR_IN_PARENS) 1928169689Skan pp_cxx_left_paren (cxx_pp); 1929169689Skan pp_cxx_identifier (cxx_pp, opstring); 193090075Sobrien dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); 193190075Sobrien if (flags & TFF_EXPR_IN_PARENS) 1932169689Skan pp_cxx_right_paren (cxx_pp); 193318334Speter} 193418334Speter 1935169689Skanstatic void 1936169689Skanreinit_cxx_pp (void) 1937169689Skan{ 1938169689Skan pp_clear_output_area (cxx_pp); 1939169689Skan pp_base (cxx_pp)->padding = pp_none; 1940169689Skan pp_indentation (cxx_pp) = 0; 1941169689Skan pp_needs_newline (cxx_pp) = false; 1942169689Skan cxx_pp->enclosing_scope = 0; 1943169689Skan} 1944169689Skan 1945169689Skan 194690075Sobrien/* Exported interface to stringifying types, exprs and decls under TFF_* 194790075Sobrien control. */ 194852284Sobrien 194990075Sobrienconst char * 1950132718Skantype_as_string (tree typ, int flags) 195118334Speter{ 1952169689Skan reinit_cxx_pp (); 195390075Sobrien dump_type (typ, flags); 1954132718Skan return pp_formatted_text (cxx_pp); 195518334Speter} 195618334Speter 195790075Sobrienconst char * 1958132718Skanexpr_as_string (tree decl, int flags) 195918334Speter{ 1960169689Skan reinit_cxx_pp (); 196190075Sobrien dump_expr (decl, flags); 1962132718Skan return pp_formatted_text (cxx_pp); 196318334Speter} 196418334Speter 196590075Sobrienconst char * 1966132718Skandecl_as_string (tree decl, int flags) 196718334Speter{ 1968169689Skan reinit_cxx_pp (); 196990075Sobrien dump_decl (decl, flags); 1970132718Skan return pp_formatted_text (cxx_pp); 197118334Speter} 197218334Speter 1973117395Skan/* Generate the three forms of printable names for cxx_printable_name. */ 197450397Sobrien 197590075Sobrienconst char * 1976132718Skanlang_decl_name (tree decl, int v) 197750397Sobrien{ 197850397Sobrien if (v >= 2) 197990075Sobrien return decl_as_string (decl, TFF_DECL_SPECIFIERS); 198050397Sobrien 1981169689Skan reinit_cxx_pp (); 198250397Sobrien if (v == 1 && DECL_CLASS_SCOPE_P (decl)) 198350397Sobrien { 198490075Sobrien dump_type (CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER); 1985169689Skan pp_cxx_colon_colon (cxx_pp); 198650397Sobrien } 198750397Sobrien 198850397Sobrien if (TREE_CODE (decl) == FUNCTION_DECL) 198990075Sobrien dump_function_name (decl, TFF_PLAIN_IDENTIFIER); 199050397Sobrien else 199190075Sobrien dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER); 199250397Sobrien 1993132718Skan return pp_formatted_text (cxx_pp); 199450397Sobrien} 199550397Sobrien 1996169689Skan/* Return the location of a tree passed to %+ formats. */ 1997169689Skan 1998132718Skanstatic location_t 1999132718Skanlocation_of (tree t) 200018334Speter{ 200150397Sobrien if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t)) 2002132718Skan t = DECL_CONTEXT (t); 200390075Sobrien else if (TYPE_P (t)) 2004132718Skan t = TYPE_MAIN_DECL (t); 200552284Sobrien else if (TREE_CODE (t) == OVERLOAD) 2006132718Skan t = OVL_FUNCTION (t); 2007169689Skan 2008132718Skan return DECL_SOURCE_LOCATION (t); 200918334Speter} 201018334Speter 201190075Sobrien/* Now the interfaces from error et al to dump_type et al. Each takes an 201290075Sobrien on/off VERBOSE flag and supply the appropriate TFF_ flags to a dump_ 201390075Sobrien function. */ 201490075Sobrien 201590075Sobrienstatic const char * 2016132718Skandecl_to_string (tree decl, int verbose) 201790075Sobrien{ 201890075Sobrien int flags = 0; 201990075Sobrien 202090075Sobrien if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE 202190075Sobrien || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE) 202290075Sobrien flags = TFF_CLASS_KEY_OR_ENUM; 202390075Sobrien if (verbose) 2024117395Skan flags |= TFF_DECL_SPECIFIERS; 202590075Sobrien else if (TREE_CODE (decl) == FUNCTION_DECL) 202690075Sobrien flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE; 202790075Sobrien flags |= TFF_TEMPLATE_HEADER; 202890075Sobrien 2029169689Skan reinit_cxx_pp (); 203090075Sobrien dump_decl (decl, flags); 2031132718Skan return pp_formatted_text (cxx_pp); 203290075Sobrien} 203390075Sobrien 203490075Sobrienstatic const char * 2035132718Skanexpr_to_string (tree decl) 203690075Sobrien{ 2037169689Skan reinit_cxx_pp (); 203890075Sobrien dump_expr (decl, 0); 2039132718Skan return pp_formatted_text (cxx_pp); 204090075Sobrien} 204190075Sobrien 204290075Sobrienstatic const char * 2043132718Skanfndecl_to_string (tree fndecl, int verbose) 204490075Sobrien{ 204590075Sobrien int flags; 204690075Sobrien 2047169689Skan flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS 2048169689Skan | TFF_TEMPLATE_HEADER; 204990075Sobrien if (verbose) 205090075Sobrien flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS; 2051169689Skan reinit_cxx_pp (); 205290075Sobrien dump_decl (fndecl, flags); 2053132718Skan return pp_formatted_text (cxx_pp); 205490075Sobrien} 205590075Sobrien 205690075Sobrien 205790075Sobrienstatic const char * 2058132718Skancode_to_string (enum tree_code c) 205918334Speter{ 206018334Speter return tree_code_name [c]; 206118334Speter} 206218334Speter 206390075Sobrienconst char * 2064132718Skanlanguage_to_string (enum languages c) 206518334Speter{ 206618334Speter switch (c) 206718334Speter { 206818334Speter case lang_c: 206918334Speter return "C"; 207018334Speter 207118334Speter case lang_cplusplus: 207218334Speter return "C++"; 207318334Speter 207450397Sobrien case lang_java: 207550397Sobrien return "Java"; 207650397Sobrien 207718334Speter default: 2078169689Skan gcc_unreachable (); 207918334Speter } 2080169689Skan return NULL; 208118334Speter} 208218334Speter 208318334Speter/* Return the proper printed version of a parameter to a C++ function. */ 208450397Sobrien 208590075Sobrienstatic const char * 2086132718Skanparm_to_string (int p) 208718334Speter{ 2088169689Skan reinit_cxx_pp (); 208918334Speter if (p < 0) 2090132718Skan pp_string (cxx_pp, "'this'"); 2091132718Skan else 2092132718Skan pp_decimal_int (cxx_pp, p + 1); 2093132718Skan return pp_formatted_text (cxx_pp); 209418334Speter} 209518334Speter 209690075Sobrienstatic const char * 2097132718Skanop_to_string (enum tree_code p) 209818334Speter{ 2099132718Skan tree id = operator_name_info[(int) p].identifier; 2100132718Skan return id ? IDENTIFIER_POINTER (id) : "<unknown>"; 210118334Speter} 210218334Speter 210390075Sobrienstatic const char * 2104132718Skantype_to_string (tree typ, int verbose) 210590075Sobrien{ 2106132718Skan int flags = 0; 210790075Sobrien if (verbose) 210890075Sobrien flags |= TFF_CLASS_KEY_OR_ENUM; 210990075Sobrien flags |= TFF_TEMPLATE_HEADER; 211090075Sobrien 2111169689Skan reinit_cxx_pp (); 211290075Sobrien dump_type (typ, flags); 2113132718Skan return pp_formatted_text (cxx_pp); 211490075Sobrien} 211590075Sobrien 211690075Sobrienstatic const char * 2117132718Skanassop_to_string (enum tree_code p) 211850397Sobrien{ 2119132718Skan tree id = assignment_operator_name_info[(int) p].identifier; 212090075Sobrien return id ? IDENTIFIER_POINTER (id) : "{unknown}"; 212150397Sobrien} 212250397Sobrien 212390075Sobrienstatic const char * 2124132718Skanargs_to_string (tree p, int verbose) 212518334Speter{ 212690075Sobrien int flags = 0; 212790075Sobrien if (verbose) 212890075Sobrien flags |= TFF_CLASS_KEY_OR_ENUM; 212990075Sobrien 213018334Speter if (p == NULL_TREE) 213150397Sobrien return ""; 213218334Speter 213390075Sobrien if (TYPE_P (TREE_VALUE (p))) 213490075Sobrien return type_as_string (p, flags); 213550397Sobrien 2136169689Skan reinit_cxx_pp (); 213750397Sobrien for (; p; p = TREE_CHAIN (p)) 213850397Sobrien { 213950397Sobrien if (TREE_VALUE (p) == null_node) 2140169689Skan pp_cxx_identifier (cxx_pp, "NULL"); 214150397Sobrien else 214290075Sobrien dump_type (error_type (TREE_VALUE (p)), flags); 214350397Sobrien if (TREE_CHAIN (p)) 2144132718Skan pp_separate_with_comma (cxx_pp); 214550397Sobrien } 2146132718Skan return pp_formatted_text (cxx_pp); 214718334Speter} 214818334Speter 214990075Sobrienstatic const char * 2150132718Skancv_to_string (tree p, int v) 215118334Speter{ 2152169689Skan reinit_cxx_pp (); 2153169689Skan pp_base (cxx_pp)->padding = v ? pp_before : pp_none; 2154169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, p); 2155132718Skan return pp_formatted_text (cxx_pp); 215690075Sobrien} 215718334Speter 2158117395Skan/* Langhook for print_error_function. */ 2159117395Skanvoid 2160132718Skancxx_print_error_function (diagnostic_context *context, const char *file) 216190075Sobrien{ 2162117395Skan lhd_print_error_function (context, file); 2163132718Skan pp_base_set_prefix (context->printer, file); 2164117395Skan maybe_print_instantiation_context (context); 216518334Speter} 216690075Sobrien 216790075Sobrienstatic void 2168132718Skancp_diagnostic_starter (diagnostic_context *context, 2169169689Skan diagnostic_info *diagnostic) 217090075Sobrien{ 2171117395Skan diagnostic_report_current_module (context); 2172117395Skan cp_print_error_function (context, diagnostic); 2173117395Skan maybe_print_instantiation_context (context); 2174132718Skan pp_base_set_prefix (context->printer, diagnostic_build_prefix (diagnostic)); 217590075Sobrien} 217690075Sobrien 217790075Sobrienstatic void 2178132718Skancp_diagnostic_finalizer (diagnostic_context *context, 2179169689Skan diagnostic_info *diagnostic ATTRIBUTE_UNUSED) 218090075Sobrien{ 2181132718Skan pp_base_destroy_prefix (context->printer); 218290075Sobrien} 218390075Sobrien 218490075Sobrien/* Print current function onto BUFFER, in the process of reporting 218590075Sobrien a diagnostic message. Called from cp_diagnostic_starter. */ 218690075Sobrienstatic void 2187132718Skancp_print_error_function (diagnostic_context *context, 2188169689Skan diagnostic_info *diagnostic) 218990075Sobrien{ 2190117395Skan if (diagnostic_last_function_changed (context)) 219190075Sobrien { 2192132718Skan const char *old_prefix = context->printer->prefix; 2193169689Skan const char *file = LOCATION_FILE (diagnostic->location); 2194169689Skan char *new_prefix = file ? file_name_as_prefix (file) : NULL; 219590075Sobrien 2196132718Skan pp_base_set_prefix (context->printer, new_prefix); 219790075Sobrien 219890075Sobrien if (current_function_decl == NULL) 2199169689Skan pp_base_string (context->printer, "At global scope:"); 220090075Sobrien else 2201169689Skan pp_printf (context->printer, "In %s %qs:", 2202169689Skan function_category (current_function_decl), 2203169689Skan cxx_printable_name (current_function_decl, 2)); 2204132718Skan pp_base_newline (context->printer); 220590075Sobrien 2206117395Skan diagnostic_set_last_function (context); 2207132718Skan pp_base_destroy_prefix (context->printer); 2208132718Skan context->printer->prefix = old_prefix; 220990075Sobrien } 221090075Sobrien} 221190075Sobrien 221290075Sobrien/* Returns a description of FUNCTION using standard terminology. */ 221390075Sobrienstatic const char * 2214132718Skanfunction_category (tree fn) 221590075Sobrien{ 221690075Sobrien if (DECL_FUNCTION_MEMBER_P (fn)) 221790075Sobrien { 221890075Sobrien if (DECL_STATIC_FUNCTION_P (fn)) 2219169689Skan return "static member function"; 222090075Sobrien else if (DECL_COPY_CONSTRUCTOR_P (fn)) 2221169689Skan return "copy constructor"; 222290075Sobrien else if (DECL_CONSTRUCTOR_P (fn)) 2223169689Skan return "constructor"; 222490075Sobrien else if (DECL_DESTRUCTOR_P (fn)) 2225169689Skan return "destructor"; 222690075Sobrien else 2227169689Skan return "member function"; 222890075Sobrien } 222990075Sobrien else 223090075Sobrien return "function"; 223190075Sobrien} 223290075Sobrien 223390075Sobrien/* Report the full context of a current template instantiation, 223490075Sobrien onto BUFFER. */ 223590075Sobrienstatic void 2236132718Skanprint_instantiation_full_context (diagnostic_context *context) 223790075Sobrien{ 223890075Sobrien tree p = current_instantiation (); 2239132718Skan location_t location = input_location; 2240169689Skan 224190075Sobrien if (p) 224290075Sobrien { 224390075Sobrien if (current_function_decl != TINST_DECL (p) 224490075Sobrien && current_function_decl != NULL_TREE) 224590075Sobrien /* We can get here during the processing of some synthesized 224690075Sobrien method. Then, TINST_DECL (p) will be the function that's causing 224790075Sobrien the synthesis. */ 224890075Sobrien ; 224990075Sobrien else 225090075Sobrien { 225190075Sobrien if (current_function_decl == TINST_DECL (p)) 2252169689Skan /* Avoid redundancy with the "In function" line. */; 225390075Sobrien else 2254132718Skan pp_verbatim (context->printer, 2255169689Skan "%s: In instantiation of %qs:\n", 2256169689Skan LOCATION_FILE (location), 2257169689Skan decl_as_string (TINST_DECL (p), 2258169689Skan TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE)); 225990075Sobrien 2260169689Skan location = TINST_LOCATION (p); 226190075Sobrien p = TREE_CHAIN (p); 226290075Sobrien } 226390075Sobrien } 226490075Sobrien 2265132718Skan print_instantiation_partial_context (context, p, location); 226690075Sobrien} 226790075Sobrien 226890075Sobrien/* Same as above but less verbose. */ 226990075Sobrienstatic void 2270132718Skanprint_instantiation_partial_context (diagnostic_context *context, 2271169689Skan tree t, location_t loc) 227290075Sobrien{ 2273169689Skan expanded_location xloc; 2274169689Skan for (; ; t = TREE_CHAIN (t)) 227590075Sobrien { 2276169689Skan xloc = expand_location (loc); 2277169689Skan if (t == NULL_TREE) 2278169689Skan break; 2279169689Skan pp_verbatim (context->printer, "%s:%d: instantiated from %qs\n", 2280169689Skan xloc.file, xloc.line, 2281169689Skan decl_as_string (TINST_DECL (t), 2282169689Skan TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE)); 2283169689Skan loc = TINST_LOCATION (t); 228490075Sobrien } 2285169689Skan pp_verbatim (context->printer, "%s:%d: instantiated from here", 2286169689Skan xloc.file, xloc.line); 2287169689Skan pp_base_newline (context->printer); 228890075Sobrien} 228990075Sobrien 229090075Sobrien/* Called from cp_thing to print the template context for an error. */ 229190075Sobrienstatic void 2292132718Skanmaybe_print_instantiation_context (diagnostic_context *context) 229390075Sobrien{ 229490075Sobrien if (!problematic_instantiation_changed () || current_instantiation () == 0) 229590075Sobrien return; 229690075Sobrien 229790075Sobrien record_last_problematic_instantiation (); 2298117395Skan print_instantiation_full_context (context); 229990075Sobrien} 230090075Sobrien 230190075Sobrien/* Report the bare minimum context of a template instantiation. */ 230290075Sobrienvoid 2303132718Skanprint_instantiation_context (void) 230490075Sobrien{ 230590075Sobrien print_instantiation_partial_context 2306132718Skan (global_dc, current_instantiation (), input_location); 2307117395Skan diagnostic_flush_buffer (global_dc); 230890075Sobrien} 230990075Sobrien 231090075Sobrien/* Called from output_format -- during diagnostic message processing -- 231190075Sobrien to handle C++ specific format specifier with the following meanings: 231290075Sobrien %A function argument-list. 231390075Sobrien %C tree code. 231490075Sobrien %D declaration. 231590075Sobrien %E expression. 231690075Sobrien %F function declaration. 231790075Sobrien %L language as used in extern "lang". 231890075Sobrien %O binary operator. 231990075Sobrien %P function parameter whose position is indicated by an integer. 232090075Sobrien %Q assignment operator. 232190075Sobrien %T type. 232290075Sobrien %V cv-qualifier. */ 2323117395Skanstatic bool 2324169689Skancp_printer (pretty_printer *pp, text_info *text, const char *spec, 2325169689Skan int precision, bool wide, bool set_locus, bool verbose) 232690075Sobrien{ 232790075Sobrien const char *result; 2328169689Skan tree t = NULL; 2329169689Skan#define next_tree (t = va_arg (*text->args_ptr, tree)) 2330117395Skan#define next_tcode va_arg (*text->args_ptr, enum tree_code) 2331117395Skan#define next_lang va_arg (*text->args_ptr, enum languages) 2332117395Skan#define next_int va_arg (*text->args_ptr, int) 233390075Sobrien 2334169689Skan if (precision != 0 || wide) 2335169689Skan return false; 233690075Sobrien 2337169689Skan if (text->locus == NULL) 2338169689Skan set_locus = false; 2339169689Skan 2340169689Skan switch (*spec) 234190075Sobrien { 234290075Sobrien case 'A': result = args_to_string (next_tree, verbose); break; 2343169689Skan case 'C': result = code_to_string (next_tcode); break; 2344169689Skan case 'D': 2345169689Skan { 2346169689Skan tree temp = next_tree; 2347169689Skan if (DECL_P (temp) 2348169689Skan && DECL_DEBUG_EXPR_IS_FROM (temp) && DECL_DEBUG_EXPR (temp)) 2349169689Skan { 2350169689Skan temp = DECL_DEBUG_EXPR (temp); 2351169689Skan if (!DECL_P (temp)) 2352169689Skan { 2353169689Skan result = expr_to_string (temp); 2354169689Skan break; 2355169689Skan } 2356169689Skan } 2357169689Skan result = decl_to_string (temp, verbose); 2358169689Skan } 2359169689Skan break; 2360169689Skan case 'E': result = expr_to_string (next_tree); break; 236190075Sobrien case 'F': result = fndecl_to_string (next_tree, verbose); break; 2362169689Skan case 'L': result = language_to_string (next_lang); break; 2363169689Skan case 'O': result = op_to_string (next_tcode); break; 2364169689Skan case 'P': result = parm_to_string (next_int); break; 2365169689Skan case 'Q': result = assop_to_string (next_tcode); break; 236690075Sobrien case 'T': result = type_to_string (next_tree, verbose); break; 236790075Sobrien case 'V': result = cv_to_string (next_tree, verbose); break; 2368169689Skan 236990075Sobrien default: 2370117395Skan return false; 237190075Sobrien } 237290075Sobrien 2373132718Skan pp_base_string (pp, result); 2374169689Skan if (set_locus && t != NULL) 2375169689Skan *text->locus = location_of (t); 2376117395Skan return true; 237790075Sobrien#undef next_tree 237890075Sobrien#undef next_tcode 237990075Sobrien#undef next_lang 238090075Sobrien#undef next_int 238190075Sobrien} 2382169689Skan 2383169689Skan/* Callback from cpp_error for PFILE to print diagnostics arising from 2384169689Skan interpreting strings. The diagnostic is of type LEVEL; MSG is the 2385169689Skan translated message and AP the arguments. */ 238690075Sobrien 2387169689Skanvoid 2388169689Skancp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, 2389169689Skan const char *msg, va_list *ap) 239090075Sobrien{ 2391169689Skan diagnostic_info diagnostic; 2392169689Skan diagnostic_t dlevel; 2393169689Skan switch (level) 239490075Sobrien { 2395169689Skan case CPP_DL_WARNING: 2396169689Skan case CPP_DL_WARNING_SYSHDR: 2397169689Skan dlevel = DK_WARNING; 2398169689Skan break; 2399169689Skan case CPP_DL_PEDWARN: 2400169689Skan dlevel = pedantic_error_kind (); 2401169689Skan break; 2402169689Skan case CPP_DL_ERROR: 2403169689Skan dlevel = DK_ERROR; 2404169689Skan break; 2405169689Skan case CPP_DL_ICE: 2406169689Skan dlevel = DK_ICE; 2407169689Skan break; 2408169689Skan default: 2409169689Skan gcc_unreachable (); 241090075Sobrien } 2411169689Skan diagnostic_set_info_translated (&diagnostic, msg, ap, 2412169689Skan input_location, dlevel); 2413117395Skan report_diagnostic (&diagnostic); 241490075Sobrien} 2415