/* 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 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"
#define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',')
static void dump_template_parms (tree, int, 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 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;
parms = TREE_CHAIN (parms);
}
- for (i = 0; VEC_iterate (tree, typenames, i, t); ++i)
+ FOR_EACH_VEC_ELT (tree, typenames, i, t)
{
if (need_comma)
pp_separate_with_comma (cxx_pp);
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:
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 TYPE_DECL:
case TREE_VEC:
case UNION_TYPE:
- case UNKNOWN_TYPE:
+ case LANG_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
{
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));
}
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)
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);
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)
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);
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
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),
const char *str;
str = decl_as_string_translate (t->decl,
TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE);
- if (flag_show_column)
+ if (context->show_column)
pp_verbatim (context->printer,
recursive_p
? _("%s:%d:%d: recursively instantiated from %qs\n")
}
else
{
- if (flag_show_column)
+ if (context->show_column)
pp_verbatim (context->printer,
recursive_p
? _("%s:%d:%d: recursively instantiated from here")
{
expanded_location xloc;
xloc = expand_location (loc);
- if (flag_show_column)
+ if (context->show_column)
pp_verbatim (context->printer,
_("%s:%d:%d: [ skipping %d instantiation contexts ]\n"),
xloc.file, xloc.line, xloc.column, skip);
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 '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();