OSDN Git Service

fortran/
[pf3gnuchains/gcc-fork.git] / gcc / tree-pretty-print.c
index cd8033a..4b9b453 100644 (file)
@@ -1,6 +1,6 @@
 /* Pretty formatting of GENERIC trees in C syntax.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011  Free Software Foundation, Inc.
    Adapted from c-pretty-print.c by Diego Novillo <dnovillo@redhat.com>
 
 This file is part of GCC.
@@ -25,15 +25,13 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "output.h"
-#include "diagnostic.h"
-#include "real.h"
+#include "tree-pretty-print.h"
 #include "hashtab.h"
 #include "tree-flow.h"
 #include "langhooks.h"
 #include "tree-iterator.h"
 #include "tree-chrec.h"
 #include "tree-pass.h"
-#include "fixed-value.h"
 #include "value-prof.h"
 #include "predict.h"
 
@@ -73,12 +71,12 @@ do_niy (pretty_printer *buffer, const_tree node)
        }
     }
 
-  pp_string (buffer, " >>>\n");
+  pp_string (buffer, " >>>");
 }
 
 /* Debugging function to print out a generic expression.  */
 
-void
+DEBUG_FUNCTION void
 debug_generic_expr (tree t)
 {
   print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS);
@@ -87,7 +85,7 @@ debug_generic_expr (tree t)
 
 /* Debugging function to print out a generic statement.  */
 
-void
+DEBUG_FUNCTION void
 debug_generic_stmt (tree t)
 {
   print_generic_stmt (stderr, t, TDF_VOPS|TDF_MEMSYMS);
@@ -96,16 +94,27 @@ debug_generic_stmt (tree t)
 
 /* Debugging function to print out a chain of trees .  */
 
-void
+DEBUG_FUNCTION void
 debug_tree_chain (tree t)
 {
+  struct pointer_set_t *seen = pointer_set_create ();
+
   while (t)
-  {
-    print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS|TDF_UID);
-    fprintf(stderr, " ");
-    t = TREE_CHAIN (t);
-  }
+    {
+      print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS|TDF_UID);
+      fprintf (stderr, " ");
+      t = TREE_CHAIN (t);
+      if (pointer_set_insert (seen, t))
+       {
+         fprintf (stderr, "... [cycled back to ");
+         print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS|TDF_UID);
+         fprintf (stderr, "]");
+         break;
+       }
+    }
   fprintf (stderr, "\n");
+
+  pointer_set_destroy (seen);
 }
 
 /* Prints declaration DECL to the FILE with details specified by FLAGS.  */
@@ -155,72 +164,59 @@ print_generic_expr (FILE *file, tree t, int flags)
   dump_generic_node (&buffer, t, 0, flags, false);
 }
 
-/* Dump the assembly name of a decl node if it's sufficiently different
-   from the decl name.  */
-
-static void
-maybe_dump_asm_name (pretty_printer *buffer, tree node, int flags)
-{
-  tree n, a;
-
-  if (flags & TDF_SLIM)
-    return;
-  if (DECL_NAME (node) == NULL || !DECL_ASSEMBLER_NAME_SET_P (node))
-    return;
-
-  n = DECL_NAME (node);
-  a = DECL_ASSEMBLER_NAME (node);
-  if (n == a)
-    return;
-  if (strncmp (IDENTIFIER_POINTER (n), "__builtin_", 10) == 0)
-    return;
-
-  pp_space (buffer);
-  pp_character (buffer, '[');
-  pp_tree_identifier (buffer, a);
-  pp_character (buffer, ']');
-}
-
 /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
    in FLAGS.  */
 
 static void
 dump_decl_name (pretty_printer *buffer, tree node, int flags)
 {
-  tree t = node;
-
-  if (DECL_NAME (t))
-    pp_tree_identifier (buffer, DECL_NAME (t));
-  if ((flags & TDF_UID)
-      || DECL_NAME (t) == NULL_TREE)
+  if (DECL_NAME (node))
+    {
+      if ((flags & TDF_ASMNAME) && DECL_ASSEMBLER_NAME_SET_P (node))
+       pp_tree_identifier (buffer, DECL_ASSEMBLER_NAME (node));
+      else
+       pp_tree_identifier (buffer, DECL_NAME (node));
+    }
+  if ((flags & TDF_UID) || DECL_NAME (node) == NULL_TREE)
     {
-      if (TREE_CODE (t) == LABEL_DECL
-          && LABEL_DECL_UID (t) != -1)
-        pp_printf (buffer, "L.%d", (int) LABEL_DECL_UID (t));
+      if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1)
+       pp_printf (buffer, "L.%d", (int) LABEL_DECL_UID (node));
+      else if (TREE_CODE (node) == DEBUG_EXPR_DECL)
+       {
+         if (flags & TDF_NOUID)
+           pp_string (buffer, "D#xxxx");
+         else
+           pp_printf (buffer, "D#%i", DEBUG_TEMP_UID (node));
+       }
       else
        {
-         char c = TREE_CODE (t) == CONST_DECL ? 'C' : 'D';
-         pp_printf (buffer, "%c.%u", c, DECL_UID (t));
+         char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
+         if (flags & TDF_NOUID)
+           pp_printf (buffer, "%c.xxxx", c);
+         else
+           pp_printf (buffer, "%c.%u", c, DECL_UID (node));
        }
     }
-
-  maybe_dump_asm_name (buffer, node, flags);
+  if ((flags & TDF_ALIAS) && DECL_PT_UID (node) != DECL_UID (node))
+    {
+      if (flags & TDF_NOUID)
+       pp_printf (buffer, "ptD.xxxx");
+      else
+       pp_printf (buffer, "ptD.%u", DECL_PT_UID (node));
+    }
 }
 
 /* Like the above, but used for pretty printing function calls.  */
 
 static void
-dump_function_name (pretty_printer *buffer, tree node)
+dump_function_name (pretty_printer *buffer, tree node, int flags)
 {
-  if (DECL_NAME (node))
-    {
-      if (TREE_CODE (node) == NOP_EXPR)
-       node = TREE_OPERAND (node, 0);
-      pp_string (buffer, lang_hooks.decl_printable_name (node, 1));
-      maybe_dump_asm_name (buffer, node, 0);
-    }
+  if (TREE_CODE (node) == NOP_EXPR)
+    node = TREE_OPERAND (node, 0);
+  if (DECL_NAME (node) && (flags & TDF_ASMNAME) == 0)
+    pp_string (buffer, lang_hooks.decl_printable_name (node, 1));
   else
-    dump_decl_name (buffer, node, 0);
+    dump_decl_name (buffer, node, flags);
 }
 
 /* Dump a function declaration.  NODE is the FUNCTION_TYPE.  BUFFER, SPC and
@@ -236,23 +232,27 @@ dump_function_declaration (pretty_printer *buffer, tree node,
   pp_space (buffer);
   pp_character (buffer, '(');
 
-  /* Print the argument types.  The last element in the list is a VOID_TYPE.
-     The following avoids printing the last element.  */
+  /* Print the argument types.  */
   arg = TYPE_ARG_TYPES (node);
-  while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
+  while (arg && arg != void_list_node && arg != error_mark_node)
     {
-      wrote_arg = true;
-      dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
-      arg = TREE_CHAIN (arg);
-      if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
+      if (wrote_arg)
        {
          pp_character (buffer, ',');
          pp_space (buffer);
        }
+      wrote_arg = true;
+      dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
+      arg = TREE_CHAIN (arg);
     }
 
-  if (!wrote_arg)
+  /* Drop the trailing void_type_node if we had any previous argument.  */
+  if (arg == void_list_node && !wrote_arg)
     pp_string (buffer, "void");
+  /* Properly dump vararg function types.  */
+  else if (!arg && wrote_arg)
+    pp_string (buffer, ", ...");
+  /* Avoid printing any arg for unprototyped functions.  */
 
   pp_character (buffer, ')');
 }
@@ -421,6 +421,17 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
       pp_character (buffer, ')');
       break;
 
+    case OMP_CLAUSE_FINAL:
+      pp_string (buffer, "final(");
+      dump_generic_node (buffer, OMP_CLAUSE_FINAL_EXPR (clause),
+         spc, flags, false);
+      pp_character (buffer, ')');
+      break;
+
+    case OMP_CLAUSE_MERGEABLE:
+      pp_string (buffer, "mergeable");
+      break;
+
     default:
       /* Should never happen.  */
       dump_generic_node (buffer, clause, spc, flags, false);
@@ -542,7 +553,7 @@ dump_block_node (pretty_printer *buffer, tree block, int spc, int flags)
       VEC(tree,gc) *nlv = BLOCK_NONLOCALIZED_VARS (block);
 
       pp_string (buffer, "NONLOCALIZED_VARS: ");
-      for (i = 0; VEC_iterate (tree, nlv, i, t); i++)
+      FOR_EACH_VEC_ELT (tree, nlv, i, t)
        {
          dump_generic_node (buffer, t, 0, flags, false);
          pp_string (buffer, " ");
@@ -643,13 +654,13 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
          {
            size_t len = TREE_VEC_LENGTH (node);
            for (i = 0; i < len - 1; i++)
-             {     
+             {
                dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
                                   false);
                pp_character (buffer, ',');
                pp_space (buffer);
              }
-           dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc, 
+           dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
                               flags, false);
          }
       }
@@ -674,6 +685,13 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
        else if (quals & TYPE_QUAL_RESTRICT)
          pp_string (buffer, "restrict ");
 
+       if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
+         {
+           pp_string (buffer, "<address-space-");
+           pp_decimal_int (buffer, TYPE_ADDR_SPACE (node));
+           pp_string (buffer, "> ");
+         }
+
        tclass = TREE_CODE_CLASS (TREE_CODE (node));
 
        if (tclass == tcc_declaration)
@@ -697,7 +715,10 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
              }
            else if (TREE_CODE (node) == VECTOR_TYPE)
              {
-               pp_string (buffer, "vector ");
+               pp_string (buffer, "vector");
+               pp_character (buffer, '(');
+               pp_wide_integer (buffer, TYPE_VECTOR_SUBPARTS (node));
+               pp_string (buffer, ") ");
                dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
              }
            else if (TREE_CODE (node) == INTEGER_TYPE)
@@ -726,6 +747,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
                pp_decimal_int (buffer, TYPE_PRECISION (node));
                pp_string (buffer, ">");
              }
+           else if (TREE_CODE (node) == VOID_TYPE)
+             pp_string (buffer, "void");
            else
               pp_string (buffer, "<unnamed type>");
          }
@@ -751,6 +774,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
          pp_string (buffer, str);
          if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
            dump_decl_name (buffer, TYPE_NAME (node), flags);
+         else if (flags & TDF_NOUID)
+           pp_printf (buffer, "<Txxxx>");
          else
            pp_printf (buffer, "<T%x>", TYPE_UID (node));
 
@@ -772,6 +797,13 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
          if (quals & TYPE_QUAL_RESTRICT)
            pp_string (buffer, " restrict");
 
+         if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
+           {
+             pp_string (buffer, " <address-space-");
+             pp_decimal_int (buffer, TYPE_ADDR_SPACE (node));
+             pp_string (buffer, ">");
+           }
+
          if (TYPE_REF_CAN_ALIAS_ALL (node))
            pp_string (buffer, " {ref-all}");
        }
@@ -781,6 +813,62 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       NIY;
       break;
 
+    case MEM_REF:
+      {
+       if (integer_zerop (TREE_OPERAND (node, 1))
+           /* Dump the types of INTEGER_CSTs explicitly, for we can't
+              infer them and MEM_ATTR caching will share MEM_REFs
+              with differently-typed op0s.  */
+           && TREE_CODE (TREE_OPERAND (node, 0)) != INTEGER_CST
+           /* Released SSA_NAMES have no TREE_TYPE.  */
+           && TREE_TYPE (TREE_OPERAND (node, 0)) != NULL_TREE
+           /* Same pointer types, but ignoring POINTER_TYPE vs.
+              REFERENCE_TYPE.  */
+           && (TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 0)))
+               == TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 1))))
+           && (TYPE_MODE (TREE_TYPE (TREE_OPERAND (node, 0)))
+               == TYPE_MODE (TREE_TYPE (TREE_OPERAND (node, 1))))
+           && (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (node, 0)))
+               == TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (node, 1))))
+           /* Same value types ignoring qualifiers.  */
+           && (TYPE_MAIN_VARIANT (TREE_TYPE (node))
+               == TYPE_MAIN_VARIANT
+                   (TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 1))))))
+         {
+           if (TREE_CODE (TREE_OPERAND (node, 0)) != ADDR_EXPR)
+             {
+               pp_string (buffer, "*");
+               dump_generic_node (buffer, TREE_OPERAND (node, 0),
+                                  spc, flags, false);
+             }
+           else
+             dump_generic_node (buffer,
+                                TREE_OPERAND (TREE_OPERAND (node, 0), 0),
+                                spc, flags, false);
+         }
+       else
+         {
+           tree ptype;
+
+           pp_string (buffer, "MEM[");
+           pp_string (buffer, "(");
+           ptype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (node, 1)));
+           dump_generic_node (buffer, ptype,
+                              spc, flags | TDF_SLIM, false);
+           pp_string (buffer, ")");
+           dump_generic_node (buffer, TREE_OPERAND (node, 0),
+                              spc, flags, false);
+           if (!integer_zerop (TREE_OPERAND (node, 1)))
+             {
+               pp_string (buffer, " + ");
+               dump_generic_node (buffer, TREE_OPERAND (node, 1),
+                                  spc, flags, false);
+             }
+           pp_string (buffer, "]");
+         }
+       break;
+      }
+
     case TARGET_MEM_REF:
       {
        const char *sep = "";
@@ -788,15 +876,22 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 
        pp_string (buffer, "MEM[");
 
-       tmp = TMR_SYMBOL (node);
-       if (tmp)
+       if (TREE_CODE (TMR_BASE (node)) == ADDR_EXPR)
          {
            pp_string (buffer, sep);
            sep = ", ";
            pp_string (buffer, "symbol: ");
-           dump_generic_node (buffer, tmp, spc, flags, false);
+           dump_generic_node (buffer, TREE_OPERAND (TMR_BASE (node), 0),
+                              spc, flags, false);
          }
-       tmp = TMR_BASE (node);
+       else
+         {
+           pp_string (buffer, sep);
+           sep = ", ";
+           pp_string (buffer, "base: ");
+           dump_generic_node (buffer, TMR_BASE (node), spc, flags, false);
+         }
+       tmp = TMR_INDEX2 (node);
        if (tmp)
          {
            pp_string (buffer, sep);
@@ -829,13 +924,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
            dump_generic_node (buffer, tmp, spc, flags, false);
          }
        pp_string (buffer, "]");
-       if (flags & TDF_DETAILS)
-         {
-           pp_string (buffer, "{");
-           dump_generic_node (buffer, TMR_ORIGINAL (node), spc, flags,
-                              false);
-           pp_string (buffer, "}");
-         }
       }
       break;
 
@@ -914,7 +1002,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
          pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
          pp_string (buffer, "B"); /* pseudo-unit */
        }
-      else if (! host_integerp (node, 0))
+      else if (host_integerp (node, 0))
+       pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
+      else if (host_integerp (node, 1))
+       pp_unsigned_wide_integer (buffer, TREE_INT_CST_LOW (node));
+      else
        {
          tree val = node;
          unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (val);
@@ -933,8 +1025,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
                   (unsigned HOST_WIDE_INT) high, low);
          pp_string (buffer, pp_buffer (buffer)->digit_buffer);
        }
-      else
-       pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
       break;
 
     case REAL_CST:
@@ -1019,6 +1109,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
        }
       if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
        dump_decl_name (buffer, TYPE_NAME (node), flags);
+      else if (flags & TDF_NOUID)
+       pp_printf (buffer, "<Txxxx>");
       else
        pp_printf (buffer, "<T%x>", TYPE_UID (node));
       dump_function_declaration (buffer, node, spc, flags);
@@ -1033,9 +1125,14 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       if (DECL_NAME (node))
        dump_decl_name (buffer, node, flags);
       else if (LABEL_DECL_UID (node) != -1)
-        pp_printf (buffer, "<L%d>", (int) LABEL_DECL_UID (node));
+       pp_printf (buffer, "<L%d>", (int) LABEL_DECL_UID (node));
       else
-        pp_printf (buffer, "<D.%u>", DECL_UID (node));
+       {
+         if (flags & TDF_NOUID)
+           pp_string (buffer, "<D.xxxx>");
+         else
+           pp_printf (buffer, "<D.%u>", DECL_UID (node));
+       }
       break;
 
     case TYPE_DECL:
@@ -1046,7 +1143,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
        }
       if (DECL_NAME (node))
        dump_decl_name (buffer, node, flags);
-      else
+      else if (TYPE_NAME (TREE_TYPE (node)) != node)
        {
          if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
               || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
@@ -1065,11 +1162,14 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
              dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
            }
        }
+      else
+       pp_string (buffer, "<anon>");
       break;
 
     case VAR_DECL:
     case PARM_DECL:
     case FIELD_DECL:
+    case DEBUG_EXPR_DECL:
     case NAMESPACE_DECL:
       dump_decl_name (buffer, node, flags);
       break;
@@ -1081,7 +1181,29 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
     case COMPONENT_REF:
       op0 = TREE_OPERAND (node, 0);
       str = ".";
-      if (TREE_CODE (op0) == INDIRECT_REF)
+      if (op0
+         && (TREE_CODE (op0) == INDIRECT_REF
+             || (TREE_CODE (op0) == MEM_REF
+                 && TREE_CODE (TREE_OPERAND (op0, 0)) != ADDR_EXPR
+                 && integer_zerop (TREE_OPERAND (op0, 1))
+                 /* Dump the types of INTEGER_CSTs explicitly, for we
+                    can't infer them and MEM_ATTR caching will share
+                    MEM_REFs with differently-typed op0s.  */
+                 && TREE_CODE (TREE_OPERAND (op0, 0)) != INTEGER_CST
+                 /* Released SSA_NAMES have no TREE_TYPE.  */
+                 && TREE_TYPE (TREE_OPERAND (op0, 0)) != NULL_TREE
+                 /* Same pointer types, but ignoring POINTER_TYPE vs.
+                    REFERENCE_TYPE.  */
+                 && (TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 0)))
+                     == TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 1))))
+                 && (TYPE_MODE (TREE_TYPE (TREE_OPERAND (op0, 0)))
+                     == TYPE_MODE (TREE_TYPE (TREE_OPERAND (op0, 1))))
+                 && (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (op0, 0)))
+                     == TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (op0, 1))))
+                 /* Same value types ignoring qualifiers.  */
+                 && (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
+                     == TYPE_MAIN_VARIANT
+                         (TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 1))))))))
        {
          op0 = TREE_OPERAND (op0, 0);
          str = "->";
@@ -1145,19 +1267,60 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       {
        unsigned HOST_WIDE_INT ix;
        tree field, val;
-       bool is_struct_init = FALSE;
+       bool is_struct_init = false;
+       bool is_array_init = false;
+       double_int curidx = double_int_zero;
        pp_character (buffer, '{');
-       if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
-           || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
-         is_struct_init = TRUE;
+       if (TREE_CLOBBER_P (node))
+         pp_string (buffer, "CLOBBER");
+       else if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
+                || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
+         is_struct_init = true;
+        else if (TREE_CODE (TREE_TYPE (node)) == ARRAY_TYPE
+                && TYPE_DOMAIN (TREE_TYPE (node))
+                && TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (node)))
+                && TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (node))))
+                   == INTEGER_CST)
+         {
+           tree minv = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (node)));
+           is_array_init = true;
+           curidx = tree_to_double_int (minv);
+         }
        FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
          {
-           if (field && is_struct_init)
+           if (field)
              {
-               pp_character (buffer, '.');
-               dump_generic_node (buffer, field, spc, flags, false);
-               pp_string (buffer, "=");
+               if (is_struct_init)
+                 {
+                   pp_character (buffer, '.');
+                   dump_generic_node (buffer, field, spc, flags, false);
+                   pp_character (buffer, '=');
+                 }
+               else if (is_array_init
+                        && (TREE_CODE (field) != INTEGER_CST
+                            || !double_int_equal_p (tree_to_double_int (field),
+                                                    curidx)))
+                 {
+                   pp_character (buffer, '[');
+                   if (TREE_CODE (field) == RANGE_EXPR)
+                     {
+                       dump_generic_node (buffer, TREE_OPERAND (field, 0), spc,
+                                          flags, false);
+                       pp_string (buffer, " ... ");
+                       dump_generic_node (buffer, TREE_OPERAND (field, 1), spc,
+                                          flags, false);
+                       if (TREE_CODE (TREE_OPERAND (field, 1)) == INTEGER_CST)
+                         curidx = tree_to_double_int (TREE_OPERAND (field, 1));
+                     }
+                   else
+                     dump_generic_node (buffer, field, spc, flags, false);
+                   if (TREE_CODE (field) == INTEGER_CST)
+                     curidx = tree_to_double_int (field);
+                   pp_string (buffer, "]=");
+                 }
              }
+            if (is_array_init)
+             curidx = double_int_add (curidx, double_int_one);
            if (val && TREE_CODE (val) == ADDR_EXPR)
              if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
                val = TREE_OPERAND (val, 0);
@@ -1340,7 +1503,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
            {
              pp_newline (buffer);
 
-             for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
+             for (op0 = BIND_EXPR_VARS (node); op0; op0 = DECL_CHAIN (op0))
                {
                  print_declaration (buffer, op0, spc+2, flags);
                  pp_newline (buffer);
@@ -1356,7 +1519,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       break;
 
     case CALL_EXPR:
-      print_call_name (buffer, CALL_EXPR_FN (node));
+      print_call_name (buffer, CALL_EXPR_FN (node), flags);
 
       /* Print parameters.  */
       pp_space (buffer);
@@ -1438,6 +1601,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
     case RROTATE_EXPR:
     case VEC_LSHIFT_EXPR:
     case VEC_RSHIFT_EXPR:
+    case WIDEN_LSHIFT_EXPR:
     case BIT_IOR_EXPR:
     case BIT_XOR_EXPR:
     case BIT_AND_EXPR:
@@ -1500,8 +1664,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
     case ADDR_EXPR:
     case PREDECREMENT_EXPR:
     case PREINCREMENT_EXPR:
-    case ALIGN_INDIRECT_REF:
-    case MISALIGNED_INDIRECT_REF:
     case INDIRECT_REF:
       if (TREE_CODE (node) == ADDR_EXPR
          && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
@@ -1518,13 +1680,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
        }
       else
        dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-
-      if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
-        {
-          pp_string (buffer, "{misalignment: ");
-          dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-          pp_character (buffer, '}');
-        }
       break;
 
     case POSTDECREMENT_EXPR:
@@ -1566,6 +1721,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       NIY;
       break;
 
+    case ADDR_SPACE_CONVERT_EXPR:
     case FIXED_CONVERT_EXPR:
     case FIX_TRUNC_EXPR:
     case FLOAT_EXPR:
@@ -1706,14 +1862,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
        pp_string (buffer, " [non-local]");
       break;
 
-    case EXC_PTR_EXPR:
-      pp_string (buffer, "<<<exception object>>>");
-      break;
-
-    case FILTER_EXPR:
-      pp_string (buffer, "<<<filter object>>>");
-      break;
-
     case LOOP_EXPR:
       pp_string (buffer, "while (1)");
       if (!(flags & TDF_SLIM))
@@ -1814,11 +1962,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       dump_generic_node (buffer, op0, spc, flags, false);
       break;
 
-    case RESX_EXPR:
-      pp_string (buffer, "resx ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      break;
-
     case ASM_EXPR:
       pp_string (buffer, "__asm__");
       if (ASM_VOLATILE_P (node))
@@ -1919,7 +2062,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
       pp_string (buffer, ">");
       break;
-      
+
     case VEC_COND_EXPR:
       pp_string (buffer, " VEC_COND_EXPR < ");
       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
@@ -1929,6 +2072,16 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
       pp_string (buffer, " > ");
       break;
+    
+    case VEC_PERM_EXPR:
+      pp_string (buffer, " VEC_PERM_EXPR < ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (buffer, " , ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (buffer, " , ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_string (buffer, " > ");
+      break;
 
     case DOT_PROD_EXPR:
       pp_string (buffer, " DOT_PROD_EXPR < ");
@@ -1940,6 +2093,36 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       pp_string (buffer, " > ");
       break;
 
+    case WIDEN_MULT_PLUS_EXPR:
+      pp_string (buffer, " WIDEN_MULT_PLUS_EXPR < ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (buffer, ", ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (buffer, ", ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_string (buffer, " > ");
+      break;
+
+    case WIDEN_MULT_MINUS_EXPR:
+      pp_string (buffer, " WIDEN_MULT_MINUS_EXPR < ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (buffer, ", ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (buffer, ", ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_string (buffer, " > ");
+      break;
+
+    case FMA_EXPR:
+      pp_string (buffer, " FMA_EXPR < ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (buffer, ", ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (buffer, ", ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
+      pp_string (buffer, " > ");
+      break;
+
     case OMP_PARALLEL:
       pp_string (buffer, "#pragma omp parallel");
       dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
@@ -2024,7 +2207,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
     case OMP_SECTION:
       pp_string (buffer, "#pragma omp section");
       goto dump_omp_body;
+
     case OMP_MASTER:
       pp_string (buffer, "#pragma omp master");
       goto dump_omp_body;
@@ -2055,6 +2238,24 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
       break;
 
+    case OMP_ATOMIC_READ:
+      pp_string (buffer, "#pragma omp atomic read");
+      newline_and_indent (buffer, spc + 2);
+      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_space (buffer);
+      break;
+
+    case OMP_ATOMIC_CAPTURE_OLD:
+    case OMP_ATOMIC_CAPTURE_NEW:
+      pp_string (buffer, "#pragma omp atomic capture");
+      newline_and_indent (buffer, spc + 2);
+      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_space (buffer);
+      pp_character (buffer, '=');
+      pp_space (buffer);
+      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+      break;
+
     case OMP_SINGLE:
       pp_string (buffer, "#pragma omp single");
       dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
@@ -2065,6 +2266,26 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       is_expr = false;
       break;
 
+    case TRANSACTION_EXPR:
+      if (TRANSACTION_EXPR_OUTER (node))
+       pp_string (buffer, "__transaction_atomic [[outer]]");
+      else if (TRANSACTION_EXPR_RELAXED (node))
+       pp_string (buffer, "__transaction_relaxed");
+      else
+       pp_string (buffer, "__transaction_atomic");
+      if (!(flags & TDF_SLIM) && TRANSACTION_EXPR_BODY (node))
+       {
+         newline_and_indent (buffer, spc);
+         pp_character (buffer, '{');
+         newline_and_indent (buffer, spc + 2);
+         dump_generic_node (buffer, TRANSACTION_EXPR_BODY (node),
+                            spc + 2, flags, false);
+         newline_and_indent (buffer, spc);
+         pp_character (buffer, '}');
+       }
+      is_expr = false;
+      break;
+
     case REDUC_MAX_EXPR:
       pp_string (buffer, " REDUC_MAX_EXPR < ");
       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
@@ -2099,6 +2320,22 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       pp_string (buffer, " > ");
       break;
 
+    case VEC_WIDEN_LSHIFT_HI_EXPR:
+      pp_string (buffer, " VEC_WIDEN_LSHIFT_HI_EXPR < ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (buffer, ", ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (buffer, " > ");
+      break;
+
+    case VEC_WIDEN_LSHIFT_LO_EXPR:
+      pp_string (buffer, " VEC_WIDEN_LSHIFT_HI_EXPR < ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (buffer, ", ");
+      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+      pp_string (buffer, " > ");
+      break;
+
     case VEC_UNPACK_HI_EXPR:
       pp_string (buffer, " VEC_UNPACK_HI_EXPR < ");
       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
@@ -2151,38 +2388,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       dump_block_node (buffer, node, spc, flags);
       break;
 
-    case VEC_EXTRACT_EVEN_EXPR:
-      pp_string (buffer, " VEC_EXTRACT_EVEN_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " > ");
-      break;
-  
-    case VEC_EXTRACT_ODD_EXPR:
-      pp_string (buffer, " VEC_EXTRACT_ODD_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " > ");
-      break;
-
-    case VEC_INTERLEAVE_HIGH_EXPR:
-      pp_string (buffer, " VEC_INTERLEAVE_HIGH_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " > ");
-      break;
-
-    case VEC_INTERLEAVE_LOW_EXPR:
-      pp_string (buffer, " VEC_INTERLEAVE_LOW_EXPR < ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, ", ");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (buffer, " > ");
-      break;
-
     default:
       NIY;
     }
@@ -2217,7 +2422,7 @@ print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
     pp_string (buffer, "static ");
 
   /* Print the type and name.  */
-  if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
+  if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
     {
       tree tmp;
 
@@ -2333,7 +2538,7 @@ print_struct_decl (pretty_printer *buffer, const_tree node, int spc, int flags)
            print_declaration (buffer, tmp, spc+2, flags);
            pp_newline (buffer);
          }
-       tmp = TREE_CHAIN (tmp);
+       tmp = DECL_CHAIN (tmp);
       }
   }
   INDENT (spc);
@@ -2421,6 +2626,9 @@ op_code_prio (enum tree_code code)
     case RSHIFT_EXPR:
     case LROTATE_EXPR:
     case RROTATE_EXPR:
+    case VEC_WIDEN_LSHIFT_HI_EXPR:
+    case VEC_WIDEN_LSHIFT_LO_EXPR:
+    case WIDEN_LSHIFT_EXPR:
       return 11;
 
     case WIDEN_SUM_EXPR:
@@ -2433,6 +2641,8 @@ op_code_prio (enum tree_code code)
     case VEC_WIDEN_MULT_LO_EXPR:
     case WIDEN_MULT_EXPR:
     case DOT_PROD_EXPR:
+    case WIDEN_MULT_PLUS_EXPR:
+    case WIDEN_MULT_MINUS_EXPR:
     case MULT_EXPR:
     case TRUNC_DIV_EXPR:
     case CEIL_DIV_EXPR:
@@ -2444,6 +2654,7 @@ op_code_prio (enum tree_code code)
     case CEIL_MOD_EXPR:
     case FLOOR_MOD_EXPR:
     case ROUND_MOD_EXPR:
+    case FMA_EXPR:
       return 13;
 
     case TRUTH_NOT_EXPR:
@@ -2453,8 +2664,6 @@ op_code_prio (enum tree_code code)
     case PREINCREMENT_EXPR:
     case PREDECREMENT_EXPR:
     case NEGATE_EXPR:
-    case ALIGN_INDIRECT_REF:
-    case MISALIGNED_INDIRECT_REF:
     case INDIRECT_REF:
     case ADDR_EXPR:
     case FLOAT_EXPR:
@@ -2595,9 +2804,12 @@ op_symbol_code (enum tree_code code)
     case VEC_RSHIFT_EXPR:
       return "v>>";
 
+    case WIDEN_LSHIFT_EXPR:
+      return "w<<";
+
     case POINTER_PLUS_EXPR:
       return "+";
+
     case PLUS_EXPR:
       return "+";
 
@@ -2624,12 +2836,6 @@ op_symbol_code (enum tree_code code)
     case INDIRECT_REF:
       return "*";
 
-    case ALIGN_INDIRECT_REF:
-      return "A*";
-
-    case MISALIGNED_INDIRECT_REF:
-      return "M*";
-
     case TRUNC_DIV_EXPR:
     case RDIV_EXPR:
       return "/";
@@ -2693,7 +2899,7 @@ op_symbol (const_tree op)
    the gimple_call_fn of a GIMPLE_CALL.  */
 
 void
-print_call_name (pretty_printer *buffer, tree node)
+print_call_name (pretty_printer *buffer, tree node, int flags)
 {
   tree op0 = node;
 
@@ -2706,7 +2912,7 @@ print_call_name (pretty_printer *buffer, tree node)
     case VAR_DECL:
     case PARM_DECL:
     case FUNCTION_DECL:
-      dump_function_name (buffer, op0);
+      dump_function_name (buffer, op0, flags);
       break;
 
     case ADDR_EXPR:
@@ -2717,36 +2923,31 @@ print_call_name (pretty_printer *buffer, tree node)
 
     case COND_EXPR:
       pp_string (buffer, "(");
-      dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
+      dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, flags, false);
       pp_string (buffer, ") ? ");
-      dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
+      dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, flags, false);
       pp_string (buffer, " : ");
-      dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
-      break;
-
-    case COMPONENT_REF:
-      /* The function is a pointer contained in a structure.  */
-      if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
-         TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
-       dump_function_name (buffer, TREE_OPERAND (op0, 1));
-      else
-       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
-      /* else
-        We can have several levels of structures and a function
-        pointer inside.  This is not implemented yet...  */
-      /*                 NIY;*/
+      dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, flags, false);
       break;
 
     case ARRAY_REF:
       if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
-       dump_function_name (buffer, TREE_OPERAND (op0, 0));
+       dump_function_name (buffer, TREE_OPERAND (op0, 0), flags);
       else
-       dump_generic_node (buffer, op0, 0, 0, false);
+       dump_generic_node (buffer, op0, 0, flags, false);
       break;
 
+    case MEM_REF:
+      if (integer_zerop (TREE_OPERAND (op0, 1)))
+       {
+         op0 = TREE_OPERAND (op0, 0);
+         goto again;
+       }
+      /* Fallthru.  */
+    case COMPONENT_REF:
     case SSA_NAME:
     case OBJ_TYPE_REF:
-      dump_generic_node (buffer, op0, 0, 0, false);
+      dump_generic_node (buffer, op0, 0, flags, false);
       break;
 
     default:
@@ -2860,3 +3061,89 @@ newline_and_indent (pretty_printer *buffer, int spc)
   pp_newline (buffer);
   INDENT (spc);
 }
+
+/* Handle a %K format for TEXT.  Separate from default_tree_printer so
+   it can also be used in front ends.
+   %K: a statement, from which EXPR_LOCATION and TREE_BLOCK will be recorded.
+*/
+
+void
+percent_K_format (text_info *text)
+{
+  tree t = va_arg (*text->args_ptr, tree), block;
+  gcc_assert (text->locus != NULL);
+  *text->locus = EXPR_LOCATION (t);
+  gcc_assert (pp_ti_abstract_origin (text) != NULL);
+  block = TREE_BLOCK (t);
+  *pp_ti_abstract_origin (text) = NULL;
+  while (block
+        && TREE_CODE (block) == BLOCK
+        && BLOCK_ABSTRACT_ORIGIN (block))
+    {
+      tree 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)
+       {
+         *pp_ti_abstract_origin (text) = block;
+         break;
+       }
+      block = BLOCK_SUPERCONTEXT (block);
+    }
+}
+
+/* Print the identifier ID to PRETTY-PRINTER.  */
+
+void
+pp_base_tree_identifier (pretty_printer *pp, tree id)
+{
+  if (pp_translate_identifiers (pp))
+    {
+      const char *text = identifier_to_locale (IDENTIFIER_POINTER (id));
+      pp_append_text (pp, text, text + strlen (text));
+    }
+  else
+    pp_append_text (pp, IDENTIFIER_POINTER (id),
+                   IDENTIFIER_POINTER (id) + IDENTIFIER_LENGTH (id));
+}
+
+/* A helper function that is used to dump function information before the
+   function dump.  */
+
+void
+dump_function_header (FILE *dump_file, tree fdecl, int flags)
+{
+  const char *dname, *aname;
+  struct cgraph_node *node = cgraph_get_node (fdecl);
+  struct function *fun = DECL_STRUCT_FUNCTION (fdecl);
+
+  dname = lang_hooks.decl_printable_name (fdecl, 2);
+
+  if (DECL_ASSEMBLER_NAME_SET_P (fdecl))
+    aname = (IDENTIFIER_POINTER
+             (DECL_ASSEMBLER_NAME (fdecl)));
+  else
+    aname = "<unset-asm-name>";
+
+  fprintf (dump_file, "\n;; Function %s (%s, funcdef_no=%d",
+          dname, aname, fun->funcdef_no);
+  if (!(flags & TDF_NOUID))
+    fprintf (dump_file, ", decl_uid=%d", DECL_UID (fdecl));
+  if (node)
+    {
+      fprintf (dump_file, ", cgraph_uid=%d)%s\n\n", node->uid,
+               node->frequency == NODE_FREQUENCY_HOT
+               ? " (hot)"
+               : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
+               ? " (unlikely executed)"
+               : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
+               ? " (executed once)"
+               : "");
+    }
+  else
+    fprintf (dump_file, ")\n\n");
+}