OSDN Git Service

* configure: Regenerate.
[pf3gnuchains/gcc-fork.git] / gcc / cp / error.c
index 1854fd6..af86cf5 100644 (file)
@@ -1,7 +1,7 @@
 /* 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 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
    This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
@@ -143,7 +143,12 @@ dump_template_argument (tree arg, int flags)
   else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
     dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
   else
-    dump_expr (arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM);
+    {
+      if (TREE_CODE (arg) == TREE_LIST)
+       arg = TREE_VALUE (arg);
+
+      dump_expr (arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM);
+    }
 }
 
 /* Dump a template-argument-list ARGS (always a TREE_VEC) under control
@@ -396,16 +401,7 @@ dump_type (tree t, int flags)
       break;
 
     case TYPE_ARGUMENT_PACK:
-      {
-        tree args = ARGUMENT_PACK_ARGS (t);
-        int i;
-        for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
-          {
-            if (i)
-              pp_separate_with_comma (cxx_pp);
-            dump_type (TREE_VEC_ELT (args, i), flags);
-          }
-      }
+      dump_template_argument (t, flags);
       break;
 
     case DECLTYPE_TYPE:
@@ -620,6 +616,7 @@ dump_type_prefix (tree t, int flags)
     case VECTOR_TYPE:
     case TYPEOF_TYPE:
     case DECLTYPE_TYPE:
+    case TYPE_PACK_EXPANSION:
       dump_type (t, flags);
       pp_base (cxx_pp)->padding = pp_before;
       break;
@@ -717,6 +714,7 @@ dump_type_suffix (tree t, int flags)
     case VECTOR_TYPE:
     case TYPEOF_TYPE:
     case DECLTYPE_TYPE:
+    case TYPE_PACK_EXPANSION:
       break;
 
     default:
@@ -756,6 +754,10 @@ dump_simple_decl (tree t, tree type, int flags)
          || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX))
     dump_scope (CP_DECL_CONTEXT (t), flags);
   flags &= ~TFF_UNQUALIFIED_NAME;
+  if ((flags & TFF_DECL_SPECIFIERS)
+      && DECL_TEMPLATE_PARM_P (t) 
+      && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (t)))
+    pp_identifier (cxx_pp, "...");
   if (DECL_NAME (t))
     dump_decl (DECL_NAME (t), flags);
   else
@@ -780,8 +782,14 @@ dump_decl (tree t, int flags)
        {
          if ((flags & TFF_DECL_SPECIFIERS)
              && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
-           /* Say `class T' not just `T'.  */
-           pp_cxx_identifier (cxx_pp, "class");
+           {
+             /* Say `class T' not just `T'.  */
+             pp_cxx_identifier (cxx_pp, "class");
+
+             /* Emit the `...' for a parameter pack.  */
+             if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+               pp_cxx_identifier (cxx_pp, "...");
+           }
 
          dump_type (TREE_TYPE (t), flags);
          break;
@@ -964,6 +972,8 @@ dump_decl (tree t, int flags)
       break;
 
     case UNBOUND_CLASS_TEMPLATE:
+    case TYPE_PACK_EXPANSION:
+    case TREE_BINFO:
       dump_type (t, flags);
       break;
 
@@ -1015,8 +1025,14 @@ dump_template_decl (tree t, int flags)
       nreverse(orig_parms);
 
       if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
-       /* Say `template<arg> class TT' not just `template<arg> TT'.  */
-       pp_cxx_identifier (cxx_pp, "class");
+       {
+         /* Say `template<arg> class TT' not just `template<arg> TT'.  */
+         pp_cxx_identifier (cxx_pp, "class");
+
+         /* If this is a parameter pack, print the ellipsis.  */
+         if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+           pp_cxx_identifier (cxx_pp, "...");
+       }
     }
 
   if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
@@ -1168,22 +1184,8 @@ dump_parameters (tree parmtypes, int flags)
          pp_cxx_identifier (cxx_pp, "...");
          break;
        }
-      if (ARGUMENT_PACK_P (TREE_VALUE (parmtypes)))
-        {
-          tree types = ARGUMENT_PACK_ARGS (TREE_VALUE (parmtypes));
-          int i, len = TREE_VEC_LENGTH (types);
-         first = 1;
-          for (i = 0; i < len; ++i)
-            {
-              if (!first)
-                pp_separate_with_comma (cxx_pp);
-              first = 0;
-              
-              dump_type (TREE_VEC_ELT (types, i), flags);
-            }
-        }
-      else
-        dump_type (TREE_VALUE (parmtypes), flags);
+
+      dump_type (TREE_VALUE (parmtypes), flags);
 
       if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes))
        {
@@ -1459,6 +1461,12 @@ dump_expr (tree t, int flags)
   if (t == 0)
     return;
 
+  if (STATEMENT_CLASS_P (t))
+    {
+      pp_cxx_identifier (cxx_pp, "<statement>");
+      return;
+    }
+
   switch (TREE_CODE (t))
     {
     case VAR_DECL:
@@ -1777,6 +1785,7 @@ dump_expr (tree t, int flags)
 
     case NOP_EXPR:
     case CONVERT_EXPR:
+    case VIEW_CONVERT_EXPR:
       {
        tree op = TREE_OPERAND (t, 0);
 
@@ -1895,10 +1904,6 @@ dump_expr (tree t, int flags)
       dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
       break;
 
-    case SCOPE_REF:
-      pp_expression (cxx_pp, t);
-      break;
-
     case CAST_EXPR:
       if (TREE_OPERAND (t, 0) == NULL_TREE
          || TREE_CHAIN (TREE_OPERAND (t, 0)))
@@ -2026,9 +2031,8 @@ dump_expr (tree t, int flags)
       dump_expr (TREE_OPERAND (t, 0), flags);
       break;
 
-    case EXPR_PACK_EXPANSION:
-      dump_expr (PACK_EXPANSION_PATTERN (t), flags);
-      pp_cxx_identifier (cxx_pp, "...");
+    case ARGUMENT_PACK_SELECT:
+      dump_template_argument (ARGUMENT_PACK_SELECT_FROM_PACK (t), flags);
       break;
 
     case RECORD_TYPE:
@@ -2058,8 +2062,29 @@ dump_expr (tree t, int flags)
       pp_cxx_trait_expression (cxx_pp, t);
       break;
 
+    case VA_ARG_EXPR:
+      pp_cxx_va_arg_expression (cxx_pp, t);
+      break;
+
+    case OFFSETOF_EXPR:
+      pp_cxx_offsetof_expression (cxx_pp, t);
+      break;
+
+    case SCOPE_REF:
+    case EXPR_PACK_EXPANSION:
     case TYPEID_EXPR:
-      pp_cxx_typeid_expression (cxx_pp, t);
+    case MEMBER_REF:
+    case DOTSTAR_EXPR:
+    case DELETE_EXPR:
+    case VEC_DELETE_EXPR:
+    case MODOP_EXPR:
+    case ABS_EXPR:
+    case VECTOR_CST:
+      pp_expression (cxx_pp, t);
+      break;
+
+    case OBJ_TYPE_REF:
+      dump_expr (resolve_virtual_fun_from_obj_type_ref (t), flags);
       break;
 
       /*  This list is incomplete, but should suffice for now.
@@ -2107,7 +2132,7 @@ reinit_cxx_pp (void)
   pp_base (cxx_pp)->padding = pp_none;
   pp_indentation (cxx_pp) = 0;
   pp_needs_newline (cxx_pp) = false;
-  cxx_pp->enclosing_scope = 0;
+  cxx_pp->enclosing_scope = current_function_decl;
 }
 
 
@@ -2325,9 +2350,10 @@ cv_to_string (tree p, int v)
 
 /* Langhook for print_error_function.  */
 void
-cxx_print_error_function (diagnostic_context *context, const char *file)
+cxx_print_error_function (diagnostic_context *context, const char *file,
+                         diagnostic_info *diagnostic)
 {
-  lhd_print_error_function (context, file);
+  lhd_print_error_function (context, file, diagnostic);
   pp_base_set_prefix (context->printer, file);
   maybe_print_instantiation_context (context);
 }
@@ -2355,23 +2381,107 @@ static void
 cp_print_error_function (diagnostic_context *context,
                         diagnostic_info *diagnostic)
 {
-  if (diagnostic_last_function_changed (context))
+  if (diagnostic_last_function_changed (context, diagnostic))
     {
       const char *old_prefix = context->printer->prefix;
       const char *file = LOCATION_FILE (diagnostic->location);
-      char *new_prefix = file ? file_name_as_prefix (file) : NULL;
+      tree abstract_origin = diagnostic->abstract_origin;
+      char *new_prefix = (file && abstract_origin == NULL)
+                        ? file_name_as_prefix (file) : NULL;
 
       pp_base_set_prefix (context->printer, new_prefix);
 
       if (current_function_decl == NULL)
        pp_base_string (context->printer, "At global scope:");
       else
-       pp_printf (context->printer, "In %s %qs:",
-                  function_category (current_function_decl),
-                  cxx_printable_name (current_function_decl, 2));
+       {
+         tree fndecl, ao;
+
+         if (abstract_origin)
+           {
+             ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin);
+             while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+               ao = BLOCK_ABSTRACT_ORIGIN (ao);
+             gcc_assert (TREE_CODE (ao) == FUNCTION_DECL);
+             fndecl = ao;
+           }
+         else
+           fndecl = current_function_decl;
+
+         pp_printf (context->printer, "In %s %qs",
+                    function_category (fndecl),
+                    cxx_printable_name (fndecl, 2));
+
+         while (abstract_origin)
+           {
+             location_t *locus;
+             tree block = abstract_origin;
+
+             locus = &BLOCK_SOURCE_LOCATION (block);
+             fndecl = NULL;
+             block = BLOCK_SUPERCONTEXT (block);
+             while (block && TREE_CODE (block) == BLOCK
+                    && BLOCK_ABSTRACT_ORIGIN (block))
+               {
+                 ao = BLOCK_ABSTRACT_ORIGIN (block);
+
+                 while (TREE_CODE (ao) == BLOCK
+                        && BLOCK_ABSTRACT_ORIGIN (ao)
+                        && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
+                   ao = BLOCK_ABSTRACT_ORIGIN (ao);
+
+                 if (TREE_CODE (ao) == FUNCTION_DECL)
+                   {
+                     fndecl = ao;
+                     break;
+                   }
+                 else if (TREE_CODE (ao) != BLOCK)
+                   break;
+
+                 block = BLOCK_SUPERCONTEXT (block);
+               }
+             if (fndecl)
+               abstract_origin = block;
+             else
+               {
+                 while (block && TREE_CODE (block) == BLOCK)
+                   block = BLOCK_SUPERCONTEXT (block);
+
+                 if (TREE_CODE (block) == FUNCTION_DECL)
+                   fndecl = block;
+                 abstract_origin = NULL;
+               }
+             if (fndecl)
+               {
+                 expanded_location s = expand_location (*locus);
+                 pp_base_character (context->printer, ',');
+                 pp_base_newline (context->printer);
+                 if (s.file != NULL)
+                   {
+#ifdef USE_MAPPED_LOCATION
+                     if (flag_show_column && s.column != 0)
+                       pp_printf (context->printer,
+                                  "    inlined from %qs at %s:%d:%d",
+                                  cxx_printable_name (fndecl, 2),
+                                  s.file, s.line, s.column);
+                     else
+#endif
+                       pp_printf (context->printer,
+                                  "    inlined from %qs at %s:%d",
+                                  cxx_printable_name (fndecl, 2),
+                                  s.file, s.line);
+
+                   }
+                 else
+                   pp_printf (context->printer, "    inlined from %qs",
+                              cxx_printable_name (fndecl, 2));
+               }
+           }
+         pp_base_character (context->printer, ':');
+       }
       pp_base_newline (context->printer);
 
-      diagnostic_set_last_function (context);
+      diagnostic_set_last_function (context, diagnostic);
       pp_base_destroy_prefix (context->printer);
       context->printer->prefix = old_prefix;
     }