OSDN Git Service

2008-08-21 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / cp / error.c
index 5a54e8c..395ede2 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
@@ -279,7 +284,10 @@ dump_type (tree t, int flags)
   switch (TREE_CODE (t))
     {
     case UNKNOWN_TYPE:
-      pp_identifier (cxx_pp, "<unresolved overloaded function type>");
+      if (t == init_list_type_node)
+       pp_identifier (cxx_pp, "<brace-enclosed initializer list>");
+      else
+       pp_identifier (cxx_pp, "<unresolved overloaded function type>");
       break;
 
     case TREE_LIST:
@@ -321,6 +329,7 @@ dump_type (tree t, int flags)
     case BOOLEAN_TYPE:
     case COMPLEX_TYPE:
     case VECTOR_TYPE:
+    case FIXED_POINT_TYPE:
       pp_type_specifier_seq (cxx_pp, t);
       break;
 
@@ -611,6 +620,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;
@@ -708,6 +718,7 @@ dump_type_suffix (tree t, int flags)
     case VECTOR_TYPE:
     case TYPEOF_TYPE:
     case DECLTYPE_TYPE:
+    case TYPE_PACK_EXPANSION:
       break;
 
     default:
@@ -747,6 +758,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
@@ -771,8 +786,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;
@@ -956,6 +977,7 @@ dump_decl (tree t, int flags)
 
     case UNBOUND_CLASS_TEMPLATE:
     case TYPE_PACK_EXPANSION:
+    case TREE_BINFO:
       dump_type (t, flags);
       break;
 
@@ -1007,8 +1029,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)
@@ -1437,6 +1465,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:
@@ -1553,43 +1587,6 @@ dump_expr (tree t, int flags)
       }
       break;
 
-    case NEW_EXPR:
-      {
-       tree type = TREE_OPERAND (t, 1);
-       tree init = TREE_OPERAND (t, 2);
-       if (NEW_EXPR_USE_GLOBAL (t))
-         pp_cxx_colon_colon (cxx_pp);
-       pp_cxx_identifier (cxx_pp, "new");
-       if (TREE_OPERAND (t, 0))
-         {
-           pp_cxx_left_paren (cxx_pp);
-           dump_expr_list (TREE_OPERAND (t, 0), flags);
-           pp_cxx_right_paren (cxx_pp);
-           pp_cxx_whitespace (cxx_pp);
-         }
-       if (TREE_CODE (type) == ARRAY_REF)
-         type = build_cplus_array_type
-           (TREE_OPERAND (type, 0),
-            build_index_type (fold_build2 (MINUS_EXPR, integer_type_node,
-                                           TREE_OPERAND (type, 1),
-                                           integer_one_node)));
-       dump_type (type, flags);
-       if (init)
-         {
-           pp_cxx_left_paren (cxx_pp);
-           if (TREE_CODE (init) == TREE_LIST)
-             dump_expr_list (init, flags);
-           else if (init == void_zero_node)
-             /* This representation indicates an empty initializer,
-                e.g.: "new int()".  */
-             ;
-           else
-             dump_expr (init, flags);
-           pp_cxx_right_paren (cxx_pp);
-         }
-      }
-      break;
-
     case TARGET_EXPR:
       /* Note that this only works for G++ target exprs.  If somebody
         builds a general TARGET_EXPR, there's no way to represent that
@@ -1753,8 +1750,8 @@ dump_expr (tree t, int flags)
       dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
       break;
 
-    case NOP_EXPR:
-    case CONVERT_EXPR:
+    CASE_CONVERT:
+    case VIEW_CONVERT_EXPR:
       {
        tree op = TREE_OPERAND (t, 0);
 
@@ -1873,10 +1870,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)))
@@ -2004,11 +1997,6 @@ 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, "...");
-      break;
-
     case ARGUMENT_PACK_SELECT:
       dump_template_argument (ARGUMENT_PACK_SELECT_FROM_PACK (t), flags);
       break;
@@ -2040,10 +2028,6 @@ dump_expr (tree t, int flags)
       pp_cxx_trait_expression (cxx_pp, t);
       break;
 
-    case TYPEID_EXPR:
-      pp_cxx_typeid_expression (cxx_pp, t);
-      break;
-
     case VA_ARG_EXPR:
       pp_cxx_va_arg_expression (cxx_pp, t);
       break;
@@ -2052,9 +2036,43 @@ dump_expr (tree t, int flags)
       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 NEW_EXPR:
+    case VEC_NEW_EXPR:
     case DELETE_EXPR:
     case VEC_DELETE_EXPR:
-      pp_cxx_delete_expression (cxx_pp, t);
+    case MODOP_EXPR:
+    case ABS_EXPR:
+    case CONJ_EXPR:
+    case VECTOR_CST:
+    case FIXED_CST:
+    case UNORDERED_EXPR:
+    case ORDERED_EXPR:
+    case UNLT_EXPR:
+    case UNLE_EXPR:
+    case UNGT_EXPR:
+    case UNGE_EXPR:
+    case UNEQ_EXPR:
+    case LTGT_EXPR:
+      pp_expression (cxx_pp, t);
+      break;
+
+    case TRUTH_AND_EXPR:
+    case TRUTH_OR_EXPR:
+    case TRUTH_XOR_EXPR:
+      if (flags & TFF_EXPR_IN_PARENS)
+       pp_cxx_left_paren (cxx_pp);
+      pp_expression (cxx_pp, t);
+      if (flags & TFF_EXPR_IN_PARENS)
+       pp_cxx_right_paren (cxx_pp);
+      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.
@@ -2102,7 +2120,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;
 }
 
 
@@ -2370,7 +2388,9 @@ cp_print_error_function (diagnostic_context *context,
          if (abstract_origin)
            {
              ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin);
-             while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+             while (TREE_CODE (ao) == BLOCK
+                    && BLOCK_ABSTRACT_ORIGIN (ao)
+                    && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
                ao = BLOCK_ABSTRACT_ORIGIN (ao);
              gcc_assert (TREE_CODE (ao) == FUNCTION_DECL);
              fndecl = ao;
@@ -2395,7 +2415,9 @@ cp_print_error_function (diagnostic_context *context,
                {
                  ao = BLOCK_ABSTRACT_ORIGIN (block);
 
-                 while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+                 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)
@@ -2426,14 +2448,12 @@ cp_print_error_function (diagnostic_context *context,
                  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),
@@ -2643,7 +2663,7 @@ cp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
       dlevel = DK_WARNING;
       break;
     case CPP_DL_PEDWARN:
-      dlevel = pedantic_error_kind ();
+      dlevel = DK_PEDWARN;
       break;
     case CPP_DL_ERROR:
       dlevel = DK_ERROR;
@@ -2659,13 +2679,20 @@ cp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
   report_diagnostic (&diagnostic);
 }
 
-/* Warn about the use of variadic templates when appropriate.  */
+/* Warn about the use of C++0x features when appropriate.  */
 void
-maybe_warn_variadic_templates (void)
+maybe_warn_cpp0x (const char* str)
 {
   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");
+    pedwarn (input_location, 0, "%s only available with -std=c++0x or -std=gnu++0x", str);
+}
+
+/* Warn about the use of variadic templates when appropriate.  */
+void
+maybe_warn_variadic_templates (void)
+{
+  maybe_warn_cpp0x ("variadic templates");
 }