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: 345261188Spfg /* APPLE LOCAL blocks 6040305 */ 346261188Spfg case BLOCK_POINTER_TYPE: 34718334Speter case REFERENCE_TYPE: 34818334Speter case OFFSET_TYPE: 34918334Speter offset_type: 35018334Speter case FUNCTION_TYPE: 35118334Speter case METHOD_TYPE: 35290075Sobrien { 35390075Sobrien dump_type_prefix (t, flags); 35490075Sobrien dump_type_suffix (t, flags); 35518334Speter break; 35690075Sobrien } 35750397Sobrien case TYPENAME_TYPE: 358169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, t); 359169689Skan pp_cxx_identifier (cxx_pp, 360169689Skan TYPENAME_IS_ENUM_P (t) ? "enum" 361169689Skan : TYPENAME_IS_CLASS_P (t) ? "class" 362169689Skan : "typename"); 36390075Sobrien dump_typename (t, flags); 36450397Sobrien break; 36550397Sobrien 36690075Sobrien case UNBOUND_CLASS_TEMPLATE: 36790075Sobrien dump_type (TYPE_CONTEXT (t), flags); 368169689Skan pp_cxx_colon_colon (cxx_pp); 369169689Skan pp_cxx_identifier (cxx_pp, "template"); 37090075Sobrien dump_type (DECL_NAME (TYPE_NAME (t)), flags); 37190075Sobrien break; 37290075Sobrien 37352284Sobrien case TYPEOF_TYPE: 374169689Skan pp_cxx_identifier (cxx_pp, "__typeof__"); 375169689Skan pp_cxx_whitespace (cxx_pp); 376169689Skan pp_cxx_left_paren (cxx_pp); 377169689Skan dump_expr (TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS); 378169689Skan pp_cxx_right_paren (cxx_pp); 37952284Sobrien break; 38052284Sobrien 38118334Speter default: 382132718Skan pp_unsupported_tree (cxx_pp, t); 383117395Skan /* Fall through to error. */ 38490075Sobrien 38590075Sobrien case ERROR_MARK: 386132718Skan pp_identifier (cxx_pp, "<type error>"); 38790075Sobrien break; 38818334Speter } 38918334Speter} 39018334Speter 39190075Sobrien/* Dump a TYPENAME_TYPE. We need to notice when the context is itself 39290075Sobrien a TYPENAME_TYPE. */ 39390075Sobrien 39490075Sobrienstatic void 395132718Skandump_typename (tree t, int flags) 39618334Speter{ 39790075Sobrien tree ctx = TYPE_CONTEXT (t); 39890075Sobrien 39990075Sobrien if (TREE_CODE (ctx) == TYPENAME_TYPE) 40090075Sobrien dump_typename (ctx, flags); 40190075Sobrien else 40290075Sobrien dump_type (ctx, flags & ~TFF_CLASS_KEY_OR_ENUM); 403169689Skan pp_cxx_colon_colon (cxx_pp); 40490075Sobrien dump_decl (TYPENAME_TYPE_FULLNAME (t), flags); 40590075Sobrien} 40690075Sobrien 40790075Sobrien/* Return the name of the supplied aggregate, or enumeral type. */ 40890075Sobrien 409169689Skanconst char * 410169689Skanclass_key_or_enum_as_string (tree t) 41190075Sobrien{ 41218334Speter if (TREE_CODE (t) == ENUMERAL_TYPE) 41318334Speter return "enum"; 41418334Speter else if (TREE_CODE (t) == UNION_TYPE) 41518334Speter return "union"; 41618334Speter else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t)) 41718334Speter return "class"; 41818334Speter else 41918334Speter return "struct"; 42018334Speter} 42118334Speter 42290075Sobrien/* Print out a class declaration T under the control of FLAGS, 42390075Sobrien in the form `class foo'. */ 42450397Sobrien 42550397Sobrienstatic void 426132718Skandump_aggr_type (tree t, int flags) 42750397Sobrien{ 42818334Speter tree name; 429169689Skan const char *variety = class_key_or_enum_as_string (t); 43090075Sobrien int typdef = 0; 43190075Sobrien int tmplate = 0; 43218334Speter 433169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, t); 43418334Speter 43590075Sobrien if (flags & TFF_CLASS_KEY_OR_ENUM) 436169689Skan pp_cxx_identifier (cxx_pp, variety); 43718334Speter 43890075Sobrien if (flags & TFF_CHASE_TYPEDEF) 43990075Sobrien t = TYPE_MAIN_VARIANT (t); 44090075Sobrien 44190075Sobrien name = TYPE_NAME (t); 44290075Sobrien 44390075Sobrien if (name) 44418334Speter { 44590075Sobrien typdef = !DECL_ARTIFICIAL (name); 44690075Sobrien tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE 447169689Skan && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t) 448169689Skan && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL 449169689Skan || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))); 45090075Sobrien dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE); 45190075Sobrien if (tmplate) 452169689Skan { 453169689Skan /* Because the template names are mangled, we have to locate 454169689Skan the most general template, and use that name. */ 455169689Skan tree tpl = CLASSTYPE_TI_TEMPLATE (t); 45690075Sobrien 457169689Skan while (DECL_TEMPLATE_INFO (tpl)) 458169689Skan tpl = DECL_TI_TEMPLATE (tpl); 459169689Skan name = tpl; 460169689Skan } 46190075Sobrien name = DECL_NAME (name); 46218334Speter } 46318334Speter 46418334Speter if (name == 0 || ANON_AGGRNAME_P (name)) 46518334Speter { 46690075Sobrien if (flags & TFF_CLASS_KEY_OR_ENUM) 467169689Skan pp_identifier (cxx_pp, "<anonymous>"); 46890075Sobrien else 469169689Skan pp_printf (pp_base (cxx_pp), "<anonymous %s>", variety); 47018334Speter } 47118334Speter else 472169689Skan pp_cxx_tree_identifier (cxx_pp, name); 47390075Sobrien if (tmplate) 47490075Sobrien dump_template_parms (TYPE_TEMPLATE_INFO (t), 475169689Skan !CLASSTYPE_USE_TEMPLATE (t), 476169689Skan flags & ~TFF_TEMPLATE_HEADER); 47718334Speter} 47818334Speter 47918334Speter/* Dump into the obstack the initial part of the output for a given type. 48018334Speter This is necessary when dealing with things like functions returning 48118334Speter functions. Examples: 48218334Speter 48318334Speter return type of `int (* fee ())()': pointer -> function -> int. Both 48418334Speter pointer (and reference and offset) and function (and member) types must 48518334Speter deal with prefix and suffix. 48618334Speter 48718334Speter Arrays must also do this for DECL nodes, like int a[], and for things like 488169689Skan int *[]&. */ 48918334Speter 490169689Skanstatic void 491132718Skandump_type_prefix (tree t, int flags) 49218334Speter{ 49318334Speter if (TYPE_PTRMEMFUNC_P (t)) 49418334Speter { 49518334Speter t = TYPE_PTRMEMFUNC_FN_TYPE (t); 49618334Speter goto offset_type; 49718334Speter } 49890075Sobrien 49918334Speter switch (TREE_CODE (t)) 50018334Speter { 50118334Speter case POINTER_TYPE: 502261188Spfg /* APPLE LOCAL blocks 6040305 */ 503261188Spfg case BLOCK_POINTER_TYPE: 50452284Sobrien case REFERENCE_TYPE: 50518334Speter { 50618334Speter tree sub = TREE_TYPE (t); 50790075Sobrien 508169689Skan dump_type_prefix (sub, flags); 509132718Skan if (TREE_CODE (sub) == ARRAY_TYPE) 51018334Speter { 511169689Skan pp_cxx_whitespace (cxx_pp); 512169689Skan pp_cxx_left_paren (cxx_pp); 51318334Speter } 514261188Spfg /* APPLE LOCAL begin blocks 6040305 */ 515261188Spfg pp_character (cxx_pp, "&*^"[(TREE_CODE (t) == POINTER_TYPE) 516261188Spfg + (TREE_CODE (t) == BLOCK_POINTER_TYPE)*2]); 517261188Spfg /* APPLE LOCAL end blocks 6040305 */ 518169689Skan pp_base (cxx_pp)->padding = pp_before; 519169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, t); 52018334Speter } 52118334Speter break; 52218334Speter 52318334Speter case OFFSET_TYPE: 52418334Speter offset_type: 525169689Skan dump_type_prefix (TREE_TYPE (t), flags); 52618334Speter if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */ 52718334Speter { 528169689Skan pp_maybe_space (cxx_pp); 529169689Skan if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) 530169689Skan pp_cxx_left_paren (cxx_pp); 53190075Sobrien dump_type (TYPE_OFFSET_BASETYPE (t), flags); 532169689Skan pp_cxx_colon_colon (cxx_pp); 53318334Speter } 534169689Skan pp_cxx_star (cxx_pp); 535169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, t); 536169689Skan pp_base (cxx_pp)->padding = pp_before; 53718334Speter break; 53818334Speter 53918334Speter /* Can only be reached through function pointer -- this would not be 540169689Skan correct if FUNCTION_DECLs used it. */ 54118334Speter case FUNCTION_TYPE: 542169689Skan dump_type_prefix (TREE_TYPE (t), flags); 543169689Skan pp_maybe_space (cxx_pp); 544169689Skan pp_cxx_left_paren (cxx_pp); 54518334Speter break; 54618334Speter 54718334Speter case METHOD_TYPE: 548169689Skan dump_type_prefix (TREE_TYPE (t), flags); 549169689Skan pp_maybe_space (cxx_pp); 550169689Skan pp_cxx_left_paren (cxx_pp); 55190075Sobrien dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags); 552169689Skan pp_cxx_colon_colon (cxx_pp); 55318334Speter break; 55418334Speter 55518334Speter case ARRAY_TYPE: 556169689Skan dump_type_prefix (TREE_TYPE (t), flags); 55718334Speter break; 55818334Speter 55918334Speter case ENUMERAL_TYPE: 56018334Speter case IDENTIFIER_NODE: 56118334Speter case INTEGER_TYPE: 56218334Speter case BOOLEAN_TYPE: 56318334Speter case REAL_TYPE: 56418334Speter case RECORD_TYPE: 56518334Speter case TEMPLATE_TYPE_PARM: 56650397Sobrien case TEMPLATE_TEMPLATE_PARM: 56790075Sobrien case BOUND_TEMPLATE_TEMPLATE_PARM: 56818334Speter case TREE_LIST: 56918334Speter case TYPE_DECL: 57018334Speter case TREE_VEC: 57118334Speter case UNION_TYPE: 57218334Speter case UNKNOWN_TYPE: 57318334Speter case VOID_TYPE: 57450397Sobrien case TYPENAME_TYPE: 57550397Sobrien case COMPLEX_TYPE: 57690075Sobrien case VECTOR_TYPE: 577117395Skan case TYPEOF_TYPE: 57890075Sobrien dump_type (t, flags); 579169689Skan pp_base (cxx_pp)->padding = pp_before; 58018334Speter break; 58190075Sobrien 58218334Speter default: 583132718Skan pp_unsupported_tree (cxx_pp, t); 58490075Sobrien /* fall through. */ 58590075Sobrien case ERROR_MARK: 586132718Skan pp_identifier (cxx_pp, "<typeprefixerror>"); 58790075Sobrien break; 58818334Speter } 58918334Speter} 59018334Speter 59190075Sobrien/* Dump the suffix of type T, under control of FLAGS. This is the part 59290075Sobrien which appears after the identifier (or function parms). */ 59390075Sobrien 59418334Speterstatic void 595132718Skandump_type_suffix (tree t, int flags) 59618334Speter{ 59718334Speter if (TYPE_PTRMEMFUNC_P (t)) 59818334Speter t = TYPE_PTRMEMFUNC_FN_TYPE (t); 59918334Speter 60018334Speter switch (TREE_CODE (t)) 60118334Speter { 60218334Speter case POINTER_TYPE: 603261188Spfg /* APPLE LOCAL blocks 6040305 */ 604261188Spfg case BLOCK_POINTER_TYPE: 60518334Speter case REFERENCE_TYPE: 60618334Speter case OFFSET_TYPE: 60718334Speter if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) 608169689Skan pp_cxx_right_paren (cxx_pp); 60990075Sobrien dump_type_suffix (TREE_TYPE (t), flags); 61018334Speter break; 61118334Speter 612132718Skan /* Can only be reached through function pointer. */ 61318334Speter case FUNCTION_TYPE: 61418334Speter case METHOD_TYPE: 61518334Speter { 61618334Speter tree arg; 617169689Skan pp_cxx_right_paren (cxx_pp); 61818334Speter arg = TYPE_ARG_TYPES (t); 61918334Speter if (TREE_CODE (t) == METHOD_TYPE) 62018334Speter arg = TREE_CHAIN (arg); 62118334Speter 62252284Sobrien /* Function pointers don't have default args. Not in standard C++, 62352284Sobrien anyway; they may in g++, but we'll just pretend otherwise. */ 62490075Sobrien dump_parameters (arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS); 62552284Sobrien 62618334Speter if (TREE_CODE (t) == METHOD_TYPE) 627169689Skan pp_cxx_cv_qualifier_seq 628169689Skan (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t)))); 629169689Skan else 630169689Skan pp_cxx_cv_qualifier_seq(cxx_pp, t); 63190075Sobrien dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags); 63290075Sobrien dump_type_suffix (TREE_TYPE (t), flags); 63318334Speter break; 63418334Speter } 63518334Speter 63618334Speter case ARRAY_TYPE: 637169689Skan pp_maybe_space (cxx_pp); 638169689Skan pp_cxx_left_bracket (cxx_pp); 63918334Speter if (TYPE_DOMAIN (t)) 64050397Sobrien { 64190075Sobrien if (host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0)) 642132718Skan pp_wide_integer 643169689Skan (cxx_pp, tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0) + 1); 64450397Sobrien else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR) 64590075Sobrien dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 646169689Skan flags & ~TFF_EXPR_IN_PARENS); 64750397Sobrien else 64890075Sobrien dump_expr (fold (cp_build_binary_op 64950397Sobrien (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 65090075Sobrien integer_one_node)), 651169689Skan flags & ~TFF_EXPR_IN_PARENS); 65250397Sobrien } 653169689Skan pp_cxx_right_bracket (cxx_pp); 65490075Sobrien dump_type_suffix (TREE_TYPE (t), flags); 65518334Speter break; 65690075Sobrien 65718334Speter case ENUMERAL_TYPE: 65818334Speter case IDENTIFIER_NODE: 65918334Speter case INTEGER_TYPE: 66018334Speter case BOOLEAN_TYPE: 66118334Speter case REAL_TYPE: 66218334Speter case RECORD_TYPE: 66318334Speter case TEMPLATE_TYPE_PARM: 66450397Sobrien case TEMPLATE_TEMPLATE_PARM: 66590075Sobrien case BOUND_TEMPLATE_TEMPLATE_PARM: 66618334Speter case TREE_LIST: 66718334Speter case TYPE_DECL: 66818334Speter case TREE_VEC: 66918334Speter case UNION_TYPE: 67018334Speter case UNKNOWN_TYPE: 67118334Speter case VOID_TYPE: 67250397Sobrien case TYPENAME_TYPE: 67350397Sobrien case COMPLEX_TYPE: 67490075Sobrien case VECTOR_TYPE: 675117395Skan case TYPEOF_TYPE: 67618334Speter break; 67718334Speter 67818334Speter default: 679132718Skan pp_unsupported_tree (cxx_pp, t); 68090075Sobrien case ERROR_MARK: 68190075Sobrien /* Don't mark it here, we should have already done in 682169689Skan dump_type_prefix. */ 68390075Sobrien break; 68418334Speter } 68518334Speter} 68618334Speter 68750397Sobrienstatic void 688132718Skandump_global_iord (tree t) 68918334Speter{ 69090075Sobrien const char *p = NULL; 69118334Speter 69290075Sobrien if (DECL_GLOBAL_CTOR_P (t)) 69390075Sobrien p = "initializers"; 69490075Sobrien else if (DECL_GLOBAL_DTOR_P (t)) 69590075Sobrien p = "destructors"; 69618334Speter else 697169689Skan gcc_unreachable (); 69890075Sobrien 699132718Skan pp_printf (pp_base (cxx_pp), "(static %s for %s)", p, input_filename); 70018334Speter} 70118334Speter 70218334Speterstatic void 703132718Skandump_simple_decl (tree t, tree type, int flags) 70450397Sobrien{ 70590075Sobrien if (flags & TFF_DECL_SPECIFIERS) 70650397Sobrien { 707169689Skan dump_type_prefix (type, flags); 708169689Skan pp_maybe_space (cxx_pp); 70950397Sobrien } 71090075Sobrien if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX) 71190075Sobrien dump_scope (CP_DECL_CONTEXT (t), flags); 71250397Sobrien if (DECL_NAME (t)) 71390075Sobrien dump_decl (DECL_NAME (t), flags); 71450397Sobrien else 715132718Skan pp_identifier (cxx_pp, "<anonymous>"); 71690075Sobrien if (flags & TFF_DECL_SPECIFIERS) 71790075Sobrien dump_type_suffix (type, flags); 71850397Sobrien} 71950397Sobrien 72090075Sobrien/* Dump a human readable string for the decl T under control of FLAGS. */ 72190075Sobrien 72250397Sobrienstatic void 723132718Skandump_decl (tree t, int flags) 72418334Speter{ 72518334Speter if (t == NULL_TREE) 72618334Speter return; 72718334Speter 72818334Speter switch (TREE_CODE (t)) 72918334Speter { 73018334Speter case TYPE_DECL: 731169689Skan /* Don't say 'typedef class A' */ 732169689Skan if (DECL_ARTIFICIAL (t)) 733169689Skan { 734169689Skan if ((flags & TFF_DECL_SPECIFIERS) 735169689Skan && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) 736169689Skan /* Say `class T' not just `T'. */ 737169689Skan pp_cxx_identifier (cxx_pp, "class"); 73850397Sobrien 739169689Skan dump_type (TREE_TYPE (t), flags); 740169689Skan break; 741169689Skan } 74290075Sobrien if (flags & TFF_DECL_SPECIFIERS) 743169689Skan pp_cxx_identifier (cxx_pp, "typedef"); 74490075Sobrien dump_simple_decl (t, DECL_ORIGINAL_TYPE (t) 74590075Sobrien ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), 746169689Skan flags); 74718334Speter break; 74890075Sobrien 74918334Speter case VAR_DECL: 75018334Speter if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t))) 75118334Speter { 752132718Skan pp_string (cxx_pp, "vtable for "); 753169689Skan gcc_assert (TYPE_P (DECL_CONTEXT (t))); 75490075Sobrien dump_type (DECL_CONTEXT (t), flags); 75518334Speter break; 75618334Speter } 757132718Skan /* Else fall through. */ 75818334Speter case FIELD_DECL: 75918334Speter case PARM_DECL: 76090075Sobrien dump_simple_decl (t, TREE_TYPE (t), flags); 76118334Speter break; 76218334Speter 76390075Sobrien case RESULT_DECL: 764132718Skan pp_string (cxx_pp, "<return value> "); 76590075Sobrien dump_simple_decl (t, TREE_TYPE (t), flags); 76690075Sobrien break; 76790075Sobrien 76818334Speter case NAMESPACE_DECL: 769132718Skan if (flags & TFF_DECL_SPECIFIERS) 770169689Skan pp_cxx_declaration (cxx_pp, t); 77152284Sobrien else 772169689Skan { 773169689Skan dump_scope (CP_DECL_CONTEXT (t), flags); 774169689Skan if (DECL_NAME (t) == NULL_TREE) 775169689Skan pp_identifier (cxx_pp, "<unnamed>"); 776169689Skan else 777169689Skan pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t)); 778169689Skan } 77918334Speter break; 78018334Speter 78150397Sobrien case SCOPE_REF: 782146895Skan pp_expression (cxx_pp, t); 78390075Sobrien break; 78450397Sobrien 78518334Speter case ARRAY_REF: 78690075Sobrien dump_decl (TREE_OPERAND (t, 0), flags); 787169689Skan pp_cxx_left_bracket (cxx_pp); 78890075Sobrien dump_decl (TREE_OPERAND (t, 1), flags); 789169689Skan pp_cxx_right_bracket (cxx_pp); 79018334Speter break; 79118334Speter 79290075Sobrien /* So that we can do dump_decl on an aggr type. */ 79318334Speter case RECORD_TYPE: 79418334Speter case UNION_TYPE: 79518334Speter case ENUMERAL_TYPE: 79690075Sobrien dump_type (t, flags); 79718334Speter break; 79818334Speter 799132718Skan case BIT_NOT_EXPR: 800132718Skan /* This is a pseudo destructor call which has not been folded into 801169689Skan a PSEUDO_DTOR_EXPR yet. */ 802169689Skan pp_cxx_complement (cxx_pp); 803132718Skan dump_type (TREE_OPERAND (t, 0), flags); 804132718Skan break; 805132718Skan 80618334Speter case TYPE_EXPR: 807169689Skan gcc_unreachable (); 80818334Speter break; 80918334Speter 81018334Speter /* These special cases are duplicated here so that other functions 81190075Sobrien can feed identifiers to error and get them demangled properly. */ 81218334Speter case IDENTIFIER_NODE: 81390075Sobrien if (IDENTIFIER_TYPENAME_P (t)) 81490075Sobrien { 815169689Skan pp_cxx_identifier (cxx_pp, "operator"); 81690075Sobrien /* Not exactly IDENTIFIER_TYPE_VALUE. */ 81790075Sobrien dump_type (TREE_TYPE (t), flags); 81890075Sobrien break; 81990075Sobrien } 82090075Sobrien else 821169689Skan pp_cxx_tree_identifier (cxx_pp, t); 82218334Speter break; 82318334Speter 82452284Sobrien case OVERLOAD: 825110611Skan if (OVL_CHAIN (t)) 826110611Skan { 827110611Skan t = OVL_CURRENT (t); 828110611Skan if (DECL_CLASS_SCOPE_P (t)) 829110611Skan { 830110611Skan dump_type (DECL_CONTEXT (t), flags); 831169689Skan pp_cxx_colon_colon (cxx_pp); 832110611Skan } 833110611Skan else if (DECL_CONTEXT (t)) 834110611Skan { 835110611Skan dump_decl (DECL_CONTEXT (t), flags); 836169689Skan pp_cxx_colon_colon (cxx_pp); 837110611Skan } 838110611Skan dump_decl (DECL_NAME (t), flags); 839110611Skan break; 840110611Skan } 841169689Skan 842110611Skan /* If there's only one function, just treat it like an ordinary 843110611Skan FUNCTION_DECL. */ 84452284Sobrien t = OVL_CURRENT (t); 84552284Sobrien /* Fall through. */ 84652284Sobrien 84718334Speter case FUNCTION_DECL: 848169689Skan if (! DECL_LANG_SPECIFIC (t)) 849169689Skan pp_identifier (cxx_pp, "<built-in>"); 850169689Skan else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t)) 85190075Sobrien dump_global_iord (t); 85218334Speter else 853169689Skan dump_function_decl (t, flags); 85418334Speter break; 85518334Speter 85618334Speter case TEMPLATE_DECL: 85790075Sobrien dump_template_decl (t, flags); 85818334Speter break; 85918334Speter 86050397Sobrien case TEMPLATE_ID_EXPR: 86150397Sobrien { 86250397Sobrien tree name = TREE_OPERAND (t, 0); 863169689Skan 86450397Sobrien if (is_overloaded_fn (name)) 86550397Sobrien name = DECL_NAME (get_first_fn (name)); 86690075Sobrien dump_decl (name, flags); 867169689Skan pp_cxx_begin_template_argument_list (cxx_pp); 868132718Skan if (TREE_OPERAND (t, 1)) 869132718Skan dump_template_argument_list (TREE_OPERAND (t, 1), flags); 870169689Skan pp_cxx_end_template_argument_list (cxx_pp); 87150397Sobrien } 87250397Sobrien break; 87350397Sobrien 87418334Speter case LABEL_DECL: 875169689Skan pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t)); 87618334Speter break; 87718334Speter 87818334Speter case CONST_DECL: 87950397Sobrien if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE) 88050397Sobrien || (DECL_INITIAL (t) && 88150397Sobrien TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX)) 88290075Sobrien dump_simple_decl (t, TREE_TYPE (t), flags); 88350397Sobrien else if (DECL_NAME (t)) 88490075Sobrien dump_decl (DECL_NAME (t), flags); 88550397Sobrien else if (DECL_INITIAL (t)) 88690075Sobrien dump_expr (DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS); 88718334Speter else 888132718Skan pp_identifier (cxx_pp, "<enumerator>"); 88918334Speter break; 89018334Speter 89150397Sobrien case USING_DECL: 892169689Skan pp_cxx_identifier (cxx_pp, "using"); 893169689Skan dump_type (USING_DECL_SCOPE (t), flags); 894169689Skan pp_cxx_colon_colon (cxx_pp); 895117395Skan dump_decl (DECL_NAME (t), flags); 89650397Sobrien break; 89750397Sobrien 898117395Skan case BASELINK: 899117395Skan dump_decl (BASELINK_FUNCTIONS (t), flags); 900117395Skan break; 901117395Skan 902132718Skan case NON_DEPENDENT_EXPR: 903132718Skan dump_expr (t, flags); 904132718Skan break; 905132718Skan 906132718Skan case TEMPLATE_TYPE_PARM: 907132718Skan if (flags & TFF_DECL_SPECIFIERS) 908169689Skan pp_cxx_declaration (cxx_pp, t); 909132718Skan else 910169689Skan pp_type_id (cxx_pp, t); 911132718Skan break; 912132718Skan 913220150Smm case UNBOUND_CLASS_TEMPLATE: 914220150Smm dump_type (t, flags); 915220150Smm break; 916220150Smm 91718334Speter default: 918132718Skan pp_unsupported_tree (cxx_pp, t); 919169689Skan /* Fall through to error. */ 92090075Sobrien 92190075Sobrien case ERROR_MARK: 922132718Skan pp_identifier (cxx_pp, "<declaration error>"); 92390075Sobrien break; 92418334Speter } 92518334Speter} 92618334Speter 92790075Sobrien/* Dump a template declaration T under control of FLAGS. This means the 92890075Sobrien 'template <...> leaders plus the 'class X' or 'void fn(...)' part. */ 92990075Sobrien 93090075Sobrienstatic void 931132718Skandump_template_decl (tree t, int flags) 93290075Sobrien{ 93390075Sobrien tree orig_parms = DECL_TEMPLATE_PARMS (t); 93490075Sobrien tree parms; 93590075Sobrien int i; 93690075Sobrien 93790075Sobrien if (flags & TFF_TEMPLATE_HEADER) 93890075Sobrien { 93990075Sobrien for (parms = orig_parms = nreverse (orig_parms); 940169689Skan parms; 941169689Skan parms = TREE_CHAIN (parms)) 942169689Skan { 94390075Sobrien tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms); 944169689Skan int len = TREE_VEC_LENGTH (inner_parms); 94590075Sobrien 946169689Skan pp_cxx_identifier (cxx_pp, "template"); 947169689Skan pp_cxx_begin_template_argument_list (cxx_pp); 94890075Sobrien 94990075Sobrien /* If we've shown the template prefix, we'd better show the 95090075Sobrien parameters' and decl's type too. */ 95190075Sobrien flags |= TFF_DECL_SPECIFIERS; 95290075Sobrien 953169689Skan for (i = 0; i < len; i++) 954169689Skan { 955169689Skan if (i) 956169689Skan pp_separate_with_comma (cxx_pp); 957169689Skan dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags); 958169689Skan } 959169689Skan pp_cxx_end_template_argument_list (cxx_pp); 960169689Skan pp_cxx_whitespace (cxx_pp); 961169689Skan } 96290075Sobrien nreverse(orig_parms); 96390075Sobrien 96490075Sobrien if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) 965117395Skan /* Say `template<arg> class TT' not just `template<arg> TT'. */ 966169689Skan pp_cxx_identifier (cxx_pp, "class"); 96790075Sobrien } 96890075Sobrien 96990075Sobrien if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) 97090075Sobrien dump_type (TREE_TYPE (t), 971169689Skan ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME 972169689Skan | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0))); 97390075Sobrien else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL) 97490075Sobrien dump_decl (DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME); 97590075Sobrien else 97690075Sobrien { 977169689Skan gcc_assert (TREE_TYPE (t)); 978169689Skan switch (NEXT_CODE (t)) 979169689Skan { 980169689Skan case METHOD_TYPE: 981169689Skan case FUNCTION_TYPE: 982169689Skan dump_function_decl (t, flags | TFF_TEMPLATE_NAME); 983169689Skan break; 984169689Skan default: 985169689Skan /* This case can occur with some invalid code. */ 986169689Skan dump_type (TREE_TYPE (t), 987169689Skan (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME 988169689Skan | (flags & TFF_DECL_SPECIFIERS 989169689Skan ? TFF_CLASS_KEY_OR_ENUM : 0)); 990169689Skan } 99190075Sobrien } 99290075Sobrien} 99390075Sobrien 99452284Sobrien/* Pretty print a function decl. There are several ways we want to print a 99590075Sobrien function declaration. The TFF_ bits in FLAGS tells us how to behave. 99690075Sobrien As error can only apply the '#' flag once to give 0 and 1 for V, there 997117395Skan is %D which doesn't print the throw specs, and %F which does. */ 99818334Speter 99918334Speterstatic void 1000132718Skandump_function_decl (tree t, int flags) 100118334Speter{ 100250397Sobrien tree fntype; 100350397Sobrien tree parmtypes; 100418334Speter tree cname = NULL_TREE; 100590075Sobrien tree template_args = NULL_TREE; 100690075Sobrien tree template_parms = NULL_TREE; 100790075Sobrien int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS; 100818334Speter 100950397Sobrien if (TREE_CODE (t) == TEMPLATE_DECL) 101050397Sobrien t = DECL_TEMPLATE_RESULT (t); 101150397Sobrien 101290075Sobrien /* Pretty print template instantiations only. */ 101390075Sobrien if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t)) 101490075Sobrien { 101590075Sobrien tree tmpl; 101690075Sobrien 101790075Sobrien template_args = DECL_TI_ARGS (t); 101890075Sobrien tmpl = most_general_template (t); 101990075Sobrien if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL) 102090075Sobrien { 102190075Sobrien template_parms = DECL_TEMPLATE_PARMS (tmpl); 102290075Sobrien t = tmpl; 102390075Sobrien } 102490075Sobrien } 102590075Sobrien 102650397Sobrien fntype = TREE_TYPE (t); 102790075Sobrien parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t); 102850397Sobrien 102952284Sobrien if (DECL_CLASS_SCOPE_P (t)) 103090075Sobrien cname = DECL_CONTEXT (t); 1031132718Skan /* This is for partially instantiated template methods. */ 103218334Speter else if (TREE_CODE (fntype) == METHOD_TYPE) 103318334Speter cname = TREE_TYPE (TREE_VALUE (parmtypes)); 103418334Speter 103590075Sobrien if (!(flags & TFF_DECL_SPECIFIERS)) 103690075Sobrien /* OK */; 103790075Sobrien else if (DECL_STATIC_FUNCTION_P (t)) 1038169689Skan pp_cxx_identifier (cxx_pp, "static"); 103990075Sobrien else if (DECL_VIRTUAL_P (t)) 1040169689Skan pp_cxx_identifier (cxx_pp, "virtual"); 104190075Sobrien 104290075Sobrien /* Print the return type? */ 104390075Sobrien if (show_return) 104490075Sobrien show_return = !DECL_CONV_FN_P (t) && !DECL_CONSTRUCTOR_P (t) 1045169689Skan && !DECL_DESTRUCTOR_P (t); 104690075Sobrien if (show_return) 1047169689Skan dump_type_prefix (TREE_TYPE (fntype), flags); 104818334Speter 104952284Sobrien /* Print the function name. */ 105018334Speter if (cname) 105118334Speter { 105290075Sobrien dump_type (cname, flags); 1053169689Skan pp_cxx_colon_colon (cxx_pp); 105418334Speter } 105590075Sobrien else 105690075Sobrien dump_scope (CP_DECL_CONTEXT (t), flags); 105790075Sobrien 105890075Sobrien dump_function_name (t, flags); 105990075Sobrien 1060132718Skan if (!(flags & TFF_NO_FUNCTION_ARGUMENTS)) 106152284Sobrien { 106290075Sobrien dump_parameters (parmtypes, flags); 106318334Speter 106490075Sobrien if (TREE_CODE (fntype) == METHOD_TYPE) 1065169689Skan { 1066169689Skan pp_base (cxx_pp)->padding = pp_before; 1067169689Skan pp_cxx_cv_qualifier_seq 1068169689Skan (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype)))); 1069169689Skan } 107018334Speter 107190075Sobrien if (flags & TFF_EXCEPTION_SPECIFICATION) 1072169689Skan { 1073169689Skan pp_base (cxx_pp)->padding = pp_before; 1074169689Skan dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags); 1075169689Skan } 107618334Speter 107790075Sobrien if (show_return) 107890075Sobrien dump_type_suffix (TREE_TYPE (fntype), flags); 107990075Sobrien } 108018334Speter 108190075Sobrien /* If T is a template instantiation, dump the parameter binding. */ 108290075Sobrien if (template_parms != NULL_TREE && template_args != NULL_TREE) 108318334Speter { 1084169689Skan pp_cxx_whitespace (cxx_pp); 1085169689Skan pp_cxx_left_bracket (cxx_pp); 1086169689Skan pp_cxx_identifier (cxx_pp, "with"); 1087169689Skan pp_cxx_whitespace (cxx_pp); 108890075Sobrien dump_template_bindings (template_parms, template_args); 1089169689Skan pp_cxx_right_bracket (cxx_pp); 109018334Speter } 109118334Speter} 109218334Speter 109390075Sobrien/* Print a parameter list. If this is for a member function, the 109490075Sobrien member object ptr (and any other hidden args) should have 1095117395Skan already been removed. */ 109652284Sobrien 109752284Sobrienstatic void 1098132718Skandump_parameters (tree parmtypes, int flags) 109952284Sobrien{ 110052284Sobrien int first; 110152284Sobrien 1102169689Skan pp_cxx_left_paren (cxx_pp); 110390075Sobrien 110452284Sobrien for (first = 1; parmtypes != void_list_node; 110552284Sobrien parmtypes = TREE_CHAIN (parmtypes)) 110652284Sobrien { 110752284Sobrien if (!first) 1108169689Skan pp_separate_with_comma (cxx_pp); 110952284Sobrien first = 0; 111052284Sobrien if (!parmtypes) 1111169689Skan { 1112169689Skan pp_cxx_identifier (cxx_pp, "..."); 1113169689Skan break; 1114169689Skan } 111590075Sobrien dump_type (TREE_VALUE (parmtypes), flags); 111690075Sobrien 111790075Sobrien if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes)) 1118169689Skan { 1119169689Skan pp_cxx_whitespace (cxx_pp); 1120169689Skan pp_equal (cxx_pp); 1121169689Skan pp_cxx_whitespace (cxx_pp); 1122169689Skan dump_expr (TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS); 1123169689Skan } 112452284Sobrien } 112552284Sobrien 1126169689Skan pp_cxx_right_paren (cxx_pp); 112752284Sobrien} 112852284Sobrien 1129117395Skan/* Print an exception specification. T is the exception specification. */ 113052284Sobrien 113152284Sobrienstatic void 1132132718Skandump_exception_spec (tree t, int flags) 113352284Sobrien{ 113452284Sobrien if (t) 113552284Sobrien { 1136169689Skan pp_cxx_identifier (cxx_pp, "throw"); 1137169689Skan pp_cxx_whitespace (cxx_pp); 1138169689Skan pp_cxx_left_paren (cxx_pp); 113952284Sobrien if (TREE_VALUE (t) != NULL_TREE) 1140169689Skan while (1) 1141169689Skan { 1142169689Skan dump_type (TREE_VALUE (t), flags); 1143169689Skan t = TREE_CHAIN (t); 1144169689Skan if (!t) 1145169689Skan break; 1146169689Skan pp_separate_with_comma (cxx_pp); 1147169689Skan } 1148169689Skan pp_cxx_right_paren (cxx_pp); 114952284Sobrien } 115052284Sobrien} 115152284Sobrien 115218334Speter/* Handle the function name for a FUNCTION_DECL node, grokking operators 115318334Speter and destructors properly. */ 115450397Sobrien 115518334Speterstatic void 1156132718Skandump_function_name (tree t, int flags) 115718334Speter{ 115818334Speter tree name = DECL_NAME (t); 115918334Speter 1160169689Skan /* We can get here with a decl that was synthesized by language- 1161169689Skan independent machinery (e.g. coverage.c) in which case it won't 1162169689Skan have a lang_specific structure attached and DECL_CONSTRUCTOR_P 1163169689Skan will crash. In this case it is safe just to print out the 1164169689Skan literal name. */ 1165169689Skan if (!DECL_LANG_SPECIFIC (t)) 1166169689Skan { 1167169689Skan pp_cxx_tree_identifier (cxx_pp, name); 1168169689Skan return; 1169169689Skan } 1170169689Skan 1171117395Skan if (TREE_CODE (t) == TEMPLATE_DECL) 1172117395Skan t = DECL_TEMPLATE_RESULT (t); 1173117395Skan 117490075Sobrien /* Don't let the user see __comp_ctor et al. */ 117590075Sobrien if (DECL_CONSTRUCTOR_P (t) 117690075Sobrien || DECL_DESTRUCTOR_P (t)) 117790075Sobrien name = constructor_name (DECL_CONTEXT (t)); 117890075Sobrien 117952284Sobrien if (DECL_DESTRUCTOR_P (t)) 118018334Speter { 1181169689Skan pp_cxx_complement (cxx_pp); 118290075Sobrien dump_decl (name, TFF_PLAIN_IDENTIFIER); 118318334Speter } 118452284Sobrien else if (DECL_CONV_FN_P (t)) 118518334Speter { 118618334Speter /* This cannot use the hack that the operator's return 118718334Speter type is stashed off of its name because it may be 118818334Speter used for error reporting. In the case of conflicting 118918334Speter declarations, both will have the same name, yet 119018334Speter the types will be different, hence the TREE_TYPE field 119118334Speter of the first name will be clobbered by the second. */ 1192169689Skan pp_cxx_identifier (cxx_pp, "operator"); 119390075Sobrien dump_type (TREE_TYPE (TREE_TYPE (t)), flags); 119418334Speter } 119518334Speter else if (IDENTIFIER_OPNAME_P (name)) 1196169689Skan pp_cxx_tree_identifier (cxx_pp, name); 119718334Speter else 119890075Sobrien dump_decl (name, flags); 119950397Sobrien 1200169689Skan if (DECL_TEMPLATE_INFO (t) 120190075Sobrien && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t) 1202169689Skan && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL 120352284Sobrien || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))) 120490075Sobrien dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags); 120590075Sobrien} 120690075Sobrien 120790075Sobrien/* Dump the template parameters from the template info INFO under control of 120890075Sobrien FLAGS. PRIMARY indicates whether this is a primary template decl, or 120990075Sobrien specialization (partial or complete). For partial specializations we show 121090075Sobrien the specialized parameter values. For a primary template we show no 121190075Sobrien decoration. */ 121290075Sobrien 121390075Sobrienstatic void 1214132718Skandump_template_parms (tree info, int primary, int flags) 121590075Sobrien{ 121690075Sobrien tree args = info ? TI_ARGS (info) : NULL_TREE; 121790075Sobrien 121890075Sobrien if (primary && flags & TFF_TEMPLATE_NAME) 121990075Sobrien return; 122090075Sobrien flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME); 1221169689Skan pp_cxx_begin_template_argument_list (cxx_pp); 122290075Sobrien 122390075Sobrien /* Be careful only to print things when we have them, so as not 122490075Sobrien to crash producing error messages. */ 122590075Sobrien if (args && !primary) 122650397Sobrien { 1227132718Skan int len, ix; 122850397Sobrien 1229132718Skan if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) 1230132718Skan args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1); 1231169689Skan 1232132718Skan len = TREE_VEC_LENGTH (args); 1233132718Skan 1234132718Skan for (ix = 0; ix != len; ix++) 1235169689Skan { 1236169689Skan tree arg = TREE_VEC_ELT (args, ix); 123790075Sobrien 1238169689Skan if (ix) 1239169689Skan pp_separate_with_comma (cxx_pp); 1240169689Skan 1241169689Skan if (!arg) 1242169689Skan pp_identifier (cxx_pp, "<template parameter error>"); 1243169689Skan else 1244169689Skan dump_template_argument (arg, flags); 1245169689Skan } 124650397Sobrien } 124790075Sobrien else if (primary) 124890075Sobrien { 124990075Sobrien tree tpl = TI_TEMPLATE (info); 125090075Sobrien tree parms = DECL_TEMPLATE_PARMS (tpl); 125190075Sobrien int len, ix; 125290075Sobrien 125390075Sobrien parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE; 125490075Sobrien len = parms ? TREE_VEC_LENGTH (parms) : 0; 125590075Sobrien 125690075Sobrien for (ix = 0; ix != len; ix++) 1257169689Skan { 1258169689Skan tree parm; 125990075Sobrien 1260169689Skan if (TREE_VEC_ELT (parms, ix) == error_mark_node) 1261169689Skan { 1262169689Skan pp_identifier (cxx_pp, "<template parameter error>"); 1263169689Skan continue; 1264169689Skan } 126590075Sobrien 1266169689Skan parm = TREE_VALUE (TREE_VEC_ELT (parms, ix)); 1267169689Skan 1268169689Skan if (ix) 1269169689Skan pp_separate_with_comma (cxx_pp); 1270169689Skan 1271169689Skan dump_decl (parm, flags & ~TFF_DECL_SPECIFIERS); 1272169689Skan } 127390075Sobrien } 1274169689Skan pp_cxx_end_template_argument_list (cxx_pp); 127518334Speter} 127618334Speter 1277132718Skan/* Print out a list of initializers (subr of dump_expr). */ 127818334Speter 127918334Speterstatic void 1280132718Skandump_expr_list (tree l, int flags) 128118334Speter{ 128218334Speter while (l) 128318334Speter { 128490075Sobrien dump_expr (TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS); 128518334Speter l = TREE_CHAIN (l); 128690075Sobrien if (l) 1287132718Skan pp_separate_with_comma (cxx_pp); 128818334Speter } 128918334Speter} 129018334Speter 1291169689Skan/* Print out a vector of initializers (subr of dump_expr). */ 1292169689Skan 1293169689Skanstatic void 1294169689Skandump_expr_init_vec (VEC(constructor_elt,gc) *v, int flags) 1295169689Skan{ 1296169689Skan unsigned HOST_WIDE_INT idx; 1297169689Skan tree value; 1298169689Skan 1299169689Skan FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value) 1300169689Skan { 1301169689Skan dump_expr (value, flags | TFF_EXPR_IN_PARENS); 1302169689Skan if (idx != VEC_length (constructor_elt, v) - 1) 1303169689Skan pp_separate_with_comma (cxx_pp); 1304169689Skan } 1305169689Skan} 1306169689Skan 1307169689Skan 1308169689Skan/* We've gotten an indirect REFERENCE (an OBJ_TYPE_REF) to a virtual 1309169689Skan function. Resolve it to a close relative -- in the sense of static 1310169689Skan type -- variant being overridden. That is close to what was written in 1311169689Skan the source code. Subroutine of dump_expr. */ 1312169689Skan 1313169689Skanstatic tree 1314169689Skanresolve_virtual_fun_from_obj_type_ref (tree ref) 1315169689Skan{ 1316169689Skan tree obj_type = TREE_TYPE (OBJ_TYPE_REF_OBJECT (ref)); 1317220150Smm HOST_WIDE_INT index = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1); 1318169689Skan tree fun = BINFO_VIRTUALS (TYPE_BINFO (TREE_TYPE (obj_type))); 1319220150Smm while (index) 1320220150Smm { 1321169689Skan fun = TREE_CHAIN (fun); 1322220150Smm index -= (TARGET_VTABLE_USES_DESCRIPTORS 1323220150Smm ? TARGET_VTABLE_USES_DESCRIPTORS : 1); 1324220150Smm } 1325169689Skan 1326169689Skan return BV_FN (fun); 1327169689Skan} 1328169689Skan 1329117395Skan/* Print out an expression E under control of FLAGS. */ 133050397Sobrien 133118334Speterstatic void 1332132718Skandump_expr (tree t, int flags) 133318334Speter{ 1334117395Skan if (t == 0) 1335117395Skan return; 1336169689Skan 133718334Speter switch (TREE_CODE (t)) 133818334Speter { 133918334Speter case VAR_DECL: 134018334Speter case PARM_DECL: 134118334Speter case FIELD_DECL: 134218334Speter case CONST_DECL: 134318334Speter case FUNCTION_DECL: 134450397Sobrien case TEMPLATE_DECL: 134550397Sobrien case NAMESPACE_DECL: 1346161651Skan case LABEL_DECL: 134790075Sobrien case OVERLOAD: 1348132718Skan case IDENTIFIER_NODE: 1349132718Skan dump_decl (t, (flags & ~TFF_DECL_SPECIFIERS) | TFF_NO_FUNCTION_ARGUMENTS); 135018334Speter break; 135118334Speter 135218334Speter case INTEGER_CST: 1353169689Skan case REAL_CST: 1354132718Skan case STRING_CST: 1355169689Skan pp_constant (cxx_pp, t); 135618334Speter break; 135718334Speter 1358132718Skan case THROW_EXPR: 1359169689Skan pp_cxx_identifier (cxx_pp, "throw"); 1360132718Skan dump_expr (TREE_OPERAND (t, 0), flags); 136118334Speter break; 136218334Speter 136352284Sobrien case PTRMEM_CST: 1364132718Skan pp_ampersand (cxx_pp); 136590075Sobrien dump_type (PTRMEM_CST_CLASS (t), flags); 1366169689Skan pp_cxx_colon_colon (cxx_pp); 1367169689Skan pp_cxx_tree_identifier (cxx_pp, DECL_NAME (PTRMEM_CST_MEMBER (t))); 136852284Sobrien break; 136952284Sobrien 137018334Speter case COMPOUND_EXPR: 1371169689Skan pp_cxx_left_paren (cxx_pp); 137290075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1373132718Skan pp_separate_with_comma (cxx_pp); 137490075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 1375169689Skan pp_cxx_right_paren (cxx_pp); 137618334Speter break; 137718334Speter 137818334Speter case COND_EXPR: 1379169689Skan pp_cxx_left_paren (cxx_pp); 138090075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1381132718Skan pp_string (cxx_pp, " ? "); 138290075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 1383132718Skan pp_string (cxx_pp, " : "); 138490075Sobrien dump_expr (TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS); 1385169689Skan pp_cxx_right_paren (cxx_pp); 138618334Speter break; 138718334Speter 138818334Speter case SAVE_EXPR: 138918334Speter if (TREE_HAS_CONSTRUCTOR (t)) 139018334Speter { 1391169689Skan pp_cxx_identifier (cxx_pp, "new"); 1392169689Skan pp_cxx_whitespace (cxx_pp); 139390075Sobrien dump_type (TREE_TYPE (TREE_TYPE (t)), flags); 139418334Speter } 139518334Speter else 1396169689Skan dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 139718334Speter break; 139818334Speter 139950397Sobrien case AGGR_INIT_EXPR: 140090075Sobrien { 140190075Sobrien tree fn = NULL_TREE; 140290075Sobrien 140390075Sobrien if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR) 140490075Sobrien fn = TREE_OPERAND (TREE_OPERAND (t, 0), 0); 140590075Sobrien 140690075Sobrien if (fn && TREE_CODE (fn) == FUNCTION_DECL) 140790075Sobrien { 140890075Sobrien if (DECL_CONSTRUCTOR_P (fn)) 1409169689Skan dump_type (DECL_CONTEXT (fn), flags); 141090075Sobrien else 141190075Sobrien dump_decl (fn, 0); 141290075Sobrien } 141390075Sobrien else 141490075Sobrien dump_expr (TREE_OPERAND (t, 0), 0); 141590075Sobrien } 1416169689Skan pp_cxx_left_paren (cxx_pp); 141750397Sobrien if (TREE_OPERAND (t, 1)) 141890075Sobrien dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags); 1419169689Skan pp_cxx_right_paren (cxx_pp); 142018334Speter break; 142118334Speter 142218334Speter case CALL_EXPR: 142318334Speter { 142418334Speter tree fn = TREE_OPERAND (t, 0); 142518334Speter tree args = TREE_OPERAND (t, 1); 142690075Sobrien 142718334Speter if (TREE_CODE (fn) == ADDR_EXPR) 142818334Speter fn = TREE_OPERAND (fn, 0); 142918334Speter 1430169689Skan /* Nobody is interested in seeing the guts of vcalls. */ 1431169689Skan if (TREE_CODE (fn) == OBJ_TYPE_REF) 1432169689Skan fn = resolve_virtual_fun_from_obj_type_ref (fn); 1433169689Skan 143450397Sobrien if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE) 143518334Speter { 143618334Speter tree ob = TREE_VALUE (args); 143718334Speter if (TREE_CODE (ob) == ADDR_EXPR) 143818334Speter { 143990075Sobrien dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS); 1440220150Smm pp_cxx_dot (cxx_pp); 144118334Speter } 144218334Speter else if (TREE_CODE (ob) != PARM_DECL 144318334Speter || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) 144418334Speter { 144590075Sobrien dump_expr (ob, flags | TFF_EXPR_IN_PARENS); 1446220150Smm pp_cxx_arrow (cxx_pp); 144718334Speter } 144818334Speter args = TREE_CHAIN (args); 144918334Speter } 145090075Sobrien dump_expr (fn, flags | TFF_EXPR_IN_PARENS); 1451169689Skan pp_cxx_left_paren (cxx_pp); 145290075Sobrien dump_expr_list (args, flags); 1453169689Skan pp_cxx_right_paren (cxx_pp); 145418334Speter } 145518334Speter break; 145618334Speter 145750397Sobrien case NEW_EXPR: 145850397Sobrien { 145950397Sobrien tree type = TREE_OPERAND (t, 1); 1460117395Skan tree init = TREE_OPERAND (t, 2); 146150397Sobrien if (NEW_EXPR_USE_GLOBAL (t)) 1462169689Skan pp_cxx_colon_colon (cxx_pp); 1463169689Skan pp_cxx_identifier (cxx_pp, "new"); 146450397Sobrien if (TREE_OPERAND (t, 0)) 146550397Sobrien { 1466169689Skan pp_cxx_left_paren (cxx_pp); 146790075Sobrien dump_expr_list (TREE_OPERAND (t, 0), flags); 1468169689Skan pp_cxx_right_paren (cxx_pp); 1469169689Skan pp_cxx_whitespace (cxx_pp); 147050397Sobrien } 147150397Sobrien if (TREE_CODE (type) == ARRAY_REF) 147250397Sobrien type = build_cplus_array_type 147350397Sobrien (TREE_OPERAND (type, 0), 1474169689Skan build_index_type (fold_build2 (MINUS_EXPR, integer_type_node, 147590075Sobrien TREE_OPERAND (type, 1), 1476169689Skan integer_one_node))); 147790075Sobrien dump_type (type, flags); 1478117395Skan if (init) 147950397Sobrien { 1480169689Skan pp_cxx_left_paren (cxx_pp); 1481117395Skan if (TREE_CODE (init) == TREE_LIST) 1482117395Skan dump_expr_list (init, flags); 1483117395Skan else if (init == void_zero_node) 1484117395Skan /* This representation indicates an empty initializer, 1485117395Skan e.g.: "new int()". */ 1486117395Skan ; 1487117395Skan else 1488117395Skan dump_expr (init, flags); 1489169689Skan pp_cxx_right_paren (cxx_pp); 149050397Sobrien } 149150397Sobrien } 149218334Speter break; 149318334Speter 149418334Speter case TARGET_EXPR: 149518334Speter /* Note that this only works for G++ target exprs. If somebody 149618334Speter builds a general TARGET_EXPR, there's no way to represent that 149718334Speter it initializes anything other that the parameter slot for the 149818334Speter default argument. Note we may have cleared out the first 149918334Speter operand in expand_expr, so don't go killing ourselves. */ 150018334Speter if (TREE_OPERAND (t, 1)) 150190075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 150218334Speter break; 150318334Speter 150490075Sobrien case INIT_EXPR: 150518334Speter case MODIFY_EXPR: 150618334Speter case PLUS_EXPR: 150718334Speter case MINUS_EXPR: 150818334Speter case MULT_EXPR: 150918334Speter case TRUNC_DIV_EXPR: 151018334Speter case TRUNC_MOD_EXPR: 151118334Speter case MIN_EXPR: 151218334Speter case MAX_EXPR: 151318334Speter case LSHIFT_EXPR: 151418334Speter case RSHIFT_EXPR: 151518334Speter case BIT_IOR_EXPR: 151618334Speter case BIT_XOR_EXPR: 151718334Speter case BIT_AND_EXPR: 151818334Speter case TRUTH_ANDIF_EXPR: 151918334Speter case TRUTH_ORIF_EXPR: 152018334Speter case LT_EXPR: 152118334Speter case LE_EXPR: 152218334Speter case GT_EXPR: 152318334Speter case GE_EXPR: 152418334Speter case EQ_EXPR: 152518334Speter case NE_EXPR: 152690075Sobrien case EXACT_DIV_EXPR: 152790075Sobrien dump_binary_op (operator_name_info[(int) TREE_CODE (t)].name, t, flags); 152818334Speter break; 152918334Speter 153018334Speter case CEIL_DIV_EXPR: 153118334Speter case FLOOR_DIV_EXPR: 153218334Speter case ROUND_DIV_EXPR: 1533146895Skan case RDIV_EXPR: 153490075Sobrien dump_binary_op ("/", t, flags); 153518334Speter break; 153618334Speter 153718334Speter case CEIL_MOD_EXPR: 153818334Speter case FLOOR_MOD_EXPR: 153918334Speter case ROUND_MOD_EXPR: 154090075Sobrien dump_binary_op ("%", t, flags); 154118334Speter break; 154218334Speter 154318334Speter case COMPONENT_REF: 154418334Speter { 154518334Speter tree ob = TREE_OPERAND (t, 0); 154618334Speter if (TREE_CODE (ob) == INDIRECT_REF) 154718334Speter { 154818334Speter ob = TREE_OPERAND (ob, 0); 154918334Speter if (TREE_CODE (ob) != PARM_DECL 1550169689Skan || (DECL_NAME (ob) 1551169689Skan && strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))) 155218334Speter { 155390075Sobrien dump_expr (ob, flags | TFF_EXPR_IN_PARENS); 1554169689Skan pp_cxx_arrow (cxx_pp); 155518334Speter } 155618334Speter } 155718334Speter else 155818334Speter { 155990075Sobrien dump_expr (ob, flags | TFF_EXPR_IN_PARENS); 1560169689Skan pp_cxx_dot (cxx_pp); 156118334Speter } 156290075Sobrien dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS); 156318334Speter } 156418334Speter break; 156518334Speter 156618334Speter case ARRAY_REF: 156790075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1568169689Skan pp_cxx_left_bracket (cxx_pp); 156990075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 1570169689Skan pp_cxx_right_bracket (cxx_pp); 157118334Speter break; 157218334Speter 1573169689Skan case UNARY_PLUS_EXPR: 1574169689Skan dump_unary_op ("+", t, flags); 157518334Speter break; 157618334Speter 157718334Speter case ADDR_EXPR: 157818334Speter if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL 157990075Sobrien || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST 158090075Sobrien /* An ADDR_EXPR can have reference type. In that case, we 158190075Sobrien shouldn't print the `&' doing so indicates to the user 158290075Sobrien that the expression has pointer type. */ 158390075Sobrien || (TREE_TYPE (t) 158490075Sobrien && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)) 158590075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1586161651Skan else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL) 1587161651Skan dump_unary_op ("&&", t, flags); 158818334Speter else 158990075Sobrien dump_unary_op ("&", t, flags); 159018334Speter break; 159118334Speter 159218334Speter case INDIRECT_REF: 159318334Speter if (TREE_HAS_CONSTRUCTOR (t)) 159418334Speter { 159518334Speter t = TREE_OPERAND (t, 0); 1596169689Skan gcc_assert (TREE_CODE (t) == CALL_EXPR); 159790075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1598169689Skan pp_cxx_left_paren (cxx_pp); 159990075Sobrien dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags); 1600169689Skan pp_cxx_right_paren (cxx_pp); 160118334Speter } 160218334Speter else 160318334Speter { 160450397Sobrien if (TREE_OPERAND (t,0) != NULL_TREE 160552284Sobrien && TREE_TYPE (TREE_OPERAND (t, 0)) 160650397Sobrien && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE) 160790075Sobrien dump_expr (TREE_OPERAND (t, 0), flags); 160818334Speter else 160990075Sobrien dump_unary_op ("*", t, flags); 161018334Speter } 161118334Speter break; 161218334Speter 161318334Speter case NEGATE_EXPR: 161418334Speter case BIT_NOT_EXPR: 161518334Speter case TRUTH_NOT_EXPR: 161618334Speter case PREDECREMENT_EXPR: 161718334Speter case PREINCREMENT_EXPR: 161890075Sobrien dump_unary_op (operator_name_info [(int)TREE_CODE (t)].name, t, flags); 161918334Speter break; 162018334Speter 162118334Speter case POSTDECREMENT_EXPR: 162218334Speter case POSTINCREMENT_EXPR: 1623169689Skan pp_cxx_left_paren (cxx_pp); 162490075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1625169689Skan pp_cxx_identifier (cxx_pp, operator_name_info[(int)TREE_CODE (t)].name); 1626169689Skan pp_cxx_right_paren (cxx_pp); 162718334Speter break; 162818334Speter 162918334Speter case NON_LVALUE_EXPR: 163018334Speter /* FIXME: This is a KLUDGE workaround for a parsing problem. There 163118334Speter should be another level of INDIRECT_REF so that I don't have to do 163218334Speter this. */ 163350397Sobrien if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE) 163418334Speter { 163518334Speter tree next = TREE_TYPE (TREE_TYPE (t)); 163618334Speter 163718334Speter while (TREE_CODE (next) == POINTER_TYPE) 163818334Speter next = TREE_TYPE (next); 163990075Sobrien 164018334Speter if (TREE_CODE (next) == FUNCTION_TYPE) 164118334Speter { 164290075Sobrien if (flags & TFF_EXPR_IN_PARENS) 1643169689Skan pp_cxx_left_paren (cxx_pp); 1644169689Skan pp_cxx_star (cxx_pp); 164590075Sobrien dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); 164690075Sobrien if (flags & TFF_EXPR_IN_PARENS) 1647169689Skan pp_cxx_right_paren (cxx_pp); 164818334Speter break; 164918334Speter } 1650132718Skan /* Else fall through. */ 165118334Speter } 165290075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 165318334Speter break; 165418334Speter 165518334Speter case NOP_EXPR: 1656169689Skan case CONVERT_EXPR: 1657132718Skan { 1658132718Skan tree op = TREE_OPERAND (t, 0); 1659169689Skan 1660132718Skan if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t))) 1661132718Skan { 1662132718Skan /* It is a cast, but we cannot tell whether it is a 1663132718Skan reinterpret or static cast. Use the C style notation. */ 1664132718Skan if (flags & TFF_EXPR_IN_PARENS) 1665169689Skan pp_cxx_left_paren (cxx_pp); 1666169689Skan pp_cxx_left_paren (cxx_pp); 1667132718Skan dump_type (TREE_TYPE (t), flags); 1668169689Skan pp_cxx_right_paren (cxx_pp); 1669132718Skan dump_expr (op, flags | TFF_EXPR_IN_PARENS); 1670132718Skan if (flags & TFF_EXPR_IN_PARENS) 1671169689Skan pp_cxx_right_paren (cxx_pp); 1672132718Skan } 1673132718Skan else 1674132718Skan dump_expr (op, flags); 1675132718Skan break; 1676132718Skan } 167790075Sobrien 167818334Speter case CONSTRUCTOR: 167950397Sobrien if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) 168050397Sobrien { 1681117395Skan tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier); 168250397Sobrien 168390075Sobrien if (integer_zerop (idx)) 168450397Sobrien { 168552284Sobrien /* A NULL pointer-to-member constant. */ 1686169689Skan pp_cxx_left_paren (cxx_pp); 1687169689Skan pp_cxx_left_paren (cxx_pp); 168890075Sobrien dump_type (TREE_TYPE (t), flags); 1689169689Skan pp_cxx_right_paren (cxx_pp); 1690169689Skan pp_character (cxx_pp, '0'); 1691169689Skan pp_cxx_right_paren (cxx_pp); 169252284Sobrien break; 169352284Sobrien } 169490075Sobrien else if (host_integerp (idx, 0)) 169552284Sobrien { 169650397Sobrien tree virtuals; 169750397Sobrien unsigned HOST_WIDE_INT n; 169850397Sobrien 169950397Sobrien t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t))); 170050397Sobrien t = TYPE_METHOD_BASETYPE (t); 1701169689Skan virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t))); 170250397Sobrien 170390075Sobrien n = tree_low_cst (idx, 0); 170490075Sobrien 170550397Sobrien /* Map vtable index back one, to allow for the null pointer to 170650397Sobrien member. */ 170750397Sobrien --n; 170850397Sobrien 170950397Sobrien while (n > 0 && virtuals) 171050397Sobrien { 171150397Sobrien --n; 171250397Sobrien virtuals = TREE_CHAIN (virtuals); 171350397Sobrien } 171450397Sobrien if (virtuals) 171550397Sobrien { 171690075Sobrien dump_expr (BV_FN (virtuals), 1717169689Skan flags | TFF_EXPR_IN_PARENS); 171850397Sobrien break; 171950397Sobrien } 172050397Sobrien } 172150397Sobrien } 1722169689Skan if (TREE_TYPE (t) && EMPTY_CONSTRUCTOR_P (t)) 1723132718Skan { 1724132718Skan dump_type (TREE_TYPE (t), 0); 1725169689Skan pp_cxx_left_paren (cxx_pp); 1726169689Skan pp_cxx_right_paren (cxx_pp); 1727132718Skan } 1728117395Skan else 1729132718Skan { 1730169689Skan pp_cxx_left_brace (cxx_pp); 1731169689Skan dump_expr_init_vec (CONSTRUCTOR_ELTS (t), flags); 1732169689Skan pp_cxx_right_brace (cxx_pp); 1733132718Skan } 1734169689Skan 173518334Speter break; 173618334Speter 173718334Speter case OFFSET_REF: 173818334Speter { 173918334Speter tree ob = TREE_OPERAND (t, 0); 174052284Sobrien if (is_dummy_object (ob)) 174152284Sobrien { 174252284Sobrien t = TREE_OPERAND (t, 1); 174352284Sobrien if (TREE_CODE (t) == FUNCTION_DECL) 174452284Sobrien /* A::f */ 174590075Sobrien dump_expr (t, flags | TFF_EXPR_IN_PARENS); 174652284Sobrien else if (BASELINK_P (t)) 1747169689Skan dump_expr (OVL_CURRENT (BASELINK_FUNCTIONS (t)), 1748117395Skan flags | TFF_EXPR_IN_PARENS); 174952284Sobrien else 175090075Sobrien dump_decl (t, flags); 175152284Sobrien } 175218334Speter else 175318334Speter { 175452284Sobrien if (TREE_CODE (ob) == INDIRECT_REF) 175552284Sobrien { 175690075Sobrien dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS); 1757169689Skan pp_cxx_arrow (cxx_pp); 1758169689Skan pp_cxx_star (cxx_pp); 175952284Sobrien } 176052284Sobrien else 176152284Sobrien { 176290075Sobrien dump_expr (ob, flags | TFF_EXPR_IN_PARENS); 1763169689Skan pp_cxx_dot (cxx_pp); 1764169689Skan pp_cxx_star (cxx_pp); 176552284Sobrien } 176690075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 176718334Speter } 176818334Speter break; 176918334Speter } 177018334Speter 177150397Sobrien case TEMPLATE_PARM_INDEX: 177290075Sobrien dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS); 177350397Sobrien break; 177450397Sobrien 177550397Sobrien case SCOPE_REF: 1776146895Skan pp_expression (cxx_pp, t); 177750397Sobrien break; 177850397Sobrien 177950397Sobrien case CAST_EXPR: 178050397Sobrien if (TREE_OPERAND (t, 0) == NULL_TREE 178150397Sobrien || TREE_CHAIN (TREE_OPERAND (t, 0))) 178250397Sobrien { 178390075Sobrien dump_type (TREE_TYPE (t), flags); 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 else 178950397Sobrien { 1790169689Skan pp_cxx_left_paren (cxx_pp); 179190075Sobrien dump_type (TREE_TYPE (t), flags); 1792169689Skan pp_cxx_right_paren (cxx_pp); 1793169689Skan pp_cxx_left_paren (cxx_pp); 179490075Sobrien dump_expr_list (TREE_OPERAND (t, 0), flags); 1795169689Skan pp_cxx_right_paren (cxx_pp); 179650397Sobrien } 179750397Sobrien break; 179850397Sobrien 179990075Sobrien case STATIC_CAST_EXPR: 1800169689Skan pp_cxx_identifier (cxx_pp, "static_cast"); 180190075Sobrien goto cast; 180290075Sobrien case REINTERPRET_CAST_EXPR: 1803169689Skan pp_cxx_identifier (cxx_pp, "reinterpret_cast"); 180490075Sobrien goto cast; 180590075Sobrien case CONST_CAST_EXPR: 1806169689Skan pp_cxx_identifier (cxx_pp, "const_cast"); 180790075Sobrien goto cast; 180890075Sobrien case DYNAMIC_CAST_EXPR: 1809169689Skan pp_cxx_identifier (cxx_pp, "dynamic_cast"); 181090075Sobrien cast: 1811169689Skan pp_cxx_begin_template_argument_list (cxx_pp); 181290075Sobrien dump_type (TREE_TYPE (t), flags); 1813169689Skan pp_cxx_end_template_argument_list (cxx_pp); 1814169689Skan pp_cxx_left_paren (cxx_pp); 181590075Sobrien dump_expr (TREE_OPERAND (t, 0), flags); 1816169689Skan pp_cxx_right_paren (cxx_pp); 181790075Sobrien break; 181890075Sobrien 181950397Sobrien case ARROW_EXPR: 182090075Sobrien dump_expr (TREE_OPERAND (t, 0), flags); 1821169689Skan pp_cxx_arrow (cxx_pp); 182250397Sobrien break; 182350397Sobrien 182450397Sobrien case SIZEOF_EXPR: 182550397Sobrien case ALIGNOF_EXPR: 182650397Sobrien if (TREE_CODE (t) == SIZEOF_EXPR) 1827169689Skan pp_cxx_identifier (cxx_pp, "sizeof"); 182890075Sobrien else 182950397Sobrien { 1830169689Skan gcc_assert (TREE_CODE (t) == ALIGNOF_EXPR); 1831169689Skan pp_cxx_identifier (cxx_pp, "__alignof__"); 183250397Sobrien } 1833169689Skan pp_cxx_whitespace (cxx_pp); 1834169689Skan pp_cxx_left_paren (cxx_pp); 183590075Sobrien if (TYPE_P (TREE_OPERAND (t, 0))) 183690075Sobrien dump_type (TREE_OPERAND (t, 0), flags); 183750397Sobrien else 1838169689Skan dump_expr (TREE_OPERAND (t, 0), flags); 1839169689Skan pp_cxx_right_paren (cxx_pp); 184050397Sobrien break; 184150397Sobrien 1842132718Skan case REALPART_EXPR: 1843132718Skan case IMAGPART_EXPR: 1844169689Skan pp_cxx_identifier (cxx_pp, operator_name_info[TREE_CODE (t)].name); 1845169689Skan pp_cxx_whitespace (cxx_pp); 1846132718Skan dump_expr (TREE_OPERAND (t, 0), flags); 1847132718Skan break; 1848132718Skan 184950397Sobrien case DEFAULT_ARG: 1850132718Skan pp_identifier (cxx_pp, "<unparsed>"); 185150397Sobrien break; 185250397Sobrien 185350397Sobrien case TRY_CATCH_EXPR: 185450397Sobrien case WITH_CLEANUP_EXPR: 185550397Sobrien case CLEANUP_POINT_EXPR: 185690075Sobrien dump_expr (TREE_OPERAND (t, 0), flags); 185750397Sobrien break; 185850397Sobrien 185990075Sobrien case PSEUDO_DTOR_EXPR: 186090075Sobrien dump_expr (TREE_OPERAND (t, 2), flags); 1861169689Skan pp_cxx_dot (cxx_pp); 186290075Sobrien dump_type (TREE_OPERAND (t, 0), flags); 1863169689Skan pp_cxx_colon_colon (cxx_pp); 1864169689Skan pp_cxx_complement (cxx_pp); 186590075Sobrien dump_type (TREE_OPERAND (t, 1), flags); 186690075Sobrien break; 186790075Sobrien 186852284Sobrien case TEMPLATE_ID_EXPR: 186990075Sobrien dump_decl (t, flags); 187052284Sobrien break; 187152284Sobrien 1872169689Skan case BIND_EXPR: 187390075Sobrien case STMT_EXPR: 1874169689Skan case STATEMENT_LIST: 187590075Sobrien /* We don't yet have a way of dumping statements in a 187690075Sobrien human-readable format. */ 1877132718Skan pp_string (cxx_pp, "({...})"); 187890075Sobrien break; 187990075Sobrien 188090075Sobrien case LOOP_EXPR: 1881132718Skan pp_string (cxx_pp, "while (1) { "); 188290075Sobrien dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); 1883169689Skan pp_cxx_right_brace (cxx_pp); 188490075Sobrien break; 188590075Sobrien 188690075Sobrien case EXIT_EXPR: 1887132718Skan pp_string (cxx_pp, "if ("); 188890075Sobrien dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); 1889132718Skan pp_string (cxx_pp, ") break; "); 189090075Sobrien break; 189190075Sobrien 1892117395Skan case BASELINK: 1893132718Skan dump_expr (get_first_fn (t), flags & ~TFF_EXPR_IN_PARENS); 1894117395Skan break; 1895117395Skan 1896132718Skan case EMPTY_CLASS_EXPR: 1897132718Skan dump_type (TREE_TYPE (t), flags); 1898169689Skan pp_cxx_left_paren (cxx_pp); 1899169689Skan pp_cxx_right_paren (cxx_pp); 1900132718Skan break; 190118334Speter 1902132718Skan case NON_DEPENDENT_EXPR: 1903132718Skan dump_expr (TREE_OPERAND (t, 0), flags); 1904132718Skan break; 1905132718Skan 190618334Speter /* This list is incomplete, but should suffice for now. 190718334Speter It is very important that `sorry' does not call 190818334Speter `report_error_function'. That could cause an infinite loop. */ 190918334Speter default: 1910132718Skan pp_unsupported_tree (cxx_pp, t); 191118334Speter /* fall through to ERROR_MARK... */ 191218334Speter case ERROR_MARK: 1913132718Skan pp_identifier (cxx_pp, "<expression error>"); 191418334Speter break; 191518334Speter } 191618334Speter} 191718334Speter 191818334Speterstatic void 1919132718Skandump_binary_op (const char *opstring, tree t, int flags) 192018334Speter{ 1921169689Skan pp_cxx_left_paren (cxx_pp); 192290075Sobrien dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); 1923169689Skan pp_cxx_whitespace (cxx_pp); 192490075Sobrien if (opstring) 1925169689Skan pp_cxx_identifier (cxx_pp, opstring); 192690075Sobrien else 1927132718Skan pp_identifier (cxx_pp, "<unknown operator>"); 1928169689Skan pp_cxx_whitespace (cxx_pp); 192990075Sobrien dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); 1930169689Skan pp_cxx_right_paren (cxx_pp); 193118334Speter} 193218334Speter 193318334Speterstatic void 1934132718Skandump_unary_op (const char *opstring, tree t, int flags) 193518334Speter{ 193690075Sobrien if (flags & TFF_EXPR_IN_PARENS) 1937169689Skan pp_cxx_left_paren (cxx_pp); 1938169689Skan pp_cxx_identifier (cxx_pp, opstring); 193990075Sobrien dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); 194090075Sobrien if (flags & TFF_EXPR_IN_PARENS) 1941169689Skan pp_cxx_right_paren (cxx_pp); 194218334Speter} 194318334Speter 1944169689Skanstatic void 1945169689Skanreinit_cxx_pp (void) 1946169689Skan{ 1947169689Skan pp_clear_output_area (cxx_pp); 1948169689Skan pp_base (cxx_pp)->padding = pp_none; 1949169689Skan pp_indentation (cxx_pp) = 0; 1950169689Skan pp_needs_newline (cxx_pp) = false; 1951169689Skan cxx_pp->enclosing_scope = 0; 1952169689Skan} 1953169689Skan 1954169689Skan 195590075Sobrien/* Exported interface to stringifying types, exprs and decls under TFF_* 195690075Sobrien control. */ 195752284Sobrien 195890075Sobrienconst char * 1959132718Skantype_as_string (tree typ, int flags) 196018334Speter{ 1961169689Skan reinit_cxx_pp (); 196290075Sobrien dump_type (typ, flags); 1963132718Skan return pp_formatted_text (cxx_pp); 196418334Speter} 196518334Speter 196690075Sobrienconst char * 1967132718Skanexpr_as_string (tree decl, int flags) 196818334Speter{ 1969169689Skan reinit_cxx_pp (); 197090075Sobrien dump_expr (decl, flags); 1971132718Skan return pp_formatted_text (cxx_pp); 197218334Speter} 197318334Speter 197490075Sobrienconst char * 1975132718Skandecl_as_string (tree decl, int flags) 197618334Speter{ 1977169689Skan reinit_cxx_pp (); 197890075Sobrien dump_decl (decl, flags); 1979132718Skan return pp_formatted_text (cxx_pp); 198018334Speter} 198118334Speter 1982117395Skan/* Generate the three forms of printable names for cxx_printable_name. */ 198350397Sobrien 198490075Sobrienconst char * 1985132718Skanlang_decl_name (tree decl, int v) 198650397Sobrien{ 198750397Sobrien if (v >= 2) 198890075Sobrien return decl_as_string (decl, TFF_DECL_SPECIFIERS); 198950397Sobrien 1990169689Skan reinit_cxx_pp (); 199150397Sobrien if (v == 1 && DECL_CLASS_SCOPE_P (decl)) 199250397Sobrien { 199390075Sobrien dump_type (CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER); 1994169689Skan pp_cxx_colon_colon (cxx_pp); 199550397Sobrien } 199650397Sobrien 199750397Sobrien if (TREE_CODE (decl) == FUNCTION_DECL) 199890075Sobrien dump_function_name (decl, TFF_PLAIN_IDENTIFIER); 199950397Sobrien else 200090075Sobrien dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER); 200150397Sobrien 2002132718Skan return pp_formatted_text (cxx_pp); 200350397Sobrien} 200450397Sobrien 2005169689Skan/* Return the location of a tree passed to %+ formats. */ 2006169689Skan 2007132718Skanstatic location_t 2008132718Skanlocation_of (tree t) 200918334Speter{ 201050397Sobrien if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t)) 2011132718Skan t = DECL_CONTEXT (t); 201290075Sobrien else if (TYPE_P (t)) 2013132718Skan t = TYPE_MAIN_DECL (t); 201452284Sobrien else if (TREE_CODE (t) == OVERLOAD) 2015132718Skan t = OVL_FUNCTION (t); 2016169689Skan 2017132718Skan return DECL_SOURCE_LOCATION (t); 201818334Speter} 201918334Speter 202090075Sobrien/* Now the interfaces from error et al to dump_type et al. Each takes an 202190075Sobrien on/off VERBOSE flag and supply the appropriate TFF_ flags to a dump_ 202290075Sobrien function. */ 202390075Sobrien 202490075Sobrienstatic const char * 2025132718Skandecl_to_string (tree decl, int verbose) 202690075Sobrien{ 202790075Sobrien int flags = 0; 202890075Sobrien 202990075Sobrien if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE 203090075Sobrien || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE) 203190075Sobrien flags = TFF_CLASS_KEY_OR_ENUM; 203290075Sobrien if (verbose) 2033117395Skan flags |= TFF_DECL_SPECIFIERS; 203490075Sobrien else if (TREE_CODE (decl) == FUNCTION_DECL) 203590075Sobrien flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE; 203690075Sobrien flags |= TFF_TEMPLATE_HEADER; 203790075Sobrien 2038169689Skan reinit_cxx_pp (); 203990075Sobrien dump_decl (decl, flags); 2040132718Skan return pp_formatted_text (cxx_pp); 204190075Sobrien} 204290075Sobrien 204390075Sobrienstatic const char * 2044132718Skanexpr_to_string (tree decl) 204590075Sobrien{ 2046169689Skan reinit_cxx_pp (); 204790075Sobrien dump_expr (decl, 0); 2048132718Skan return pp_formatted_text (cxx_pp); 204990075Sobrien} 205090075Sobrien 205190075Sobrienstatic const char * 2052132718Skanfndecl_to_string (tree fndecl, int verbose) 205390075Sobrien{ 205490075Sobrien int flags; 205590075Sobrien 2056169689Skan flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS 2057169689Skan | TFF_TEMPLATE_HEADER; 205890075Sobrien if (verbose) 205990075Sobrien flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS; 2060169689Skan reinit_cxx_pp (); 206190075Sobrien dump_decl (fndecl, flags); 2062132718Skan return pp_formatted_text (cxx_pp); 206390075Sobrien} 206490075Sobrien 206590075Sobrien 206690075Sobrienstatic const char * 2067132718Skancode_to_string (enum tree_code c) 206818334Speter{ 206918334Speter return tree_code_name [c]; 207018334Speter} 207118334Speter 207290075Sobrienconst char * 2073132718Skanlanguage_to_string (enum languages c) 207418334Speter{ 207518334Speter switch (c) 207618334Speter { 207718334Speter case lang_c: 207818334Speter return "C"; 207918334Speter 208018334Speter case lang_cplusplus: 208118334Speter return "C++"; 208218334Speter 208350397Sobrien case lang_java: 208450397Sobrien return "Java"; 208550397Sobrien 208618334Speter default: 2087169689Skan gcc_unreachable (); 208818334Speter } 2089169689Skan return NULL; 209018334Speter} 209118334Speter 209218334Speter/* Return the proper printed version of a parameter to a C++ function. */ 209350397Sobrien 209490075Sobrienstatic const char * 2095132718Skanparm_to_string (int p) 209618334Speter{ 2097169689Skan reinit_cxx_pp (); 209818334Speter if (p < 0) 2099132718Skan pp_string (cxx_pp, "'this'"); 2100132718Skan else 2101132718Skan pp_decimal_int (cxx_pp, p + 1); 2102132718Skan return pp_formatted_text (cxx_pp); 210318334Speter} 210418334Speter 210590075Sobrienstatic const char * 2106132718Skanop_to_string (enum tree_code p) 210718334Speter{ 2108132718Skan tree id = operator_name_info[(int) p].identifier; 2109132718Skan return id ? IDENTIFIER_POINTER (id) : "<unknown>"; 211018334Speter} 211118334Speter 211290075Sobrienstatic const char * 2113132718Skantype_to_string (tree typ, int verbose) 211490075Sobrien{ 2115132718Skan int flags = 0; 211690075Sobrien if (verbose) 211790075Sobrien flags |= TFF_CLASS_KEY_OR_ENUM; 211890075Sobrien flags |= TFF_TEMPLATE_HEADER; 211990075Sobrien 2120169689Skan reinit_cxx_pp (); 212190075Sobrien dump_type (typ, flags); 2122132718Skan return pp_formatted_text (cxx_pp); 212390075Sobrien} 212490075Sobrien 212590075Sobrienstatic const char * 2126132718Skanassop_to_string (enum tree_code p) 212750397Sobrien{ 2128132718Skan tree id = assignment_operator_name_info[(int) p].identifier; 212990075Sobrien return id ? IDENTIFIER_POINTER (id) : "{unknown}"; 213050397Sobrien} 213150397Sobrien 213290075Sobrienstatic const char * 2133132718Skanargs_to_string (tree p, int verbose) 213418334Speter{ 213590075Sobrien int flags = 0; 213690075Sobrien if (verbose) 213790075Sobrien flags |= TFF_CLASS_KEY_OR_ENUM; 213890075Sobrien 213918334Speter if (p == NULL_TREE) 214050397Sobrien return ""; 214118334Speter 214290075Sobrien if (TYPE_P (TREE_VALUE (p))) 214390075Sobrien return type_as_string (p, flags); 214450397Sobrien 2145169689Skan reinit_cxx_pp (); 214650397Sobrien for (; p; p = TREE_CHAIN (p)) 214750397Sobrien { 214850397Sobrien if (TREE_VALUE (p) == null_node) 2149169689Skan pp_cxx_identifier (cxx_pp, "NULL"); 215050397Sobrien else 215190075Sobrien dump_type (error_type (TREE_VALUE (p)), flags); 215250397Sobrien if (TREE_CHAIN (p)) 2153132718Skan pp_separate_with_comma (cxx_pp); 215450397Sobrien } 2155132718Skan return pp_formatted_text (cxx_pp); 215618334Speter} 215718334Speter 215890075Sobrienstatic const char * 2159132718Skancv_to_string (tree p, int v) 216018334Speter{ 2161169689Skan reinit_cxx_pp (); 2162169689Skan pp_base (cxx_pp)->padding = v ? pp_before : pp_none; 2163169689Skan pp_cxx_cv_qualifier_seq (cxx_pp, p); 2164132718Skan return pp_formatted_text (cxx_pp); 216590075Sobrien} 216618334Speter 2167117395Skan/* Langhook for print_error_function. */ 2168117395Skanvoid 2169132718Skancxx_print_error_function (diagnostic_context *context, const char *file) 217090075Sobrien{ 2171117395Skan lhd_print_error_function (context, file); 2172132718Skan pp_base_set_prefix (context->printer, file); 2173117395Skan maybe_print_instantiation_context (context); 217418334Speter} 217590075Sobrien 217690075Sobrienstatic void 2177132718Skancp_diagnostic_starter (diagnostic_context *context, 2178169689Skan diagnostic_info *diagnostic) 217990075Sobrien{ 2180117395Skan diagnostic_report_current_module (context); 2181117395Skan cp_print_error_function (context, diagnostic); 2182117395Skan maybe_print_instantiation_context (context); 2183132718Skan pp_base_set_prefix (context->printer, diagnostic_build_prefix (diagnostic)); 218490075Sobrien} 218590075Sobrien 218690075Sobrienstatic void 2187132718Skancp_diagnostic_finalizer (diagnostic_context *context, 2188169689Skan diagnostic_info *diagnostic ATTRIBUTE_UNUSED) 218990075Sobrien{ 2190132718Skan pp_base_destroy_prefix (context->printer); 219190075Sobrien} 219290075Sobrien 219390075Sobrien/* Print current function onto BUFFER, in the process of reporting 219490075Sobrien a diagnostic message. Called from cp_diagnostic_starter. */ 219590075Sobrienstatic void 2196132718Skancp_print_error_function (diagnostic_context *context, 2197169689Skan diagnostic_info *diagnostic) 219890075Sobrien{ 2199117395Skan if (diagnostic_last_function_changed (context)) 220090075Sobrien { 2201132718Skan const char *old_prefix = context->printer->prefix; 2202169689Skan const char *file = LOCATION_FILE (diagnostic->location); 2203169689Skan char *new_prefix = file ? file_name_as_prefix (file) : NULL; 220490075Sobrien 2205132718Skan pp_base_set_prefix (context->printer, new_prefix); 220690075Sobrien 220790075Sobrien if (current_function_decl == NULL) 2208169689Skan pp_base_string (context->printer, "At global scope:"); 220990075Sobrien else 2210169689Skan pp_printf (context->printer, "In %s %qs:", 2211169689Skan function_category (current_function_decl), 2212169689Skan cxx_printable_name (current_function_decl, 2)); 2213132718Skan pp_base_newline (context->printer); 221490075Sobrien 2215117395Skan diagnostic_set_last_function (context); 2216132718Skan pp_base_destroy_prefix (context->printer); 2217132718Skan context->printer->prefix = old_prefix; 221890075Sobrien } 221990075Sobrien} 222090075Sobrien 222190075Sobrien/* Returns a description of FUNCTION using standard terminology. */ 222290075Sobrienstatic const char * 2223132718Skanfunction_category (tree fn) 222490075Sobrien{ 222590075Sobrien if (DECL_FUNCTION_MEMBER_P (fn)) 222690075Sobrien { 222790075Sobrien if (DECL_STATIC_FUNCTION_P (fn)) 2228169689Skan return "static member function"; 222990075Sobrien else if (DECL_COPY_CONSTRUCTOR_P (fn)) 2230169689Skan return "copy constructor"; 223190075Sobrien else if (DECL_CONSTRUCTOR_P (fn)) 2232169689Skan return "constructor"; 223390075Sobrien else if (DECL_DESTRUCTOR_P (fn)) 2234169689Skan return "destructor"; 223590075Sobrien else 2236169689Skan return "member function"; 223790075Sobrien } 223890075Sobrien else 223990075Sobrien return "function"; 224090075Sobrien} 224190075Sobrien 224290075Sobrien/* Report the full context of a current template instantiation, 224390075Sobrien onto BUFFER. */ 224490075Sobrienstatic void 2245132718Skanprint_instantiation_full_context (diagnostic_context *context) 224690075Sobrien{ 224790075Sobrien tree p = current_instantiation (); 2248132718Skan location_t location = input_location; 2249169689Skan 225090075Sobrien if (p) 225190075Sobrien { 225290075Sobrien if (current_function_decl != TINST_DECL (p) 225390075Sobrien && current_function_decl != NULL_TREE) 225490075Sobrien /* We can get here during the processing of some synthesized 225590075Sobrien method. Then, TINST_DECL (p) will be the function that's causing 225690075Sobrien the synthesis. */ 225790075Sobrien ; 225890075Sobrien else 225990075Sobrien { 226090075Sobrien if (current_function_decl == TINST_DECL (p)) 2261169689Skan /* Avoid redundancy with the "In function" line. */; 226290075Sobrien else 2263132718Skan pp_verbatim (context->printer, 2264169689Skan "%s: In instantiation of %qs:\n", 2265169689Skan LOCATION_FILE (location), 2266169689Skan decl_as_string (TINST_DECL (p), 2267169689Skan TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE)); 226890075Sobrien 2269169689Skan location = TINST_LOCATION (p); 227090075Sobrien p = TREE_CHAIN (p); 227190075Sobrien } 227290075Sobrien } 227390075Sobrien 2274132718Skan print_instantiation_partial_context (context, p, location); 227590075Sobrien} 227690075Sobrien 227790075Sobrien/* Same as above but less verbose. */ 227890075Sobrienstatic void 2279132718Skanprint_instantiation_partial_context (diagnostic_context *context, 2280169689Skan tree t, location_t loc) 228190075Sobrien{ 2282169689Skan expanded_location xloc; 2283169689Skan for (; ; t = TREE_CHAIN (t)) 228490075Sobrien { 2285169689Skan xloc = expand_location (loc); 2286169689Skan if (t == NULL_TREE) 2287169689Skan break; 2288169689Skan pp_verbatim (context->printer, "%s:%d: instantiated from %qs\n", 2289169689Skan xloc.file, xloc.line, 2290169689Skan decl_as_string (TINST_DECL (t), 2291169689Skan TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE)); 2292169689Skan loc = TINST_LOCATION (t); 229390075Sobrien } 2294169689Skan pp_verbatim (context->printer, "%s:%d: instantiated from here", 2295169689Skan xloc.file, xloc.line); 2296169689Skan pp_base_newline (context->printer); 229790075Sobrien} 229890075Sobrien 229990075Sobrien/* Called from cp_thing to print the template context for an error. */ 230090075Sobrienstatic void 2301132718Skanmaybe_print_instantiation_context (diagnostic_context *context) 230290075Sobrien{ 230390075Sobrien if (!problematic_instantiation_changed () || current_instantiation () == 0) 230490075Sobrien return; 230590075Sobrien 230690075Sobrien record_last_problematic_instantiation (); 2307117395Skan print_instantiation_full_context (context); 230890075Sobrien} 230990075Sobrien 231090075Sobrien/* Report the bare minimum context of a template instantiation. */ 231190075Sobrienvoid 2312132718Skanprint_instantiation_context (void) 231390075Sobrien{ 231490075Sobrien print_instantiation_partial_context 2315132718Skan (global_dc, current_instantiation (), input_location); 2316117395Skan diagnostic_flush_buffer (global_dc); 231790075Sobrien} 231890075Sobrien 231990075Sobrien/* Called from output_format -- during diagnostic message processing -- 232090075Sobrien to handle C++ specific format specifier with the following meanings: 232190075Sobrien %A function argument-list. 232290075Sobrien %C tree code. 232390075Sobrien %D declaration. 232490075Sobrien %E expression. 232590075Sobrien %F function declaration. 232690075Sobrien %L language as used in extern "lang". 232790075Sobrien %O binary operator. 232890075Sobrien %P function parameter whose position is indicated by an integer. 232990075Sobrien %Q assignment operator. 233090075Sobrien %T type. 233190075Sobrien %V cv-qualifier. */ 2332117395Skanstatic bool 2333169689Skancp_printer (pretty_printer *pp, text_info *text, const char *spec, 2334169689Skan int precision, bool wide, bool set_locus, bool verbose) 233590075Sobrien{ 233690075Sobrien const char *result; 2337169689Skan tree t = NULL; 2338169689Skan#define next_tree (t = va_arg (*text->args_ptr, tree)) 2339117395Skan#define next_tcode va_arg (*text->args_ptr, enum tree_code) 2340117395Skan#define next_lang va_arg (*text->args_ptr, enum languages) 2341117395Skan#define next_int va_arg (*text->args_ptr, int) 234290075Sobrien 2343169689Skan if (precision != 0 || wide) 2344169689Skan return false; 234590075Sobrien 2346169689Skan if (text->locus == NULL) 2347169689Skan set_locus = false; 2348169689Skan 2349169689Skan switch (*spec) 235090075Sobrien { 235190075Sobrien case 'A': result = args_to_string (next_tree, verbose); break; 2352169689Skan case 'C': result = code_to_string (next_tcode); break; 2353169689Skan case 'D': 2354169689Skan { 2355169689Skan tree temp = next_tree; 2356169689Skan if (DECL_P (temp) 2357169689Skan && DECL_DEBUG_EXPR_IS_FROM (temp) && DECL_DEBUG_EXPR (temp)) 2358169689Skan { 2359169689Skan temp = DECL_DEBUG_EXPR (temp); 2360169689Skan if (!DECL_P (temp)) 2361169689Skan { 2362169689Skan result = expr_to_string (temp); 2363169689Skan break; 2364169689Skan } 2365169689Skan } 2366169689Skan result = decl_to_string (temp, verbose); 2367169689Skan } 2368169689Skan break; 2369169689Skan case 'E': result = expr_to_string (next_tree); break; 237090075Sobrien case 'F': result = fndecl_to_string (next_tree, verbose); break; 2371169689Skan case 'L': result = language_to_string (next_lang); break; 2372169689Skan case 'O': result = op_to_string (next_tcode); break; 2373169689Skan case 'P': result = parm_to_string (next_int); break; 2374169689Skan case 'Q': result = assop_to_string (next_tcode); break; 237590075Sobrien case 'T': result = type_to_string (next_tree, verbose); break; 237690075Sobrien case 'V': result = cv_to_string (next_tree, verbose); break; 2377169689Skan 237890075Sobrien default: 2379117395Skan return false; 238090075Sobrien } 238190075Sobrien 2382132718Skan pp_base_string (pp, result); 2383169689Skan if (set_locus && t != NULL) 2384169689Skan *text->locus = location_of (t); 2385117395Skan return true; 238690075Sobrien#undef next_tree 238790075Sobrien#undef next_tcode 238890075Sobrien#undef next_lang 238990075Sobrien#undef next_int 239090075Sobrien} 2391169689Skan 2392169689Skan/* Callback from cpp_error for PFILE to print diagnostics arising from 2393169689Skan interpreting strings. The diagnostic is of type LEVEL; MSG is the 2394169689Skan translated message and AP the arguments. */ 239590075Sobrien 2396169689Skanvoid 2397169689Skancp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, 2398169689Skan const char *msg, va_list *ap) 239990075Sobrien{ 2400169689Skan diagnostic_info diagnostic; 2401169689Skan diagnostic_t dlevel; 2402169689Skan switch (level) 240390075Sobrien { 2404169689Skan case CPP_DL_WARNING: 2405169689Skan case CPP_DL_WARNING_SYSHDR: 2406169689Skan dlevel = DK_WARNING; 2407169689Skan break; 2408169689Skan case CPP_DL_PEDWARN: 2409169689Skan dlevel = pedantic_error_kind (); 2410169689Skan break; 2411169689Skan case CPP_DL_ERROR: 2412169689Skan dlevel = DK_ERROR; 2413169689Skan break; 2414169689Skan case CPP_DL_ICE: 2415169689Skan dlevel = DK_ICE; 2416169689Skan break; 2417169689Skan default: 2418169689Skan gcc_unreachable (); 241990075Sobrien } 2420169689Skan diagnostic_set_info_translated (&diagnostic, msg, ap, 2421169689Skan input_location, dlevel); 2422117395Skan report_diagnostic (&diagnostic); 242390075Sobrien} 2424