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