OSDN Git Service

Fix up whitespacing
[pf3gnuchains/gcc-fork.git] / gcc / cp / error.c
index 3d202d6..91a73cc 100644 (file)
@@ -16,8 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -86,8 +86,8 @@ static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *);
 static void cp_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
 static void cp_print_error_function (diagnostic_context *, diagnostic_info *);
 
-static bool cp_printer (pretty_printer *, text_info *);
-static tree locate_error (const char *, va_list);
+static bool cp_printer (pretty_printer *, text_info *, const char *,
+                       int, bool, bool, bool);
 static location_t location_of (tree);
 
 void
@@ -259,7 +259,7 @@ dump_type (tree t, int flags)
   switch (TREE_CODE (t))
     {
     case UNKNOWN_TYPE:
-      pp_identifier (cxx_pp, "<unknown type>");
+      pp_identifier (cxx_pp, "<unresolved overloaded function type>");
       break;
 
     case TREE_LIST:
@@ -437,9 +437,7 @@ dump_aggr_type (tree t, int flags)
       typdef = !DECL_ARTIFICIAL (name);
       tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
                && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
-               && (CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
-                   || TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
-                   || DECL_TEMPLATE_SPECIALIZATION (CLASSTYPE_TI_TEMPLATE (t))
+               && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
                    || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
       dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE);
       if (tmplate)
@@ -744,7 +742,6 @@ dump_decl (tree t, int flags)
       /* Else fall through.  */
     case FIELD_DECL:
     case PARM_DECL:
-    case ALIAS_DECL:
       dump_simple_decl (t, TREE_TYPE (t), flags);
       break;
 
@@ -878,7 +875,7 @@ dump_decl (tree t, int flags)
 
     case USING_DECL:
       pp_cxx_identifier (cxx_pp, "using");
-      dump_type (DECL_INITIAL (t), flags);
+      dump_type (USING_DECL_SCOPE (t), flags);
       pp_cxx_colon_colon (cxx_pp);
       dump_decl (DECL_NAME (t), flags);
       break;
@@ -1183,9 +1180,7 @@ dump_function_name (tree t, int flags)
 
   if (DECL_TEMPLATE_INFO (t)
       && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
-      && (DECL_TEMPLATE_SPECIALIZATION (t)
-         || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
-         || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t))
+      && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
          || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
     dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags);
 }
@@ -1266,6 +1261,40 @@ dump_expr_list (tree l, int flags)
     }
 }
 
+/* Print out a vector of initializers (subr of dump_expr).  */
+
+static void
+dump_expr_init_vec (VEC(constructor_elt,gc) *v, int flags)
+{
+  unsigned HOST_WIDE_INT idx;
+  tree value;
+
+  FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
+    {
+      dump_expr (value, flags | TFF_EXPR_IN_PARENS);
+      if (idx != VEC_length (constructor_elt, v) - 1)
+       pp_separate_with_comma (cxx_pp);
+    }
+}
+
+
+/* We've gotten an indirect REFERENCE (an OBJ_TYPE_REF) to a virtual
+   function.  Resolve it to a close relative -- in the sense of static
+   type -- variant being overridden.  That is close to what was written in
+   the source code.  Subroutine of dump_expr.  */
+
+static tree
+resolve_virtual_fun_from_obj_type_ref (tree ref)
+{
+  tree obj_type = TREE_TYPE (OBJ_TYPE_REF_OBJECT (ref));
+  int index = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1);
+  tree fun = BINFO_VIRTUALS (TYPE_BINFO (TREE_TYPE (obj_type)));
+    while (index--)
+      fun = TREE_CHAIN (fun);
+
+  return BV_FN (fun);
+}
+
 /* Print out an expression E under control of FLAGS.  */
 
 static void
@@ -1283,22 +1312,16 @@ dump_expr (tree t, int flags)
     case FUNCTION_DECL:
     case TEMPLATE_DECL:
     case NAMESPACE_DECL:
+    case LABEL_DECL:
     case OVERLOAD:
     case IDENTIFIER_NODE:
       dump_decl (t, (flags & ~TFF_DECL_SPECIFIERS) | TFF_NO_FUNCTION_ARGUMENTS);
       break;
 
-    case STRING_CST:
-      if (PAREN_STRING_LITERAL_P (t))
-       pp_cxx_left_paren (cxx_pp);
-      pp_c_constant (pp_c_base (cxx_pp), t);
-      if (PAREN_STRING_LITERAL_P (t))
-       pp_cxx_right_paren (cxx_pp);
-      break;
-
     case INTEGER_CST:
     case REAL_CST:
-       pp_c_constant (pp_c_base (cxx_pp), t);
+    case STRING_CST:
+      pp_constant (cxx_pp, t);
       break;
 
     case THROW_EXPR:
@@ -1373,6 +1396,10 @@ dump_expr (tree t, int flags)
        if (TREE_CODE (fn) == ADDR_EXPR)
          fn = TREE_OPERAND (fn, 0);
 
+       /* Nobody is interested in seeing the guts of vcalls.  */
+       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)
          {
            tree ob = TREE_VALUE (args);
@@ -1525,6 +1552,8 @@ dump_expr (tree t, int flags)
          || (TREE_TYPE (t)
              && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE))
        dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+      else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL)
+       dump_unary_op ("&&", t, flags);
       else
        dump_unary_op ("&", t, flags);
       break;
@@ -1659,7 +1688,7 @@ dump_expr (tree t, int flags)
                }
            }
        }
-      if (TREE_TYPE (t) && !CONSTRUCTOR_ELTS (t))
+      if (TREE_TYPE (t) && EMPTY_CONSTRUCTOR_P (t))
        {
          dump_type (TREE_TYPE (t), 0);
          pp_cxx_left_paren (cxx_pp);
@@ -1668,7 +1697,7 @@ dump_expr (tree t, int flags)
       else
        {
          pp_cxx_left_brace (cxx_pp);
-         dump_expr_list (CONSTRUCTOR_ELTS (t), flags);
+         dump_expr_init_vec (CONSTRUCTOR_ELTS (t), flags);
          pp_cxx_right_brace (cxx_pp);
        }
 
@@ -1942,6 +1971,8 @@ lang_decl_name (tree decl, int v)
   return pp_formatted_text (cxx_pp);
 }
 
+/* Return the location of a tree passed to %+ formats.  */
+
 static location_t
 location_of (tree t)
 {
@@ -1991,7 +2022,8 @@ fndecl_to_string (tree fndecl, int verbose)
 {
   int flags;
 
-  flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS;
+  flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS
+    | TFF_TEMPLATE_HEADER;
   if (verbose)
     flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS;
   reinit_cxx_pp ();
@@ -2023,7 +2055,7 @@ language_to_string (enum languages c)
     default:
       gcc_unreachable ();
     }
-  return 0;
+  return NULL;
 }
 
 /* Return the proper printed version of a parameter to a C++ function.  */
@@ -2228,8 +2260,9 @@ print_instantiation_partial_context (diagnostic_context *context,
                                   TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
       loc = TINST_LOCATION (t);
     }
-  pp_verbatim (context->printer, "%s:%d:   instantiated from here\n",
+  pp_verbatim (context->printer, "%s:%d:   instantiated from here",
               xloc.file, xloc.line);
+  pp_base_newline (context->printer);
 }
 
 /* Called from cp_thing to print the template context for an error.  */
@@ -2266,24 +2299,23 @@ print_instantiation_context (void)
    %T   type.
    %V   cv-qualifier.  */
 static bool
-cp_printer (pretty_printer *pp, text_info *text)
+cp_printer (pretty_printer *pp, text_info *text, const char *spec,
+           int precision, bool wide, bool set_locus, bool verbose)
 {
-  int verbose = 0;
   const char *result;
-#define next_tree    va_arg (*text->args_ptr, tree)
+  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_int     va_arg (*text->args_ptr, int)
 
-  if (*text->format_spec == '+')
-    ++text->format_spec;
-  if (*text->format_spec == '#')
-    {
-      verbose = 1;
-      ++text->format_spec;
-    }
+  if (precision != 0 || wide)
+    return false;
+
+  if (text->locus == NULL)
+    set_locus = false;
 
-  switch (*text->format_spec)
+  switch (*spec)
     {
     case 'A': result = args_to_string (next_tree, verbose);    break;
     case 'C': result = code_to_string (next_tcode);            break;
@@ -2302,131 +2334,44 @@ cp_printer (pretty_printer *pp, text_info *text)
     }
 
   pp_base_string (pp, result);
+  if (set_locus && t != NULL)
+    *text->locus = location_of (t);
   return true;
 #undef next_tree
 #undef next_tcode
 #undef next_lang
 #undef next_int
 }
-
-/* These are temporary wrapper functions which handle the historic
-   behavior of cp_*_at.  */
-
-static tree
-locate_error (const char *gmsgid, va_list ap)
-{
-  tree here = 0, t;
-  int plus = 0;
-  const char *f;
-
-  for (f = gmsgid; *f; f++)
-    {
-      plus = 0;
-      if (*f == '%')
-       {
-         if (*++f == 'q')
-           ++f;                        /* ignore quoting flag.  */
-
-         if (*f == '+')
-           {
-             ++f;
-             plus = 1;
-           }
-         if (*f == '#')
-           f++;
-
-         switch (*f)
-           {
-             /* Just ignore these possibilities.  */
-           case '%':                                           break;
-           case 'P':
-           case 'd':   (void) va_arg (ap, int);                break;
-           case 's':   (void) va_arg (ap, char *);             break;
-           case 'L':   (void) va_arg (ap, enum languages);     break;
-           case 'C':
-           case 'O':
-           case 'Q':   (void) va_arg (ap, enum tree_code);     break;
-
-             /* These take a tree, which may be where the error is
-                located.  */
-           case 'A':
-           case 'D':
-           case 'E':
-           case 'F':
-           case 'T':
-           case 'V':
-             t = va_arg (ap, tree);
-             if (!here || plus)
-               here = t;
-             break;
-
-           default:
-             errorcount = 0;  /* damn ICE suppression */
-             internal_error ("unexpected letter %qc in locate_error\n", *f);
-           }
-       }
-    }
-
-  if (here == 0)
-    here = va_arg (ap, tree);
-
-  return here;
-}
-
-
-void
-cp_error_at (const char *gmsgid, ...)
-{
-  tree here;
-  diagnostic_info diagnostic;
-  va_list ap;
-
-  va_start (ap, gmsgid);
-  here = locate_error (gmsgid, ap);
-  va_end (ap);
-
-  va_start (ap, gmsgid);
-  diagnostic_set_info (&diagnostic, gmsgid, &ap,
-                      input_location, DK_ERROR);
-  cp_diagnostic_starter (global_dc, &diagnostic);
-  diagnostic_set_info (&diagnostic, gmsgid, &ap,
-                      location_of (here), DK_ERROR);
-  report_diagnostic (&diagnostic);
-  va_end (ap);
-}
-
-void
-cp_warning_at (const char *gmsgid, ...)
-{
-  tree here;
-  diagnostic_info diagnostic;
-  va_list ap;
-
-  va_start (ap, gmsgid);
-  here = locate_error (gmsgid, ap);
-  va_end (ap);
-
-  va_start (ap, gmsgid);
-  diagnostic_set_info (&diagnostic, gmsgid, &ap,
-                      location_of (here), DK_WARNING);
-  report_diagnostic (&diagnostic);
-  va_end (ap);
-}
+\f
+/* Callback from cpp_error for PFILE to print diagnostics arising from
+   interpreting strings.  The diagnostic is of type LEVEL; MSG is the
+   translated message and AP the arguments.  */
 
 void
-cp_pedwarn_at (const char *gmsgid, ...)
+cp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
+             const char *msg, va_list *ap)
 {
-  tree here;
   diagnostic_info diagnostic;
-  va_list ap;
-
-  va_start (ap, gmsgid);
-  here = locate_error (gmsgid, ap);
-  va_end (ap);
-
-  va_start (ap, gmsgid);
-  diagnostic_set_info (&diagnostic, gmsgid, &ap,
-                      location_of (here), pedantic_error_kind());
+  diagnostic_t dlevel;
+  switch (level)
+    {
+    case CPP_DL_WARNING:
+    case CPP_DL_WARNING_SYSHDR:
+      dlevel = DK_WARNING;
+      break;
+    case CPP_DL_PEDWARN:
+      dlevel = pedantic_error_kind ();
+      break;
+    case CPP_DL_ERROR:
+      dlevel = DK_ERROR;
+      break;
+    case CPP_DL_ICE:
+      dlevel = DK_ICE;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+  diagnostic_set_info_translated (&diagnostic, msg, ap,
+                                 input_location, dlevel);
   report_diagnostic (&diagnostic);
-  va_end (ap);
 }