OSDN Git Service

* configure: Regenerate.
[pf3gnuchains/gcc-fork.git] / gcc / cp / error.c
index 1b70bbb..af86cf5 100644 (file)
@@ -1,12 +1,12 @@
 /* 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 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
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -15,9 +15,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 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, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -66,6 +65,8 @@ static void dump_aggr_type (tree, int);
 static void dump_type_prefix (tree, int);
 static void dump_type_suffix (tree, int);
 static void dump_function_name (tree, int);
+static void dump_call_expr_args (tree, int, bool);
+static void dump_aggr_init_expr_args (tree, int, bool);
 static void dump_expr_list (tree, int);
 static void dump_global_iord (tree);
 static void dump_parameters (tree, int);
@@ -81,7 +82,8 @@ static const char *function_category (tree);
 static void maybe_print_instantiation_context (diagnostic_context *);
 static void print_instantiation_full_context (diagnostic_context *);
 static void print_instantiation_partial_context (diagnostic_context *,
-                                                tree, location_t);
+                                                struct tinst_level *,
+                                                location_t);
 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 *);
@@ -136,10 +138,17 @@ dump_scope (tree scope, int flags)
 static void
 dump_template_argument (tree arg, int flags)
 {
-  if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
+  if (ARGUMENT_PACK_P (arg))
+    dump_template_argument_list (ARGUMENT_PACK_ARGS (arg), 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
@@ -154,9 +163,17 @@ dump_template_argument_list (tree args, int flags)
 
   for (i = 0; i< n; ++i)
     {
-      if (need_comma)
+      tree arg = TREE_VEC_ELT (args, i);
+
+      /* Only print a comma if we know there is an argument coming. In
+         the case of an empty template argument pack, no actual
+         argument will be printed.  */
+      if (need_comma
+          && (!ARGUMENT_PACK_P (arg)
+              || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
        pp_separate_with_comma (cxx_pp);
-      dump_template_argument (TREE_VEC_ELT (args, i), flags);
+
+      dump_template_argument (arg, flags);
       need_comma = 1;
     }
 }
@@ -166,14 +183,22 @@ dump_template_argument_list (tree args, int flags)
 static void
 dump_template_parameter (tree parm, int flags)
 {
-  tree p = TREE_VALUE (parm);
-  tree a = TREE_PURPOSE (parm);
+  tree p;
+  tree a;
+
+  if (parm == error_mark_node)
+   return;
+
+  p = TREE_VALUE (parm);
+  a = TREE_PURPOSE (parm);
 
   if (TREE_CODE (p) == TYPE_DECL)
     {
       if (flags & TFF_DECL_SPECIFIERS)
        {
          pp_cxx_identifier (cxx_pp, "class");
+          if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (p)))
+            pp_cxx_identifier (cxx_pp, "...");
          if (DECL_NAME (p))
            pp_cxx_tree_identifier (cxx_pp, DECL_NAME (p));
        }
@@ -370,6 +395,23 @@ dump_type (tree t, int flags)
       pp_cxx_right_paren (cxx_pp);
       break;
 
+    case TYPE_PACK_EXPANSION:
+      dump_type (PACK_EXPANSION_PATTERN (t), flags);
+      pp_cxx_identifier (cxx_pp, "...");
+      break;
+
+    case TYPE_ARGUMENT_PACK:
+      dump_template_argument (t, flags);
+      break;
+
+    case DECLTYPE_TYPE:
+      pp_cxx_identifier (cxx_pp, "decltype");
+      pp_cxx_whitespace (cxx_pp);
+      pp_cxx_left_paren (cxx_pp);
+      dump_expr (DECLTYPE_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
+      pp_cxx_right_paren (cxx_pp);
+      break;
+
     default:
       pp_unsupported_tree (cxx_pp, t);
       /* Fall through to error.  */
@@ -439,7 +481,10 @@ dump_aggr_type (tree t, int flags)
                && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (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 (! (flags & TFF_UNQUALIFIED_NAME))
+       dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE);
+      flags &= ~TFF_UNQUALIFIED_NAME;
       if (tmplate)
        {
          /* Because the template names are mangled, we have to locate
@@ -501,7 +546,15 @@ dump_type_prefix (tree t, int flags)
            pp_cxx_whitespace (cxx_pp);
            pp_cxx_left_paren (cxx_pp);
          }
-       pp_character (cxx_pp, "&*"[TREE_CODE (t) == POINTER_TYPE]);
+       if (TREE_CODE (t) == POINTER_TYPE)
+         pp_character(cxx_pp, '*');
+       else if (TREE_CODE (t) == REFERENCE_TYPE)
+       {
+         if (TYPE_REF_IS_RVALUE (t))
+           pp_string (cxx_pp, "&&");
+         else
+           pp_character (cxx_pp, '&');
+       }
        pp_base (cxx_pp)->padding = pp_before;
        pp_cxx_cv_qualifier_seq (cxx_pp, t);
       }
@@ -562,6 +615,8 @@ dump_type_prefix (tree t, int flags)
     case COMPLEX_TYPE:
     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;
@@ -623,16 +678,16 @@ dump_type_suffix (tree t, int flags)
       pp_cxx_left_bracket (cxx_pp);
       if (TYPE_DOMAIN (t))
        {
-         if (host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0))
-           pp_wide_integer
-             (cxx_pp, tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0) + 1);
-         else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR)
-           dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0),
+         tree dtype = TYPE_DOMAIN (t);
+         tree max = TYPE_MAX_VALUE (dtype);
+         if (host_integerp (max, 0))
+           pp_wide_integer (cxx_pp, tree_low_cst (max, 0) + 1);
+         else if (TREE_CODE (max) == MINUS_EXPR)
+           dump_expr (TREE_OPERAND (max, 0),
                       flags & ~TFF_EXPR_IN_PARENS);
          else
-           dump_expr (fold (cp_build_binary_op
-                            (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
-                             integer_one_node)),
+           dump_expr (fold_build2 (PLUS_EXPR, dtype, max,
+                                   build_int_cst (dtype, 1)),
                       flags & ~TFF_EXPR_IN_PARENS);
        }
       pp_cxx_right_bracket (cxx_pp);
@@ -658,6 +713,8 @@ dump_type_suffix (tree t, int flags)
     case COMPLEX_TYPE:
     case VECTOR_TYPE:
     case TYPEOF_TYPE:
+    case DECLTYPE_TYPE:
+    case TYPE_PACK_EXPANSION:
       break;
 
     default:
@@ -689,11 +746,18 @@ dump_simple_decl (tree t, tree type, int flags)
 {
   if (flags & TFF_DECL_SPECIFIERS)
     {
-      dump_type_prefix (type, flags);
+      dump_type_prefix (type, flags & ~TFF_UNQUALIFIED_NAME);
       pp_maybe_space (cxx_pp);
     }
-  if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)
+  if (! (flags & TFF_UNQUALIFIED_NAME)
+      && (!DECL_INITIAL (t)
+         || 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
@@ -718,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;
@@ -755,7 +825,9 @@ dump_decl (tree t, int flags)
        pp_cxx_declaration (cxx_pp, t);
       else
        {
-         dump_scope (CP_DECL_CONTEXT (t), flags);
+         if (! (flags & TFF_UNQUALIFIED_NAME))
+           dump_scope (CP_DECL_CONTEXT (t), flags);
+         flags &= ~TFF_UNQUALIFIED_NAME;
          if (DECL_NAME (t) == NULL_TREE)
            pp_identifier (cxx_pp, "<unnamed>");
          else
@@ -880,6 +952,10 @@ dump_decl (tree t, int flags)
       dump_decl (DECL_NAME (t), flags);
       break;
 
+    case STATIC_ASSERT:
+      pp_cxx_declaration (cxx_pp, t);
+      break;
+
     case BASELINK:
       dump_decl (BASELINK_FUNCTIONS (t), flags);
       break;
@@ -895,6 +971,12 @@ dump_decl (tree t, int flags)
        pp_type_id (cxx_pp, t);
       break;
 
+    case UNBOUND_CLASS_TEMPLATE:
+    case TYPE_PACK_EXPANSION:
+    case TREE_BINFO:
+      dump_type (t, flags);
+      break;
+
     default:
       pp_unsupported_tree (cxx_pp, t);
       /* Fall through to error.  */
@@ -943,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)
@@ -986,7 +1074,9 @@ dump_function_decl (tree t, int flags)
   tree template_args = NULL_TREE;
   tree template_parms = NULL_TREE;
   int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
+  int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME);
 
+  flags &= ~TFF_UNQUALIFIED_NAME;
   if (TREE_CODE (t) == TEMPLATE_DECL)
     t = DECL_TEMPLATE_RESULT (t);
 
@@ -1028,7 +1118,9 @@ dump_function_decl (tree t, int flags)
     dump_type_prefix (TREE_TYPE (fntype), flags);
 
   /* Print the function name.  */
-  if (cname)
+  if (!do_outer_scope)
+    /* Nothing.  */;
+  else if (cname)
     {
       dump_type (cname, flags);
       pp_cxx_colon_colon (cxx_pp);
@@ -1078,8 +1170,7 @@ dump_function_decl (tree t, int flags)
 static void
 dump_parameters (tree parmtypes, int flags)
 {
-  int first;
-
+  int first = 1;
   pp_cxx_left_paren (cxx_pp);
 
   for (first = 1; parmtypes != void_list_node;
@@ -1093,6 +1184,7 @@ dump_parameters (tree parmtypes, int flags)
          pp_cxx_identifier (cxx_pp, "...");
          break;
        }
+
       dump_type (TREE_VALUE (parmtypes), flags);
 
       if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes))
@@ -1216,14 +1308,19 @@ dump_template_parms (tree info, int primary, int flags)
        {
          tree arg = TREE_VEC_ELT (args, ix);
 
-         if (ix)
-           pp_separate_with_comma (cxx_pp);
-
-         if (!arg)
-           pp_identifier (cxx_pp, "<template parameter error>");
-         else
-           dump_template_argument (arg, flags);
-       }
+          /* Only print a comma if we know there is an argument coming. In
+             the case of an empty template argument pack, no actual
+             argument will be printed.  */
+          if (ix
+              && (!ARGUMENT_PACK_P (arg)
+                  || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
+            pp_separate_with_comma (cxx_pp);
+          
+          if (!arg)
+            pp_identifier (cxx_pp, "<template parameter error>");
+          else
+            dump_template_argument (arg, flags);
+        }
     }
   else if (primary)
     {
@@ -1236,7 +1333,15 @@ dump_template_parms (tree info, int primary, int flags)
 
       for (ix = 0; ix != len; ix++)
        {
-         tree parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
+         tree parm;
+
+          if (TREE_VEC_ELT (parms, ix) == error_mark_node)
+            {
+              pp_identifier (cxx_pp, "<template parameter error>");
+              continue;
+            }
+
+          parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
 
          if (ix)
            pp_separate_with_comma (cxx_pp);
@@ -1247,6 +1352,55 @@ dump_template_parms (tree info, int primary, int flags)
   pp_cxx_end_template_argument_list (cxx_pp);
 }
 
+/* Print out the arguments of CALL_EXPR T as a parenthesized list using
+   flags FLAGS.  Skip over the first argument if SKIPFIRST is true.  */
+
+static void
+dump_call_expr_args (tree t, int flags, bool skipfirst)
+{
+  tree arg;
+  call_expr_arg_iterator iter;
+  
+  pp_cxx_left_paren (cxx_pp);
+  FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
+    {
+      if (skipfirst)
+       skipfirst = false;
+      else
+       {
+         dump_expr (arg, flags | TFF_EXPR_IN_PARENS);
+         if (more_call_expr_args_p (&iter))
+           pp_separate_with_comma (cxx_pp);
+       }
+    }
+  pp_cxx_right_paren (cxx_pp);
+}
+
+/* Print out the arguments of AGGR_INIT_EXPR T as a parenthesized list
+   using flags FLAGS.  Skip over the first argument if SKIPFIRST is
+   true.  */
+
+static void
+dump_aggr_init_expr_args (tree t, int flags, bool skipfirst)
+{
+  tree arg;
+  aggr_init_expr_arg_iterator iter;
+  
+  pp_cxx_left_paren (cxx_pp);
+  FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
+    {
+      if (skipfirst)
+       skipfirst = false;
+      else
+       {
+         dump_expr (arg, flags | TFF_EXPR_IN_PARENS);
+         if (more_aggr_init_expr_args_p (&iter))
+           pp_separate_with_comma (cxx_pp);
+       }
+    }
+  pp_cxx_right_paren (cxx_pp);
+}
+
 /* Print out a list of initializers (subr of dump_expr).  */
 
 static void
@@ -1278,6 +1432,27 @@ dump_expr_init_vec (VEC(constructor_elt,gc) *v, int flags)
 }
 
 
+/* 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));
+  HOST_WIDE_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);
+      index -= (TARGET_VTABLE_USES_DESCRIPTORS
+               ? TARGET_VTABLE_USES_DESCRIPTORS : 1);
+    }
+
+  return BV_FN (fun);
+}
+
 /* Print out an expression E under control of FLAGS.  */
 
 static void
@@ -1286,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:
@@ -1295,22 +1476,17 @@ 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:
+    case COMPLEX_CST:
+      pp_constant (cxx_pp, t);
       break;
 
     case THROW_EXPR:
@@ -1358,8 +1534,8 @@ dump_expr (tree t, int flags)
       {
        tree fn = NULL_TREE;
 
-       if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
-         fn = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
+       if (TREE_CODE (AGGR_INIT_EXPR_FN (t)) == ADDR_EXPR)
+         fn = TREE_OPERAND (AGGR_INIT_EXPR_FN (t), 0);
 
        if (fn && TREE_CODE (fn) == FUNCTION_DECL)
          {
@@ -1369,42 +1545,41 @@ dump_expr (tree t, int flags)
              dump_decl (fn, 0);
          }
        else
-         dump_expr (TREE_OPERAND (t, 0), 0);
+         dump_expr (AGGR_INIT_EXPR_FN (t), 0);
       }
-      pp_cxx_left_paren (cxx_pp);
-      if (TREE_OPERAND (t, 1))
-       dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
-      pp_cxx_right_paren (cxx_pp);
+      dump_aggr_init_expr_args (t, flags, true);
       break;
 
     case CALL_EXPR:
       {
-       tree fn = TREE_OPERAND (t, 0);
-       tree args = TREE_OPERAND (t, 1);
+       tree fn = CALL_EXPR_FN (t);
+       bool skipfirst = false;
 
        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);
+           tree ob = CALL_EXPR_ARG (t, 0);
            if (TREE_CODE (ob) == ADDR_EXPR)
              {
                dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
-               pp_dot (cxx_pp);
+               pp_cxx_dot (cxx_pp);
              }
            else if (TREE_CODE (ob) != PARM_DECL
                     || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
              {
                dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
-               pp_arrow (cxx_pp);
+               pp_cxx_arrow (cxx_pp);
              }
-           args = TREE_CHAIN (args);
+           skipfirst = true;
          }
        dump_expr (fn, flags | TFF_EXPR_IN_PARENS);
-       pp_cxx_left_paren (cxx_pp);
-       dump_expr_list (args, flags);
-       pp_cxx_right_paren (cxx_pp);
+       dump_call_expr_args (t, flags, skipfirst);
       }
       break;
 
@@ -1455,6 +1630,10 @@ dump_expr (tree t, int flags)
        dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
       break;
 
+    case POINTER_PLUS_EXPR:
+      dump_binary_op ("+", t, flags);
+      break;
+
     case INIT_EXPR:
     case MODIFY_EXPR:
     case PLUS_EXPR:
@@ -1537,6 +1716,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;
@@ -1546,10 +1727,8 @@ dump_expr (tree t, int flags)
        {
          t = TREE_OPERAND (t, 0);
          gcc_assert (TREE_CODE (t) == CALL_EXPR);
-         dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
-         pp_cxx_left_paren (cxx_pp);
-         dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
-         pp_cxx_right_paren (cxx_pp);
+         dump_expr (CALL_EXPR_FN (t), flags | TFF_EXPR_IN_PARENS);
+         dump_call_expr_args (t, flags, true);
        }
       else
        {
@@ -1606,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);
 
@@ -1724,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)))
@@ -1855,6 +2031,62 @@ dump_expr (tree t, int flags)
       dump_expr (TREE_OPERAND (t, 0), flags);
       break;
 
+    case ARGUMENT_PACK_SELECT:
+      dump_template_argument (ARGUMENT_PACK_SELECT_FROM_PACK (t), flags);
+      break;
+
+    case RECORD_TYPE:
+    case UNION_TYPE:
+    case ENUMERAL_TYPE:
+    case REAL_TYPE:
+    case VOID_TYPE:
+    case BOOLEAN_TYPE:
+    case INTEGER_TYPE:
+    case COMPLEX_TYPE:
+    case VECTOR_TYPE:
+      pp_type_specifier_seq (cxx_pp, t);
+      break;
+
+    case TYPENAME_TYPE:
+      /* We get here when we want to print a dependent type as an
+         id-expression, without any disambiguator decoration.  */
+      pp_id_expression (cxx_pp, t);
+      break;
+
+    case TEMPLATE_TYPE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
+      dump_type (t, flags);
+      break;
+
+    case TRAIT_EXPR:
+      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:
+    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.
          It is very important that `sorry' does not call
          `report_error_function'.  That could cause an infinite loop.  */
@@ -1900,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;
 }
 
 
@@ -2005,7 +2237,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 ();
@@ -2037,7 +2270,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.  */
@@ -2117,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);
 }
@@ -2147,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;
     }
@@ -2195,30 +2513,30 @@ function_category (tree fn)
 static void
 print_instantiation_full_context (diagnostic_context *context)
 {
-  tree p = current_instantiation ();
+  struct tinst_level *p = current_instantiation ();
   location_t location = input_location;
 
   if (p)
     {
-      if (current_function_decl != TINST_DECL (p)
+      if (current_function_decl != p->decl
          && current_function_decl != NULL_TREE)
        /* We can get here during the processing of some synthesized
-          method.  Then, TINST_DECL (p) will be the function that's causing
+          method.  Then, P->DECL will be the function that's causing
           the synthesis.  */
        ;
       else
        {
-         if (current_function_decl == TINST_DECL (p))
+         if (current_function_decl == p->decl)
            /* Avoid redundancy with the "In function" line.  */;
          else
            pp_verbatim (context->printer,
                         "%s: In instantiation of %qs:\n",
                         LOCATION_FILE (location),
-                        decl_as_string (TINST_DECL (p),
+                        decl_as_string (p->decl,
                                         TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
 
-         location = TINST_LOCATION (p);
-         p = TREE_CHAIN (p);
+         location = p->locus;
+         p = p->next;
        }
     }
 
@@ -2228,19 +2546,19 @@ print_instantiation_full_context (diagnostic_context *context)
 /* Same as above but less verbose.  */
 static void
 print_instantiation_partial_context (diagnostic_context *context,
-                                    tree t, location_t loc)
+                                    struct tinst_level *t, location_t loc)
 {
   expanded_location xloc;
-  for (; ; t = TREE_CHAIN (t))
+  for (; ; t = t->next)
     {
       xloc = expand_location (loc);
-      if (t == NULL_TREE)
+      if (t == NULL)
        break;
       pp_verbatim (context->printer, "%s:%d:   instantiated from %qs\n",
                   xloc.file, xloc.line,
-                  decl_as_string (TINST_DECL (t),
+                  decl_as_string (t->decl,
                                   TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
-      loc = TINST_LOCATION (t);
+      loc = t->locus;
     }
   pp_verbatim (context->printer, "%s:%d:   instantiated from here",
               xloc.file, xloc.line);
@@ -2301,7 +2619,22 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
     {
     case 'A': result = args_to_string (next_tree, verbose);    break;
     case 'C': result = code_to_string (next_tcode);            break;
-    case 'D': result = decl_to_string (next_tree, verbose);    break;
+    case 'D':
+      {
+       tree temp = next_tree;
+       if (DECL_P (temp)
+           && DECL_DEBUG_EXPR_IS_FROM (temp) && DECL_DEBUG_EXPR (temp))
+         {
+           temp = DECL_DEBUG_EXPR (temp);
+           if (!DECL_P (temp))
+             {
+               result = expr_to_string (temp);
+               break;
+             }
+         }
+       result = decl_to_string (temp, verbose);
+      }
+      break;
     case 'E': result = expr_to_string (next_tree);             break;
     case 'F': result = fndecl_to_string (next_tree, verbose);  break;
     case 'L': result = language_to_string (next_lang);         break;
@@ -2324,3 +2657,47 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
 #undef next_lang
 #undef next_int
 }
+\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_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
+             const char *msg, va_list *ap)
+{
+  diagnostic_info diagnostic;
+  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);
+}
+
+/* Warn about the use of variadic templates when appropriate.  */
+void
+maybe_warn_variadic_templates (void)
+{
+  if ((cxx_dialect == cxx98) && !in_system_header)
+    /* We really want to suppress this warning in system headers,
+       because libstdc++ uses variadic templates even when we aren't
+       in C++0x mode. */
+    pedwarn ("ISO C++ does not include variadic templates");
+}