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