OSDN Git Service

2010-12-09 Martin Jambor <mjambor@suse.cz>
[pf3gnuchains/gcc-fork.git] / gcc / cp / error.c
index 592f360..4fb47dc 100644 (file)
@@ -24,7 +24,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "cp-tree.h"
-#include "toplev.h"
 #include "flags.h"
 #include "diagnostic.h"
 #include "tree-diagnostic.h"
@@ -33,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #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, ',')
 
@@ -86,6 +86,7 @@ static void dump_scope (tree, int);
 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 *,
@@ -97,7 +98,6 @@ 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 (void)
@@ -115,7 +115,7 @@ 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;
@@ -304,7 +304,7 @@ dump_template_bindings (tree parms, tree args, VEC(tree,gc)* typenames)
       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);
@@ -329,6 +329,25 @@ dump_type (tree t, int flags)
   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;
 
@@ -481,6 +500,10 @@ dump_type (tree t, int flags)
       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.  */
@@ -709,6 +732,7 @@ dump_type_prefix (tree t, int flags)
     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;
@@ -811,6 +835,7 @@ dump_type_suffix (tree t, int flags)
     case DECLTYPE_TYPE:
     case TYPE_PACK_EXPANSION:
     case FIXED_POINT_TYPE:
+    case NULLPTR_TYPE:
       break;
 
     default:
@@ -842,10 +867,14 @@ dump_simple_decl (tree t, tree type, int flags)
 {
   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);
@@ -870,6 +899,18 @@ dump_decl (tree t, int 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:
@@ -926,7 +967,7 @@ dump_decl (tree t, int flags)
            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));
        }
@@ -1227,7 +1268,7 @@ dump_function_decl (tree t, int flags)
   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)));
@@ -1268,12 +1309,16 @@ dump_function_decl (tree t, int flags)
   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)
@@ -1336,6 +1381,7 @@ static void
 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;
@@ -1369,7 +1415,15 @@ dump_parameters (tree parmtypes, int flags)
 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);
@@ -1645,6 +1699,7 @@ dump_expr (tree t, int flags)
     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;
@@ -1730,7 +1785,9 @@ dump_expr (tree t, int flags)
        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)
@@ -1872,6 +1929,34 @@ dump_expr (tree t, int flags)
        }
       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:
@@ -1918,8 +2003,21 @@ dump_expr (tree t, int flags)
     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.  */
@@ -2097,6 +2195,22 @@ dump_expr (tree t, int flags)
       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);
@@ -2373,7 +2487,7 @@ lang_decl_name (tree decl, int v, bool translate)
 
 /* 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))
@@ -2383,7 +2497,9 @@ location_of (tree t)
   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
@@ -2550,6 +2666,7 @@ cp_diagnostic_starter (diagnostic_context *context,
   diagnostic_report_current_module (context);
   cp_print_error_function (context, diagnostic);
   maybe_print_instantiation_context (context);
+  maybe_print_constexpr_context (context);
   pp_base_set_prefix (context->printer, diagnostic_build_prefix (context,
                                                                 diagnostic));
 }
@@ -2870,6 +2987,31 @@ print_instantiation_context (void)
   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.
@@ -2989,6 +3131,11 @@ maybe_warn_cpp0x (cpp0x_warn_str str)
        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();