00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "tree.h"
00027 #include "cp-tree.h"
00028 #include "real.h"
00029 #include "toplev.h"
00030 #include "flags.h"
00031 #include "diagnostic.h"
00032 #include "langhooks-def.h"
00033 #include "cxx-pretty-print.h"
00034
00035 #define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',')
00036
00037
00038
00039
00040 static cxx_pretty_printer scratch_pretty_printer;
00041 #define cxx_pp (&scratch_pretty_printer)
00042
00043 # define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T)))
00044
00045 static const char *args_to_string (tree, int);
00046 static const char *assop_to_string (enum tree_code);
00047 static const char *code_to_string (enum tree_code);
00048 static const char *cv_to_string (tree, int);
00049 static const char *decl_to_string (tree, int);
00050 static const char *expr_to_string (tree);
00051 static const char *fndecl_to_string (tree, int);
00052 static const char *op_to_string (enum tree_code);
00053 static const char *parm_to_string (int);
00054 static const char *type_to_string (tree, int);
00055
00056 static void dump_type (tree, int);
00057 static void dump_typename (tree, int);
00058 static void dump_simple_decl (tree, tree, int);
00059 static void dump_decl (tree, int);
00060 static void dump_template_decl (tree, int);
00061 static void dump_function_decl (tree, int);
00062 static void dump_expr (tree, int);
00063 static void dump_unary_op (const char *, tree, int);
00064 static void dump_binary_op (const char *, tree, int);
00065 static void dump_aggr_type (tree, int);
00066 static void dump_type_prefix (tree, int);
00067 static void dump_type_suffix (tree, int);
00068 static void dump_function_name (tree, int);
00069 static void dump_expr_list (tree, int);
00070 static void dump_global_iord (tree);
00071 static void dump_parameters (tree, int);
00072 static void dump_exception_spec (tree, int);
00073 static void dump_template_argument (tree, int);
00074 static void dump_template_argument_list (tree, int);
00075 static void dump_template_parameter (tree, int);
00076 static void dump_template_bindings (tree, tree);
00077 static void dump_scope (tree, int);
00078 static void dump_template_parms (tree, int, int);
00079
00080 static const char *function_category (tree);
00081 static void maybe_print_instantiation_context (diagnostic_context *);
00082 static void print_instantiation_full_context (diagnostic_context *);
00083 static void print_instantiation_partial_context (diagnostic_context *,
00084 tree, location_t);
00085 static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *);
00086 static void cp_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
00087 static void cp_print_error_function (diagnostic_context *, diagnostic_info *);
00088
00089 static bool cp_printer (pretty_printer *, text_info *);
00090 static tree locate_error (const char *, va_list);
00091 static location_t location_of (tree);
00092
00093 void
00094 init_error (void)
00095 {
00096 diagnostic_starter (global_dc) = cp_diagnostic_starter;
00097 diagnostic_finalizer (global_dc) = cp_diagnostic_finalizer;
00098 diagnostic_format_decoder (global_dc) = cp_printer;
00099
00100 pp_construct (pp_base (cxx_pp), NULL, 0);
00101 pp_cxx_pretty_printer_init (cxx_pp);
00102 }
00103
00104
00105
00106 static void
00107 dump_scope (tree scope, int flags)
00108 {
00109 int f = ~TFF_RETURN_TYPE & (flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF));
00110
00111 if (scope == NULL_TREE)
00112 return;
00113
00114 if (TREE_CODE (scope) == NAMESPACE_DECL)
00115 {
00116 if (scope != global_namespace)
00117 {
00118 dump_decl (scope, f);
00119 pp_cxx_colon_colon (cxx_pp);
00120 }
00121 }
00122 else if (AGGREGATE_TYPE_P (scope))
00123 {
00124 dump_type (scope, f);
00125 pp_cxx_colon_colon (cxx_pp);
00126 }
00127 else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL)
00128 {
00129 dump_function_decl (scope, f);
00130 pp_cxx_colon_colon (cxx_pp);
00131 }
00132 }
00133
00134
00135
00136 static void
00137 dump_template_argument (tree arg, int flags)
00138 {
00139 if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
00140 dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
00141 else
00142 dump_expr (arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM);
00143 }
00144
00145
00146
00147
00148 static void
00149 dump_template_argument_list (tree args, int flags)
00150 {
00151 int n = TREE_VEC_LENGTH (args);
00152 int need_comma = 0;
00153 int i;
00154
00155 for (i = 0; i< n; ++i)
00156 {
00157 if (need_comma)
00158 pp_separate_with_comma (cxx_pp);
00159 dump_template_argument (TREE_VEC_ELT (args, i), flags);
00160 need_comma = 1;
00161 }
00162 }
00163
00164
00165
00166 static void
00167 dump_template_parameter (tree parm, int flags)
00168 {
00169 tree p = TREE_VALUE (parm);
00170 tree a = TREE_PURPOSE (parm);
00171
00172 if (TREE_CODE (p) == TYPE_DECL)
00173 {
00174 if (flags & TFF_DECL_SPECIFIERS)
00175 {
00176 pp_cxx_identifier (cxx_pp, "class");
00177 if (DECL_NAME (p))
00178 pp_cxx_tree_identifier (cxx_pp, DECL_NAME (p));
00179 }
00180 else if (DECL_NAME (p))
00181 pp_cxx_tree_identifier (cxx_pp, DECL_NAME (p));
00182 else
00183 pp_cxx_canonical_template_parameter (cxx_pp, TREE_TYPE (p));
00184 }
00185 else
00186 dump_decl (p, flags | TFF_DECL_SPECIFIERS);
00187
00188 if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE)
00189 {
00190 pp_cxx_whitespace (cxx_pp);
00191 pp_equal (cxx_pp);
00192 pp_cxx_whitespace (cxx_pp);
00193 if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
00194 dump_type (a, flags & ~TFF_CHASE_TYPEDEF);
00195 else
00196 dump_expr (a, flags | TFF_EXPR_IN_PARENS);
00197 }
00198 }
00199
00200
00201
00202
00203
00204 static void
00205 dump_template_bindings (tree parms, tree args)
00206 {
00207 int need_comma = 0;
00208
00209 while (parms)
00210 {
00211 tree p = TREE_VALUE (parms);
00212 int lvl = TMPL_PARMS_DEPTH (parms);
00213 int arg_idx = 0;
00214 int i;
00215
00216 for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
00217 {
00218 tree arg = NULL_TREE;
00219
00220
00221 if (TMPL_ARGS_DEPTH (args) >= lvl)
00222 {
00223 tree lvl_args = TMPL_ARGS_LEVEL (args, lvl);
00224 if (NUM_TMPL_ARGS (lvl_args) > arg_idx)
00225 arg = TREE_VEC_ELT (lvl_args, arg_idx);
00226 }
00227
00228 if (need_comma)
00229 pp_separate_with_comma (cxx_pp);
00230 dump_template_parameter (TREE_VEC_ELT (p, i), TFF_PLAIN_IDENTIFIER);
00231 pp_cxx_whitespace (cxx_pp);
00232 pp_equal (cxx_pp);
00233 pp_cxx_whitespace (cxx_pp);
00234 if (arg)
00235 dump_template_argument (arg, TFF_PLAIN_IDENTIFIER);
00236 else
00237 pp_identifier (cxx_pp, "<missing>");
00238
00239 ++arg_idx;
00240 need_comma = 1;
00241 }
00242
00243 parms = TREE_CHAIN (parms);
00244 }
00245 }
00246
00247
00248
00249
00250 static void
00251 dump_type (tree t, int flags)
00252 {
00253 if (t == NULL_TREE)
00254 return;
00255
00256 if (TYPE_PTRMEMFUNC_P (t))
00257 goto offset_type;
00258
00259 switch (TREE_CODE (t))
00260 {
00261 case UNKNOWN_TYPE:
00262 pp_identifier (cxx_pp, "<unknown type>");
00263 break;
00264
00265 case TREE_LIST:
00266
00267 dump_parameters (t, flags);
00268 break;
00269
00270 case IDENTIFIER_NODE:
00271 pp_cxx_tree_identifier (cxx_pp, t);
00272 break;
00273
00274 case TREE_BINFO:
00275 dump_type (BINFO_TYPE (t), flags);
00276 break;
00277
00278 case RECORD_TYPE:
00279 case UNION_TYPE:
00280 case ENUMERAL_TYPE:
00281 dump_aggr_type (t, flags);
00282 break;
00283
00284 case TYPE_DECL:
00285 if (flags & TFF_CHASE_TYPEDEF)
00286 {
00287 dump_type (DECL_ORIGINAL_TYPE (t)
00288 ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags);
00289 break;
00290 }
00291
00292
00293 case TEMPLATE_DECL:
00294 case NAMESPACE_DECL:
00295 dump_decl (t, flags & ~TFF_DECL_SPECIFIERS);
00296 break;
00297
00298 case INTEGER_TYPE:
00299 case REAL_TYPE:
00300 case VOID_TYPE:
00301 case BOOLEAN_TYPE:
00302 case COMPLEX_TYPE:
00303 case VECTOR_TYPE:
00304 pp_type_specifier_seq (cxx_pp, t);
00305 break;
00306
00307 case TEMPLATE_TEMPLATE_PARM:
00308
00309 if (TYPE_IDENTIFIER (t))
00310 pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
00311 else
00312 pp_cxx_canonical_template_parameter (cxx_pp, t);
00313 break;
00314
00315 case BOUND_TEMPLATE_TEMPLATE_PARM:
00316 {
00317 tree args = TYPE_TI_ARGS (t);
00318 pp_cxx_cv_qualifier_seq (cxx_pp, t);
00319 pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
00320 pp_cxx_begin_template_argument_list (cxx_pp);
00321 dump_template_argument_list (args, flags);
00322 pp_cxx_end_template_argument_list (cxx_pp);
00323 }
00324 break;
00325
00326 case TEMPLATE_TYPE_PARM:
00327 pp_cxx_cv_qualifier_seq (cxx_pp, t);
00328 if (TYPE_IDENTIFIER (t))
00329 pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
00330 else
00331 pp_cxx_canonical_template_parameter
00332 (cxx_pp, TEMPLATE_TYPE_PARM_INDEX (t));
00333 break;
00334
00335
00336
00337 case ARRAY_TYPE:
00338 case POINTER_TYPE:
00339 case REFERENCE_TYPE:
00340 case OFFSET_TYPE:
00341 offset_type:
00342 case FUNCTION_TYPE:
00343 case METHOD_TYPE:
00344 {
00345 dump_type_prefix (t, flags);
00346 dump_type_suffix (t, flags);
00347 break;
00348 }
00349 case TYPENAME_TYPE:
00350 pp_cxx_cv_qualifier_seq (cxx_pp, t);
00351 pp_cxx_identifier (cxx_pp,
00352 TYPENAME_IS_ENUM_P (t) ? "enum"
00353 : TYPENAME_IS_CLASS_P (t) ? "class"
00354 : "typename");
00355 dump_typename (t, flags);
00356 break;
00357
00358 case UNBOUND_CLASS_TEMPLATE:
00359 dump_type (TYPE_CONTEXT (t), flags);
00360 pp_cxx_colon_colon (cxx_pp);
00361 pp_cxx_identifier (cxx_pp, "template");
00362 dump_type (DECL_NAME (TYPE_NAME (t)), flags);
00363 break;
00364
00365 case TYPEOF_TYPE:
00366 pp_cxx_identifier (cxx_pp, "__typeof__");
00367 pp_cxx_whitespace (cxx_pp);
00368 pp_cxx_left_paren (cxx_pp);
00369 dump_expr (TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
00370 pp_cxx_right_paren (cxx_pp);
00371 break;
00372
00373 default:
00374 pp_unsupported_tree (cxx_pp, t);
00375
00376
00377 case ERROR_MARK:
00378 pp_identifier (cxx_pp, "<type error>");
00379 break;
00380 }
00381 }
00382
00383
00384
00385
00386 static void
00387 dump_typename (tree t, int flags)
00388 {
00389 tree ctx = TYPE_CONTEXT (t);
00390
00391 if (TREE_CODE (ctx) == TYPENAME_TYPE)
00392 dump_typename (ctx, flags);
00393 else
00394 dump_type (ctx, flags & ~TFF_CLASS_KEY_OR_ENUM);
00395 pp_cxx_colon_colon (cxx_pp);
00396 dump_decl (TYPENAME_TYPE_FULLNAME (t), flags);
00397 }
00398
00399
00400
00401 const char *
00402 class_key_or_enum_as_string (tree t)
00403 {
00404 if (TREE_CODE (t) == ENUMERAL_TYPE)
00405 return "enum";
00406 else if (TREE_CODE (t) == UNION_TYPE)
00407 return "union";
00408 else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
00409 return "class";
00410 else
00411 return "struct";
00412 }
00413
00414
00415
00416
00417 static void
00418 dump_aggr_type (tree t, int flags)
00419 {
00420 tree name;
00421 const char *variety = class_key_or_enum_as_string (t);
00422 int typdef = 0;
00423 int tmplate = 0;
00424
00425 pp_cxx_cv_qualifier_seq (cxx_pp, t);
00426
00427 if (flags & TFF_CLASS_KEY_OR_ENUM)
00428 pp_cxx_identifier (cxx_pp, variety);
00429
00430 if (flags & TFF_CHASE_TYPEDEF)
00431 t = TYPE_MAIN_VARIANT (t);
00432
00433 name = TYPE_NAME (t);
00434
00435 if (name)
00436 {
00437 typdef = !DECL_ARTIFICIAL (name);
00438 tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
00439 && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
00440 && (CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
00441 || TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
00442 || DECL_TEMPLATE_SPECIALIZATION (CLASSTYPE_TI_TEMPLATE (t))
00443 || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
00444 dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE);
00445 if (tmplate)
00446 {
00447
00448
00449 tree tpl = CLASSTYPE_TI_TEMPLATE (t);
00450
00451 while (DECL_TEMPLATE_INFO (tpl))
00452 tpl = DECL_TI_TEMPLATE (tpl);
00453 name = tpl;
00454 }
00455 name = DECL_NAME (name);
00456 }
00457
00458 if (name == 0 || ANON_AGGRNAME_P (name))
00459 {
00460 if (flags & TFF_CLASS_KEY_OR_ENUM)
00461 pp_identifier (cxx_pp, "<anonymous>");
00462 else
00463 pp_printf (pp_base (cxx_pp), "<anonymous %s>", variety);
00464 }
00465 else
00466 pp_cxx_tree_identifier (cxx_pp, name);
00467 if (tmplate)
00468 dump_template_parms (TYPE_TEMPLATE_INFO (t),
00469 !CLASSTYPE_USE_TEMPLATE (t),
00470 flags & ~TFF_TEMPLATE_HEADER);
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 static void
00485 dump_type_prefix (tree t, int flags)
00486 {
00487 if (TYPE_PTRMEMFUNC_P (t))
00488 {
00489 t = TYPE_PTRMEMFUNC_FN_TYPE (t);
00490 goto offset_type;
00491 }
00492
00493 switch (TREE_CODE (t))
00494 {
00495 case POINTER_TYPE:
00496 case REFERENCE_TYPE:
00497 {
00498 tree sub = TREE_TYPE (t);
00499
00500 dump_type_prefix (sub, flags);
00501 if (TREE_CODE (sub) == ARRAY_TYPE)
00502 {
00503 pp_cxx_whitespace (cxx_pp);
00504 pp_cxx_left_paren (cxx_pp);
00505 }
00506 pp_character (cxx_pp, "&*"[TREE_CODE (t) == POINTER_TYPE]);
00507 pp_base (cxx_pp)->padding = pp_before;
00508 pp_cxx_cv_qualifier_seq (cxx_pp, t);
00509 }
00510 break;
00511
00512 case OFFSET_TYPE:
00513 offset_type:
00514 dump_type_prefix (TREE_TYPE (t), flags);
00515 if (TREE_CODE (t) == OFFSET_TYPE)
00516 {
00517 pp_maybe_space (cxx_pp);
00518 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
00519 pp_cxx_left_paren (cxx_pp);
00520 dump_type (TYPE_OFFSET_BASETYPE (t), flags);
00521 pp_cxx_colon_colon (cxx_pp);
00522 }
00523 pp_cxx_star (cxx_pp);
00524 pp_cxx_cv_qualifier_seq (cxx_pp, t);
00525 pp_base (cxx_pp)->padding = pp_before;
00526 break;
00527
00528
00529
00530 case FUNCTION_TYPE:
00531 dump_type_prefix (TREE_TYPE (t), flags);
00532 pp_maybe_space (cxx_pp);
00533 pp_cxx_left_paren (cxx_pp);
00534 break;
00535
00536 case METHOD_TYPE:
00537 dump_type_prefix (TREE_TYPE (t), flags);
00538 pp_maybe_space (cxx_pp);
00539 pp_cxx_left_paren (cxx_pp);
00540 dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags);
00541 pp_cxx_colon_colon (cxx_pp);
00542 break;
00543
00544 case ARRAY_TYPE:
00545 dump_type_prefix (TREE_TYPE (t), flags);
00546 break;
00547
00548 case ENUMERAL_TYPE:
00549 case IDENTIFIER_NODE:
00550 case INTEGER_TYPE:
00551 case BOOLEAN_TYPE:
00552 case REAL_TYPE:
00553 case RECORD_TYPE:
00554 case TEMPLATE_TYPE_PARM:
00555 case TEMPLATE_TEMPLATE_PARM:
00556 case BOUND_TEMPLATE_TEMPLATE_PARM:
00557 case TREE_LIST:
00558 case TYPE_DECL:
00559 case TREE_VEC:
00560 case UNION_TYPE:
00561 case UNKNOWN_TYPE:
00562 case VOID_TYPE:
00563 case TYPENAME_TYPE:
00564 case COMPLEX_TYPE:
00565 case VECTOR_TYPE:
00566 case TYPEOF_TYPE:
00567 dump_type (t, flags);
00568 pp_base (cxx_pp)->padding = pp_before;
00569 break;
00570
00571 default:
00572 pp_unsupported_tree (cxx_pp, t);
00573
00574 case ERROR_MARK:
00575 pp_identifier (cxx_pp, "<typeprefixerror>");
00576 break;
00577 }
00578 }
00579
00580
00581
00582
00583 static void
00584 dump_type_suffix (tree t, int flags)
00585 {
00586 if (TYPE_PTRMEMFUNC_P (t))
00587 t = TYPE_PTRMEMFUNC_FN_TYPE (t);
00588
00589 switch (TREE_CODE (t))
00590 {
00591 case POINTER_TYPE:
00592 case REFERENCE_TYPE:
00593 case OFFSET_TYPE:
00594 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
00595 pp_cxx_right_paren (cxx_pp);
00596 dump_type_suffix (TREE_TYPE (t), flags);
00597 break;
00598
00599
00600 case FUNCTION_TYPE:
00601 case METHOD_TYPE:
00602 {
00603 tree arg;
00604 pp_cxx_right_paren (cxx_pp);
00605 arg = TYPE_ARG_TYPES (t);
00606 if (TREE_CODE (t) == METHOD_TYPE)
00607 arg = TREE_CHAIN (arg);
00608
00609
00610
00611 dump_parameters (arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
00612
00613 if (TREE_CODE (t) == METHOD_TYPE)
00614 pp_cxx_cv_qualifier_seq
00615 (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
00616 else
00617 pp_cxx_cv_qualifier_seq(cxx_pp, t);
00618 dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags);
00619 dump_type_suffix (TREE_TYPE (t), flags);
00620 break;
00621 }
00622
00623 case ARRAY_TYPE:
00624 pp_maybe_space (cxx_pp);
00625 pp_cxx_left_bracket (cxx_pp);
00626 if (TYPE_DOMAIN (t))
00627 {
00628 if (host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0))
00629 pp_wide_integer
00630 (cxx_pp, tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0) + 1);
00631 else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR)
00632 dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0),
00633 flags & ~TFF_EXPR_IN_PARENS);
00634 else
00635 dump_expr (fold (cp_build_binary_op
00636 (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
00637 integer_one_node)),
00638 flags & ~TFF_EXPR_IN_PARENS);
00639 }
00640 pp_cxx_right_bracket (cxx_pp);
00641 dump_type_suffix (TREE_TYPE (t), flags);
00642 break;
00643
00644 case ENUMERAL_TYPE:
00645 case IDENTIFIER_NODE:
00646 case INTEGER_TYPE:
00647 case BOOLEAN_TYPE:
00648 case REAL_TYPE:
00649 case RECORD_TYPE:
00650 case TEMPLATE_TYPE_PARM:
00651 case TEMPLATE_TEMPLATE_PARM:
00652 case BOUND_TEMPLATE_TEMPLATE_PARM:
00653 case TREE_LIST:
00654 case TYPE_DECL:
00655 case TREE_VEC:
00656 case UNION_TYPE:
00657 case UNKNOWN_TYPE:
00658 case VOID_TYPE:
00659 case TYPENAME_TYPE:
00660 case COMPLEX_TYPE:
00661 case VECTOR_TYPE:
00662 case TYPEOF_TYPE:
00663 break;
00664
00665 default:
00666 pp_unsupported_tree (cxx_pp, t);
00667 case ERROR_MARK:
00668
00669
00670 break;
00671 }
00672 }
00673
00674 static void
00675 dump_global_iord (tree t)
00676 {
00677 const char *p = NULL;
00678
00679 if (DECL_GLOBAL_CTOR_P (t))
00680 p = "initializers";
00681 else if (DECL_GLOBAL_DTOR_P (t))
00682 p = "destructors";
00683 else
00684 gcc_unreachable ();
00685
00686 pp_printf (pp_base (cxx_pp), "(static %s for %s)", p, input_filename);
00687 }
00688
00689 static void
00690 dump_simple_decl (tree t, tree type, int flags)
00691 {
00692 if (flags & TFF_DECL_SPECIFIERS)
00693 {
00694 dump_type_prefix (type, flags);
00695 pp_maybe_space (cxx_pp);
00696 }
00697 if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)
00698 dump_scope (CP_DECL_CONTEXT (t), flags);
00699 if (DECL_NAME (t))
00700 dump_decl (DECL_NAME (t), flags);
00701 else
00702 pp_identifier (cxx_pp, "<anonymous>");
00703 if (flags & TFF_DECL_SPECIFIERS)
00704 dump_type_suffix (type, flags);
00705 }
00706
00707
00708
00709 static void
00710 dump_decl (tree t, int flags)
00711 {
00712 if (t == NULL_TREE)
00713 return;
00714
00715 switch (TREE_CODE (t))
00716 {
00717 case TYPE_DECL:
00718
00719 if (DECL_ARTIFICIAL (t))
00720 {
00721 if ((flags & TFF_DECL_SPECIFIERS)
00722 && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
00723
00724 pp_cxx_identifier (cxx_pp, "class");
00725
00726 dump_type (TREE_TYPE (t), flags);
00727 break;
00728 }
00729 if (flags & TFF_DECL_SPECIFIERS)
00730 pp_cxx_identifier (cxx_pp, "typedef");
00731 dump_simple_decl (t, DECL_ORIGINAL_TYPE (t)
00732 ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
00733 flags);
00734 break;
00735
00736 case VAR_DECL:
00737 if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
00738 {
00739 pp_string (cxx_pp, "vtable for ");
00740 gcc_assert (TYPE_P (DECL_CONTEXT (t)));
00741 dump_type (DECL_CONTEXT (t), flags);
00742 break;
00743 }
00744
00745 case FIELD_DECL:
00746 case PARM_DECL:
00747 dump_simple_decl (t, TREE_TYPE (t), flags);
00748 break;
00749
00750 case RESULT_DECL:
00751 pp_string (cxx_pp, "<return value> ");
00752 dump_simple_decl (t, TREE_TYPE (t), flags);
00753 break;
00754
00755 case NAMESPACE_DECL:
00756 if (flags & TFF_DECL_SPECIFIERS)
00757 pp_cxx_declaration (cxx_pp, t);
00758 else
00759 {
00760 dump_scope (CP_DECL_CONTEXT (t), flags);
00761 if (DECL_NAME (t) == NULL_TREE)
00762 pp_identifier (cxx_pp, "<unnamed>");
00763 else
00764 pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t));
00765 }
00766 break;
00767
00768 case SCOPE_REF:
00769 pp_expression (cxx_pp, t);
00770 break;
00771
00772 case ARRAY_REF:
00773 dump_decl (TREE_OPERAND (t, 0), flags);
00774 pp_cxx_left_bracket (cxx_pp);
00775 dump_decl (TREE_OPERAND (t, 1), flags);
00776 pp_cxx_right_bracket (cxx_pp);
00777 break;
00778
00779
00780 case RECORD_TYPE:
00781 case UNION_TYPE:
00782 case ENUMERAL_TYPE:
00783 dump_type (t, flags);
00784 break;
00785
00786 case BIT_NOT_EXPR:
00787
00788
00789 pp_cxx_complement (cxx_pp);
00790 dump_type (TREE_OPERAND (t, 0), flags);
00791 break;
00792
00793 case TYPE_EXPR:
00794 gcc_unreachable ();
00795 break;
00796
00797
00798
00799 case IDENTIFIER_NODE:
00800 if (IDENTIFIER_TYPENAME_P (t))
00801 {
00802 pp_cxx_identifier (cxx_pp, "operator");
00803
00804 dump_type (TREE_TYPE (t), flags);
00805 break;
00806 }
00807 else
00808 pp_cxx_tree_identifier (cxx_pp, t);
00809 break;
00810
00811 case OVERLOAD:
00812 if (OVL_CHAIN (t))
00813 {
00814 t = OVL_CURRENT (t);
00815 if (DECL_CLASS_SCOPE_P (t))
00816 {
00817 dump_type (DECL_CONTEXT (t), flags);
00818 pp_cxx_colon_colon (cxx_pp);
00819 }
00820 else if (DECL_CONTEXT (t))
00821 {
00822 dump_decl (DECL_CONTEXT (t), flags);
00823 pp_cxx_colon_colon (cxx_pp);
00824 }
00825 dump_decl (DECL_NAME (t), flags);
00826 break;
00827 }
00828
00829
00830
00831 t = OVL_CURRENT (t);
00832
00833
00834 case FUNCTION_DECL:
00835 if (! DECL_LANG_SPECIFIC (t))
00836 pp_identifier (cxx_pp, "<built-in>");
00837 else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
00838 dump_global_iord (t);
00839 else
00840 dump_function_decl (t, flags);
00841 break;
00842
00843 case TEMPLATE_DECL:
00844 dump_template_decl (t, flags);
00845 break;
00846
00847 case TEMPLATE_ID_EXPR:
00848 {
00849 tree name = TREE_OPERAND (t, 0);
00850
00851 if (is_overloaded_fn (name))
00852 name = DECL_NAME (get_first_fn (name));
00853 dump_decl (name, flags);
00854 pp_cxx_begin_template_argument_list (cxx_pp);
00855 if (TREE_OPERAND (t, 1))
00856 dump_template_argument_list (TREE_OPERAND (t, 1), flags);
00857 pp_cxx_end_template_argument_list (cxx_pp);
00858 }
00859 break;
00860
00861 case LABEL_DECL:
00862 pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t));
00863 break;
00864
00865 case CONST_DECL:
00866 if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
00867 || (DECL_INITIAL (t) &&
00868 TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
00869 dump_simple_decl (t, TREE_TYPE (t), flags);
00870 else if (DECL_NAME (t))
00871 dump_decl (DECL_NAME (t), flags);
00872 else if (DECL_INITIAL (t))
00873 dump_expr (DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
00874 else
00875 pp_identifier (cxx_pp, "<enumerator>");
00876 break;
00877
00878 case USING_DECL:
00879 pp_cxx_identifier (cxx_pp, "using");
00880 dump_type (DECL_INITIAL (t), flags);
00881 pp_cxx_colon_colon (cxx_pp);
00882 dump_decl (DECL_NAME (t), flags);
00883 break;
00884
00885 case BASELINK:
00886 dump_decl (BASELINK_FUNCTIONS (t), flags);
00887 break;
00888
00889 case NON_DEPENDENT_EXPR:
00890 dump_expr (t, flags);
00891 break;
00892
00893 case TEMPLATE_TYPE_PARM:
00894 if (flags & TFF_DECL_SPECIFIERS)
00895 pp_cxx_declaration (cxx_pp, t);
00896 else
00897 pp_type_id (cxx_pp, t);
00898 break;
00899
00900 default:
00901 pp_unsupported_tree (cxx_pp, t);
00902
00903
00904 case ERROR_MARK:
00905 pp_identifier (cxx_pp, "<declaration error>");
00906 break;
00907 }
00908 }
00909
00910
00911
00912
00913 static void
00914 dump_template_decl (tree t, int flags)
00915 {
00916 tree orig_parms = DECL_TEMPLATE_PARMS (t);
00917 tree parms;
00918 int i;
00919
00920 if (flags & TFF_TEMPLATE_HEADER)
00921 {
00922 for (parms = orig_parms = nreverse (orig_parms);
00923 parms;
00924 parms = TREE_CHAIN (parms))
00925 {
00926 tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
00927 int len = TREE_VEC_LENGTH (inner_parms);
00928
00929 pp_cxx_identifier (cxx_pp, "template");
00930 pp_cxx_begin_template_argument_list (cxx_pp);
00931
00932
00933
00934 flags |= TFF_DECL_SPECIFIERS;
00935
00936 for (i = 0; i < len; i++)
00937 {
00938 if (i)
00939 pp_separate_with_comma (cxx_pp);
00940 dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags);
00941 }
00942 pp_cxx_end_template_argument_list (cxx_pp);
00943 pp_cxx_whitespace (cxx_pp);
00944 }
00945 nreverse(orig_parms);
00946
00947 if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
00948
00949 pp_cxx_identifier (cxx_pp, "class");
00950 }
00951
00952 if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
00953 dump_type (TREE_TYPE (t),
00954 ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
00955 | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)));
00956 else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL)
00957 dump_decl (DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME);
00958 else
00959 {
00960 gcc_assert (TREE_TYPE (t));
00961 switch (NEXT_CODE (t))
00962 {
00963 case METHOD_TYPE:
00964 case FUNCTION_TYPE:
00965 dump_function_decl (t, flags | TFF_TEMPLATE_NAME);
00966 break;
00967 default:
00968
00969 dump_type (TREE_TYPE (t),
00970 (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
00971 | (flags & TFF_DECL_SPECIFIERS
00972 ? TFF_CLASS_KEY_OR_ENUM : 0));
00973 }
00974 }
00975 }
00976
00977
00978
00979
00980
00981
00982 static void
00983 dump_function_decl (tree t, int flags)
00984 {
00985 tree fntype;
00986 tree parmtypes;
00987 tree cname = NULL_TREE;
00988 tree template_args = NULL_TREE;
00989 tree template_parms = NULL_TREE;
00990 int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
00991
00992 if (TREE_CODE (t) == TEMPLATE_DECL)
00993 t = DECL_TEMPLATE_RESULT (t);
00994
00995
00996 if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t))
00997 {
00998 tree tmpl;
00999
01000 template_args = DECL_TI_ARGS (t);
01001 tmpl = most_general_template (t);
01002 if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL)
01003 {
01004 template_parms = DECL_TEMPLATE_PARMS (tmpl);
01005 t = tmpl;
01006 }
01007 }
01008
01009 fntype = TREE_TYPE (t);
01010 parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
01011
01012 if (DECL_CLASS_SCOPE_P (t))
01013 cname = DECL_CONTEXT (t);
01014
01015 else if (TREE_CODE (fntype) == METHOD_TYPE)
01016 cname = TREE_TYPE (TREE_VALUE (parmtypes));
01017
01018 if (!(flags & TFF_DECL_SPECIFIERS))
01019 ;
01020 else if (DECL_STATIC_FUNCTION_P (t))
01021 pp_cxx_identifier (cxx_pp, "static");
01022 else if (DECL_VIRTUAL_P (t))
01023 pp_cxx_identifier (cxx_pp, "virtual");
01024
01025
01026 if (show_return)
01027 show_return = !DECL_CONV_FN_P (t) && !DECL_CONSTRUCTOR_P (t)
01028 && !DECL_DESTRUCTOR_P (t);
01029 if (show_return)
01030 dump_type_prefix (TREE_TYPE (fntype), flags);
01031
01032
01033 if (cname)
01034 {
01035 dump_type (cname, flags);
01036 pp_cxx_colon_colon (cxx_pp);
01037 }
01038 else
01039 dump_scope (CP_DECL_CONTEXT (t), flags);
01040
01041 dump_function_name (t, flags);
01042
01043 if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
01044 {
01045 dump_parameters (parmtypes, flags);
01046
01047 if (TREE_CODE (fntype) == METHOD_TYPE)
01048 {
01049 pp_base (cxx_pp)->padding = pp_before;
01050 pp_cxx_cv_qualifier_seq
01051 (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))));
01052 }
01053
01054 if (flags & TFF_EXCEPTION_SPECIFICATION)
01055 {
01056 pp_base (cxx_pp)->padding = pp_before;
01057 dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags);
01058 }
01059
01060 if (show_return)
01061 dump_type_suffix (TREE_TYPE (fntype), flags);
01062 }
01063
01064
01065 if (template_parms != NULL_TREE && template_args != NULL_TREE)
01066 {
01067 pp_cxx_whitespace (cxx_pp);
01068 pp_cxx_left_bracket (cxx_pp);
01069 pp_cxx_identifier (cxx_pp, "with");
01070 pp_cxx_whitespace (cxx_pp);
01071 dump_template_bindings (template_parms, template_args);
01072 pp_cxx_right_bracket (cxx_pp);
01073 }
01074 }
01075
01076
01077
01078
01079
01080 static void
01081 dump_parameters (tree parmtypes, int flags)
01082 {
01083 int first;
01084
01085 pp_cxx_left_paren (cxx_pp);
01086
01087 for (first = 1; parmtypes != void_list_node;
01088 parmtypes = TREE_CHAIN (parmtypes))
01089 {
01090 if (!first)
01091 pp_separate_with_comma (cxx_pp);
01092 first = 0;
01093 if (!parmtypes)
01094 {
01095 pp_cxx_identifier (cxx_pp, "...");
01096 break;
01097 }
01098 dump_type (TREE_VALUE (parmtypes), flags);
01099
01100 if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes))
01101 {
01102 pp_cxx_whitespace (cxx_pp);
01103 pp_equal (cxx_pp);
01104 pp_cxx_whitespace (cxx_pp);
01105 dump_expr (TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS);
01106 }
01107 }
01108
01109 pp_cxx_right_paren (cxx_pp);
01110 }
01111
01112
01113
01114 static void
01115 dump_exception_spec (tree t, int flags)
01116 {
01117 if (t)
01118 {
01119 pp_cxx_identifier (cxx_pp, "throw");
01120 pp_cxx_whitespace (cxx_pp);
01121 pp_cxx_left_paren (cxx_pp);
01122 if (TREE_VALUE (t) != NULL_TREE)
01123 while (1)
01124 {
01125 dump_type (TREE_VALUE (t), flags);
01126 t = TREE_CHAIN (t);
01127 if (!t)
01128 break;
01129 pp_separate_with_comma (cxx_pp);
01130 }
01131 pp_cxx_right_paren (cxx_pp);
01132 }
01133 }
01134
01135
01136
01137
01138 static void
01139 dump_function_name (tree t, int flags)
01140 {
01141 tree name = DECL_NAME (t);
01142
01143
01144
01145
01146
01147
01148 if (!DECL_LANG_SPECIFIC (t))
01149 {
01150 pp_cxx_tree_identifier (cxx_pp, name);
01151 return;
01152 }
01153
01154 if (TREE_CODE (t) == TEMPLATE_DECL)
01155 t = DECL_TEMPLATE_RESULT (t);
01156
01157
01158 if (DECL_CONSTRUCTOR_P (t)
01159 || DECL_DESTRUCTOR_P (t))
01160 name = constructor_name (DECL_CONTEXT (t));
01161
01162 if (DECL_DESTRUCTOR_P (t))
01163 {
01164 pp_cxx_complement (cxx_pp);
01165 dump_decl (name, TFF_PLAIN_IDENTIFIER);
01166 }
01167 else if (DECL_CONV_FN_P (t))
01168 {
01169
01170
01171
01172
01173
01174
01175 pp_cxx_identifier (cxx_pp, "operator");
01176 dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
01177 }
01178 else if (IDENTIFIER_OPNAME_P (name))
01179 pp_cxx_tree_identifier (cxx_pp, name);
01180 else
01181 dump_decl (name, flags);
01182
01183 if (DECL_TEMPLATE_INFO (t)
01184 && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
01185 && (DECL_TEMPLATE_SPECIALIZATION (t)
01186 || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
01187 || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t))
01188 || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
01189 dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags);
01190 }
01191
01192
01193
01194
01195
01196
01197
01198 static void
01199 dump_template_parms (tree info, int primary, int flags)
01200 {
01201 tree args = info ? TI_ARGS (info) : NULL_TREE;
01202
01203 if (primary && flags & TFF_TEMPLATE_NAME)
01204 return;
01205 flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME);
01206 pp_cxx_begin_template_argument_list (cxx_pp);
01207
01208
01209
01210 if (args && !primary)
01211 {
01212 int len, ix;
01213
01214 if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
01215 args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
01216
01217 len = TREE_VEC_LENGTH (args);
01218
01219 for (ix = 0; ix != len; ix++)
01220 {
01221 tree arg = TREE_VEC_ELT (args, ix);
01222
01223 if (ix)
01224 pp_separate_with_comma (cxx_pp);
01225
01226 if (!arg)
01227 pp_identifier (cxx_pp, "<template parameter error>");
01228 else
01229 dump_template_argument (arg, flags);
01230 }
01231 }
01232 else if (primary)
01233 {
01234 tree tpl = TI_TEMPLATE (info);
01235 tree parms = DECL_TEMPLATE_PARMS (tpl);
01236 int len, ix;
01237
01238 parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE;
01239 len = parms ? TREE_VEC_LENGTH (parms) : 0;
01240
01241 for (ix = 0; ix != len; ix++)
01242 {
01243 tree parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
01244
01245 if (ix)
01246 pp_separate_with_comma (cxx_pp);
01247
01248 dump_decl (parm, flags & ~TFF_DECL_SPECIFIERS);
01249 }
01250 }
01251 pp_cxx_end_template_argument_list (cxx_pp);
01252 }
01253
01254
01255
01256 static void
01257 dump_expr_list (tree l, int flags)
01258 {
01259 while (l)
01260 {
01261 dump_expr (TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS);
01262 l = TREE_CHAIN (l);
01263 if (l)
01264 pp_separate_with_comma (cxx_pp);
01265 }
01266 }
01267
01268
01269
01270 static void
01271 dump_expr (tree t, int flags)
01272 {
01273 if (t == 0)
01274 return;
01275
01276 switch (TREE_CODE (t))
01277 {
01278 case VAR_DECL:
01279 case PARM_DECL:
01280 case FIELD_DECL:
01281 case CONST_DECL:
01282 case FUNCTION_DECL:
01283 case TEMPLATE_DECL:
01284 case NAMESPACE_DECL:
01285 case OVERLOAD:
01286 case IDENTIFIER_NODE:
01287 dump_decl (t, (flags & ~TFF_DECL_SPECIFIERS) | TFF_NO_FUNCTION_ARGUMENTS);
01288 break;
01289
01290 case STRING_CST:
01291 if (PAREN_STRING_LITERAL_P (t))
01292 pp_cxx_left_paren (cxx_pp);
01293 pp_c_constant (pp_c_base (cxx_pp), t);
01294 if (PAREN_STRING_LITERAL_P (t))
01295 pp_cxx_right_paren (cxx_pp);
01296 break;
01297
01298 case INTEGER_CST:
01299 case REAL_CST:
01300 pp_c_constant (pp_c_base (cxx_pp), t);
01301 break;
01302
01303 case THROW_EXPR:
01304 pp_cxx_identifier (cxx_pp, "throw");
01305 dump_expr (TREE_OPERAND (t, 0), flags);
01306 break;
01307
01308 case PTRMEM_CST:
01309 pp_ampersand (cxx_pp);
01310 dump_type (PTRMEM_CST_CLASS (t), flags);
01311 pp_cxx_colon_colon (cxx_pp);
01312 pp_cxx_tree_identifier (cxx_pp, DECL_NAME (PTRMEM_CST_MEMBER (t)));
01313 break;
01314
01315 case COMPOUND_EXPR:
01316 pp_cxx_left_paren (cxx_pp);
01317 dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
01318 pp_separate_with_comma (cxx_pp);
01319 dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
01320 pp_cxx_right_paren (cxx_pp);
01321 break;
01322
01323 case COND_EXPR:
01324 pp_cxx_left_paren (cxx_pp);
01325 dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
01326 pp_string (cxx_pp, " ? ");
01327 dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
01328 pp_string (cxx_pp, " : ");
01329 dump_expr (TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS);
01330 pp_cxx_right_paren (cxx_pp);
01331 break;
01332
01333 case SAVE_EXPR:
01334 if (TREE_HAS_CONSTRUCTOR (t))
01335 {
01336 pp_cxx_identifier (cxx_pp, "new");
01337 pp_cxx_whitespace (cxx_pp);
01338 dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
01339 }
01340 else
01341 dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
01342 break;
01343
01344 case AGGR_INIT_EXPR:
01345 {
01346 tree fn = NULL_TREE;
01347
01348 if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
01349 fn = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
01350
01351 if (fn && TREE_CODE (fn) == FUNCTION_DECL)
01352 {
01353 if (DECL_CONSTRUCTOR_P (fn))
01354 dump_type (DECL_CONTEXT (fn), flags);
01355 else
01356 dump_decl (fn, 0);
01357 }
01358 else
01359 dump_expr (TREE_OPERAND (t, 0), 0);
01360 }
01361 pp_cxx_left_paren (cxx_pp);
01362 if (TREE_OPERAND (t, 1))
01363 dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
01364 pp_cxx_right_paren (cxx_pp);
01365 break;
01366
01367 case CALL_EXPR:
01368 {
01369 tree fn = TREE_OPERAND (t, 0);
01370 tree args = TREE_OPERAND (t, 1);
01371
01372 if (TREE_CODE (fn) == ADDR_EXPR)
01373 fn = TREE_OPERAND (fn, 0);
01374
01375 if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)
01376 {
01377 tree ob = TREE_VALUE (args);
01378 if (TREE_CODE (ob) == ADDR_EXPR)
01379 {
01380 dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
01381 pp_dot (cxx_pp);
01382 }
01383 else if (TREE_CODE (ob) != PARM_DECL
01384 || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
01385 {
01386 dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
01387 pp_arrow (cxx_pp);
01388 }
01389 args = TREE_CHAIN (args);
01390 }
01391 dump_expr (fn, flags | TFF_EXPR_IN_PARENS);
01392 pp_cxx_left_paren (cxx_pp);
01393 dump_expr_list (args, flags);
01394 pp_cxx_right_paren (cxx_pp);
01395 }
01396 break;
01397
01398 case NEW_EXPR:
01399 {
01400 tree type = TREE_OPERAND (t, 1);
01401 tree init = TREE_OPERAND (t, 2);
01402 if (NEW_EXPR_USE_GLOBAL (t))
01403 pp_cxx_colon_colon (cxx_pp);
01404 pp_cxx_identifier (cxx_pp, "new");
01405 if (TREE_OPERAND (t, 0))
01406 {
01407 pp_cxx_left_paren (cxx_pp);
01408 dump_expr_list (TREE_OPERAND (t, 0), flags);
01409 pp_cxx_right_paren (cxx_pp);
01410 pp_cxx_whitespace (cxx_pp);
01411 }
01412 if (TREE_CODE (type) == ARRAY_REF)
01413 type = build_cplus_array_type
01414 (TREE_OPERAND (type, 0),
01415 build_index_type (fold (build2 (MINUS_EXPR, integer_type_node,
01416 TREE_OPERAND (type, 1),
01417 integer_one_node))));
01418 dump_type (type, flags);
01419 if (init)
01420 {
01421 pp_cxx_left_paren (cxx_pp);
01422 if (TREE_CODE (init) == TREE_LIST)
01423 dump_expr_list (init, flags);
01424 else if (init == void_zero_node)
01425
01426
01427 ;
01428 else
01429 dump_expr (init, flags);
01430 pp_cxx_right_paren (cxx_pp);
01431 }
01432 }
01433 break;
01434
01435 case TARGET_EXPR:
01436
01437
01438
01439
01440
01441 if (TREE_OPERAND (t, 1))
01442 dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
01443 break;
01444
01445 case INIT_EXPR:
01446 case MODIFY_EXPR:
01447 case PLUS_EXPR:
01448 case MINUS_EXPR:
01449 case MULT_EXPR:
01450 case TRUNC_DIV_EXPR:
01451 case TRUNC_MOD_EXPR:
01452 case MIN_EXPR:
01453 case MAX_EXPR:
01454 case LSHIFT_EXPR:
01455 case RSHIFT_EXPR:
01456 case BIT_IOR_EXPR:
01457 case BIT_XOR_EXPR:
01458 case BIT_AND_EXPR:
01459 case TRUTH_ANDIF_EXPR:
01460 case TRUTH_ORIF_EXPR:
01461 case LT_EXPR:
01462 case LE_EXPR:
01463 case GT_EXPR:
01464 case GE_EXPR:
01465 case EQ_EXPR:
01466 case NE_EXPR:
01467 case EXACT_DIV_EXPR:
01468 dump_binary_op (operator_name_info[(int) TREE_CODE (t)].name, t, flags);
01469 break;
01470
01471 case CEIL_DIV_EXPR:
01472 case FLOOR_DIV_EXPR:
01473 case ROUND_DIV_EXPR:
01474 case RDIV_EXPR:
01475 dump_binary_op ("/", t, flags);
01476 break;
01477
01478 case CEIL_MOD_EXPR:
01479 case FLOOR_MOD_EXPR:
01480 case ROUND_MOD_EXPR:
01481 dump_binary_op ("%", t, flags);
01482 break;
01483
01484 case COMPONENT_REF:
01485 {
01486 tree ob = TREE_OPERAND (t, 0);
01487 if (TREE_CODE (ob) == INDIRECT_REF)
01488 {
01489 ob = TREE_OPERAND (ob, 0);
01490 if (TREE_CODE (ob) != PARM_DECL
01491 || (DECL_NAME (ob)
01492 && strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")))
01493 {
01494 dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
01495 pp_cxx_arrow (cxx_pp);
01496 }
01497 }
01498 else
01499 {
01500 dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
01501 pp_cxx_dot (cxx_pp);
01502 }
01503 dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
01504 }
01505 break;
01506
01507 case ARRAY_REF:
01508 dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
01509 pp_cxx_left_bracket (cxx_pp);
01510 dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
01511 pp_cxx_right_bracket (cxx_pp);
01512 break;
01513
01514 case CONVERT_EXPR:
01515 if (TREE_TYPE (t) && VOID_TYPE_P (TREE_TYPE (t)))
01516 {
01517 pp_cxx_left_paren (cxx_pp);
01518 dump_type (TREE_TYPE (t), flags);
01519 pp_cxx_right_paren (cxx_pp);
01520 dump_expr (TREE_OPERAND (t, 0), flags);
01521 }
01522 else
01523 dump_unary_op ("+", t, flags);
01524 break;
01525
01526 case ADDR_EXPR:
01527 if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
01528 || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST
01529
01530
01531
01532 || (TREE_TYPE (t)
01533 && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE))
01534 dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
01535 else
01536 dump_unary_op ("&", t, flags);
01537 break;
01538
01539 case INDIRECT_REF:
01540 if (TREE_HAS_CONSTRUCTOR (t))
01541 {
01542 t = TREE_OPERAND (t, 0);
01543 gcc_assert (TREE_CODE (t) == CALL_EXPR);
01544 dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
01545 pp_cxx_left_paren (cxx_pp);
01546 dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
01547 pp_cxx_right_paren (cxx_pp);
01548 }
01549 else
01550 {
01551 if (TREE_OPERAND (t,0) != NULL_TREE
01552 && TREE_TYPE (TREE_OPERAND (t, 0))
01553 && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
01554 dump_expr (TREE_OPERAND (t, 0), flags);
01555 else
01556 dump_unary_op ("*", t, flags);
01557 }
01558 break;
01559
01560 case NEGATE_EXPR:
01561 case BIT_NOT_EXPR:
01562 case TRUTH_NOT_EXPR:
01563 case PREDECREMENT_EXPR:
01564 case PREINCREMENT_EXPR:
01565 dump_unary_op (operator_name_info [(int)TREE_CODE (t)].name, t, flags);
01566 break;
01567
01568 case POSTDECREMENT_EXPR:
01569 case POSTINCREMENT_EXPR:
01570 pp_cxx_left_paren (cxx_pp);
01571 dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
01572 pp_cxx_identifier (cxx_pp, operator_name_info[(int)TREE_CODE (t)].name);
01573 pp_cxx_right_paren (cxx_pp);
01574 break;
01575
01576 case NON_LVALUE_EXPR:
01577
01578
01579
01580 if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)
01581 {
01582 tree next = TREE_TYPE (TREE_TYPE (t));
01583
01584 while (TREE_CODE (next) == POINTER_TYPE)
01585 next = TREE_TYPE (next);
01586
01587 if (TREE_CODE (next) == FUNCTION_TYPE)
01588 {
01589 if (flags & TFF_EXPR_IN_PARENS)
01590 pp_cxx_left_paren (cxx_pp);
01591 pp_cxx_star (cxx_pp);
01592 dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
01593 if (flags & TFF_EXPR_IN_PARENS)
01594 pp_cxx_right_paren (cxx_pp);
01595 break;
01596 }
01597
01598 }
01599 dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
01600 break;
01601
01602 case NOP_EXPR:
01603 {
01604 tree op = TREE_OPERAND (t, 0);
01605
01606 if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t)))
01607 {
01608
01609
01610 if (flags & TFF_EXPR_IN_PARENS)
01611 pp_cxx_left_paren (cxx_pp);
01612 pp_cxx_left_paren (cxx_pp);
01613 dump_type (TREE_TYPE (t), flags);
01614 pp_cxx_right_paren (cxx_pp);
01615 dump_expr (op, flags | TFF_EXPR_IN_PARENS);
01616 if (flags & TFF_EXPR_IN_PARENS)
01617 pp_cxx_right_paren (cxx_pp);
01618 }
01619 else
01620 dump_expr (op, flags);
01621 break;
01622 }
01623
01624 case CONSTRUCTOR:
01625 if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
01626 {
01627 tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier);
01628
01629 if (integer_zerop (idx))
01630 {
01631
01632 pp_cxx_left_paren (cxx_pp);
01633 pp_cxx_left_paren (cxx_pp);
01634 dump_type (TREE_TYPE (t), flags);
01635 pp_cxx_right_paren (cxx_pp);
01636 pp_character (cxx_pp, '0');
01637 pp_cxx_right_paren (cxx_pp);
01638 break;
01639 }
01640 else if (host_integerp (idx, 0))
01641 {
01642 tree virtuals;
01643 unsigned HOST_WIDE_INT n;
01644
01645 t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
01646 t = TYPE_METHOD_BASETYPE (t);
01647 virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t)));
01648
01649 n = tree_low_cst (idx, 0);
01650
01651
01652
01653 --n;
01654
01655 while (n > 0 && virtuals)
01656 {
01657 --n;
01658 virtuals = TREE_CHAIN (virtuals);
01659 }
01660 if (virtuals)
01661 {
01662 dump_expr (BV_FN (virtuals),
01663 flags | TFF_EXPR_IN_PARENS);
01664 break;
01665 }
01666 }
01667 }
01668 if (TREE_TYPE (t) && !CONSTRUCTOR_ELTS (t))
01669 {
01670 dump_type (TREE_TYPE (t), 0);
01671 pp_cxx_left_paren (cxx_pp);
01672 pp_cxx_right_paren (cxx_pp);
01673 }
01674 else
01675 {
01676 pp_cxx_left_brace (cxx_pp);
01677 dump_expr_list (CONSTRUCTOR_ELTS (t), flags);
01678 pp_cxx_right_brace (cxx_pp);
01679 }
01680
01681 break;
01682
01683 case OFFSET_REF:
01684 {
01685 tree ob = TREE_OPERAND (t, 0);
01686 if (is_dummy_object (ob))
01687 {
01688 t = TREE_OPERAND (t, 1);
01689 if (TREE_CODE (t) == FUNCTION_DECL)
01690
01691 dump_expr (t, flags | TFF_EXPR_IN_PARENS);
01692 else if (BASELINK_P (t))
01693 dump_expr (OVL_CURRENT (BASELINK_FUNCTIONS (t)),
01694 flags | TFF_EXPR_IN_PARENS);
01695 else
01696 dump_decl (t, flags);
01697 }
01698 else
01699 {
01700 if (TREE_CODE (ob) == INDIRECT_REF)
01701 {
01702 dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
01703 pp_cxx_arrow (cxx_pp);
01704 pp_cxx_star (cxx_pp);
01705 }
01706 else
01707 {
01708 dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
01709 pp_cxx_dot (cxx_pp);
01710 pp_cxx_star (cxx_pp);
01711 }
01712 dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
01713 }
01714 break;
01715 }
01716
01717 case TEMPLATE_PARM_INDEX:
01718 dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
01719 break;
01720
01721 case SCOPE_REF:
01722 pp_expression (cxx_pp, t);
01723 break;
01724
01725 case CAST_EXPR:
01726 if (TREE_OPERAND (t, 0) == NULL_TREE
01727 || TREE_CHAIN (TREE_OPERAND (t, 0)))
01728 {
01729 dump_type (TREE_TYPE (t), flags);
01730 pp_cxx_left_paren (cxx_pp);
01731 dump_expr_list (TREE_OPERAND (t, 0), flags);
01732 pp_cxx_right_paren (cxx_pp);
01733 }
01734 else
01735 {
01736 pp_cxx_left_paren (cxx_pp);
01737 dump_type (TREE_TYPE (t), flags);
01738 pp_cxx_right_paren (cxx_pp);
01739 pp_cxx_left_paren (cxx_pp);
01740 dump_expr_list (TREE_OPERAND (t, 0), flags);
01741 pp_cxx_right_paren (cxx_pp);
01742 }
01743 break;
01744
01745 case STATIC_CAST_EXPR:
01746 pp_cxx_identifier (cxx_pp, "static_cast");
01747 goto cast;
01748 case REINTERPRET_CAST_EXPR:
01749 pp_cxx_identifier (cxx_pp, "reinterpret_cast");
01750 goto cast;
01751 case CONST_CAST_EXPR:
01752 pp_cxx_identifier (cxx_pp, "const_cast");
01753 goto cast;
01754 case DYNAMIC_CAST_EXPR:
01755 pp_cxx_identifier (cxx_pp, "dynamic_cast");
01756 cast:
01757 pp_cxx_begin_template_argument_list (cxx_pp);
01758 dump_type (TREE_TYPE (t), flags);
01759 pp_cxx_end_template_argument_list (cxx_pp);
01760 pp_cxx_left_paren (cxx_pp);
01761 dump_expr (TREE_OPERAND (t, 0), flags);
01762 pp_cxx_right_paren (cxx_pp);
01763 break;
01764
01765 case ARROW_EXPR:
01766 dump_expr (TREE_OPERAND (t, 0), flags);
01767 pp_cxx_arrow (cxx_pp);
01768 break;
01769
01770 case SIZEOF_EXPR:
01771 case ALIGNOF_EXPR:
01772 if (TREE_CODE (t) == SIZEOF_EXPR)
01773 pp_cxx_identifier (cxx_pp, "sizeof");
01774 else
01775 {
01776 gcc_assert (TREE_CODE (t) == ALIGNOF_EXPR);
01777 pp_cxx_identifier (cxx_pp, "__alignof__");
01778 }
01779 pp_cxx_whitespace (cxx_pp);
01780 pp_cxx_left_paren (cxx_pp);
01781 if (TYPE_P (TREE_OPERAND (t, 0)))
01782 dump_type (TREE_OPERAND (t, 0), flags);
01783 else
01784 dump_expr (TREE_OPERAND (t, 0), flags);
01785 pp_cxx_right_paren (cxx_pp);
01786 break;
01787
01788 case REALPART_EXPR:
01789 case IMAGPART_EXPR:
01790 pp_cxx_identifier (cxx_pp, operator_name_info[TREE_CODE (t)].name);
01791 pp_cxx_whitespace (cxx_pp);
01792 dump_expr (TREE_OPERAND (t, 0), flags);
01793 break;
01794
01795 case DEFAULT_ARG:
01796 pp_identifier (cxx_pp, "<unparsed>");
01797 break;
01798
01799 case TRY_CATCH_EXPR:
01800 case WITH_CLEANUP_EXPR:
01801 case CLEANUP_POINT_EXPR:
01802 dump_expr (TREE_OPERAND (t, 0), flags);
01803 break;
01804
01805 case PSEUDO_DTOR_EXPR:
01806 dump_expr (TREE_OPERAND (t, 2), flags);
01807 pp_cxx_dot (cxx_pp);
01808 dump_type (TREE_OPERAND (t, 0), flags);
01809 pp_cxx_colon_colon (cxx_pp);
01810 pp_cxx_complement (cxx_pp);
01811 dump_type (TREE_OPERAND (t, 1), flags);
01812 break;
01813
01814 case TEMPLATE_ID_EXPR:
01815 dump_decl (t, flags);
01816 break;
01817
01818 case BIND_EXPR:
01819 case STMT_EXPR:
01820 case STATEMENT_LIST:
01821
01822
01823 pp_string (cxx_pp, "({...})");
01824 break;
01825
01826 case LOOP_EXPR:
01827 pp_string (cxx_pp, "while (1) { ");
01828 dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
01829 pp_cxx_right_brace (cxx_pp);
01830 break;
01831
01832 case EXIT_EXPR:
01833 pp_string (cxx_pp, "if (");
01834 dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
01835 pp_string (cxx_pp, ") break; ");
01836 break;
01837
01838 case BASELINK:
01839 dump_expr (get_first_fn (t), flags & ~TFF_EXPR_IN_PARENS);
01840 break;
01841
01842 case EMPTY_CLASS_EXPR:
01843 dump_type (TREE_TYPE (t), flags);
01844 pp_cxx_left_paren (cxx_pp);
01845 pp_cxx_right_paren (cxx_pp);
01846 break;
01847
01848 case NON_DEPENDENT_EXPR:
01849 dump_expr (TREE_OPERAND (t, 0), flags);
01850 break;
01851
01852
01853
01854
01855 default:
01856 pp_unsupported_tree (cxx_pp, t);
01857
01858 case ERROR_MARK:
01859 pp_identifier (cxx_pp, "<expression error>");
01860 break;
01861 }
01862 }
01863
01864 static void
01865 dump_binary_op (const char *opstring, tree t, int flags)
01866 {
01867 pp_cxx_left_paren (cxx_pp);
01868 dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
01869 pp_cxx_whitespace (cxx_pp);
01870 if (opstring)
01871 pp_cxx_identifier (cxx_pp, opstring);
01872 else
01873 pp_identifier (cxx_pp, "<unknown operator>");
01874 pp_cxx_whitespace (cxx_pp);
01875 dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
01876 pp_cxx_right_paren (cxx_pp);
01877 }
01878
01879 static void
01880 dump_unary_op (const char *opstring, tree t, int flags)
01881 {
01882 if (flags & TFF_EXPR_IN_PARENS)
01883 pp_cxx_left_paren (cxx_pp);
01884 pp_cxx_identifier (cxx_pp, opstring);
01885 dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
01886 if (flags & TFF_EXPR_IN_PARENS)
01887 pp_cxx_right_paren (cxx_pp);
01888 }
01889
01890 static void
01891 reinit_cxx_pp (void)
01892 {
01893 pp_clear_output_area (cxx_pp);
01894 pp_base (cxx_pp)->padding = pp_none;
01895 pp_indentation (cxx_pp) = 0;
01896 pp_needs_newline (cxx_pp) = false;
01897 cxx_pp->enclosing_scope = 0;
01898 }
01899
01900
01901
01902
01903
01904 const char *
01905 type_as_string (tree typ, int flags)
01906 {
01907 reinit_cxx_pp ();
01908 dump_type (typ, flags);
01909 return pp_formatted_text (cxx_pp);
01910 }
01911
01912 const char *
01913 expr_as_string (tree decl, int flags)
01914 {
01915 reinit_cxx_pp ();
01916 dump_expr (decl, flags);
01917 return pp_formatted_text (cxx_pp);
01918 }
01919
01920 const char *
01921 decl_as_string (tree decl, int flags)
01922 {
01923 reinit_cxx_pp ();
01924 dump_decl (decl, flags);
01925 return pp_formatted_text (cxx_pp);
01926 }
01927
01928
01929
01930 const char *
01931 lang_decl_name (tree decl, int v)
01932 {
01933 if (v >= 2)
01934 return decl_as_string (decl, TFF_DECL_SPECIFIERS);
01935
01936 reinit_cxx_pp ();
01937 if (v == 1 && DECL_CLASS_SCOPE_P (decl))
01938 {
01939 dump_type (CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER);
01940 pp_cxx_colon_colon (cxx_pp);
01941 }
01942
01943 if (TREE_CODE (decl) == FUNCTION_DECL)
01944 dump_function_name (decl, TFF_PLAIN_IDENTIFIER);
01945 else
01946 dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
01947
01948 return pp_formatted_text (cxx_pp);
01949 }
01950
01951 static location_t
01952 location_of (tree t)
01953 {
01954 if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
01955 t = DECL_CONTEXT (t);
01956 else if (TYPE_P (t))
01957 t = TYPE_MAIN_DECL (t);
01958 else if (TREE_CODE (t) == OVERLOAD)
01959 t = OVL_FUNCTION (t);
01960
01961 return DECL_SOURCE_LOCATION (t);
01962 }
01963
01964
01965
01966
01967
01968 static const char *
01969 decl_to_string (tree decl, int verbose)
01970 {
01971 int flags = 0;
01972
01973 if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE
01974 || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE)
01975 flags = TFF_CLASS_KEY_OR_ENUM;
01976 if (verbose)
01977 flags |= TFF_DECL_SPECIFIERS;
01978 else if (TREE_CODE (decl) == FUNCTION_DECL)
01979 flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE;
01980 flags |= TFF_TEMPLATE_HEADER;
01981
01982 reinit_cxx_pp ();
01983 dump_decl (decl, flags);
01984 return pp_formatted_text (cxx_pp);
01985 }
01986
01987 static const char *
01988 expr_to_string (tree decl)
01989 {
01990 reinit_cxx_pp ();
01991 dump_expr (decl, 0);
01992 return pp_formatted_text (cxx_pp);
01993 }
01994
01995 static const char *
01996 fndecl_to_string (tree fndecl, int verbose)
01997 {
01998 int flags;
01999
02000 flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS;
02001 if (verbose)
02002 flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS;
02003 reinit_cxx_pp ();
02004 dump_decl (fndecl, flags);
02005 return pp_formatted_text (cxx_pp);
02006 }
02007
02008
02009 static const char *
02010 code_to_string (enum tree_code c)
02011 {
02012 return tree_code_name [c];
02013 }
02014
02015 const char *
02016 language_to_string (enum languages c)
02017 {
02018 switch (c)
02019 {
02020 case lang_c:
02021 return "C";
02022
02023 case lang_cplusplus:
02024 return "C++";
02025
02026 case lang_java:
02027 return "Java";
02028
02029 default:
02030 gcc_unreachable ();
02031 }
02032 return 0;
02033 }
02034
02035
02036
02037 static const char *
02038 parm_to_string (int p)
02039 {
02040 reinit_cxx_pp ();
02041 if (p < 0)
02042 pp_string (cxx_pp, "'this'");
02043 else
02044 pp_decimal_int (cxx_pp, p + 1);
02045 return pp_formatted_text (cxx_pp);
02046 }
02047
02048 static const char *
02049 op_to_string (enum tree_code p)
02050 {
02051 tree id = operator_name_info[(int) p].identifier;
02052 return id ? IDENTIFIER_POINTER (id) : "<unknown>";
02053 }
02054
02055 static const char *
02056 type_to_string (tree typ, int verbose)
02057 {
02058 int flags = 0;
02059 if (verbose)
02060 flags |= TFF_CLASS_KEY_OR_ENUM;
02061 flags |= TFF_TEMPLATE_HEADER;
02062
02063 reinit_cxx_pp ();
02064 dump_type (typ, flags);
02065 return pp_formatted_text (cxx_pp);
02066 }
02067
02068 static const char *
02069 assop_to_string (enum tree_code p)
02070 {
02071 tree id = assignment_operator_name_info[(int) p].identifier;
02072 return id ? IDENTIFIER_POINTER (id) : "{unknown}";
02073 }
02074
02075 static const char *
02076 args_to_string (tree p, int verbose)
02077 {
02078 int flags = 0;
02079 if (verbose)
02080 flags |= TFF_CLASS_KEY_OR_ENUM;
02081
02082 if (p == NULL_TREE)
02083 return "";
02084
02085 if (TYPE_P (TREE_VALUE (p)))
02086 return type_as_string (p, flags);
02087
02088 reinit_cxx_pp ();
02089 for (; p; p = TREE_CHAIN (p))
02090 {
02091 if (TREE_VALUE (p) == null_node)
02092 pp_cxx_identifier (cxx_pp, "NULL");
02093 else
02094 dump_type (error_type (TREE_VALUE (p)), flags);
02095 if (TREE_CHAIN (p))
02096 pp_separate_with_comma (cxx_pp);
02097 }
02098 return pp_formatted_text (cxx_pp);
02099 }
02100
02101 static const char *
02102 cv_to_string (tree p, int v)
02103 {
02104 reinit_cxx_pp ();
02105 pp_base (cxx_pp)->padding = v ? pp_before : pp_none;
02106 pp_cxx_cv_qualifier_seq (cxx_pp, p);
02107 return pp_formatted_text (cxx_pp);
02108 }
02109
02110
02111 void
02112 cxx_print_error_function (diagnostic_context *context, const char *file)
02113 {
02114 lhd_print_error_function (context, file);
02115 pp_base_set_prefix (context->printer, file);
02116 maybe_print_instantiation_context (context);
02117 }
02118
02119 static void
02120 cp_diagnostic_starter (diagnostic_context *context,
02121 diagnostic_info *diagnostic)
02122 {
02123 diagnostic_report_current_module (context);
02124 cp_print_error_function (context, diagnostic);
02125 maybe_print_instantiation_context (context);
02126 pp_base_set_prefix (context->printer, diagnostic_build_prefix (diagnostic));
02127 }
02128
02129 static void
02130 cp_diagnostic_finalizer (diagnostic_context *context,
02131 diagnostic_info *diagnostic ATTRIBUTE_UNUSED)
02132 {
02133 pp_base_destroy_prefix (context->printer);
02134 }
02135
02136
02137
02138 static void
02139 cp_print_error_function (diagnostic_context *context,
02140 diagnostic_info *diagnostic)
02141 {
02142 if (diagnostic_last_function_changed (context))
02143 {
02144 const char *old_prefix = context->printer->prefix;
02145 const char *file = LOCATION_FILE (diagnostic->location);
02146 char *new_prefix = file ? file_name_as_prefix (file) : NULL;
02147
02148 pp_base_set_prefix (context->printer, new_prefix);
02149
02150 if (current_function_decl == NULL)
02151 pp_base_string (context->printer, "At global scope:");
02152 else
02153 pp_printf (context->printer, "In %s %qs:",
02154 function_category (current_function_decl),
02155 cxx_printable_name (current_function_decl, 2));
02156 pp_base_newline (context->printer);
02157
02158 diagnostic_set_last_function (context);
02159 pp_base_destroy_prefix (context->printer);
02160 context->printer->prefix = old_prefix;
02161 }
02162 }
02163
02164
02165 static const char *
02166 function_category (tree fn)
02167 {
02168 if (DECL_FUNCTION_MEMBER_P (fn))
02169 {
02170 if (DECL_STATIC_FUNCTION_P (fn))
02171 return "static member function";
02172 else if (DECL_COPY_CONSTRUCTOR_P (fn))
02173 return "copy constructor";
02174 else if (DECL_CONSTRUCTOR_P (fn))
02175 return "constructor";
02176 else if (DECL_DESTRUCTOR_P (fn))
02177 return "destructor";
02178 else
02179 return "member function";
02180 }
02181 else
02182 return "function";
02183 }
02184
02185
02186
02187 static void
02188 print_instantiation_full_context (diagnostic_context *context)
02189 {
02190 tree p = current_instantiation ();
02191 location_t location = input_location;
02192
02193 if (p)
02194 {
02195 if (current_function_decl != TINST_DECL (p)
02196 && current_function_decl != NULL_TREE)
02197
02198
02199
02200 ;
02201 else
02202 {
02203 if (current_function_decl == TINST_DECL (p))
02204 ;
02205 else
02206 pp_verbatim (context->printer,
02207 "%s: In instantiation of %qs:\n",
02208 LOCATION_FILE (location),
02209 decl_as_string (TINST_DECL (p),
02210 TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
02211
02212 location = TINST_LOCATION (p);
02213 p = TREE_CHAIN (p);
02214 }
02215 }
02216
02217 print_instantiation_partial_context (context, p, location);
02218 }
02219
02220
02221 static void
02222 print_instantiation_partial_context (diagnostic_context *context,
02223 tree t, location_t loc)
02224 {
02225 expanded_location xloc;
02226 for (; ; t = TREE_CHAIN (t))
02227 {
02228 xloc = expand_location (loc);
02229 if (t == NULL_TREE)
02230 break;
02231 pp_verbatim (context->printer, "%s:%d: instantiated from %qs\n",
02232 xloc.file, xloc.line,
02233 decl_as_string (TINST_DECL (t),
02234 TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
02235 loc = TINST_LOCATION (t);
02236 }
02237 pp_verbatim (context->printer, "%s:%d: instantiated from here\n",
02238 xloc.file, xloc.line);
02239 }
02240
02241
02242 static void
02243 maybe_print_instantiation_context (diagnostic_context *context)
02244 {
02245 if (!problematic_instantiation_changed () || current_instantiation () == 0)
02246 return;
02247
02248 record_last_problematic_instantiation ();
02249 print_instantiation_full_context (context);
02250 }
02251
02252
02253 void
02254 print_instantiation_context (void)
02255 {
02256 print_instantiation_partial_context
02257 (global_dc, current_instantiation (), input_location);
02258 diagnostic_flush_buffer (global_dc);
02259 }
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274 static bool
02275 cp_printer (pretty_printer *pp, text_info *text)
02276 {
02277 int verbose = 0;
02278 const char *result;
02279 #define next_tree va_arg (*text->args_ptr, tree)
02280 #define next_tcode va_arg (*text->args_ptr, enum tree_code)
02281 #define next_lang va_arg (*text->args_ptr, enum languages)
02282 #define next_int va_arg (*text->args_ptr, int)
02283
02284 if (*text->format_spec == '+')
02285 ++text->format_spec;
02286 if (*text->format_spec == '#')
02287 {
02288 verbose = 1;
02289 ++text->format_spec;
02290 }
02291
02292 switch (*text->format_spec)
02293 {
02294 case 'A': result = args_to_string (next_tree, verbose); break;
02295 case 'C': result = code_to_string (next_tcode); break;
02296 case 'D': result = decl_to_string (next_tree, verbose); break;
02297 case 'E': result = expr_to_string (next_tree); break;
02298 case 'F': result = fndecl_to_string (next_tree, verbose); break;
02299 case 'L': result = language_to_string (next_lang); break;
02300 case 'O': result = op_to_string (next_tcode); break;
02301 case 'P': result = parm_to_string (next_int); break;
02302 case 'Q': result = assop_to_string (next_tcode); break;
02303 case 'T': result = type_to_string (next_tree, verbose); break;
02304 case 'V': result = cv_to_string (next_tree, verbose); break;
02305
02306 default:
02307 return false;
02308 }
02309
02310 pp_base_string (pp, result);
02311 return true;
02312 #undef next_tree
02313 #undef next_tcode
02314 #undef next_lang
02315 #undef next_int
02316 }
02317
02318
02319
02320
02321 static tree
02322 locate_error (const char *gmsgid, va_list ap)
02323 {
02324 tree here = 0, t;
02325 int plus = 0;
02326 const char *f;
02327
02328 for (f = gmsgid; *f; f++)
02329 {
02330 plus = 0;
02331 if (*f == '%')
02332 {
02333 if (*++f == 'q')
02334 ++f;
02335
02336 if (*f == '+')
02337 {
02338 ++f;
02339 plus = 1;
02340 }
02341 if (*f == '#')
02342 f++;
02343
02344 switch (*f)
02345 {
02346
02347 case '%': break;
02348 case 'P':
02349 case 'd': (void) va_arg (ap, int); break;
02350 case 's': (void) va_arg (ap, char *); break;
02351 case 'L': (void) va_arg (ap, enum languages); break;
02352 case 'C':
02353 case 'O':
02354 case 'Q': (void) va_arg (ap, enum tree_code); break;
02355
02356
02357
02358 case 'A':
02359 case 'D':
02360 case 'E':
02361 case 'F':
02362 case 'T':
02363 case 'V':
02364 t = va_arg (ap, tree);
02365 if (!here || plus)
02366 here = t;
02367 break;
02368
02369 default:
02370 errorcount = 0;
02371 internal_error ("unexpected letter %qc in locate_error\n", *f);
02372 }
02373 }
02374 }
02375
02376 if (here == 0)
02377 here = va_arg (ap, tree);
02378
02379 return here;
02380 }
02381
02382
02383 void
02384 cp_error_at (const char *gmsgid, ...)
02385 {
02386 tree here;
02387 diagnostic_info diagnostic;
02388 va_list ap;
02389
02390 va_start (ap, gmsgid);
02391 here = locate_error (gmsgid, ap);
02392 va_end (ap);
02393
02394 va_start (ap, gmsgid);
02395 diagnostic_set_info (&diagnostic, gmsgid, &ap,
02396 input_location, DK_ERROR);
02397 cp_diagnostic_starter (global_dc, &diagnostic);
02398 diagnostic_set_info (&diagnostic, gmsgid, &ap,
02399 location_of (here), DK_ERROR);
02400 report_diagnostic (&diagnostic);
02401 va_end (ap);
02402 }
02403
02404 void
02405 cp_warning_at (const char *gmsgid, ...)
02406 {
02407 tree here;
02408 diagnostic_info diagnostic;
02409 va_list ap;
02410
02411 va_start (ap, gmsgid);
02412 here = locate_error (gmsgid, ap);
02413 va_end (ap);
02414
02415 va_start (ap, gmsgid);
02416 diagnostic_set_info (&diagnostic, gmsgid, &ap,
02417 location_of (here), DK_WARNING);
02418 report_diagnostic (&diagnostic);
02419 va_end (ap);
02420 }
02421
02422 void
02423 cp_pedwarn_at (const char *gmsgid, ...)
02424 {
02425 tree here;
02426 diagnostic_info diagnostic;
02427 va_list ap;
02428
02429 va_start (ap, gmsgid);
02430 here = locate_error (gmsgid, ap);
02431 va_end (ap);
02432
02433 va_start (ap, gmsgid);
02434 diagnostic_set_info (&diagnostic, gmsgid, &ap,
02435 location_of (here), pedantic_error_kind());
02436 report_diagnostic (&diagnostic);
02437 va_end (ap);
02438 }