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