static cxx_pretty_printer scratch_pretty_printer;
#define cxx_pp (&scratch_pretty_printer)
+/* Translate if being used for diagnostics, but not for dump files or
+ __PRETTY_FUNCTION. */
+#define M_(msgid) (pp_translate_identifiers (cxx_pp) ? _(msgid) : (msgid))
+
# define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T)))
static const char *args_to_string (tree, int);
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, tree, int);
+static void dump_template_argument_list (tree, int);
static void dump_template_parameter (tree, int);
static void dump_template_bindings (tree, tree, VEC(tree,gc) *);
static void dump_scope (tree, int);
static void dump_template_parms (tree, int, int);
-
-static int count_non_default_template_args (tree, tree);
-
+static int get_non_default_template_args_count (tree, int);
static const char *function_category (tree);
static void maybe_print_instantiation_context (diagnostic_context *);
static void print_instantiation_full_context (diagnostic_context *);
dump_template_argument (tree arg, int flags)
{
if (ARGUMENT_PACK_P (arg))
- dump_template_argument_list (ARGUMENT_PACK_ARGS (arg), NULL_TREE, flags);
+ 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
match the (optional) default template parameter in PARAMS */
static int
-count_non_default_template_args (tree args, tree params)
+get_non_default_template_args_count (tree args, int flags)
{
- int n = TREE_VEC_LENGTH (args);
- int last;
-
- if (params == NULL_TREE || !flag_pretty_templates)
+ int n = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (args));
+
+ if (/* We use this flag when generating debug information. We don't
+ want to expand templates at this point, for this may generate
+ new decls, which gets decl counts out of sync, which may in
+ turn cause codegen differences between compilations with and
+ without -g. */
+ (flags & TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS) != 0
+ || !flag_pretty_templates)
return n;
- for (last = n - 1; last >= 0; --last)
- {
- tree param = TREE_VEC_ELT (params, last);
- tree def = TREE_PURPOSE (param);
-
- if (!def)
- break;
- if (uses_template_parms (def))
- {
- ++processing_template_decl;
- def = tsubst_copy_and_build (def, args, tf_none, NULL_TREE, false, true);
- --processing_template_decl;
- }
- if (!cp_tree_equal (TREE_VEC_ELT (args, last), def))
- break;
- }
-
- return last + 1;
+ return GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (INNERMOST_TEMPLATE_ARGS (args));
}
/* Dump a template-argument-list ARGS (always a TREE_VEC) under control
of FLAGS. */
static void
-dump_template_argument_list (tree args, tree parms, int flags)
+dump_template_argument_list (tree args, int flags)
{
- int n = count_non_default_template_args (args, parms);
+ int n = get_non_default_template_args_count (args, flags);
int need_comma = 0;
int i;
pp_equal (cxx_pp);
pp_cxx_whitespace (cxx_pp);
if (arg)
- dump_template_argument (arg, TFF_PLAIN_IDENTIFIER);
+ {
+ if (ARGUMENT_PACK_P (arg))
+ pp_cxx_left_brace (cxx_pp);
+ dump_template_argument (arg, TFF_PLAIN_IDENTIFIER);
+ if (ARGUMENT_PACK_P (arg))
+ pp_cxx_right_brace (cxx_pp);
+ }
else
- pp_string (cxx_pp, _("<missing>"));
+ pp_string (cxx_pp, M_("<missing>"));
++arg_idx;
need_comma = 1;
t = tsubst (t, args, tf_none, NULL_TREE);
/* Strip typedefs. We can't just use TFF_CHASE_TYPEDEF because
pp_simple_type_specifier doesn't know about it. */
- t = canonical_type_variant (t);
+ t = strip_typedefs (t);
dump_type (t, TFF_PLAIN_IDENTIFIER);
}
}
switch (TREE_CODE (t))
{
- case UNKNOWN_TYPE:
+ case LANG_TYPE:
if (t == init_list_type_node)
- pp_string (cxx_pp, _("<brace-enclosed initializer list>"));
+ pp_string (cxx_pp, M_("<brace-enclosed initializer list>"));
+ else if (t == unknown_type_node)
+ pp_string (cxx_pp, M_("<unresolved overloaded function type>"));
else
- pp_string (cxx_pp, _("<unresolved overloaded function type>"));
+ {
+ pp_cxx_cv_qualifier_seq (cxx_pp, t);
+ pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
+ }
break;
case TREE_LIST:
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, NULL_TREE, flags);
+ dump_template_argument_list (args, flags);
pp_cxx_end_template_argument_list (cxx_pp);
}
break;
break;
case UNBOUND_CLASS_TEMPLATE:
- dump_type (TYPE_CONTEXT (t), flags);
- pp_cxx_colon_colon (cxx_pp);
+ if (! (flags & TFF_UNQUALIFIED_NAME))
+ {
+ dump_type (TYPE_CONTEXT (t), flags);
+ pp_cxx_colon_colon (cxx_pp);
+ }
pp_cxx_ws_string (cxx_pp, "template");
dump_type (DECL_NAME (TYPE_NAME (t)), flags);
break;
/* Fall through to error. */
case ERROR_MARK:
- pp_string (cxx_pp, _("<type error>"));
+ pp_string (cxx_pp, M_("<type error>"));
break;
}
}
{
typdef = !DECL_ARTIFICIAL (name);
- if (typdef
- && ((flags & TFF_CHASE_TYPEDEF)
- || (!flag_pretty_templates && DECL_LANG_SPECIFIC (name)
- && DECL_TEMPLATE_INFO (name))))
+ if ((typdef
+ && ((flags & TFF_CHASE_TYPEDEF)
+ || (!flag_pretty_templates && DECL_LANG_SPECIFIC (name)
+ && DECL_TEMPLATE_INFO (name))))
+ || DECL_SELF_REFERENCE_P (name))
{
t = TYPE_MAIN_VARIANT (t);
name = TYPE_NAME (t);
if (name == 0 || ANON_AGGRNAME_P (name))
{
if (flags & TFF_CLASS_KEY_OR_ENUM)
- pp_string (cxx_pp, _("<anonymous>"));
+ pp_string (cxx_pp, M_("<anonymous>"));
else
- pp_printf (pp_base (cxx_pp), _("<anonymous %s>"), variety);
+ pp_printf (pp_base (cxx_pp), M_("<anonymous %s>"), variety);
+ }
+ else if (LAMBDANAME_P (name))
+ {
+ /* A lambda's "type" is essentially its signature. */
+ pp_string (cxx_pp, M_("<lambda"));
+ if (lambda_function (t))
+ dump_parameters (FUNCTION_FIRST_USER_PARMTYPE (lambda_function (t)),
+ flags);
+ pp_character(cxx_pp, '>');
}
else
pp_cxx_tree_identifier (cxx_pp, name);
case TYPE_DECL:
case TREE_VEC:
case UNION_TYPE:
- case UNKNOWN_TYPE:
+ case LANG_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
pp_unsupported_tree (cxx_pp, t);
/* fall through. */
case ERROR_MARK:
- pp_string (cxx_pp, _("<typeprefixerror>"));
+ pp_string (cxx_pp, M_("<typeprefixerror>"));
break;
}
}
dump_expr (TREE_OPERAND (max, 0),
flags & ~TFF_EXPR_IN_PARENS);
else
- dump_expr (fold_build2 (PLUS_EXPR, dtype, max,
+ dump_expr (fold_build2_loc (input_location,
+ PLUS_EXPR, dtype, max,
build_int_cst (dtype, 1)),
flags & ~TFF_EXPR_IN_PARENS);
}
case TYPE_DECL:
case TREE_VEC:
case UNION_TYPE:
- case UNKNOWN_TYPE:
+ case LANG_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
const char *p = NULL;
if (DECL_GLOBAL_CTOR_P (t))
- p = _("(static initializers for %s)");
+ p = M_("(static initializers for %s)");
else if (DECL_GLOBAL_DTOR_P (t))
- p = _("(static destructors for %s)");
+ p = M_("(static destructors for %s)");
else
gcc_unreachable ();
if (DECL_NAME (t))
dump_decl (DECL_NAME (t), flags);
else
- pp_string (cxx_pp, _("<anonymous>"));
+ pp_string (cxx_pp, M_("<anonymous>"));
if (flags & TFF_DECL_SPECIFIERS)
dump_type_suffix (type, flags);
}
{
case TYPE_DECL:
/* Don't say 'typedef class A' */
- if (DECL_ARTIFICIAL (t))
+ if (DECL_ARTIFICIAL (t) && !DECL_SELF_REFERENCE_P (t))
{
if ((flags & TFF_DECL_SPECIFIERS)
&& TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
dump_type (TREE_TYPE (t), flags);
break;
}
- if (flags & TFF_DECL_SPECIFIERS)
+ if ((flags & TFF_DECL_SPECIFIERS)
+ && !DECL_SELF_REFERENCE_P (t))
pp_cxx_ws_string (cxx_pp, "typedef");
dump_simple_decl (t, DECL_ORIGINAL_TYPE (t)
? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
case VAR_DECL:
if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
{
- pp_string (cxx_pp, _("vtable for "));
+ pp_string (cxx_pp, M_("vtable for "));
gcc_assert (TYPE_P (DECL_CONTEXT (t)));
dump_type (DECL_CONTEXT (t), flags);
break;
break;
case RESULT_DECL:
- pp_string (cxx_pp, _("<return value> "));
+ pp_string (cxx_pp, M_("<return value> "));
dump_simple_decl (t, TREE_TYPE (t), flags);
break;
dump_scope (CP_DECL_CONTEXT (t), flags);
flags &= ~TFF_UNQUALIFIED_NAME;
if (DECL_NAME (t) == NULL_TREE)
- pp_string (cxx_pp, _("<unnamed>"));
+ pp_string (cxx_pp, M_("<unnamed>"));
else
pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t));
}
break;
case SCOPE_REF:
- pp_expression (cxx_pp, t);
+ dump_type (TREE_OPERAND (t, 0), flags);
+ pp_string (cxx_pp, "::");
+ dump_decl (TREE_OPERAND (t, 1), flags|TFF_UNQUALIFIED_NAME);
break;
case ARRAY_REF:
case FUNCTION_DECL:
if (! DECL_LANG_SPECIFIC (t))
- pp_string (cxx_pp, _("<built-in>"));
+ pp_string (cxx_pp, M_("<built-in>"));
else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
dump_global_iord (t);
else
dump_decl (name, flags);
pp_cxx_begin_template_argument_list (cxx_pp);
if (TREE_OPERAND (t, 1))
- dump_template_argument_list (TREE_OPERAND (t, 1), NULL_TREE, flags);
+ dump_template_argument_list (TREE_OPERAND (t, 1), flags);
pp_cxx_end_template_argument_list (cxx_pp);
}
break;
else if (DECL_INITIAL (t))
dump_expr (DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
else
- pp_string (cxx_pp, _("<enumerator>"));
+ pp_string (cxx_pp, M_("<enumerator>"));
break;
case USING_DECL:
/* Fall through to error. */
case ERROR_MARK:
- pp_string (cxx_pp, _("<declaration error>"));
+ pp_string (cxx_pp, M_("<declaration error>"));
break;
}
}
}
/* find_typenames looks through the type of the function template T
- and returns a VEC containing any typedefs or TYPENAME_TYPEs it finds. */
+ and returns a VEC containing any typedefs, decltypes or TYPENAME_TYPEs
+ it finds. */
struct find_typenames_t
{
if (TYPE_P (*tp) && is_typedef_decl (TYPE_NAME (*tp)))
/* Add the type of the typedef without any additional cv-quals. */
mv = TREE_TYPE (TYPE_NAME (*tp));
- else if (TREE_CODE (*tp) == TYPENAME_TYPE)
+ else if (TREE_CODE (*tp) == TYPENAME_TYPE
+ || TREE_CODE (*tp) == DECLTYPE_TYPE)
/* Add the typename without any cv-qualifiers. */
mv = TYPE_MAIN_VARIANT (*tp);
tree exceptions;
VEC(tree,gc) *typenames = NULL;
+ if (LAMBDA_FUNCTION_P (t))
+ {
+ /* A lambda's signature is essentially its "type", so defer. */
+ gcc_assert (LAMBDA_TYPE_P (DECL_CONTEXT (t)));
+ dump_type (DECL_CONTEXT (t), flags);
+ return;
+ }
+
flags &= ~TFF_UNQUALIFIED_NAME;
if (TREE_CODE (t) == TEMPLATE_DECL)
t = DECL_TEMPLATE_RESULT (t);
{
pp_cxx_whitespace (cxx_pp);
pp_cxx_left_bracket (cxx_pp);
- pp_cxx_ws_string (cxx_pp, _("with"));
+ pp_cxx_ws_string (cxx_pp, M_("with"));
pp_cxx_whitespace (cxx_pp);
dump_template_bindings (template_parms, template_args, typenames);
pp_cxx_right_bracket (cxx_pp);
/* Don't let the user see __comp_ctor et al. */
if (DECL_CONSTRUCTOR_P (t)
|| DECL_DESTRUCTOR_P (t))
- name = constructor_name (DECL_CONTEXT (t));
+ {
+ if (LAMBDA_TYPE_P (DECL_CONTEXT (t)))
+ name = get_identifier ("<lambda>");
+ else
+ name = constructor_name (DECL_CONTEXT (t));
+ }
if (DECL_DESTRUCTOR_P (t))
{
pp_cxx_ws_string (cxx_pp, "operator");
dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
}
- else if (IDENTIFIER_OPNAME_P (name))
+ else if (name && IDENTIFIER_OPNAME_P (name))
pp_cxx_tree_identifier (cxx_pp, name);
else
dump_decl (name, flags);
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. */
+ to crash producing error messages. */
if (args && !primary)
{
int len, ix;
- /* We don't know the parms for a friend template specialization. */
- tree params = (TREE_CODE (TI_TEMPLATE (info)) == TEMPLATE_DECL
- ? DECL_INNERMOST_TEMPLATE_PARMS (TI_TEMPLATE (info))
- : NULL_TREE);
-
- if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
- args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
-
- len = count_non_default_template_args (args, params);
+ len = get_non_default_template_args_count (args, flags);
+ args = INNERMOST_TEMPLATE_ARGS (args);
for (ix = 0; ix != len; ix++)
{
tree arg = TREE_VEC_ELT (args, ix);
pp_separate_with_comma (cxx_pp);
if (!arg)
- pp_string (cxx_pp, _("<template parameter error>"));
+ pp_string (cxx_pp, M_("<template parameter error>"));
else
dump_template_argument (arg, flags);
}
if (TREE_VEC_ELT (parms, ix) == error_mark_node)
{
- pp_string (cxx_pp, _("<template parameter error>"));
+ pp_string (cxx_pp, M_("<template parameter error>"));
continue;
}
if (STATEMENT_CLASS_P (t))
{
- pp_cxx_ws_string (cxx_pp, _("<statement>"));
+ pp_cxx_ws_string (cxx_pp, M_("<statement>"));
return;
}
case THROW_EXPR:
/* While waiting for caret diagnostics, avoid printing
__cxa_allocate_exception, __cxa_throw, and the like. */
- pp_cxx_ws_string (cxx_pp, _("<throw-expression>"));
+ pp_cxx_ws_string (cxx_pp, M_("<throw-expression>"));
break;
case PTRMEM_CST:
break;
case DEFAULT_ARG:
- pp_string (cxx_pp, _("<unparsed>"));
+ pp_string (cxx_pp, M_("<unparsed>"));
break;
case TRY_CATCH_EXPR:
break;
case SCOPE_REF:
+ dump_decl (t, flags);
+ break;
+
case EXPR_PACK_EXPANSION:
case TYPEID_EXPR:
case MEMBER_REF:
pp_unsupported_tree (cxx_pp, t);
/* fall through to ERROR_MARK... */
case ERROR_MARK:
- pp_string (cxx_pp, _("<expression error>"));
+ pp_string (cxx_pp, M_("<expression error>"));
break;
}
}
if (opstring)
pp_cxx_ws_string (cxx_pp, opstring);
else
- pp_string (cxx_pp, _("<unknown operator>"));
+ pp_string (cxx_pp, M_("<unknown operator>"));
pp_cxx_whitespace (cxx_pp);
dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
pp_cxx_right_paren (cxx_pp);
type_as_string (tree typ, int flags)
{
reinit_cxx_pp ();
+ pp_translate_identifiers (cxx_pp) = false;
+ dump_type (typ, flags);
+ return pp_formatted_text (cxx_pp);
+}
+
+const char *
+type_as_string_translate (tree typ, int flags)
+{
+ reinit_cxx_pp ();
dump_type (typ, flags);
return pp_formatted_text (cxx_pp);
}
expr_as_string (tree decl, int flags)
{
reinit_cxx_pp ();
+ pp_translate_identifiers (cxx_pp) = false;
dump_expr (decl, flags);
return pp_formatted_text (cxx_pp);
}
decl_as_string (tree decl, int flags)
{
reinit_cxx_pp ();
+ pp_translate_identifiers (cxx_pp) = false;
+ dump_decl (decl, flags);
+ return pp_formatted_text (cxx_pp);
+}
+
+const char *
+decl_as_string_translate (tree decl, int flags)
+{
+ reinit_cxx_pp ();
dump_decl (decl, flags);
return pp_formatted_text (cxx_pp);
}
/* Generate the three forms of printable names for cxx_printable_name. */
const char *
-lang_decl_name (tree decl, int v)
+lang_decl_name (tree decl, int v, bool translate)
{
if (v >= 2)
- return decl_as_string (decl, TFF_DECL_SPECIFIERS);
+ return (translate
+ ? decl_as_string_translate (decl, TFF_DECL_SPECIFIERS)
+ : decl_as_string (decl, TFF_DECL_SPECIFIERS));
reinit_cxx_pp ();
- if (v == 1 && DECL_CLASS_SCOPE_P (decl))
+ pp_translate_identifiers (cxx_pp) = translate;
+ if (v == 1
+ && (DECL_CLASS_SCOPE_P (decl)
+ || (DECL_NAMESPACE_SCOPE_P (decl)
+ && CP_DECL_CONTEXT (decl) != global_namespace)))
{
dump_type (CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER);
pp_cxx_colon_colon (cxx_pp);
op_to_string (enum tree_code p)
{
tree id = operator_name_info[(int) p].identifier;
- return id ? IDENTIFIER_POINTER (id) : _("<unknown>");
+ return id ? IDENTIFIER_POINTER (id) : M_("<unknown>");
}
static const char *
assop_to_string (enum tree_code p)
{
tree id = assignment_operator_name_info[(int) p].identifier;
- return id ? IDENTIFIER_POINTER (id) : _("{unknown}");
+ return id ? IDENTIFIER_POINTER (id) : M_("{unknown}");
}
static const char *
return "";
if (TYPE_P (TREE_VALUE (p)))
- return type_as_string (p, flags);
+ return type_as_string_translate (p, flags);
reinit_cxx_pp ();
for (; p; p = TREE_CHAIN (p))
fndecl = current_function_decl;
pp_printf (context->printer, function_category (fndecl),
- cxx_printable_name (fndecl, 2));
+ cxx_printable_name_translate (fndecl, 2));
while (abstract_origin)
{
while (block && TREE_CODE (block) == BLOCK)
block = BLOCK_SUPERCONTEXT (block);
- if (TREE_CODE (block) == FUNCTION_DECL)
+ if (block && TREE_CODE (block) == FUNCTION_DECL)
fndecl = block;
abstract_origin = NULL;
}
if (flag_show_column && s.column != 0)
pp_printf (context->printer,
_(" inlined from %qs at %s:%d:%d"),
- cxx_printable_name (fndecl, 2),
+ cxx_printable_name_translate (fndecl, 2),
s.file, s.line, s.column);
else
pp_printf (context->printer,
_(" inlined from %qs at %s:%d"),
- cxx_printable_name (fndecl, 2),
+ cxx_printable_name_translate (fndecl, 2),
s.file, s.line);
}
else
pp_printf (context->printer, _(" inlined from %qs"),
- cxx_printable_name (fndecl, 2));
+ cxx_printable_name_translate (fndecl, 2));
}
}
pp_base_character (context->printer, ':');
static const char *
function_category (tree fn)
{
- if (DECL_FUNCTION_MEMBER_P (fn))
+ /* We can get called from the middle-end for diagnostics of function
+ clones. Make sure we have language specific information before
+ dereferencing it. */
+ if (DECL_LANG_SPECIFIC (STRIP_TEMPLATE (fn))
+ && DECL_FUNCTION_MEMBER_P (fn))
{
if (DECL_STATIC_FUNCTION_P (fn))
return _("In static member function %qs");
return _("In constructor %qs");
else if (DECL_DESTRUCTOR_P (fn))
return _("In destructor %qs");
+ else if (LAMBDA_FUNCTION_P (fn))
+ return _("In lambda function");
else
return _("In member function %qs");
}
pp_verbatim (context->printer,
_("%s: In instantiation of %qs:\n"),
LOCATION_FILE (location),
- decl_as_string (p->decl,
- TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
+ decl_as_string_translate (p->decl,
+ TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
location = p->locus;
p = p->next;
print_instantiation_partial_context (context, p, location);
}
-/* Same as above but less verbose. */
+/* Helper function of print_instantiation_partial_context() that
+ prints a single line of instantiation context. */
+
static void
-print_instantiation_partial_context (diagnostic_context *context,
- struct tinst_level *t, location_t loc)
+print_instantiation_partial_context_line (diagnostic_context *context,
+ const struct tinst_level *t,
+ location_t loc, bool recursive_p)
{
expanded_location xloc;
- for (; ; t = t->next)
+ xloc = expand_location (loc);
+
+ if (t != NULL)
{
- xloc = expand_location (loc);
- if (t == NULL)
- break;
- pp_verbatim (context->printer, _("%s:%d: instantiated from %qs\n"),
- xloc.file, xloc.line,
- decl_as_string (t->decl,
- TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
+ const char *str;
+ str = decl_as_string_translate (t->decl,
+ TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE);
+ if (flag_show_column)
+ pp_verbatim (context->printer,
+ recursive_p
+ ? _("%s:%d:%d: recursively instantiated from %qs\n")
+ : _("%s:%d:%d: instantiated from %qs\n"),
+ xloc.file, xloc.line, xloc.column, str);
+ else
+ pp_verbatim (context->printer,
+ recursive_p
+ ? _("%s:%d: recursively instantiated from %qs\n")
+ : _("%s:%d: recursively instantiated from %qs\n"),
+ xloc.file, xloc.line, str);
+ }
+ else
+ {
+ if (flag_show_column)
+ pp_verbatim (context->printer,
+ recursive_p
+ ? _("%s:%d:%d: recursively instantiated from here")
+ : _("%s:%d:%d: instantiated from here"),
+ xloc.file, xloc.line, xloc.column);
+ else
+ pp_verbatim (context->printer,
+ recursive_p
+ ? _("%s:%d: recursively instantiated from here")
+ : _("%s:%d: instantiated from here"),
+ xloc.file, xloc.line);
+ }
+}
+
+/* Same as print_instantiation_full_context but less verbose. */
+
+static void
+print_instantiation_partial_context (diagnostic_context *context,
+ struct tinst_level *t0, location_t loc)
+{
+ struct tinst_level *t;
+ int n_total = 0;
+ int n;
+ location_t prev_loc = loc;
+
+ for (t = t0; t != NULL; t = t->next)
+ if (prev_loc != t->locus)
+ {
+ prev_loc = t->locus;
+ n_total++;
+ }
+
+ t = t0;
+
+ if (n_total >= 12)
+ {
+ int skip = n_total - 10;
+ for (n = 0; n < 5; n++)
+ {
+ gcc_assert (t != NULL);
+ if (loc != t->locus)
+ print_instantiation_partial_context_line (context, t, loc,
+ /*recursive_p=*/false);
+ loc = t->locus;
+ t = t->next;
+ }
+ if (t != NULL && skip > 1)
+ {
+ expanded_location xloc;
+ xloc = expand_location (loc);
+ if (flag_show_column)
+ pp_verbatim (context->printer,
+ _("%s:%d:%d: [ skipping %d instantiation contexts ]\n"),
+ xloc.file, xloc.line, xloc.column, skip);
+ else
+ pp_verbatim (context->printer,
+ _("%s:%d: [ skipping %d instantiation contexts ]\n"),
+ xloc.file, xloc.line, skip);
+
+ do {
+ loc = t->locus;
+ t = t->next;
+ } while (t != NULL && --skip > 0);
+ }
+ }
+
+ while (t != NULL)
+ {
+ while (t->next != NULL && t->locus == t->next->locus)
+ {
+ loc = t->locus;
+ t = t->next;
+ }
+ print_instantiation_partial_context_line (context, t, loc,
+ t->locus == loc);
loc = t->locus;
+ t = t->next;
}
- pp_verbatim (context->printer, _("%s:%d: instantiated from here"),
- xloc.file, xloc.line);
+ print_instantiation_partial_context_line (context, NULL, loc,
+ /*recursive_p=*/false);
pp_base_newline (context->printer);
}
const char *result;
tree t = NULL;
#define next_tree (t = va_arg (*text->args_ptr, tree))
-#define next_tcode va_arg (*text->args_ptr, enum tree_code)
-#define next_lang va_arg (*text->args_ptr, enum languages)
+#define next_tcode ((enum tree_code) va_arg (*text->args_ptr, int))
+#define next_lang ((enum languages) va_arg (*text->args_ptr, int))
#define next_int va_arg (*text->args_ptr, int)
if (precision != 0 || wide)
\f
/* Warn about the use of C++0x features when appropriate. */
void
-maybe_warn_cpp0x (const char* str)
+maybe_warn_cpp0x (cpp0x_warn_str str)
{
if ((cxx_dialect == cxx98) && !in_system_header)
/* We really want to suppress this warning in system headers,
because libstdc++ uses variadic templates even when we aren't
in C++0x mode. */
- pedwarn (input_location, 0, "%s only available with -std=c++0x or -std=gnu++0x", str);
+ switch (str)
+ {
+ case CPP0X_INITIALIZER_LISTS:
+ pedwarn (input_location, 0,
+ "extended initializer lists "
+ "only available with -std=c++0x or -std=gnu++0x");
+ break;
+ case CPP0X_EXPLICIT_CONVERSION:
+ pedwarn (input_location, 0,
+ "explicit conversion operators "
+ "only available with -std=c++0x or -std=gnu++0x");
+ break;
+ case CPP0X_VARIADIC_TEMPLATES:
+ pedwarn (input_location, 0,
+ "variadic templates "
+ "only available with -std=c++0x or -std=gnu++0x");
+ break;
+ case CPP0X_LAMBDA_EXPR:
+ pedwarn (input_location, 0,
+ "lambda expressions "
+ "only available with -std=c++0x or -std=gnu++0x");
+ break;
+ case CPP0X_AUTO:
+ pedwarn (input_location, 0,
+ "C++0x auto only available with -std=c++0x or -std=gnu++0x");
+ break;
+ case CPP0X_SCOPED_ENUMS:
+ pedwarn (input_location, 0,
+ "scoped enums only available with -std=c++0x or -std=gnu++0x");
+ break;
+ case CPP0X_DEFAULTED_DELETED:
+ pedwarn (input_location, 0,
+ "defaulted and deleted functions "
+ "only available with -std=c++0x or -std=gnu++0x");
+ break;
+ default:
+ gcc_unreachable();
+ }
}
/* Warn about the use of variadic templates when appropriate. */
void
maybe_warn_variadic_templates (void)
{
- maybe_warn_cpp0x ("variadic templates");
+ maybe_warn_cpp0x (CPP0X_VARIADIC_TEMPLATES);
}