X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=gcc%2Fcp%2Ferror.c;fp=gcc%2Fcp%2Ferror.c;h=aebd65f31d4573b8027795c47511830e3b3756a7;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=719343697a7f9c9df5f367ea2c6a62f2bf7de81f;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 71934369..aebd65f3 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1,144 +1,112 @@ /* Call-backs for C++ error reporting. This code is non-reentrant. - Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002 - Free Software Foundation, Inc. - This file is part of GNU CC. + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, + 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify +GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. -GNU CC is distributed in the hope that it will be useful, +GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "tree.h" #include "cp-tree.h" #include "real.h" -#include "obstack.h" #include "toplev.h" #include "flags.h" #include "diagnostic.h" +#include "langhooks-def.h" +#include "cxx-pretty-print.h" -enum pad { none, before, after }; - -#define sorry_for_unsupported_tree(T) \ - sorry ("`%s' not supported by %s", tree_code_name[(int) TREE_CODE (T)], \ - __FUNCTION__) - -#define print_scope_operator(BUFFER) output_add_string ((BUFFER), "::") -#define print_left_paren(BUFFER) output_add_character ((BUFFER), '(') -#define print_right_paren(BUFFER) output_add_character ((BUFFER), ')') -#define print_left_bracket(BUFFER) output_add_character ((BUFFER), '[') -#define print_right_bracket(BUFFER) output_add_character ((BUFFER), ']') -#define print_template_argument_list_start(BUFFER) \ - print_non_consecutive_character ((BUFFER), '<') -#define print_template_argument_list_end(BUFFER) \ - print_non_consecutive_character ((BUFFER), '>') -#define print_whitespace(BUFFER, TFI) \ - do { \ - output_add_space (BUFFER); \ - put_whitespace (TFI) = none; \ - } while (0) -#define print_tree_identifier(BUFFER, TID) \ - output_add_string ((BUFFER), IDENTIFIER_POINTER (TID)) -#define print_identifier(BUFFER, ID) output_add_string ((BUFFER), (ID)) -#define separate_with_comma(BUFFER) output_add_string ((BUFFER), ", ") +#define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',') /* The global buffer where we dump everything. It is there only for transitional purpose. It is expected, in the near future, to be completely removed. */ -static output_buffer scratch_buffer_rec; -static output_buffer *scratch_buffer = &scratch_buffer_rec; +static cxx_pretty_printer scratch_pretty_printer; +#define cxx_pp (&scratch_pretty_printer) # define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T))) -#define reinit_global_formatting_buffer() \ - output_clear_message_text (scratch_buffer) - -static const char *args_to_string PARAMS ((tree, int)); -static const char *assop_to_string PARAMS ((enum tree_code, int)); -static const char *code_to_string PARAMS ((enum tree_code, int)); -static const char *cv_to_string PARAMS ((tree, int)); -static const char *decl_to_string PARAMS ((tree, int)); -static const char *expr_to_string PARAMS ((tree, int)); -static const char *fndecl_to_string PARAMS ((tree, int)); -static const char *op_to_string PARAMS ((enum tree_code, int)); -static const char *parm_to_string PARAMS ((int, int)); -static const char *type_to_string PARAMS ((tree, int)); - -static void dump_type PARAMS ((tree, int)); -static void dump_typename PARAMS ((tree, int)); -static void dump_simple_decl PARAMS ((tree, tree, int)); -static void dump_decl PARAMS ((tree, int)); -static void dump_template_decl PARAMS ((tree, int)); -static void dump_function_decl PARAMS ((tree, int)); -static void dump_expr PARAMS ((tree, int)); -static void dump_unary_op PARAMS ((const char *, tree, int)); -static void dump_binary_op PARAMS ((const char *, tree, int)); -static void dump_aggr_type PARAMS ((tree, int)); -static enum pad dump_type_prefix PARAMS ((tree, int)); -static void dump_type_suffix PARAMS ((tree, int)); -static void dump_function_name PARAMS ((tree, int)); -static void dump_expr_list PARAMS ((tree, int)); -static void dump_global_iord PARAMS ((tree)); -static enum pad dump_qualifiers PARAMS ((tree, enum pad)); -static void dump_char PARAMS ((int)); -static void dump_parameters PARAMS ((tree, int)); -static void dump_exception_spec PARAMS ((tree, int)); -static const char *class_key_or_enum PARAMS ((tree)); -static void dump_template_argument PARAMS ((tree, int)); -static void dump_template_argument_list PARAMS ((tree, int)); -static void dump_template_parameter PARAMS ((tree, int)); -static void dump_template_bindings PARAMS ((tree, tree)); -static void dump_scope PARAMS ((tree, int)); -static void dump_template_parms PARAMS ((tree, int, int)); - -static const char *function_category PARAMS ((tree)); -static void lang_print_error_function PARAMS ((diagnostic_context *, - const char *)); -static void maybe_print_instantiation_context PARAMS ((output_buffer *)); -static void print_instantiation_full_context PARAMS ((output_buffer *)); -static void print_instantiation_partial_context PARAMS ((output_buffer *, tree, - const char *, int)); -static void cp_diagnostic_starter PARAMS ((output_buffer *, - diagnostic_context *)); -static void cp_diagnostic_finalizer PARAMS ((output_buffer *, - diagnostic_context *)); -static void cp_print_error_function PARAMS ((output_buffer *, - diagnostic_context *)); - -static int cp_printer PARAMS ((output_buffer *)); -static void print_non_consecutive_character PARAMS ((output_buffer *, int)); -static void print_integer PARAMS ((output_buffer *, HOST_WIDE_INT)); -static tree locate_error PARAMS ((const char *, va_list)); +static const char *args_to_string (tree, int); +static const char *assop_to_string (enum tree_code); +static const char *code_to_string (enum tree_code); +static const char *cv_to_string (tree, int); +static const char *decl_to_string (tree, int); +static const char *expr_to_string (tree); +static const char *fndecl_to_string (tree, int); +static const char *op_to_string (enum tree_code); +static const char *parm_to_string (int); +static const char *type_to_string (tree, int); + +static void dump_type (tree, int); +static void dump_typename (tree, int); +static void dump_simple_decl (tree, tree, int); +static void dump_decl (tree, int); +static void dump_template_decl (tree, int); +static void dump_function_decl (tree, int); +static void dump_expr (tree, int); +static void dump_unary_op (const char *, tree, int); +static void dump_binary_op (const char *, tree, int); +static void dump_aggr_type (tree, int); +static void dump_type_prefix (tree, int); +static void dump_type_suffix (tree, int); +static void dump_function_name (tree, int); +static void dump_call_expr_args (tree, int, bool); +static void dump_aggr_init_expr_args (tree, int, bool); +static void dump_expr_list (tree, int); +static void dump_global_iord (tree); +static void dump_parameters (tree, int); +static void dump_exception_spec (tree, int); +static void dump_template_argument (tree, int); +static void dump_template_argument_list (tree, int); +static void dump_template_parameter (tree, int); +static void dump_template_bindings (tree, tree); +static void dump_scope (tree, int); +static void dump_template_parms (tree, int, int); + +static const char *function_category (tree); +static void maybe_print_instantiation_context (diagnostic_context *); +static void print_instantiation_full_context (diagnostic_context *); +static void print_instantiation_partial_context (diagnostic_context *, + struct tinst_level *, + location_t); +static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *); +static void cp_diagnostic_finalizer (diagnostic_context *, diagnostic_info *); +static void cp_print_error_function (diagnostic_context *, diagnostic_info *); + +static bool cp_printer (pretty_printer *, text_info *, const char *, + int, bool, bool, bool); +static location_t location_of (tree); void -init_error () +init_error (void) { - print_error_function = lang_print_error_function; diagnostic_starter (global_dc) = cp_diagnostic_starter; diagnostic_finalizer (global_dc) = cp_diagnostic_finalizer; diagnostic_format_decoder (global_dc) = cp_printer; - init_output_buffer (scratch_buffer, /* prefix */NULL, /* line-width */0); + pp_construct (pp_base (cxx_pp), NULL, 0); + pp_cxx_pretty_printer_init (cxx_pp); } /* Dump a scope, if deemed necessary. */ static void -dump_scope (scope, flags) - tree scope; - int flags; +dump_scope (tree scope, int flags) { int f = ~TFF_RETURN_TYPE & (flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF)); @@ -148,81 +116,46 @@ dump_scope (scope, flags) if (TREE_CODE (scope) == NAMESPACE_DECL) { if (scope != global_namespace) - { - dump_decl (scope, f); - print_scope_operator (scratch_buffer); - } + { + dump_decl (scope, f); + pp_cxx_colon_colon (cxx_pp); + } } else if (AGGREGATE_TYPE_P (scope)) { dump_type (scope, f); - print_scope_operator (scratch_buffer); + pp_cxx_colon_colon (cxx_pp); } else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL) { dump_function_decl (scope, f); - print_scope_operator (scratch_buffer); + pp_cxx_colon_colon (cxx_pp); } } -/* Dump type qualifiers, providing padding as requested. Return an - indication of whether we dumped something. */ - -static enum pad -dump_qualifiers (t, p) - tree t; - enum pad p; -{ - static const int masks[] = - {TYPE_QUAL_CONST, TYPE_QUAL_VOLATILE, TYPE_QUAL_RESTRICT}; - static const char *const names[] = - {"const", "volatile", "__restrict"}; - int ix; - int quals = TYPE_QUALS (t); - int do_after = p == after; - - if (quals) - { - for (ix = 0; ix != 3; ix++) - if (masks[ix] & quals) - { - if (p == before) - output_add_space (scratch_buffer); - p = before; - print_identifier (scratch_buffer, names[ix]); - } - if (do_after) - output_add_space (scratch_buffer); - } - else - p = none; - return p; -} - -/* This must be large enough to hold any printed integer or floating-point - value. */ -static char digit_buffer[128]; - /* Dump the template ARGument under control of FLAGS. */ static void -dump_template_argument (arg, flags) - tree arg; - int flags; +dump_template_argument (tree arg, int flags) { - if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL) + if (ARGUMENT_PACK_P (arg)) + dump_template_argument_list (ARGUMENT_PACK_ARGS (arg), flags); + else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL) dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM); else - dump_expr (arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM); + { + if (TREE_CODE (arg) == TREE_LIST) + arg = TREE_VALUE (arg); + + dump_expr (arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM); + } } /* Dump a template-argument-list ARGS (always a TREE_VEC) under control of FLAGS. */ static void -dump_template_argument_list (args, flags) - tree args; - int flags; +dump_template_argument_list (tree args, int flags) { int n = TREE_VEC_LENGTH (args); int need_comma = 0; @@ -230,9 +163,17 @@ dump_template_argument_list (args, flags) for (i = 0; i< n; ++i) { - if (need_comma) - separate_with_comma (scratch_buffer); - dump_template_argument (TREE_VEC_ELT (args, i), flags); + tree arg = TREE_VEC_ELT (args, i); + + /* Only print a comma if we know there is an argument coming. In + the case of an empty template argument pack, no actual + argument will be printed. */ + if (need_comma + && (!ARGUMENT_PACK_P (arg) + || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0)) + pp_separate_with_comma (cxx_pp); + + dump_template_argument (arg, flags); need_comma = 1; } } @@ -240,39 +181,44 @@ dump_template_argument_list (args, flags) /* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS. */ static void -dump_template_parameter (parm, flags) - tree parm; - int flags; +dump_template_parameter (tree parm, int flags) { - tree p = TREE_VALUE (parm); - tree a = TREE_PURPOSE (parm); + tree p; + tree a; + + if (parm == error_mark_node) + return; + + p = TREE_VALUE (parm); + a = TREE_PURPOSE (parm); if (TREE_CODE (p) == TYPE_DECL) { if (flags & TFF_DECL_SPECIFIERS) - { - print_identifier (scratch_buffer, "class"); - if (DECL_NAME (p)) - { - output_add_space (scratch_buffer); - print_tree_identifier (scratch_buffer, DECL_NAME (p)); - } - } + { + pp_cxx_identifier (cxx_pp, "class"); + if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (p))) + pp_cxx_identifier (cxx_pp, "..."); + if (DECL_NAME (p)) + pp_cxx_tree_identifier (cxx_pp, DECL_NAME (p)); + } else if (DECL_NAME (p)) - print_tree_identifier (scratch_buffer, DECL_NAME (p)); + pp_cxx_tree_identifier (cxx_pp, DECL_NAME (p)); else - print_identifier (scratch_buffer, "{template default argument error}"); + pp_cxx_canonical_template_parameter (cxx_pp, TREE_TYPE (p)); } else dump_decl (p, flags | TFF_DECL_SPECIFIERS); if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE) { - output_add_string (scratch_buffer, " = "); + pp_cxx_whitespace (cxx_pp); + pp_equal (cxx_pp); + pp_cxx_whitespace (cxx_pp); if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL) - dump_type (a, flags & ~TFF_CHASE_TYPEDEF); + dump_type (a, flags & ~TFF_CHASE_TYPEDEF); else - dump_expr (a, flags | TFF_EXPR_IN_PARENS); + dump_expr (a, flags | TFF_EXPR_IN_PARENS); } } @@ -281,8 +227,7 @@ dump_template_parameter (parm, flags) TREE_VEC. */ static void -dump_template_bindings (parms, args) - tree parms, args; +dump_template_bindings (tree parms, tree args) { int need_comma = 0; @@ -306,13 +251,15 @@ dump_template_bindings (parms, args) } if (need_comma) - separate_with_comma (scratch_buffer); + pp_separate_with_comma (cxx_pp); dump_template_parameter (TREE_VEC_ELT (p, i), TFF_PLAIN_IDENTIFIER); - output_add_string (scratch_buffer, " = "); + pp_cxx_whitespace (cxx_pp); + pp_equal (cxx_pp); + pp_cxx_whitespace (cxx_pp); if (arg) dump_template_argument (arg, TFF_PLAIN_IDENTIFIER); else - print_identifier (scratch_buffer, ""); + pp_identifier (cxx_pp, ""); ++arg_idx; need_comma = 1; @@ -322,13 +269,11 @@ dump_template_bindings (parms, args) } } -/* Dump into the obstack a human-readable equivalent of TYPE. FLAGS - controls the format. */ +/* Dump a human-readable equivalent of TYPE. FLAGS controls the + format. */ static void -dump_type (t, flags) - tree t; - int flags; +dump_type (tree t, int flags) { if (t == NULL_TREE) return; @@ -339,7 +284,10 @@ dump_type (t, flags) switch (TREE_CODE (t)) { case UNKNOWN_TYPE: - print_identifier (scratch_buffer, ""); + if (t == init_list_type_node) + pp_identifier (cxx_pp, ""); + else + pp_identifier (cxx_pp, ""); break; case TREE_LIST: @@ -348,10 +296,10 @@ dump_type (t, flags) break; case IDENTIFIER_NODE: - print_tree_identifier (scratch_buffer, t); + pp_cxx_tree_identifier (cxx_pp, t); break; - case TREE_VEC: + case TREE_BINFO: dump_type (BINFO_TYPE (t), flags); break; @@ -363,85 +311,54 @@ dump_type (t, flags) case TYPE_DECL: if (flags & TFF_CHASE_TYPEDEF) - { - dump_type (DECL_ORIGINAL_TYPE (t) - ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags); - break; - } - /* else fallthrough */ + { + dump_type (DECL_ORIGINAL_TYPE (t) + ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags); + break; + } + /* Else fall through. */ case TEMPLATE_DECL: case NAMESPACE_DECL: dump_decl (t, flags & ~TFF_DECL_SPECIFIERS); break; - case COMPLEX_TYPE: - output_add_string (scratch_buffer, "__complex__ "); - dump_type (TREE_TYPE (t), flags); - break; - - case VECTOR_TYPE: - output_add_string (scratch_buffer, "vector "); - { - /* The subtype of a VECTOR_TYPE is something like intQI_type_node, - which has no name and is not very useful for diagnostics. So - look up the equivalent C type and print its name. */ - tree elt = TREE_TYPE (t); - elt = type_for_mode (TYPE_MODE (elt), TREE_UNSIGNED (elt)); - dump_type (elt, flags); - } - break; - case INTEGER_TYPE: - if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t)) - output_add_string (scratch_buffer, "unsigned "); - else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t)) - output_add_string (scratch_buffer, "signed "); - - /* fall through. */ case REAL_TYPE: case VOID_TYPE: case BOOLEAN_TYPE: - { - tree type; - dump_qualifiers (t, after); - type = flags & TFF_CHASE_TYPEDEF ? TYPE_MAIN_VARIANT (t) : t; - if (TYPE_NAME (type) && TYPE_IDENTIFIER (type)) - print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (type)); - else - /* Types like intQI_type_node and friends have no names. - These don't come up in user error messages, but it's nice - to be able to print them from the debugger. */ - print_identifier (scratch_buffer, ""); - } + case COMPLEX_TYPE: + case VECTOR_TYPE: + case FIXED_POINT_TYPE: + pp_type_specifier_seq (cxx_pp, t); break; case TEMPLATE_TEMPLATE_PARM: - /* For parameters inside template signature. */ + /* For parameters inside template signature. */ if (TYPE_IDENTIFIER (t)) - print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t)); + pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); else - print_identifier - (scratch_buffer, ""); + pp_cxx_canonical_template_parameter (cxx_pp, t); break; case BOUND_TEMPLATE_TEMPLATE_PARM: { tree args = TYPE_TI_ARGS (t); - print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t)); - print_template_argument_list_start (scratch_buffer); - dump_template_argument_list (args, flags); - print_template_argument_list_end (scratch_buffer); + pp_cxx_cv_qualifier_seq (cxx_pp, t); + pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); + pp_cxx_begin_template_argument_list (cxx_pp); + dump_template_argument_list (args, flags); + pp_cxx_end_template_argument_list (cxx_pp); } break; case TEMPLATE_TYPE_PARM: - dump_qualifiers (t, after); + pp_cxx_cv_qualifier_seq (cxx_pp, t); if (TYPE_IDENTIFIER (t)) - print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t)); + pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); else - print_identifier - (scratch_buffer, ""); + pp_cxx_canonical_template_parameter + (cxx_pp, TEMPLATE_TYPE_PARM_INDEX (t)); break; /* This is not always necessary for pointers and such, but doing this @@ -459,30 +376,52 @@ dump_type (t, flags) break; } case TYPENAME_TYPE: - if (IMPLICIT_TYPENAME_P (t)) - output_add_string (scratch_buffer, "typename "); + pp_cxx_cv_qualifier_seq (cxx_pp, t); + pp_cxx_identifier (cxx_pp, + TYPENAME_IS_ENUM_P (t) ? "enum" + : TYPENAME_IS_CLASS_P (t) ? "class" + : "typename"); dump_typename (t, flags); break; case UNBOUND_CLASS_TEMPLATE: dump_type (TYPE_CONTEXT (t), flags); - print_scope_operator (scratch_buffer); - print_identifier (scratch_buffer, "template "); + pp_cxx_colon_colon (cxx_pp); + pp_cxx_identifier (cxx_pp, "template"); dump_type (DECL_NAME (TYPE_NAME (t)), flags); break; case TYPEOF_TYPE: - output_add_string (scratch_buffer, "__typeof ("); - dump_expr (TYPE_FIELDS (t), flags & ~TFF_EXPR_IN_PARENS); - print_right_paren (scratch_buffer); + pp_cxx_identifier (cxx_pp, "__typeof__"); + pp_cxx_whitespace (cxx_pp); + pp_cxx_left_paren (cxx_pp); + dump_expr (TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS); + pp_cxx_right_paren (cxx_pp); + break; + + case TYPE_PACK_EXPANSION: + dump_type (PACK_EXPANSION_PATTERN (t), flags); + pp_cxx_identifier (cxx_pp, "..."); + break; + + case TYPE_ARGUMENT_PACK: + dump_template_argument (t, flags); + break; + + case DECLTYPE_TYPE: + pp_cxx_identifier (cxx_pp, "decltype"); + pp_cxx_whitespace (cxx_pp); + pp_cxx_left_paren (cxx_pp); + dump_expr (DECLTYPE_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS); + pp_cxx_right_paren (cxx_pp); break; default: - sorry_for_unsupported_tree (t); - /* Fall through to error. */ + pp_unsupported_tree (cxx_pp, t); + /* Fall through to error. */ case ERROR_MARK: - print_identifier (scratch_buffer, ""); + pp_identifier (cxx_pp, ""); break; } } @@ -491,9 +430,7 @@ dump_type (t, flags) a TYPENAME_TYPE. */ static void -dump_typename (t, flags) - tree t; - int flags; +dump_typename (tree t, int flags) { tree ctx = TYPE_CONTEXT (t); @@ -501,18 +438,22 @@ dump_typename (t, flags) dump_typename (ctx, flags); else dump_type (ctx, flags & ~TFF_CLASS_KEY_OR_ENUM); - print_scope_operator (scratch_buffer); + pp_cxx_colon_colon (cxx_pp); dump_decl (TYPENAME_TYPE_FULLNAME (t), flags); } /* Return the name of the supplied aggregate, or enumeral type. */ -static const char * -class_key_or_enum (t) - tree t; +const char * +class_key_or_enum_as_string (tree t) { - if (TREE_CODE (t) == ENUMERAL_TYPE) - return "enum"; + if (TREE_CODE (t) == ENUMERAL_TYPE) + { + if (SCOPED_ENUM_P (t)) + return "enum class"; + else + return "enum"; + } else if (TREE_CODE (t) == UNION_TYPE) return "union"; else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t)) @@ -525,22 +466,17 @@ class_key_or_enum (t) in the form `class foo'. */ static void -dump_aggr_type (t, flags) - tree t; - int flags; +dump_aggr_type (tree t, int flags) { tree name; - const char *variety = class_key_or_enum (t); + const char *variety = class_key_or_enum_as_string (t); int typdef = 0; int tmplate = 0; - dump_qualifiers (t, after); + pp_cxx_cv_qualifier_seq (cxx_pp, t); if (flags & TFF_CLASS_KEY_OR_ENUM) - { - print_identifier (scratch_buffer, variety); - output_add_space (scratch_buffer); - } + pp_cxx_identifier (cxx_pp, variety); if (flags & TFF_CHASE_TYPEDEF) t = TYPE_MAIN_VARIANT (t); @@ -551,38 +487,39 @@ dump_aggr_type (t, flags) { typdef = !DECL_ARTIFICIAL (name); tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE - && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t) - && (CLASSTYPE_TEMPLATE_SPECIALIZATION (t) - || TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL - || DECL_TEMPLATE_SPECIALIZATION (CLASSTYPE_TI_TEMPLATE (t)) - || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))); - dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE); + && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t) + && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL + || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))); + + if (! (flags & TFF_UNQUALIFIED_NAME)) + dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE); + flags &= ~TFF_UNQUALIFIED_NAME; if (tmplate) - { - /* Because the template names are mangled, we have to locate - the most general template, and use that name. */ - tree tpl = CLASSTYPE_TI_TEMPLATE (t); - - while (DECL_TEMPLATE_INFO (tpl)) - tpl = DECL_TI_TEMPLATE (tpl); - name = tpl; - } + { + /* Because the template names are mangled, we have to locate + the most general template, and use that name. */ + tree tpl = CLASSTYPE_TI_TEMPLATE (t); + + while (DECL_TEMPLATE_INFO (tpl)) + tpl = DECL_TI_TEMPLATE (tpl); + name = tpl; + } name = DECL_NAME (name); } if (name == 0 || ANON_AGGRNAME_P (name)) { if (flags & TFF_CLASS_KEY_OR_ENUM) - print_identifier (scratch_buffer, ""); + pp_identifier (cxx_pp, ""); else - output_printf (scratch_buffer, "", variety); + pp_printf (pp_base (cxx_pp), "", variety); } else - print_tree_identifier (scratch_buffer, name); + pp_cxx_tree_identifier (cxx_pp, name); if (tmplate) dump_template_parms (TYPE_TEMPLATE_INFO (t), - !CLASSTYPE_USE_TEMPLATE (t), - flags & ~TFF_TEMPLATE_HEADER); + !CLASSTYPE_USE_TEMPLATE (t), + flags & ~TFF_TEMPLATE_HEADER); } /* Dump into the obstack the initial part of the output for a given type. @@ -594,18 +531,11 @@ dump_aggr_type (t, flags) deal with prefix and suffix. Arrays must also do this for DECL nodes, like int a[], and for things like - int *[]&. - - Return indicates how you should pad an object name after this. I.e. you - want to pad non-*, non-& cores, but not pad * or & types. */ + int *[]&. */ -static enum pad -dump_type_prefix (t, flags) - tree t; - int flags; +static void +dump_type_prefix (tree t, int flags) { - enum pad padding = before; - if (TYPE_PTRMEMFUNC_P (t)) { t = TYPE_PTRMEMFUNC_FN_TYPE (t); @@ -619,59 +549,59 @@ dump_type_prefix (t, flags) { tree sub = TREE_TYPE (t); - padding = dump_type_prefix (sub, flags); - /* A tree for a member pointer looks like pointer to offset, - so let the OFFSET_TYPE case handle it. */ - if (!TYPE_PTRMEM_P (t)) + dump_type_prefix (sub, flags); + if (TREE_CODE (sub) == ARRAY_TYPE + || TREE_CODE (sub) == FUNCTION_TYPE) { - if (TREE_CODE (sub) == ARRAY_TYPE) - { - output_add_space (scratch_buffer); - print_left_paren (scratch_buffer); - } - output_add_character - (scratch_buffer, "&*"[TREE_CODE (t) == POINTER_TYPE]); - padding = dump_qualifiers (t, before); + pp_cxx_whitespace (cxx_pp); + pp_cxx_left_paren (cxx_pp); } + if (TREE_CODE (t) == POINTER_TYPE) + pp_character(cxx_pp, '*'); + else if (TREE_CODE (t) == REFERENCE_TYPE) + { + if (TYPE_REF_IS_RVALUE (t)) + pp_string (cxx_pp, "&&"); + else + pp_character (cxx_pp, '&'); + } + pp_base (cxx_pp)->padding = pp_before; + pp_cxx_cv_qualifier_seq (cxx_pp, t); } break; case OFFSET_TYPE: offset_type: - padding = dump_type_prefix (TREE_TYPE (t), flags); + dump_type_prefix (TREE_TYPE (t), flags); if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */ { - if (padding != none) - output_add_space (scratch_buffer); + pp_maybe_space (cxx_pp); + if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) + pp_cxx_left_paren (cxx_pp); dump_type (TYPE_OFFSET_BASETYPE (t), flags); - print_scope_operator (scratch_buffer); + pp_cxx_colon_colon (cxx_pp); } - output_add_character (scratch_buffer, '*'); - padding = dump_qualifiers (t, none); + pp_cxx_star (cxx_pp); + pp_cxx_cv_qualifier_seq (cxx_pp, t); + pp_base (cxx_pp)->padding = pp_before; break; - /* Can only be reached through function pointer -- this would not be - correct if FUNCTION_DECLs used it. */ + /* This can be reached without a pointer when dealing with + templates, e.g. std::is_function. */ case FUNCTION_TYPE: - padding = dump_type_prefix (TREE_TYPE (t), flags); - if (padding != none) - output_add_space (scratch_buffer); - print_left_paren (scratch_buffer); - padding = none; + dump_type_prefix (TREE_TYPE (t), flags); break; case METHOD_TYPE: - padding = dump_type_prefix (TREE_TYPE (t), flags); - if (padding != none) - output_add_space (scratch_buffer); - print_left_paren (scratch_buffer); - padding = none; + dump_type_prefix (TREE_TYPE (t), flags); + pp_maybe_space (cxx_pp); + pp_cxx_left_paren (cxx_pp); dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags); - print_scope_operator (scratch_buffer); + pp_cxx_colon_colon (cxx_pp); break; case ARRAY_TYPE: - padding = dump_type_prefix (TREE_TYPE (t), flags); + dump_type_prefix (TREE_TYPE (t), flags); break; case ENUMERAL_TYPE: @@ -693,27 +623,27 @@ dump_type_prefix (t, flags) case COMPLEX_TYPE: case VECTOR_TYPE: case TYPEOF_TYPE: + case DECLTYPE_TYPE: + case TYPE_PACK_EXPANSION: + case FIXED_POINT_TYPE: dump_type (t, flags); - padding = before; + pp_base (cxx_pp)->padding = pp_before; break; default: - sorry_for_unsupported_tree (t); + pp_unsupported_tree (cxx_pp, t); /* fall through. */ case ERROR_MARK: - print_identifier (scratch_buffer, ""); + pp_identifier (cxx_pp, ""); break; } - return padding; } /* Dump the suffix of type T, under control of FLAGS. This is the part which appears after the identifier (or function parms). */ static void -dump_type_suffix (t, flags) - tree t; - int flags; +dump_type_suffix (tree t, int flags) { if (TYPE_PTRMEMFUNC_P (t)) t = TYPE_PTRMEMFUNC_FN_TYPE (t); @@ -723,17 +653,19 @@ dump_type_suffix (t, flags) case POINTER_TYPE: case REFERENCE_TYPE: case OFFSET_TYPE: - if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) - print_right_paren (scratch_buffer); + if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE + || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) + pp_cxx_right_paren (cxx_pp); dump_type_suffix (TREE_TYPE (t), flags); break; - /* Can only be reached through function pointer */ case FUNCTION_TYPE: case METHOD_TYPE: { tree arg; - print_right_paren (scratch_buffer); + if (TREE_CODE (t) == METHOD_TYPE) + /* Can only be reached through a pointer. */ + pp_cxx_right_paren (cxx_pp); arg = TYPE_ARG_TYPES (t); if (TREE_CODE (t) == METHOD_TYPE) arg = TREE_CHAIN (arg); @@ -743,31 +675,33 @@ dump_type_suffix (t, flags) dump_parameters (arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS); if (TREE_CODE (t) == METHOD_TYPE) - dump_qualifiers - (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before); + pp_cxx_cv_qualifier_seq + (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t)))); + else + pp_cxx_cv_qualifier_seq (cxx_pp, t); dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags); dump_type_suffix (TREE_TYPE (t), flags); break; } case ARRAY_TYPE: - print_left_bracket (scratch_buffer); + pp_maybe_space (cxx_pp); + pp_cxx_left_bracket (cxx_pp); if (TYPE_DOMAIN (t)) { - if (host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0)) - print_integer - (scratch_buffer, - tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0) + 1); - else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR) - dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), - flags & ~TFF_EXPR_IN_PARENS); + tree dtype = TYPE_DOMAIN (t); + tree max = TYPE_MAX_VALUE (dtype); + if (host_integerp (max, 0)) + pp_wide_integer (cxx_pp, tree_low_cst (max, 0) + 1); + else if (TREE_CODE (max) == MINUS_EXPR) + dump_expr (TREE_OPERAND (max, 0), + flags & ~TFF_EXPR_IN_PARENS); else - dump_expr (fold (cp_build_binary_op - (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)), - integer_one_node)), - flags & ~TFF_EXPR_IN_PARENS); + dump_expr (fold_build2 (PLUS_EXPR, dtype, max, + build_int_cst (dtype, 1)), + flags & ~TFF_EXPR_IN_PARENS); } - print_right_bracket (scratch_buffer); + pp_cxx_right_bracket (cxx_pp); dump_type_suffix (TREE_TYPE (t), flags); break; @@ -790,20 +724,22 @@ dump_type_suffix (t, flags) case COMPLEX_TYPE: case VECTOR_TYPE: case TYPEOF_TYPE: + case DECLTYPE_TYPE: + case TYPE_PACK_EXPANSION: + case FIXED_POINT_TYPE: break; default: - sorry_for_unsupported_tree (t); + pp_unsupported_tree (cxx_pp, t); case ERROR_MARK: /* Don't mark it here, we should have already done in - dump_type_prefix. */ + dump_type_prefix. */ break; } } static void -dump_global_iord (t) - tree t; +dump_global_iord (tree t) { const char *p = NULL; @@ -812,28 +748,32 @@ dump_global_iord (t) else if (DECL_GLOBAL_DTOR_P (t)) p = "destructors"; else - abort (); + gcc_unreachable (); - output_printf (scratch_buffer, "(static %s for %s)", p, input_filename); + pp_printf (pp_base (cxx_pp), "(static %s for %s)", p, input_filename); } static void -dump_simple_decl (t, type, flags) - tree t; - tree type; - int flags; +dump_simple_decl (tree t, tree type, int flags) { if (flags & TFF_DECL_SPECIFIERS) { - if (dump_type_prefix (type, flags) != none) - output_add_space (scratch_buffer); + dump_type_prefix (type, flags & ~TFF_UNQUALIFIED_NAME); + pp_maybe_space (cxx_pp); } - if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX) + if (! (flags & TFF_UNQUALIFIED_NAME) + && (!DECL_INITIAL (t) + || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)) dump_scope (CP_DECL_CONTEXT (t), flags); + flags &= ~TFF_UNQUALIFIED_NAME; + if ((flags & TFF_DECL_SPECIFIERS) + && DECL_TEMPLATE_PARM_P (t) + && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (t))) + pp_identifier (cxx_pp, "..."); if (DECL_NAME (t)) dump_decl (DECL_NAME (t), flags); else - print_identifier (scratch_buffer, ""); + pp_identifier (cxx_pp, ""); if (flags & TFF_DECL_SPECIFIERS) dump_type_suffix (type, flags); } @@ -841,9 +781,7 @@ dump_simple_decl (t, type, flags) /* Dump a human readable string for the decl T under control of FLAGS. */ static void -dump_decl (t, flags) - tree t; - int flags; +dump_decl (tree t, int flags) { if (t == NULL_TREE) return; @@ -851,64 +789,73 @@ dump_decl (t, flags) switch (TREE_CODE (t)) { case TYPE_DECL: - { - /* Don't say 'typedef class A' */ - if (DECL_ARTIFICIAL (t)) - { - if ((flags & TFF_DECL_SPECIFIERS) - && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) - /* Say `class T' not just `T'. */ - output_add_string (scratch_buffer, "class "); + /* Don't say 'typedef class A' */ + if (DECL_ARTIFICIAL (t)) + { + if ((flags & TFF_DECL_SPECIFIERS) + && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) + { + /* Say `class T' not just `T'. */ + pp_cxx_identifier (cxx_pp, "class"); - dump_type (TREE_TYPE (t), flags); - break; - } - } + /* Emit the `...' for a parameter pack. */ + if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t))) + pp_cxx_identifier (cxx_pp, "..."); + } + + dump_type (TREE_TYPE (t), flags); + break; + } if (flags & TFF_DECL_SPECIFIERS) - output_add_string (scratch_buffer, "typedef "); + pp_cxx_identifier (cxx_pp, "typedef"); dump_simple_decl (t, DECL_ORIGINAL_TYPE (t) ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), - flags); + flags); break; case VAR_DECL: if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t))) { - output_add_string (scratch_buffer, "vtable for "); - my_friendly_assert (TYPE_P (DECL_CONTEXT (t)), 20010720); + pp_string (cxx_pp, "vtable for "); + gcc_assert (TYPE_P (DECL_CONTEXT (t))); dump_type (DECL_CONTEXT (t), flags); break; } - /* else fall through */ + /* Else fall through. */ case FIELD_DECL: case PARM_DECL: dump_simple_decl (t, TREE_TYPE (t), flags); break; case RESULT_DECL: - output_add_string (scratch_buffer, " "); + pp_string (cxx_pp, " "); dump_simple_decl (t, TREE_TYPE (t), flags); break; case NAMESPACE_DECL: - dump_scope (CP_DECL_CONTEXT (t), flags); - if (DECL_NAME (t) == anonymous_namespace_name) - print_identifier (scratch_buffer, ""); + if (flags & TFF_DECL_SPECIFIERS) + pp_cxx_declaration (cxx_pp, t); else - print_tree_identifier (scratch_buffer, DECL_NAME (t)); + { + if (! (flags & TFF_UNQUALIFIED_NAME)) + dump_scope (CP_DECL_CONTEXT (t), flags); + flags &= ~TFF_UNQUALIFIED_NAME; + if (DECL_NAME (t) == NULL_TREE) + pp_identifier (cxx_pp, ""); + else + pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t)); + } break; case SCOPE_REF: - dump_decl (TREE_OPERAND (t, 0), flags & ~TFF_DECL_SPECIFIERS); - print_scope_operator (scratch_buffer); - dump_decl (TREE_OPERAND (t, 1), flags); + pp_expression (cxx_pp, t); break; case ARRAY_REF: dump_decl (TREE_OPERAND (t, 0), flags); - print_left_bracket (scratch_buffer); + pp_cxx_left_bracket (cxx_pp); dump_decl (TREE_OPERAND (t, 1), flags); - print_right_bracket (scratch_buffer); + pp_cxx_right_bracket (cxx_pp); break; /* So that we can do dump_decl on an aggr type. */ @@ -918,8 +865,15 @@ dump_decl (t, flags) dump_type (t, flags); break; + case BIT_NOT_EXPR: + /* This is a pseudo destructor call which has not been folded into + a PSEUDO_DTOR_EXPR yet. */ + pp_cxx_complement (cxx_pp); + dump_type (TREE_OPERAND (t, 0), flags); + break; + case TYPE_EXPR: - abort (); + gcc_unreachable (); break; /* These special cases are duplicated here so that other functions @@ -927,13 +881,13 @@ dump_decl (t, flags) case IDENTIFIER_NODE: if (IDENTIFIER_TYPENAME_P (t)) { - output_add_string (scratch_buffer, "operator "); + pp_cxx_identifier (cxx_pp, "operator"); /* Not exactly IDENTIFIER_TYPE_VALUE. */ dump_type (TREE_TYPE (t), flags); break; } else - print_tree_identifier (scratch_buffer, t); + pp_cxx_tree_identifier (cxx_pp, t); break; case OVERLOAD: @@ -943,29 +897,29 @@ dump_decl (t, flags) if (DECL_CLASS_SCOPE_P (t)) { dump_type (DECL_CONTEXT (t), flags); - output_add_string (scratch_buffer, "::"); + pp_cxx_colon_colon (cxx_pp); } else if (DECL_CONTEXT (t)) { dump_decl (DECL_CONTEXT (t), flags); - output_add_string (scratch_buffer, "::"); + pp_cxx_colon_colon (cxx_pp); } dump_decl (DECL_NAME (t), flags); break; } - + /* If there's only one function, just treat it like an ordinary FUNCTION_DECL. */ t = OVL_CURRENT (t); /* Fall through. */ case FUNCTION_DECL: - if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t)) + if (! DECL_LANG_SPECIFIC (t)) + pp_identifier (cxx_pp, ""); + else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t)) dump_global_iord (t); - else if (! DECL_LANG_SPECIFIC (t)) - print_identifier (scratch_buffer, ""); else - dump_function_decl (t, flags); + dump_function_decl (t, flags); break; case TEMPLATE_DECL: @@ -974,28 +928,20 @@ dump_decl (t, flags) case TEMPLATE_ID_EXPR: { - tree args; tree name = TREE_OPERAND (t, 0); + if (is_overloaded_fn (name)) name = DECL_NAME (get_first_fn (name)); dump_decl (name, flags); - print_template_argument_list_start (scratch_buffer); - for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args)) - { - dump_template_argument (TREE_VALUE (args), flags); - if (TREE_CHAIN (args)) - separate_with_comma (scratch_buffer); - } - print_template_argument_list_end (scratch_buffer); + pp_cxx_begin_template_argument_list (cxx_pp); + if (TREE_OPERAND (t, 1)) + dump_template_argument_list (TREE_OPERAND (t, 1), flags); + pp_cxx_end_template_argument_list (cxx_pp); } break; - case LOOKUP_EXPR: - dump_decl (TREE_OPERAND (t, 0), flags); - break; - case LABEL_DECL: - print_tree_identifier (scratch_buffer, DECL_NAME (t)); + pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t)); break; case CONST_DECL: @@ -1008,22 +954,47 @@ dump_decl (t, flags) else if (DECL_INITIAL (t)) dump_expr (DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS); else - print_identifier (scratch_buffer, "enumerator"); + pp_identifier (cxx_pp, ""); break; case USING_DECL: - output_add_string (scratch_buffer, "using "); - dump_type (DECL_INITIAL (t), flags); - print_scope_operator (scratch_buffer); - print_tree_identifier (scratch_buffer, DECL_NAME (t)); + pp_cxx_identifier (cxx_pp, "using"); + dump_type (USING_DECL_SCOPE (t), flags); + pp_cxx_colon_colon (cxx_pp); + dump_decl (DECL_NAME (t), flags); + break; + + case STATIC_ASSERT: + pp_cxx_declaration (cxx_pp, t); + break; + + case BASELINK: + dump_decl (BASELINK_FUNCTIONS (t), flags); + break; + + case NON_DEPENDENT_EXPR: + dump_expr (t, flags); + break; + + case TEMPLATE_TYPE_PARM: + if (flags & TFF_DECL_SPECIFIERS) + pp_cxx_declaration (cxx_pp, t); + else + pp_type_id (cxx_pp, t); + break; + + case UNBOUND_CLASS_TEMPLATE: + case TYPE_PACK_EXPANSION: + case TREE_BINFO: + dump_type (t, flags); break; default: - sorry_for_unsupported_tree (t); - /* Fallthrough to error. */ + pp_unsupported_tree (cxx_pp, t); + /* Fall through to error. */ case ERROR_MARK: - print_identifier (scratch_buffer, ""); + pp_identifier (cxx_pp, ""); break; } } @@ -1032,9 +1003,7 @@ dump_decl (t, flags) 'template <...> leaders plus the 'class X' or 'void fn(...)' part. */ static void -dump_template_decl (t, flags) - tree t; - int flags; +dump_template_decl (tree t, int flags) { tree orig_parms = DECL_TEMPLATE_PARMS (t); tree parms; @@ -1043,66 +1012,75 @@ dump_template_decl (t, flags) if (flags & TFF_TEMPLATE_HEADER) { for (parms = orig_parms = nreverse (orig_parms); - parms; - parms = TREE_CHAIN (parms)) - { + parms; + parms = TREE_CHAIN (parms)) + { tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms); - int len = TREE_VEC_LENGTH (inner_parms); + int len = TREE_VEC_LENGTH (inner_parms); - output_add_string (scratch_buffer, "template<"); + pp_cxx_identifier (cxx_pp, "template"); + pp_cxx_begin_template_argument_list (cxx_pp); /* If we've shown the template prefix, we'd better show the parameters' and decl's type too. */ flags |= TFF_DECL_SPECIFIERS; - for (i = 0; i < len; i++) - { - if (i) - separate_with_comma (scratch_buffer); - dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags); - } - print_template_argument_list_end (scratch_buffer); - output_add_space (scratch_buffer); - } + for (i = 0; i < len; i++) + { + if (i) + pp_separate_with_comma (cxx_pp); + dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags); + } + pp_cxx_end_template_argument_list (cxx_pp); + pp_cxx_whitespace (cxx_pp); + } nreverse(orig_parms); if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) - /* Say `template class TT' not just `template TT'. */ - output_add_string (scratch_buffer, "class "); + { + /* Say `template class TT' not just `template TT'. */ + pp_cxx_identifier (cxx_pp, "class"); + + /* If this is a parameter pack, print the ellipsis. */ + if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t))) + pp_cxx_identifier (cxx_pp, "..."); + } } - if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) + if (DECL_TEMPLATE_RESULT (t) + && TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) dump_type (TREE_TYPE (t), - ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME - | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0))); - else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL) + ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME + | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0))); + else if (DECL_TEMPLATE_RESULT (t) + && TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL) dump_decl (DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME); - else if (TREE_TYPE (t) == NULL_TREE) - abort (); else - switch (NEXT_CODE (t)) { - case METHOD_TYPE: - case FUNCTION_TYPE: - dump_function_decl (t, flags | TFF_TEMPLATE_NAME); - break; - default: - /* This case can occur with some illegal code. */ - dump_type (TREE_TYPE (t), - (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME - | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)); + gcc_assert (TREE_TYPE (t)); + switch (NEXT_CODE (t)) + { + case METHOD_TYPE: + case FUNCTION_TYPE: + dump_function_decl (t, flags | TFF_TEMPLATE_NAME); + break; + default: + /* This case can occur with some invalid code. */ + dump_type (TREE_TYPE (t), + (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME + | (flags & TFF_DECL_SPECIFIERS + ? TFF_CLASS_KEY_OR_ENUM : 0)); + } } } /* Pretty print a function decl. There are several ways we want to print a function declaration. The TFF_ bits in FLAGS tells us how to behave. As error can only apply the '#' flag once to give 0 and 1 for V, there - is %D which doesn't print the throw specs, and %F which does. */ + is %D which doesn't print the throw specs, and %F which does. */ static void -dump_function_decl (t, flags) - tree t; - int flags; +dump_function_decl (tree t, int flags) { tree fntype; tree parmtypes; @@ -1110,10 +1088,17 @@ dump_function_decl (t, flags) tree template_args = NULL_TREE; tree template_parms = NULL_TREE; int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS; + int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME); + tree exceptions; + flags &= ~TFF_UNQUALIFIED_NAME; if (TREE_CODE (t) == TEMPLATE_DECL) t = DECL_TEMPLATE_RESULT (t); + /* Save the exceptions, in case t is a specialization and we are + emitting an error about incompatible specifications. */ + exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t)); + /* Pretty print template instantiations only. */ if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t)) { @@ -1133,48 +1118,53 @@ dump_function_decl (t, flags) if (DECL_CLASS_SCOPE_P (t)) cname = DECL_CONTEXT (t); - /* this is for partially instantiated template methods */ + /* This is for partially instantiated template methods. */ else if (TREE_CODE (fntype) == METHOD_TYPE) cname = TREE_TYPE (TREE_VALUE (parmtypes)); if (!(flags & TFF_DECL_SPECIFIERS)) /* OK */; else if (DECL_STATIC_FUNCTION_P (t)) - print_identifier (scratch_buffer, "static "); + pp_cxx_identifier (cxx_pp, "static"); else if (DECL_VIRTUAL_P (t)) - print_identifier (scratch_buffer, "virtual "); + pp_cxx_identifier (cxx_pp, "virtual"); /* Print the return type? */ if (show_return) show_return = !DECL_CONV_FN_P (t) && !DECL_CONSTRUCTOR_P (t) - && !DECL_DESTRUCTOR_P (t); + && !DECL_DESTRUCTOR_P (t); if (show_return) - { - dump_type_prefix (TREE_TYPE (fntype), flags); - output_add_space (scratch_buffer); - } + dump_type_prefix (TREE_TYPE (fntype), flags); /* Print the function name. */ - if (cname) + if (!do_outer_scope) + /* Nothing. */; + else if (cname) { dump_type (cname, flags); - print_scope_operator (scratch_buffer); + pp_cxx_colon_colon (cxx_pp); } else dump_scope (CP_DECL_CONTEXT (t), flags); dump_function_name (t, flags); - if (1) + if (!(flags & TFF_NO_FUNCTION_ARGUMENTS)) { dump_parameters (parmtypes, flags); if (TREE_CODE (fntype) == METHOD_TYPE) - dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), - before); + { + pp_base (cxx_pp)->padding = pp_before; + pp_cxx_cv_qualifier_seq + (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype)))); + } if (flags & TFF_EXCEPTION_SPECIFICATION) - dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags); + { + pp_base (cxx_pp)->padding = pp_before; + dump_exception_spec (exceptions, flags); + } if (show_return) dump_type_suffix (TREE_TYPE (fntype), flags); @@ -1183,68 +1173,71 @@ dump_function_decl (t, flags) /* If T is a template instantiation, dump the parameter binding. */ if (template_parms != NULL_TREE && template_args != NULL_TREE) { - output_add_string (scratch_buffer, " [with "); + pp_cxx_whitespace (cxx_pp); + pp_cxx_left_bracket (cxx_pp); + pp_cxx_identifier (cxx_pp, "with"); + pp_cxx_whitespace (cxx_pp); dump_template_bindings (template_parms, template_args); - print_right_bracket (scratch_buffer); + pp_cxx_right_bracket (cxx_pp); } } /* Print a parameter list. If this is for a member function, the member object ptr (and any other hidden args) should have - already been removed. */ + already been removed. */ static void -dump_parameters (parmtypes, flags) - tree parmtypes; - int flags; +dump_parameters (tree parmtypes, int flags) { - int first; - - print_left_paren (scratch_buffer); + int first = 1; + pp_cxx_left_paren (cxx_pp); for (first = 1; parmtypes != void_list_node; parmtypes = TREE_CHAIN (parmtypes)) { if (!first) - separate_with_comma (scratch_buffer); + pp_separate_with_comma (cxx_pp); first = 0; if (!parmtypes) - { - print_identifier (scratch_buffer, "..."); - break; - } + { + pp_cxx_identifier (cxx_pp, "..."); + break; + } + dump_type (TREE_VALUE (parmtypes), flags); if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes)) - { - output_add_string (scratch_buffer, " = "); - dump_expr (TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS); - } + { + pp_cxx_whitespace (cxx_pp); + pp_equal (cxx_pp); + pp_cxx_whitespace (cxx_pp); + dump_expr (TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS); + } } - print_right_paren (scratch_buffer); + pp_cxx_right_paren (cxx_pp); } -/* Print an exception specification. T is the exception specification. */ +/* Print an exception specification. T is the exception specification. */ static void -dump_exception_spec (t, flags) - tree t; - int flags; +dump_exception_spec (tree t, int flags) { if (t) { - output_add_string (scratch_buffer, " throw ("); + pp_cxx_identifier (cxx_pp, "throw"); + pp_cxx_whitespace (cxx_pp); + pp_cxx_left_paren (cxx_pp); if (TREE_VALUE (t) != NULL_TREE) - while (1) - { - dump_type (TREE_VALUE (t), flags); - t = TREE_CHAIN (t); - if (!t) - break; - separate_with_comma (scratch_buffer); - } - print_right_paren (scratch_buffer); + while (1) + { + dump_type (TREE_VALUE (t), flags); + t = TREE_CHAIN (t); + if (!t) + break; + pp_separate_with_comma (cxx_pp); + } + pp_cxx_right_paren (cxx_pp); } } @@ -1252,12 +1245,24 @@ dump_exception_spec (t, flags) and destructors properly. */ static void -dump_function_name (t, flags) - tree t; - int flags; +dump_function_name (tree t, int flags) { tree name = DECL_NAME (t); + /* We can get here with a decl that was synthesized by language- + independent machinery (e.g. coverage.c) in which case it won't + have a lang_specific structure attached and DECL_CONSTRUCTOR_P + will crash. In this case it is safe just to print out the + literal name. */ + if (!DECL_LANG_SPECIFIC (t)) + { + pp_cxx_tree_identifier (cxx_pp, name); + return; + } + + if (TREE_CODE (t) == TEMPLATE_DECL) + t = DECL_TEMPLATE_RESULT (t); + /* Don't let the user see __comp_ctor et al. */ if (DECL_CONSTRUCTOR_P (t) || DECL_DESTRUCTOR_P (t)) @@ -1265,7 +1270,7 @@ dump_function_name (t, flags) if (DECL_DESTRUCTOR_P (t)) { - output_add_character (scratch_buffer, '~'); + pp_cxx_complement (cxx_pp); dump_decl (name, TFF_PLAIN_IDENTIFIER); } else if (DECL_CONV_FN_P (t)) @@ -1276,19 +1281,17 @@ dump_function_name (t, flags) declarations, both will have the same name, yet the types will be different, hence the TREE_TYPE field of the first name will be clobbered by the second. */ - output_add_string (scratch_buffer, "operator "); + pp_cxx_identifier (cxx_pp, "operator"); dump_type (TREE_TYPE (TREE_TYPE (t)), flags); } else if (IDENTIFIER_OPNAME_P (name)) - print_tree_identifier (scratch_buffer, name); + pp_cxx_tree_identifier (cxx_pp, name); else dump_decl (name, flags); - if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t) + if (DECL_TEMPLATE_INFO (t) && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t) - && (DECL_TEMPLATE_SPECIALIZATION (t) - || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL - || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t)) + && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))) dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags); } @@ -1300,57 +1303,42 @@ dump_function_name (t, flags) decoration. */ static void -dump_template_parms (info, primary, flags) - tree info; - int primary; - int flags; +dump_template_parms (tree info, int primary, int flags) { tree args = info ? TI_ARGS (info) : NULL_TREE; if (primary && flags & TFF_TEMPLATE_NAME) return; flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME); - print_template_argument_list_start (scratch_buffer); + pp_cxx_begin_template_argument_list (cxx_pp); /* Be careful only to print things when we have them, so as not to crash producing error messages. */ if (args && !primary) { - int len = 0; - int ix = 0; - int need_comma = 0; + int len, ix; - if (TREE_CODE (args) == TREE_VEC) - { - if (TREE_VEC_LENGTH (args) > 0 - && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) - args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1); + if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) + args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1); - len = TREE_VEC_LENGTH (args); - } - else if (TREE_CODE (args) == TREE_LIST) - len = -1; - while (ix != len && args) - { - tree arg; - if (len >= 0) - { - arg = TREE_VEC_ELT (args, ix); - ix++; - } - else - { - arg = TREE_VALUE (args); - args = TREE_CHAIN (args); - } - if (need_comma) - separate_with_comma (scratch_buffer); + len = TREE_VEC_LENGTH (args); + + for (ix = 0; ix != len; ix++) + { + tree arg = TREE_VEC_ELT (args, ix); + + /* Only print a comma if we know there is an argument coming. In + the case of an empty template argument pack, no actual + argument will be printed. */ + if (ix + && (!ARGUMENT_PACK_P (arg) + || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0)) + pp_separate_with_comma (cxx_pp); if (!arg) - print_identifier (scratch_buffer, "