/* Call-backs for C++ error reporting.
This code is non-reentrant.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
+ 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
-#include "real.h"
-#include "toplev.h"
#include "flags.h"
#include "diagnostic.h"
+#include "tree-diagnostic.h"
#include "langhooks-def.h"
#include "intl.h"
#include "cxx-pretty-print.h"
+#include "tree-pretty-print.h"
#include "pointer-set.h"
+#include "c-family/c-objc.h"
#define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',')
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, int);
-
+static int get_non_default_template_args_count (tree, int);
static const char *function_category (tree);
+static void maybe_print_constexpr_context (diagnostic_context *);
static void maybe_print_instantiation_context (diagnostic_context *);
static void print_instantiation_full_context (diagnostic_context *);
static void print_instantiation_partial_context (diagnostic_context *,
static bool cp_printer (pretty_printer *, text_info *, const char *,
int, bool, bool, bool);
-static location_t location_of (tree);
void
init_error (void)
static void
dump_scope (tree scope, int flags)
{
- int f = ~TFF_RETURN_TYPE & (flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF));
+ int f = flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF);
if (scope == NULL_TREE)
return;
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, int flags)
+get_non_default_template_args_count (tree args, int flags)
{
- int n = TREE_VEC_LENGTH (args);
- int last;
+ int n = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (args));
- if (params == NULL_TREE
- /* We use this flag when generating debug information. We don't
+ 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
+ (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;
- /* This speculative substitution must not cause any classes to be
- instantiated that otherwise wouldn't be. */
- def = tsubst_copy_and_build (def, args, tf_no_class_instantiations,
- 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, flags);
+ int n = get_non_default_template_args_count (args, flags);
int need_comma = 0;
int i;
parms = TREE_CHAIN (parms);
}
- for (i = 0; VEC_iterate (tree, typenames, i, t); ++i)
+ FOR_EACH_VEC_ELT (tree, typenames, i, t)
{
+ bool dependent = uses_template_parms (args);
if (need_comma)
pp_separate_with_comma (cxx_pp);
dump_type (t, TFF_PLAIN_IDENTIFIER);
pp_cxx_whitespace (cxx_pp);
pp_equal (cxx_pp);
pp_cxx_whitespace (cxx_pp);
+ push_deferring_access_checks (dk_no_check);
+ if (dependent)
+ ++processing_template_decl;
t = tsubst (t, args, tf_none, NULL_TREE);
+ if (dependent)
+ --processing_template_decl;
+ pop_deferring_access_checks ();
/* Strip typedefs. We can't just use TFF_CHASE_TYPEDEF because
pp_simple_type_specifier doesn't know about it. */
t = strip_typedefs (t);
if (t == NULL_TREE)
return;
+ /* Don't print e.g. "struct mytypedef". */
+ if (TYPE_P (t) && typedef_variant_p (t))
+ {
+ tree decl = TYPE_NAME (t);
+ if ((flags & TFF_CHASE_TYPEDEF)
+ || DECL_SELF_REFERENCE_P (decl)
+ || (!flag_pretty_templates
+ && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)))
+ t = strip_typedefs (t);
+ else if (same_type_p (t, TREE_TYPE (decl)))
+ t = decl;
+ else
+ {
+ pp_cxx_cv_qualifier_seq (cxx_pp, t);
+ pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
+ return;
+ }
+ }
+
if (TYPE_PTRMEMFUNC_P (t))
goto offset_type;
switch (TREE_CODE (t))
{
- case UNKNOWN_TYPE:
+ case LANG_TYPE:
if (t == init_list_type_node)
pp_string (cxx_pp, M_("<brace-enclosed initializer list>"));
- else
+ else if (t == unknown_type_node)
pp_string (cxx_pp, M_("<unresolved overloaded function type>"));
+ else
+ {
+ 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;
pp_cxx_right_paren (cxx_pp);
break;
+ case UNDERLYING_TYPE:
+ pp_cxx_ws_string (cxx_pp, "__underlying_type");
+ pp_cxx_whitespace (cxx_pp);
+ pp_cxx_left_paren (cxx_pp);
+ dump_expr (UNDERLYING_TYPE_TYPE (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_ws_string (cxx_pp, "...");
pp_cxx_right_paren (cxx_pp);
break;
+ case NULLPTR_TYPE:
+ pp_string (cxx_pp, "std::nullptr_t");
+ break;
+
default:
pp_unsupported_tree (cxx_pp, t);
/* Fall through to error. */
{
pp_cxx_whitespace (cxx_pp);
pp_cxx_left_paren (cxx_pp);
+ pp_c_attributes_display (pp_c_base (cxx_pp),
+ TYPE_ATTRIBUTES (sub));
}
if (TREE_CODE (t) == POINTER_TYPE)
pp_character(cxx_pp, '*');
case TYPE_DECL:
case TREE_VEC:
case UNION_TYPE:
- case UNKNOWN_TYPE:
+ case LANG_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
case VECTOR_TYPE:
case TYPEOF_TYPE:
+ case UNDERLYING_TYPE:
case DECLTYPE_TYPE:
case TYPE_PACK_EXPANSION:
case FIXED_POINT_TYPE:
+ case NULLPTR_TYPE:
dump_type (t, flags);
pp_base (cxx_pp)->padding = pp_before;
break;
dump_parameters (arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
if (TREE_CODE (t) == METHOD_TYPE)
- pp_cxx_cv_qualifier_seq
- (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
+ pp_cxx_cv_qualifier_seq (cxx_pp, class_of_this_parm (t));
else
pp_cxx_cv_qualifier_seq (cxx_pp, t);
dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags);
case TYPE_DECL:
case TREE_VEC:
case UNION_TYPE:
- case UNKNOWN_TYPE:
+ case LANG_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
case VECTOR_TYPE:
case TYPEOF_TYPE:
+ case UNDERLYING_TYPE:
case DECLTYPE_TYPE:
case TYPE_PACK_EXPANSION:
case FIXED_POINT_TYPE:
+ case NULLPTR_TYPE:
break;
default:
{
if (flags & TFF_DECL_SPECIFIERS)
{
+ if (TREE_CODE (t) == VAR_DECL
+ && DECL_DECLARED_CONSTEXPR_P (t))
+ pp_cxx_ws_string (cxx_pp, "constexpr");
dump_type_prefix (type, flags & ~TFF_UNQUALIFIED_NAME);
pp_maybe_space (cxx_pp);
}
if (! (flags & TFF_UNQUALIFIED_NAME)
+ && TREE_CODE (t) != PARM_DECL
&& (!DECL_INITIAL (t)
|| TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX))
dump_scope (CP_DECL_CONTEXT (t), flags);
if (t == NULL_TREE)
return;
+ /* If doing Objective-C++, give Objective-C a chance to demangle
+ Objective-C method names. */
+ if (c_dialect_objc ())
+ {
+ const char *demangled = objc_maybe_printable_name (t, flags);
+ if (demangled)
+ {
+ pp_string (cxx_pp, demangled);
+ return;
+ }
+ }
+
switch (TREE_CODE (t))
{
case TYPE_DECL:
dump_scope (CP_DECL_CONTEXT (t), flags);
flags &= ~TFF_UNQUALIFIED_NAME;
if (DECL_NAME (t) == NULL_TREE)
- pp_string (cxx_pp, M_("<unnamed>"));
+ pp_cxx_ws_string (cxx_pp, M_("{anonymous}"));
else
pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t));
}
dump_type (DECL_CONTEXT (t), flags);
pp_cxx_colon_colon (cxx_pp);
}
- else if (DECL_CONTEXT (t))
+ else if (!DECL_FILE_SCOPE_P (t))
{
dump_decl (DECL_CONTEXT (t), flags);
pp_cxx_colon_colon (cxx_pp);
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;
tree exceptions;
VEC(tree,gc) *typenames = NULL;
- if (LAMBDA_FUNCTION_P (t))
+ if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t))
{
/* A lambda's signature is essentially its "type", so defer. */
gcc_assert (LAMBDA_TYPE_P (DECL_CONTEXT (t)));
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))
- pp_cxx_ws_string (cxx_pp, "static");
- else if (DECL_VIRTUAL_P (t))
- pp_cxx_ws_string (cxx_pp, "virtual");
+ if (flags & TFF_DECL_SPECIFIERS)
+ {
+ if (DECL_STATIC_FUNCTION_P (t))
+ pp_cxx_ws_string (cxx_pp, "static");
+ else if (DECL_VIRTUAL_P (t))
+ pp_cxx_ws_string (cxx_pp, "virtual");
+
+ if (DECL_DECLARED_CONSTEXPR_P (STRIP_TEMPLATE (t)))
+ pp_cxx_ws_string (cxx_pp, "constexpr");
+ }
/* Print the return type? */
if (show_return)
if (TREE_CODE (fntype) == METHOD_TYPE)
{
pp_base (cxx_pp)->padding = pp_before;
- pp_cxx_cv_qualifier_seq
- (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))));
+ pp_cxx_cv_qualifier_seq (cxx_pp, class_of_this_parm (fntype));
}
if (flags & TFF_EXCEPTION_SPECIFICATION)
dump_parameters (tree parmtypes, int flags)
{
int first = 1;
+ flags &= ~TFF_SCOPE;
pp_cxx_left_paren (cxx_pp);
for (first = 1; parmtypes != void_list_node;
static void
dump_exception_spec (tree t, int flags)
{
- if (t)
+ if (t && TREE_PURPOSE (t))
+ {
+ pp_cxx_ws_string (cxx_pp, "noexcept");
+ pp_cxx_whitespace (cxx_pp);
+ pp_cxx_left_paren (cxx_pp);
+ dump_expr (TREE_PURPOSE (t), flags);
+ pp_cxx_right_paren (cxx_pp);
+ }
+ else if (t)
{
pp_cxx_ws_string (cxx_pp, "throw");
pp_cxx_whitespace (cxx_pp);
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);
+ len = get_non_default_template_args_count (args, flags);
args = INNERMOST_TEMPLATE_ARGS (args);
- len = count_non_default_template_args (args, params, flags);
-
for (ix = 0; ix != len; ix++)
{
tree arg = TREE_VEC_ELT (args, ix);
case NAMESPACE_DECL:
case LABEL_DECL:
case OVERLOAD:
+ case TYPE_DECL:
case IDENTIFIER_NODE:
dump_decl (t, (flags & ~TFF_DECL_SPECIFIERS) | TFF_NO_FUNCTION_ARGUMENTS);
break;
if (TREE_CODE (fn) == OBJ_TYPE_REF)
fn = resolve_virtual_fun_from_obj_type_ref (fn);
- if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)
+ if (TREE_TYPE (fn) != NULL_TREE
+ && NEXT_CODE (fn) == METHOD_TYPE
+ && call_expr_nargs (t))
{
tree ob = CALL_EXPR_ARG (t, 0);
if (TREE_CODE (ob) == ADDR_EXPR)
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")))
{
dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
- pp_cxx_arrow (cxx_pp);
+ if (TREE_CODE (TREE_TYPE (ob)) == REFERENCE_TYPE)
+ pp_cxx_dot (cxx_pp);
+ else
+ pp_cxx_arrow (cxx_pp);
}
}
else
}
break;
+ case MEM_REF:
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
+ && integer_zerop (TREE_OPERAND (t, 1)))
+ dump_expr (TREE_OPERAND (TREE_OPERAND (t, 0), 0), flags);
+ else
+ {
+ pp_cxx_star (cxx_pp);
+ if (!integer_zerop (TREE_OPERAND (t, 1)))
+ {
+ pp_cxx_left_paren (cxx_pp);
+ if (!integer_onep (TYPE_SIZE_UNIT
+ (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))))))
+ {
+ pp_cxx_left_paren (cxx_pp);
+ dump_type (ptr_type_node, flags);
+ pp_cxx_right_paren (cxx_pp);
+ }
+ }
+ dump_expr (TREE_OPERAND (t, 0), flags);
+ if (!integer_zerop (TREE_OPERAND (t, 1)))
+ {
+ pp_cxx_ws_string (cxx_pp, "+");
+ dump_expr (fold_convert (ssizetype, TREE_OPERAND (t, 1)), flags);
+ pp_cxx_right_paren (cxx_pp);
+ }
+ }
+ break;
+
case NEGATE_EXPR:
case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR:
case VIEW_CONVERT_EXPR:
{
tree op = TREE_OPERAND (t, 0);
-
- if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t)))
+ tree ttype = TREE_TYPE (t);
+ tree optype = TREE_TYPE (op);
+
+ if (TREE_CODE (ttype) != TREE_CODE (optype)
+ && POINTER_TYPE_P (ttype)
+ && POINTER_TYPE_P (optype)
+ && same_type_p (TREE_TYPE (optype),
+ TREE_TYPE (ttype)))
+ {
+ if (TREE_CODE (ttype) == REFERENCE_TYPE)
+ dump_unary_op ("*", t, flags);
+ else
+ dump_unary_op ("&", t, flags);
+ }
+ else if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t)))
{
/* It is a cast, but we cannot tell whether it is a
reinterpret or static cast. Use the C style notation. */
pp_cxx_right_paren (cxx_pp);
break;
+ case AT_ENCODE_EXPR:
+ pp_cxx_ws_string (cxx_pp, "@encode");
+ pp_cxx_whitespace (cxx_pp);
+ pp_cxx_left_paren (cxx_pp);
+ dump_type (TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (cxx_pp);
+ break;
+
+ case NOEXCEPT_EXPR:
+ pp_cxx_ws_string (cxx_pp, "noexcept");
+ pp_cxx_whitespace (cxx_pp);
+ pp_cxx_left_paren (cxx_pp);
+ dump_expr (TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (cxx_pp);
+ break;
+
case REALPART_EXPR:
case IMAGPART_EXPR:
pp_cxx_ws_string (cxx_pp, operator_name_info[TREE_CODE (t)].name);
/* Return the location of a tree passed to %+ formats. */
-static location_t
+location_t
location_of (tree t)
{
if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
t = DECL_CONTEXT (t);
else if (TYPE_P (t))
- t = TYPE_MAIN_DECL (t);
+ {
+ t = TYPE_MAIN_DECL (t);
+ if (t == NULL_TREE)
+ return input_location;
+ }
else if (TREE_CODE (t) == OVERLOAD)
t = OVL_FUNCTION (t);
- return DECL_SOURCE_LOCATION (t);
+ if (DECL_P (t))
+ return DECL_SOURCE_LOCATION (t);
+ return EXPR_LOC_OR_HERE (t);
}
/* Now the interfaces from error et al to dump_type et al. Each takes an
return pp_formatted_text (cxx_pp);
}
+/* Pretty-print a deduction substitution (from deduction_tsubst_fntype). P
+ is a TREE_LIST with purpose the TEMPLATE_DECL, value the template
+ arguments. */
+
+static const char *
+subst_to_string (tree p)
+{
+ tree decl = TREE_PURPOSE (p);
+ tree targs = TREE_VALUE (p);
+ tree tparms = DECL_TEMPLATE_PARMS (decl);
+ int flags = TFF_DECL_SPECIFIERS|TFF_TEMPLATE_HEADER;
+
+ if (p == NULL_TREE)
+ return "";
+
+ reinit_cxx_pp ();
+ dump_template_decl (TREE_PURPOSE (p), flags);
+ pp_cxx_whitespace (cxx_pp);
+ pp_cxx_left_bracket (cxx_pp);
+ pp_cxx_ws_string (cxx_pp, M_("with"));
+ pp_cxx_whitespace (cxx_pp);
+ dump_template_bindings (tparms, targs, NULL);
+ pp_cxx_right_bracket (cxx_pp);
+ return pp_formatted_text (cxx_pp);
+}
+
static const char *
cv_to_string (tree p, int v)
{
diagnostic_report_current_module (context);
cp_print_error_function (context, diagnostic);
maybe_print_instantiation_context (context);
- pp_base_set_prefix (context->printer, diagnostic_build_prefix (diagnostic));
+ maybe_print_constexpr_context (context);
+ pp_base_set_prefix (context->printer, diagnostic_build_prefix (context,
+ diagnostic));
}
static void
{
const char *old_prefix = context->printer->prefix;
const char *file = LOCATION_FILE (diagnostic->location);
- tree abstract_origin = diagnostic->abstract_origin;
+ tree abstract_origin = diagnostic_abstract_origin (diagnostic);
char *new_prefix = (file && abstract_origin == NULL)
? file_name_as_prefix (file) : NULL;
pp_base_newline (context->printer);
if (s.file != NULL)
{
- if (flag_show_column && s.column != 0)
+ if (context->show_column && s.column != 0)
pp_printf (context->printer,
_(" inlined from %qs at %s:%d:%d"),
cxx_printable_name_translate (fndecl, 2),
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;
- const char *str;
- for (; ; t = t->next)
+ xloc = expand_location (loc);
+
+ if (context->show_column)
+ pp_verbatim (context->printer, _("%s:%d:%d: "),
+ xloc.file, xloc.line, xloc.column);
+ else
+ pp_verbatim (context->printer, _("%s:%d: "),
+ xloc.file, xloc.line);
+
+ if (t != NULL)
{
- xloc = expand_location (loc);
- if (t == NULL)
- break;
- str = decl_as_string_translate (t->decl,
- TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE);
- if (flag_show_column)
+ if (TREE_CODE (t->decl) == TREE_LIST)
pp_verbatim (context->printer,
- _("%s:%d:%d: instantiated from %qs\n"),
- xloc.file, xloc.line, xloc.column, str);
+ recursive_p
+ ? _("recursively required by substitution of %qS\n")
+ : _("required by substitution of %qS\n"),
+ t->decl);
else
pp_verbatim (context->printer,
- _("%s:%d: instantiated from %qs\n"),
- xloc.file, xloc.line, str);
- loc = t->locus;
+ recursive_p
+ ? _("recursively required from %q#D\n")
+ : _("required from %q#D\n"),
+ t->decl);
}
- if (flag_show_column)
- pp_verbatim (context->printer, _("%s:%d:%d: instantiated from here"),
- xloc.file, xloc.line, xloc.column);
else
- pp_verbatim (context->printer, _("%s:%d: instantiated from here"),
- xloc.file, xloc.line);
+ {
+ pp_verbatim (context->printer,
+ recursive_p
+ ? _("recursively required from here")
+ : _("required from here"));
+ }
+}
+
+/* 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 (context->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;
+ }
+ print_instantiation_partial_context_line (context, NULL, loc,
+ /*recursive_p=*/false);
pp_base_newline (context->printer);
}
diagnostic_flush_buffer (global_dc);
}
\f
+/* Report what constexpr call(s) we're trying to expand, if any. */
+
+void
+maybe_print_constexpr_context (diagnostic_context *context)
+{
+ VEC(tree,heap) *call_stack = cx_error_context ();
+ unsigned ix;
+ tree t;
+
+ FOR_EACH_VEC_ELT (tree, call_stack, ix, t)
+ {
+ expanded_location xloc = expand_location (EXPR_LOCATION (t));
+ const char *s = expr_as_string (t, 0);
+ if (context->show_column)
+ pp_verbatim (context->printer,
+ _("%s:%d:%d: in constexpr expansion of %qs"),
+ xloc.file, xloc.line, xloc.column, s);
+ else
+ pp_verbatim (context->printer,
+ _("%s:%d: in constexpr expansion of %qs"),
+ xloc.file, xloc.line, s);
+ pp_base_newline (context->printer);
+ }
+}
+\f
/* Called from output_format -- during diagnostic message processing --
to handle C++ specific format specifier with the following meanings:
%A function argument-list.
case 'O': result = op_to_string (next_tcode); break;
case 'P': result = parm_to_string (next_int); break;
case 'Q': result = assop_to_string (next_tcode); break;
+ case 'S': result = subst_to_string (next_tree); break;
case 'T': result = type_to_string (next_tree, verbose); break;
case 'V': result = cv_to_string (next_tree, verbose); break;
+ case 'K':
+ percent_K_format (text);
+ return true;
+
default:
return false;
}
pedwarn (input_location, 0,
"defaulted and deleted functions "
"only available with -std=c++0x or -std=gnu++0x");
+ break;
+ case CPP0X_INLINE_NAMESPACES:
+ pedwarn (input_location, OPT_pedantic,
+ "inline namespaces "
+ "only available with -std=c++0x or -std=gnu++0x");
break;
default:
gcc_unreachable();
va_end (ap);
return report_diagnostic (&diagnostic);
}
+
+/* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is what
+ we found when we tried to do the lookup. LOCATION is the location of
+ the NAME identifier. */
+
+void
+qualified_name_lookup_error (tree scope, tree name,
+ tree decl, location_t location)
+{
+ if (scope == error_mark_node)
+ ; /* We already complained. */
+ else if (TYPE_P (scope))
+ {
+ if (!COMPLETE_TYPE_P (scope))
+ error_at (location, "incomplete type %qT used in nested name specifier",
+ scope);
+ else if (TREE_CODE (decl) == TREE_LIST)
+ {
+ error_at (location, "reference to %<%T::%D%> is ambiguous",
+ scope, name);
+ print_candidates (decl);
+ }
+ else
+ error_at (location, "%qD is not a member of %qT", name, scope);
+ }
+ else if (scope != global_namespace)
+ {
+ error_at (location, "%qD is not a member of %qD", name, scope);
+ suggest_alternatives_for (location, name);
+ }
+ else
+ {
+ error_at (location, "%<::%D%> has not been declared", name);
+ suggest_alternatives_for (location, name);
+ }
+}