OSDN Git Service

PR c++/49107
[pf3gnuchains/gcc-fork.git] / gcc / cp / error.c
index cff822a..96796c2 100644 (file)
@@ -1,7 +1,8 @@
 /* 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, 2010 Free Software Foundation, Inc.
+   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
@@ -24,7 +25,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 +33,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 +87,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 +99,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)
@@ -304,15 +305,22 @@ 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)
     {
+      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);
@@ -483,6 +491,14 @@ dump_type (tree t, int flags)
       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, "...");
@@ -500,6 +516,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.  */
@@ -657,6 +677,8 @@ dump_type_prefix (tree t, int flags)
          {
            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, '*');
@@ -725,9 +747,11 @@ dump_type_prefix (tree t, int flags)
     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;
@@ -777,8 +801,7 @@ dump_type_suffix (tree t, int flags)
        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);
@@ -827,9 +850,11 @@ dump_type_suffix (tree t, int flags)
     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:
@@ -861,6 +886,9 @@ 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);
     }
@@ -890,6 +918,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:
@@ -1006,7 +1046,7 @@ dump_decl (tree t, int flags)
              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);
@@ -1288,12 +1328,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)
@@ -1322,8 +1366,7 @@ dump_function_decl (tree t, int flags)
       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)
@@ -1395,7 +1438,10 @@ dump_exception_spec (tree t, int flags)
       pp_cxx_ws_string (cxx_pp, "noexcept");
       pp_cxx_whitespace (cxx_pp);
       pp_cxx_left_paren (cxx_pp);
-      dump_expr (TREE_PURPOSE (t), flags);
+      if (DEFERRED_NOEXCEPT_SPEC_P (t))
+       pp_cxx_ws_string (cxx_pp, "<uninstantiated>");
+      else
+       dump_expr (TREE_PURPOSE (t), flags);
       pp_cxx_right_paren (cxx_pp);
     }
   else if (t)
@@ -1674,6 +1720,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;
@@ -1846,7 +1893,10 @@ dump_expr (tree t, int flags)
                    && 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
@@ -1903,6 +1953,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:
@@ -1949,8 +2027,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.  */
@@ -2128,6 +2219,14 @@ 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);
@@ -2412,17 +2511,23 @@ 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))
     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
@@ -2563,6 +2668,32 @@ args_to_string (tree p, int verbose)
   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)
 {
@@ -2589,6 +2720,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));
 }
@@ -2785,38 +2917,34 @@ print_instantiation_partial_context_line (diagnostic_context *context,
   expanded_location xloc;
   xloc = expand_location (loc);
 
-  if (t != NULL) 
+  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)
     {
-      const char *str;
-      str = decl_as_string_translate (t->decl,
-                                     TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE);
-      if (context->show_column)
+      if (TREE_CODE (t->decl) == TREE_LIST)
        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);
+                    ? _("recursively required by substitution of %qS\n")
+                    : _("required by substitution of %qS\n"),
+                    t->decl);
       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);
+                    ? _("recursively required from %q#D\n")
+                    : _("required from %q#D\n"),
+                    t->decl);
     }
   else
     {
-      if (context->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);
+      pp_verbatim (context->printer,
+                  recursive_p
+                  ? _("recursively required from here")
+                  : _("required from here"));
     }
 }
 
@@ -2909,6 +3037,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.
@@ -2965,6 +3118,7 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
     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;
 
@@ -3028,6 +3182,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();
@@ -3059,3 +3218,39 @@ pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...)
   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);
+    }
+}