diff gcc/c-family/c-pretty-print.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents 561a7518be6b
children ab0bcb71f44d 84e7813d76e9
line wrap: on
line diff
--- a/gcc/c-family/c-pretty-print.c	Sun Aug 21 07:07:55 2011 +0900
+++ b/gcc/c-family/c-pretty-print.c	Fri Oct 27 22:46:09 2017 +0900
@@ -1,6 +1,5 @@
 /* Subroutines common to both C and C++ pretty-printers.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2002-2017 Free Software Foundation, Inc.
    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
 
 This file is part of GCC.
@@ -22,17 +21,13 @@
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "tree.h"
+#include "c-pretty-print.h"
+#include "diagnostic.h"
+#include "stor-layout.h"
+#include "stringpool.h"
+#include "attribs.h"
 #include "intl.h"
-#include "c-pretty-print.h"
 #include "tree-pretty-print.h"
-#include "tree-iterator.h"
-#include "diagnostic.h"
-
-/* Translate if being used for diagnostics, but not for dump files or
-   __PRETTY_FUNCTION.  */
-#define M_(msgid) (pp_translate_identifiers (pp) ? _(msgid) : (msgid))
 
 /* The pretty-printer code is primarily designed to closely follow
    (GNU) C and C++ grammars.  That is to be contrasted with spaghetti
@@ -44,7 +39,7 @@
 
 #define pp_c_maybe_whitespace(PP)            \
    do {                                      \
-     if (pp_base (PP)->padding == pp_before) \
+     if ((PP)->padding == pp_before) \
        pp_c_whitespace (PP);                 \
    } while (0)
 
@@ -55,7 +50,6 @@
 static void pp_c_initializer_list (c_pretty_printer *, tree);
 static void pp_c_brace_enclosed_initializer_list (c_pretty_printer *, tree);
 
-static void pp_c_multiplicative_expression (c_pretty_printer *, tree);
 static void pp_c_additive_expression (c_pretty_printer *, tree);
 static void pp_c_shift_expression (c_pretty_printer *, tree);
 static void pp_c_relational_expression (c_pretty_printer *, tree);
@@ -64,8 +58,6 @@
 static void pp_c_exclusive_or_expression (c_pretty_printer *, tree);
 static void pp_c_inclusive_or_expression (c_pretty_printer *, tree);
 static void pp_c_logical_and_expression (c_pretty_printer *, tree);
-static void pp_c_conditional_expression (c_pretty_printer *, tree);
-static void pp_c_assignment_expression (c_pretty_printer *, tree);
 
 /* declarations.  */
 
@@ -76,98 +68,98 @@
 pp_c_whitespace (c_pretty_printer *pp)
 {
   pp_space (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_left_paren (c_pretty_printer *pp)
 {
   pp_left_paren (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_right_paren (c_pretty_printer *pp)
 {
   pp_right_paren (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_left_brace (c_pretty_printer *pp)
 {
   pp_left_brace (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_right_brace (c_pretty_printer *pp)
 {
   pp_right_brace (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_left_bracket (c_pretty_printer *pp)
 {
   pp_left_bracket (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_right_bracket (c_pretty_printer *pp)
 {
   pp_right_bracket (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_dot (c_pretty_printer *pp)
 {
   pp_dot (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_ampersand (c_pretty_printer *pp)
 {
   pp_ampersand (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_star (c_pretty_printer *pp)
 {
   pp_star (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_arrow (c_pretty_printer *pp)
 {
   pp_arrow (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_semicolon (c_pretty_printer *pp)
 {
   pp_semicolon (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_complement (c_pretty_printer *pp)
 {
   pp_complement (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 void
 pp_c_exclamation (c_pretty_printer *pp)
 {
   pp_exclamation (pp);
-  pp_base (pp)->padding = pp_none;
+  pp->padding = pp_none;
 }
 
 /* Print out the external representation of QUALIFIERS.  */
@@ -176,7 +168,6 @@
 pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type)
 {
   const char *p = pp_last_position_in_text (pp);
-  bool previous = false;
 
   if (!qualifiers)
     return;
@@ -187,26 +178,15 @@
   if (p != NULL && (*p == '*' || *p == '&'))
     pp_c_whitespace (pp);
 
+  if (qualifiers & TYPE_QUAL_ATOMIC)
+    pp_c_ws_string (pp, "_Atomic");
   if (qualifiers & TYPE_QUAL_CONST)
-    {
-      pp_c_ws_string (pp, func_type ? "__attribute__((const))" : "const");
-      previous = true;
-    }
-
+    pp_c_ws_string (pp, func_type ? "__attribute__((const))" : "const");
   if (qualifiers & TYPE_QUAL_VOLATILE)
-    {
-      if (previous)
-        pp_c_whitespace (pp);
-      pp_c_ws_string (pp, func_type ? "__attribute__((noreturn))" : "volatile");
-      previous = true;
-    }
-
+    pp_c_ws_string (pp, func_type ? "__attribute__((noreturn))" : "volatile");
   if (qualifiers & TYPE_QUAL_RESTRICT)
-    {
-      if (previous)
-        pp_c_whitespace (pp);
-      pp_c_ws_string (pp, flag_isoc99 ? "restrict" : "__restrict__");
-    }
+    pp_c_ws_string (pp, (flag_isoc99 && !c_dialect_cxx ()
+			 ? "restrict" : "__restrict__"));
 }
 
 /* Pretty-print T using the type-cast notation '( type-name )'.  */
@@ -215,7 +195,7 @@
 pp_c_type_cast (c_pretty_printer *pp, tree t)
 {
   pp_c_left_paren (pp);
-  pp_type_id (pp, t);
+  pp->type_id (t);
   pp_c_right_paren (pp);
 }
 
@@ -251,6 +231,7 @@
        __restrict__                          -- GNU C
        address-space-qualifier		     -- GNU C
        volatile
+       _Atomic                               -- C11
 
    address-space-qualifier:
        identifier			     -- GNU C  */
@@ -303,7 +284,7 @@
       /* ??? This node is now in GENERIC and so shouldn't be here.  But
 	 we'll fix that later.  */
     case DECL_EXPR:
-      pp_declaration (pp, DECL_EXPR_DECL (t));
+      pp->declaration (DECL_EXPR_DECL (t));
       pp_needs_newline (pp) = true;
       break;
 
@@ -312,7 +293,10 @@
     }
 }
 
-/* type-specifier:
+/* simple-type-specifier:
+     type-specifier
+
+   type-specifier:
       void
       char
       short
@@ -335,17 +319,17 @@
       __vector__   */
 
 void
-pp_c_type_specifier (c_pretty_printer *pp, tree t)
+c_pretty_printer::simple_type_specifier (tree t)
 {
   const enum tree_code code = TREE_CODE (t);
   switch (code)
     {
     case ERROR_MARK:
-      pp_c_ws_string (pp, M_("<type-error>"));
+      translate_string ("<type-error>");
       break;
 
     case IDENTIFIER_NODE:
-      pp_c_tree_decl_identifier (pp, t);
+      pp_c_identifier (this, IDENTIFIER_POINTER (t));
       break;
 
     case VOID_TYPE:
@@ -356,22 +340,25 @@
       if (TYPE_NAME (t))
 	{
 	  t = TYPE_NAME (t);
-	  pp_c_type_specifier (pp, t);
+	  simple_type_specifier (t);
 	}
       else
 	{
 	  int prec = TYPE_PRECISION (t);
+	  tree common_t;
 	  if (ALL_FIXED_POINT_MODE_P (TYPE_MODE (t)))
-	    t = c_common_type_for_mode (TYPE_MODE (t), TYPE_SATURATING (t));
+	    common_t = c_common_type_for_mode (TYPE_MODE (t),
+					       TYPE_SATURATING (t));
 	  else
-	    t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t));
-	  if (TYPE_NAME (t))
+	    common_t = c_common_type_for_mode (TYPE_MODE (t),
+					       TYPE_UNSIGNED (t));
+	  if (common_t && TYPE_NAME (common_t))
 	    {
-	      pp_c_type_specifier (pp, t);
-	      if (TYPE_PRECISION (t) != prec)
+	      simple_type_specifier (common_t);
+	      if (TYPE_PRECISION (common_t) != prec)
 		{
-		  pp_string (pp, ":");
-		  pp_decimal_int (pp, prec);
+		  pp_colon (this);
+		  pp_decimal_int (this, prec);
 		}
 	    }
 	  else
@@ -379,52 +366,54 @@
 	      switch (code)
 		{
 		case INTEGER_TYPE:
-		  pp_string (pp, (TYPE_UNSIGNED (t)
-				  ? M_("<unnamed-unsigned:")
-				  : M_("<unnamed-signed:")));
+		  translate_string (TYPE_UNSIGNED (t)
+                                    ? "<unnamed-unsigned:"
+                                    : "<unnamed-signed:");
 		  break;
 		case REAL_TYPE:
-		  pp_string (pp, M_("<unnamed-float:"));
+		  translate_string ("<unnamed-float:");
 		  break;
 		case FIXED_POINT_TYPE:
-		  pp_string (pp, M_("<unnamed-fixed:"));
+		  translate_string ("<unnamed-fixed:");
 		  break;
 		default:
 		  gcc_unreachable ();
 		}
-	      pp_decimal_int (pp, prec);
-	      pp_string (pp, ">");
+	      pp_decimal_int (this, prec);
+	      pp_greater (this);
 	    }
 	}
       break;
 
     case TYPE_DECL:
       if (DECL_NAME (t))
-	pp_id_expression (pp, t);
+	id_expression (t);
       else
-	pp_c_ws_string (pp, M_("<typedef-error>"));
+	translate_string ("<typedef-error>");
       break;
 
     case UNION_TYPE:
     case RECORD_TYPE:
     case ENUMERAL_TYPE:
-      if (code == UNION_TYPE)
-	pp_c_ws_string (pp, "union");
+      if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
+	/* Don't decorate the type if this is a typedef name.  */;
+      else if (code == UNION_TYPE)
+	pp_c_ws_string (this, "union");
       else if (code == RECORD_TYPE)
-	pp_c_ws_string (pp, "struct");
+	pp_c_ws_string (this, "struct");
       else if (code == ENUMERAL_TYPE)
-	pp_c_ws_string (pp, "enum");
+	pp_c_ws_string (this, "enum");
       else
-	pp_c_ws_string (pp, M_("<tag-error>"));
+	translate_string ("<tag-error>");
 
       if (TYPE_NAME (t))
-	pp_id_expression (pp, TYPE_NAME (t));
+	id_expression (TYPE_NAME (t));
       else
-	pp_c_ws_string (pp, M_("<anonymous>"));
+	translate_string ("<anonymous>");
       break;
 
     default:
-      pp_unsupported_tree (pp, t);
+      pp_unsupported_tree (this, t);
       break;
     }
 }
@@ -438,14 +427,14 @@
   function declarations, this routine prints not just the
   specifier-qualifier-list of such entities or types of such entities,
   but also the 'pointer' production part of their declarators.  The
-  remaining part is done by pp_declarator or pp_c_abstract_declarator.  */
+  remaining part is done by declarator() or abstract_declarator().  */
 
 void
 pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t)
 {
   const enum tree_code code = TREE_CODE (t);
 
-  if (TREE_CODE (t) != POINTER_TYPE)
+  if (!(pp->flags & pp_c_flag_gnu_v3) && code != POINTER_TYPE)
     pp_c_type_qualifier_list (pp, t);
   switch (code)
     {
@@ -460,6 +449,7 @@
 	  {
 	    pp_c_whitespace (pp);
 	    pp_c_left_paren (pp);
+	    pp_c_attributes_display (pp, TYPE_ATTRIBUTES (pointee));
 	  }
 	else if (!c_dialect_cxx ())
 	  pp_c_whitespace (pp);
@@ -475,7 +465,8 @@
     case VECTOR_TYPE:
     case COMPLEX_TYPE:
       if (code == COMPLEX_TYPE)
-	pp_c_ws_string (pp, flag_isoc99 ? "_Complex" : "__complex__");
+	pp_c_ws_string (pp, (flag_isoc99 && !c_dialect_cxx ()
+			     ? "_Complex" : "__complex__"));
       else if (code == VECTOR_TYPE)
 	{
 	  pp_c_ws_string (pp, "__vector");
@@ -488,9 +479,11 @@
       break;
 
     default:
-      pp_simple_type_specifier (pp, t);
+      pp->simple_type_specifier (t);
       break;
     }
+  if ((pp->flags & pp_c_flag_gnu_v3) && code != POINTER_TYPE)
+    pp_c_type_qualifier_list (pp, t);
 }
 
 /* parameter-type-list:
@@ -521,12 +514,17 @@
 	  if (!first)
 	    pp_separate_with (pp, ',');
 	  first = false;
-	  pp_declaration_specifiers
-	    (pp, want_parm_decl ? parms : TREE_VALUE (parms));
+	  pp->declaration_specifiers
+	    (want_parm_decl ? parms : TREE_VALUE (parms));
 	  if (want_parm_decl)
-	    pp_declarator (pp, parms);
+	    pp->declarator (parms);
 	  else
-	    pp_abstract_declarator (pp, TREE_VALUE (parms));
+	    pp->abstract_declarator (TREE_VALUE (parms));
+	}
+      if (!first && !parms)
+	{
+	  pp_separate_with (pp, ',');
+	  pp_c_ws_string (pp, "...");
 	}
     }
   pp_c_right_paren (pp);
@@ -536,18 +534,18 @@
       pointer
       pointer(opt) direct-abstract-declarator  */
 
-static void
-pp_c_abstract_declarator (c_pretty_printer *pp, tree t)
+void
+c_pretty_printer::abstract_declarator (tree t)
 {
   if (TREE_CODE (t) == POINTER_TYPE)
     {
       if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
 	  || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
-	pp_c_right_paren (pp);
+	pp_c_right_paren (this);
       t = TREE_TYPE (t);
     }
 
-  pp_direct_abstract_declarator (pp, t);
+  direct_abstract_declarator (t);
 }
 
 /* direct-abstract-declarator:
@@ -557,34 +555,34 @@
       direct-abstract-declarator(opt) ( parameter-type-list(opt) )  */
 
 void
-pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t)
+c_pretty_printer::direct_abstract_declarator (tree t)
 {
   switch (TREE_CODE (t))
     {
     case POINTER_TYPE:
-      pp_abstract_declarator (pp, t);
+      abstract_declarator (t);
       break;
 
     case FUNCTION_TYPE:
-      pp_c_parameter_type_list (pp, t);
-      pp_direct_abstract_declarator (pp, TREE_TYPE (t));
+      pp_c_parameter_type_list (this, t);
+      direct_abstract_declarator (TREE_TYPE (t));
       break;
 
     case ARRAY_TYPE:
-      pp_c_left_bracket (pp);
+      pp_c_left_bracket (this);
       if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t)))
 	{
 	  tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (t));
 	  tree type = TREE_TYPE (maxval);
 
-	  if (host_integerp (maxval, 0))
-	    pp_wide_integer (pp, tree_low_cst (maxval, 0) + 1);
+	  if (tree_fits_shwi_p (maxval))
+	    pp_wide_integer (this, tree_to_shwi (maxval) + 1);
 	  else
-	    pp_expression (pp, fold_build2 (PLUS_EXPR, type, maxval,
-					    build_int_cst (type, 1)));
+	    expression (fold_build2 (PLUS_EXPR, type, maxval,
+                                     build_int_cst (type, 1)));
 	}
-      pp_c_right_bracket (pp);
-      pp_direct_abstract_declarator (pp, TREE_TYPE (t));
+      pp_c_right_bracket (this);
+      direct_abstract_declarator (TREE_TYPE (t));
       break;
 
     case IDENTIFIER_NODE:
@@ -602,7 +600,7 @@
       break;
 
     default:
-      pp_unsupported_tree (pp, t);
+      pp_unsupported_tree (this, t);
       break;
     }
 }
@@ -611,10 +609,10 @@
       specifier-qualifier-list  abstract-declarator(opt)  */
 
 void
-pp_c_type_id (c_pretty_printer *pp, tree t)
+c_pretty_printer::type_id (tree t)
 {
-  pp_c_specifier_qualifier_list (pp, t);
-  pp_abstract_declarator (pp, t);
+  pp_c_specifier_qualifier_list (this, t);
+  abstract_declarator (t);
 }
 
 /* storage-class-specifier:
@@ -625,16 +623,16 @@
       register  */
 
 void
-pp_c_storage_class_specifier (c_pretty_printer *pp, tree t)
+c_pretty_printer::storage_class_specifier (tree t)
 {
   if (TREE_CODE (t) == TYPE_DECL)
-    pp_c_ws_string (pp, "typedef");
+    pp_c_ws_string (this, "typedef");
   else if (DECL_P (t))
     {
       if (DECL_REGISTER (t))
-	pp_c_ws_string (pp, "register");
-      else if (TREE_STATIC (t) && TREE_CODE (t) == VAR_DECL)
-	pp_c_ws_string (pp, "static");
+	pp_c_ws_string (this, "register");
+      else if (TREE_STATIC (t) && VAR_P (t))
+	pp_c_ws_string (this, "static");
     }
 }
 
@@ -642,10 +640,10 @@
       inline   */
 
 void
-pp_c_function_specifier (c_pretty_printer *pp, tree t)
+c_pretty_printer::function_specifier (tree t)
 {
   if (TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (t))
-    pp_c_ws_string (pp, "inline");
+    pp_c_ws_string (this, "inline");
 }
 
 /* declaration-specifiers:
@@ -655,11 +653,11 @@
       function-specifier declaration-specifiers(opt)  */
 
 void
-pp_c_declaration_specifiers (c_pretty_printer *pp, tree t)
+c_pretty_printer::declaration_specifiers (tree t)
 {
-  pp_storage_class_specifier (pp, t);
-  pp_function_specifier (pp, t);
-  pp_c_specifier_qualifier_list (pp, DECL_P (t) ?  TREE_TYPE (t) : t);
+  storage_class_specifier (t);
+  function_specifier (t);
+  pp_c_specifier_qualifier_list (this, DECL_P (t) ?  TREE_TYPE (t) : t);
 }
 
 /* direct-declarator
@@ -673,7 +671,7 @@
       direct-declarator ( identifier-list(opt) )  */
 
 void
-pp_c_direct_declarator (c_pretty_printer *pp, tree t)
+c_pretty_printer::direct_declarator (tree t)
 {
   switch (TREE_CODE (t))
     {
@@ -682,29 +680,29 @@
     case TYPE_DECL:
     case FIELD_DECL:
     case LABEL_DECL:
-      pp_c_space_for_pointer_operator (pp, TREE_TYPE (t));
-      pp_c_tree_decl_identifier (pp, t);
+      pp_c_space_for_pointer_operator (this, TREE_TYPE (t));
+      pp_c_tree_decl_identifier (this, t);
       break;
 
     case ARRAY_TYPE:
     case POINTER_TYPE:
-      pp_abstract_declarator (pp, TREE_TYPE (t));
+      abstract_declarator (TREE_TYPE (t));
       break;
 
     case FUNCTION_TYPE:
-      pp_parameter_list (pp, t);
-      pp_abstract_declarator (pp, TREE_TYPE (t));
+      pp_parameter_list (this, t);
+      abstract_declarator (TREE_TYPE (t));
       break;
 
     case FUNCTION_DECL:
-      pp_c_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
-      pp_c_tree_decl_identifier (pp, t);
-      if (pp_c_base (pp)->flags & pp_c_flag_abstract)
-	pp_abstract_declarator (pp, TREE_TYPE (t));
+      pp_c_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
+      pp_c_tree_decl_identifier (this, t);
+      if (flags & pp_c_flag_abstract)
+	abstract_declarator (TREE_TYPE (t));
       else
 	{
-	  pp_parameter_list (pp, t);
-	  pp_abstract_declarator (pp, TREE_TYPE (TREE_TYPE (t)));
+	  pp_parameter_list (this, t);
+	  abstract_declarator (TREE_TYPE (TREE_TYPE (t)));
 	}
       break;
 
@@ -717,7 +715,7 @@
       break;
 
     default:
-      pp_unsupported_tree (pp, t);
+      pp_unsupported_tree (this, t);
       break;
     }
 }
@@ -727,7 +725,7 @@
       pointer(opt)  direct-declarator   */
 
 void
-pp_c_declarator (c_pretty_printer *pp, tree t)
+c_pretty_printer::declarator (tree t)
 {
   switch (TREE_CODE (t))
     {
@@ -746,12 +744,12 @@
     case FUNCTION_TYPE:
     case FUNCTION_DECL:
     case TYPE_DECL:
-      pp_direct_declarator (pp, t);
+      direct_declarator (t);
     break;
 
 
     default:
-      pp_unsupported_tree (pp, t);
+      pp_unsupported_tree (this, t);
       break;
     }
 }
@@ -760,10 +758,10 @@
       declaration-specifiers init-declarator-list(opt) ;  */
 
 void
-pp_c_declaration (c_pretty_printer *pp, tree t)
+c_pretty_printer::declaration (tree t)
 {
-  pp_declaration_specifiers (pp, t);
-  pp_c_init_declarator (pp, t);
+  declaration_specifiers (t);
+  pp_c_init_declarator (this, t);
 }
 
 /* Pretty-print ATTRIBUTES using GNU C extension syntax.  */
@@ -790,18 +788,62 @@
   pp_c_right_paren (pp);
 }
 
+/* Pretty-print ATTRIBUTES using GNU C extension syntax for attributes
+   marked to be displayed on disgnostic.  */
+
+void
+pp_c_attributes_display (c_pretty_printer *pp, tree a)
+{
+  bool is_first = true;
+
+  if (a == NULL_TREE)
+    return;
+
+  for (; a != NULL_TREE; a = TREE_CHAIN (a))
+    {
+      const struct attribute_spec *as;
+      as = lookup_attribute_spec (TREE_PURPOSE (a));
+      if (!as || as->affects_type_identity == false)
+        continue;
+      if (c_dialect_cxx ()
+	  && !strcmp ("transaction_safe", as->name))
+	/* In C++ transaction_safe is printed at the end of the declarator.  */
+	continue;
+      if (is_first)
+       {
+         pp_c_ws_string (pp, "__attribute__");
+         pp_c_left_paren (pp);
+         pp_c_left_paren (pp);
+         is_first = false;
+       }
+      else
+       {
+         pp_separate_with (pp, ',');
+       }
+      pp_tree_identifier (pp, TREE_PURPOSE (a));
+      if (TREE_VALUE (a))
+       pp_c_call_argument_list (pp, TREE_VALUE (a));
+    }
+
+  if (!is_first)
+    {
+      pp_c_right_paren (pp);
+      pp_c_right_paren (pp);
+      pp_c_whitespace (pp);
+    }
+}
+
 /* function-definition:
       declaration-specifiers declarator compound-statement  */
 
 void
 pp_c_function_definition (c_pretty_printer *pp, tree t)
 {
-  pp_declaration_specifiers (pp, t);
-  pp_declarator (pp, t);
+  pp->declaration_specifiers (t);
+  pp->declarator (t);
   pp_needs_newline (pp) = true;
-  pp_statement (pp, DECL_SAVED_TREE (t));
-  pp_newline (pp);
-  pp_flush (pp);
+  pp->statement (DECL_SAVED_TREE (t));
+  pp_newline_and_flush (pp);
 }
 
 
@@ -854,39 +896,36 @@
   pp_doublequote (pp);
 }
 
+/* Pretty-print a VOID_CST (void_node).  */
+
+static void
+pp_c_void_constant (c_pretty_printer *pp)
+{
+  pp_c_type_cast (pp, void_type_node);
+  pp_string (pp, "0");
+}
+
 /* Pretty-print an INTEGER literal.  */
 
 static void
 pp_c_integer_constant (c_pretty_printer *pp, tree i)
 {
-  tree type = TREE_TYPE (i);
-
-  if (TREE_INT_CST_HIGH (i) == 0)
-    pp_wide_integer (pp, TREE_INT_CST_LOW (i));
+  if (tree_fits_shwi_p (i))
+    pp_wide_integer (pp, tree_to_shwi (i));
+  else if (tree_fits_uhwi_p (i))
+    pp_unsigned_wide_integer (pp, tree_to_uhwi (i));
   else
     {
-      unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (i);
-      HOST_WIDE_INT high = TREE_INT_CST_HIGH (i);
-      if (tree_int_cst_sgn (i) < 0)
+      wide_int wi = wi::to_wide (i);
+
+      if (wi::lt_p (wi::to_wide (i), 0, TYPE_SIGN (TREE_TYPE (i))))
 	{
-	  pp_character (pp, '-');
-	  high = ~high + !low;
-	  low = -low;
+	  pp_minus (pp);
+	  wi = -wi;
 	}
-      sprintf (pp_buffer (pp)->digit_buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-	       (unsigned HOST_WIDE_INT) high, (unsigned HOST_WIDE_INT) low);
+      print_hex (wi, pp_buffer (pp)->digit_buffer);
       pp_string (pp, pp_buffer (pp)->digit_buffer);
     }
-  if (TYPE_UNSIGNED (type))
-    pp_character (pp, 'u');
-  if (type == long_integer_type_node || type == long_unsigned_type_node)
-    pp_character (pp, 'l');
-  else if (type == long_long_integer_type_node
-	   || type == long_long_unsigned_type_node)
-    pp_string (pp, "ll");
-  else if (type == int128_integer_type_node
-           || type == int128_unsigned_type_node)
-    pp_string (pp, "I128");
 }
 
 /* Print out a CHARACTER literal.  */
@@ -894,14 +933,8 @@
 static void
 pp_c_character_constant (c_pretty_printer *pp, tree c)
 {
-  tree type = TREE_TYPE (c);
-  if (type == wchar_type_node)
-    pp_character (pp, 'L');
   pp_quote (pp);
-  if (host_integerp (c, TYPE_UNSIGNED (type)))
-    pp_c_char (pp, tree_low_cst (c, TYPE_UNSIGNED (type)));
-  else
-    pp_scalar (pp, "\\x%x", (unsigned) TREE_INT_CST_LOW (c));
+  pp_c_char (pp, (unsigned) TREE_INT_CST_LOW (c));
   pp_quote (pp);
 }
 
@@ -953,7 +986,7 @@
     ;
 
   if (value != NULL_TREE)
-    pp_id_expression (pp, TREE_PURPOSE (value));
+    pp->id_expression (TREE_PURPOSE (value));
   else
     {
       /* Value must have been cast.  */
@@ -969,8 +1002,20 @@
 static void
 pp_c_floating_constant (c_pretty_printer *pp, tree r)
 {
+  const struct real_format *fmt
+    = REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (r)));
+
+  REAL_VALUE_TYPE floating_cst = TREE_REAL_CST (r);
+  bool is_decimal = floating_cst.decimal;
+
+  /* See ISO C++ WG N1822.  Note: The fraction 643/2136 approximates
+     log10(2) to 7 significant digits.  */
+  int max_digits10 = 2 + (is_decimal ? fmt->p : fmt->p * 643L / 2136);
+
   real_to_decimal (pp_buffer (pp)->digit_buffer, &TREE_REAL_CST (r),
-		   sizeof (pp_buffer (pp)->digit_buffer), 0, 1);
+		   sizeof (pp_buffer (pp)->digit_buffer),
+		   max_digits10, 1);
+
   pp_string (pp, pp_buffer(pp)->digit_buffer);
   if (TREE_TYPE (r) == float_type_node)
     pp_character (pp, 'f');
@@ -982,6 +1027,16 @@
     pp_string (pp, "dd");
   else if (TREE_TYPE (r) == dfloat32_type_node)
     pp_string (pp, "df");
+  else if (TREE_TYPE (r) != double_type_node)
+    for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
+      if (TREE_TYPE (r) == FLOATN_NX_TYPE_NODE (i))
+	{
+	  pp_character (pp, 'f');
+	  pp_decimal_int (pp, floatn_nx_types[i].n);
+	  if (floatn_nx_types[i].extended)
+	    pp_character (pp, 'x');
+	  break;
+	}
 }
 
 /* Print out a FIXED value as a decimal-floating-constant.  */
@@ -1041,7 +1096,7 @@
 	 == TREE_OPERAND (TREE_OPERAND (imagexpr, 0), 0))
     {
       pp_c_type_cast (pp, type);
-      pp_expression (pp, TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0));
+      pp->expression (TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0));
       return;
     }
 
@@ -1052,7 +1107,7 @@
       pp_c_type_cast (pp, type);
       if (TREE_CODE (realexpr) == NOP_EXPR)
 	realexpr = TREE_OPERAND (realexpr, 0);
-      pp_expression (pp, realexpr);
+      pp->expression (realexpr);
       return;
     }
 
@@ -1067,48 +1122,52 @@
       character-constant   */
 
 void
-pp_c_constant (c_pretty_printer *pp, tree e)
+c_pretty_printer::constant (tree e)
 {
   const enum tree_code code = TREE_CODE (e);
 
   switch (code)
     {
+    case VOID_CST:
+      pp_c_void_constant (this);
+      break;
+
     case INTEGER_CST:
       {
 	tree type = TREE_TYPE (e);
 	if (type == boolean_type_node)
-	  pp_c_bool_constant (pp, e);
+	  pp_c_bool_constant (this, e);
 	else if (type == char_type_node)
-	  pp_c_character_constant (pp, e);
+	  pp_c_character_constant (this, e);
 	else if (TREE_CODE (type) == ENUMERAL_TYPE
-		 && pp_c_enumeration_constant (pp, e))
+		 && pp_c_enumeration_constant (this, e))
 	  ;
 	else
-	  pp_c_integer_constant (pp, e);
+	  pp_c_integer_constant (this, e);
       }
       break;
 
     case REAL_CST:
-      pp_c_floating_constant (pp, e);
+      pp_c_floating_constant (this, e);
       break;
 
     case FIXED_CST:
-      pp_c_fixed_constant (pp, e);
+      pp_c_fixed_constant (this, e);
       break;
 
     case STRING_CST:
-      pp_c_string_literal (pp, e);
+      pp_c_string_literal (this, e);
       break;
 
     case COMPLEX_CST:
       /* Sometimes, we are confused and we think a complex literal
          is a constant.  Such thing is a compound literal which
          grammatically belongs to postfix-expr production.  */
-      pp_c_compound_literal (pp, e);
+      pp_c_compound_literal (this, e);
       break;
 
     default:
-      pp_unsupported_tree (pp, e);
+      pp_unsupported_tree (this, e);
       break;
     }
 }
@@ -1121,7 +1180,16 @@
 {
   pp_c_maybe_whitespace (pp);
   pp_string (pp, str);
-  pp_base (pp)->padding = pp_before;
+  pp->padding = pp_before;
+}
+
+void
+c_pretty_printer::translate_string (const char *gmsgid)
+{
+  if (pp_translate_identifiers (this))
+    pp_c_ws_string (this, _(gmsgid));
+  else
+    pp_c_ws_string (this, gmsgid);
 }
 
 /* Pretty-print an IDENTIFIER_NODE, which may contain UTF-8 sequences
@@ -1133,7 +1201,7 @@
 {
   pp_c_maybe_whitespace (pp);
   pp_identifier (pp, id);
-  pp_base (pp)->padding = pp_before;
+  pp->padding = pp_before;
 }
 
 /* Pretty-print a C primary-expression.
@@ -1144,7 +1212,7 @@
       ( expression )   */
 
 void
-pp_c_primary_expression (c_pretty_printer *pp, tree e)
+c_pretty_printer::primary_expression (tree e)
 {
   switch (TREE_CODE (e))
     {
@@ -1154,49 +1222,50 @@
     case CONST_DECL:
     case FUNCTION_DECL:
     case LABEL_DECL:
-      pp_c_tree_decl_identifier (pp, e);
+      pp_c_tree_decl_identifier (this, e);
       break;
 
     case IDENTIFIER_NODE:
-      pp_c_tree_identifier (pp, e);
+      pp_c_tree_identifier (this, e);
       break;
 
     case ERROR_MARK:
-      pp_c_ws_string (pp, M_("<erroneous-expression>"));
+      translate_string ("<erroneous-expression>");
       break;
 
     case RESULT_DECL:
-      pp_c_ws_string (pp, M_("<return-value>"));
+      translate_string ("<return-value>");
       break;
 
+    case VOID_CST:
     case INTEGER_CST:
     case REAL_CST:
     case FIXED_CST:
     case STRING_CST:
-      pp_c_constant (pp, e);
+      constant (e);
       break;
 
     case TARGET_EXPR:
-      pp_c_ws_string (pp, "__builtin_memcpy");
-      pp_c_left_paren (pp);
-      pp_ampersand (pp);
-      pp_primary_expression (pp, TREE_OPERAND (e, 0));
-      pp_separate_with (pp, ',');
-      pp_ampersand (pp);
-      pp_initializer (pp, TREE_OPERAND (e, 1));
+      pp_c_ws_string (this, "__builtin_memcpy");
+      pp_c_left_paren (this);
+      pp_ampersand (this);
+      primary_expression (TREE_OPERAND (e, 0));
+      pp_separate_with (this, ',');
+      pp_ampersand (this);
+      initializer (TREE_OPERAND (e, 1));
       if (TREE_OPERAND (e, 2))
 	{
-	  pp_separate_with (pp, ',');
-	  pp_c_expression (pp, TREE_OPERAND (e, 2));
+	  pp_separate_with (this, ',');
+	  expression (TREE_OPERAND (e, 2));
 	}
-      pp_c_right_paren (pp);
+      pp_c_right_paren (this);
       break;
 
     default:
       /* FIXME:  Make sure we won't get into an infinite loop.  */
-      pp_c_left_paren (pp);
-      pp_expression (pp, e);
-      pp_c_right_paren (pp);
+      pp_c_left_paren (this);
+      expression (e);
+      pp_c_right_paren (this);
       break;
     }
 }
@@ -1207,13 +1276,13 @@
       { initializer-list }
       { initializer-list , }   */
 
-static void
-pp_c_initializer (c_pretty_printer *pp, tree e)
+void
+c_pretty_printer::initializer (tree e)
 {
   if (TREE_CODE (e) == CONSTRUCTOR)
-    pp_c_brace_enclosed_initializer_list (pp, e);
+    pp_c_brace_enclosed_initializer_list (this, e);
   else
-    pp_expression (pp, e);
+    expression (e);
 }
 
 /* init-declarator:
@@ -1223,7 +1292,7 @@
 void
 pp_c_init_declarator (c_pretty_printer *pp, tree t)
 {
-  pp_declarator (pp, t);
+  pp->declarator (t);
   /* We don't want to output function definitions here.  There are handled
      elsewhere (and the syntactic form is bogus anyway).  */
   if (TREE_CODE (t) != FUNCTION_DECL && DECL_INITIAL (t))
@@ -1236,7 +1305,7 @@
       if (TREE_CODE (init) == TREE_LIST)
 	{
 	  pp_c_left_paren (pp);
-	  pp_expression (pp, TREE_VALUE (init));
+	  pp->expression (TREE_VALUE (init));
 	  pp_right_paren (pp);
 	}
       else
@@ -1244,7 +1313,7 @@
 	  pp_space (pp);
 	  pp_equal (pp);
 	  pp_space (pp);
-	  pp_c_initializer (pp, init);
+	  pp->initializer (init);
 	}
     }
 }
@@ -1288,19 +1357,19 @@
 	    if (code == RECORD_TYPE || code == UNION_TYPE)
 	      {
 		pp_c_dot (pp);
-		pp_c_primary_expression (pp, TREE_PURPOSE (init));
+		pp->primary_expression (TREE_PURPOSE (init));
 	      }
 	    else
 	      {
 		pp_c_left_bracket (pp);
 		if (TREE_PURPOSE (init))
-		  pp_c_constant (pp, TREE_PURPOSE (init));
+		  pp->constant (TREE_PURPOSE (init));
 		pp_c_right_bracket (pp);
 	      }
 	    pp_c_whitespace (pp);
 	    pp_equal (pp);
 	    pp_c_whitespace (pp);
-	    pp_initializer (pp, TREE_VALUE (init));
+	    pp->initializer (TREE_VALUE (init));
 	    if (TREE_CHAIN (init))
 	      pp_separate_with (pp, ',');
 	  }
@@ -1309,7 +1378,15 @@
 
     case VECTOR_TYPE:
       if (TREE_CODE (e) == VECTOR_CST)
-	pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e));
+	{
+	  unsigned i;
+	  for (i = 0; i < VECTOR_CST_NELTS (e); ++i)
+	    {
+	      if (i > 0)
+		pp_separate_with (pp, ',');
+	      pp->expression (VECTOR_CST_ELT (e, i));
+	    }
+	}
       else
 	break;
       return;
@@ -1318,9 +1395,9 @@
       if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR)
 	{
 	  const bool cst = TREE_CODE (e) == COMPLEX_CST;
-	  pp_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
+	  pp->expression (cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
 	  pp_separate_with (pp, ',');
-	  pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
+	  pp->expression (cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
 	}
       else
 	break;
@@ -1351,7 +1428,7 @@
        identifier  */
 
 void
-pp_c_id_expression (c_pretty_printer *pp, tree t)
+c_pretty_printer::id_expression (tree t)
 {
   switch (TREE_CODE (t))
     {
@@ -1362,15 +1439,15 @@
     case FUNCTION_DECL:
     case FIELD_DECL:
     case LABEL_DECL:
-      pp_c_tree_decl_identifier (pp, t);
+      pp_c_tree_decl_identifier (this, t);
       break;
 
     case IDENTIFIER_NODE:
-      pp_c_tree_identifier (pp, t);
+      pp_c_tree_identifier (this, t);
       break;
 
     default:
-      pp_unsupported_tree (pp, t);
+      pp_unsupported_tree (this, t);
       break;
     }
 }
@@ -1387,117 +1464,136 @@
       ( type-name ) { initializer-list , }  */
 
 void
-pp_c_postfix_expression (c_pretty_printer *pp, tree e)
+c_pretty_printer::postfix_expression (tree e)
 {
   enum tree_code code = TREE_CODE (e);
   switch (code)
     {
     case POSTINCREMENT_EXPR:
     case POSTDECREMENT_EXPR:
-      pp_postfix_expression (pp, TREE_OPERAND (e, 0));
-      pp_string (pp, code == POSTINCREMENT_EXPR ? "++" : "--");
+      postfix_expression (TREE_OPERAND (e, 0));
+      pp_string (this, code == POSTINCREMENT_EXPR ? "++" : "--");
       break;
 
     case ARRAY_REF:
-      pp_postfix_expression (pp, TREE_OPERAND (e, 0));
-      pp_c_left_bracket (pp);
-      pp_expression (pp, TREE_OPERAND (e, 1));
-      pp_c_right_bracket (pp);
+      postfix_expression (TREE_OPERAND (e, 0));
+      pp_c_left_bracket (this);
+      expression (TREE_OPERAND (e, 1));
+      pp_c_right_bracket (this);
       break;
 
+    case ARRAY_NOTATION_REF:
+      postfix_expression (ARRAY_NOTATION_ARRAY (e));
+      pp_c_left_bracket (this);
+      expression (ARRAY_NOTATION_START (e));
+      pp_colon (this);
+      expression (ARRAY_NOTATION_LENGTH (e));
+      pp_colon (this);
+      expression (ARRAY_NOTATION_STRIDE (e));
+      pp_c_right_bracket (this);
+      break;
+      
     case CALL_EXPR:
       {
 	call_expr_arg_iterator iter;
 	tree arg;
-	pp_postfix_expression (pp, CALL_EXPR_FN (e));
-	pp_c_left_paren (pp);
+	postfix_expression (CALL_EXPR_FN (e));
+	pp_c_left_paren (this);
 	FOR_EACH_CALL_EXPR_ARG (arg, iter, e)
 	  {
-	    pp_expression (pp, arg);
+	    expression (arg);
 	    if (more_call_expr_args_p (&iter))
-	      pp_separate_with (pp, ',');
+	      pp_separate_with (this, ',');
 	  }
-	pp_c_right_paren (pp);
+	pp_c_right_paren (this);
 	break;
       }
 
     case UNORDERED_EXPR:
-      pp_c_ws_string (pp, flag_isoc99
+      pp_c_ws_string (this, flag_isoc99
 			   ? "isunordered"
 			   : "__builtin_isunordered");
       goto two_args_fun;
 
     case ORDERED_EXPR:
-      pp_c_ws_string (pp, flag_isoc99
+      pp_c_ws_string (this, flag_isoc99
 			   ? "!isunordered"
 			   : "!__builtin_isunordered");
       goto two_args_fun;
 
     case UNLT_EXPR:
-      pp_c_ws_string (pp, flag_isoc99
+      pp_c_ws_string (this, flag_isoc99
 			   ? "!isgreaterequal"
 			   : "!__builtin_isgreaterequal");
       goto two_args_fun;
 
     case UNLE_EXPR:
-      pp_c_ws_string (pp, flag_isoc99
+      pp_c_ws_string (this, flag_isoc99
 			   ? "!isgreater"
 			   : "!__builtin_isgreater");
       goto two_args_fun;
 
     case UNGT_EXPR:
-      pp_c_ws_string (pp, flag_isoc99
+      pp_c_ws_string (this, flag_isoc99
 			   ? "!islessequal"
 			   : "!__builtin_islessequal");
       goto two_args_fun;
 
     case UNGE_EXPR:
-      pp_c_ws_string (pp, flag_isoc99
+      pp_c_ws_string (this, flag_isoc99
 			   ? "!isless"
 			   : "!__builtin_isless");
       goto two_args_fun;
 
     case UNEQ_EXPR:
-      pp_c_ws_string (pp, flag_isoc99
+      pp_c_ws_string (this, flag_isoc99
 			   ? "!islessgreater"
 			   : "!__builtin_islessgreater");
       goto two_args_fun;
 
     case LTGT_EXPR:
-      pp_c_ws_string (pp, flag_isoc99
+      pp_c_ws_string (this, flag_isoc99
 			   ? "islessgreater"
 			   : "__builtin_islessgreater");
       goto two_args_fun;
 
+    case MAX_EXPR:
+      pp_c_ws_string (this, "max");
+      goto two_args_fun;
+
+    case MIN_EXPR:
+      pp_c_ws_string (this, "min");
+      goto two_args_fun;
+
     two_args_fun:
-      pp_c_left_paren (pp);
-      pp_expression (pp, TREE_OPERAND (e, 0));
-      pp_separate_with (pp, ',');
-      pp_expression (pp, TREE_OPERAND (e, 1));
-      pp_c_right_paren (pp);
+      pp_c_left_paren (this);
+      expression (TREE_OPERAND (e, 0));
+      pp_separate_with (this, ',');
+      expression (TREE_OPERAND (e, 1));
+      pp_c_right_paren (this);
       break;
 
     case ABS_EXPR:
-      pp_c_ws_string (pp, "__builtin_abs");
-      pp_c_left_paren (pp);
-      pp_expression (pp, TREE_OPERAND (e, 0));
-      pp_c_right_paren (pp);
+      pp_c_ws_string (this, "__builtin_abs");
+      pp_c_left_paren (this);
+      expression (TREE_OPERAND (e, 0));
+      pp_c_right_paren (this);
       break;
 
     case COMPONENT_REF:
       {
 	tree object = TREE_OPERAND (e, 0);
-	if (TREE_CODE (object) == INDIRECT_REF)
+	if (INDIRECT_REF_P (object))
 	  {
-	    pp_postfix_expression (pp, TREE_OPERAND (object, 0));
-	    pp_c_arrow (pp);
+	    postfix_expression (TREE_OPERAND (object, 0));
+	    pp_c_arrow (this);
 	  }
 	else
 	  {
-	    pp_postfix_expression (pp, object);
-	    pp_c_dot (pp);
+	    postfix_expression (object);
+	    pp_c_dot (this);
 	  }
-	pp_expression (pp, TREE_OPERAND (e, 1));
+	expression (TREE_OPERAND (e, 1));
       }
       break;
 
@@ -1509,67 +1605,67 @@
 	if (type
 	    && tree_int_cst_equal (TYPE_SIZE (type), TREE_OPERAND (e, 1)))
 	  {
-	    HOST_WIDE_INT bitpos = tree_low_cst (TREE_OPERAND (e, 2), 0);
-	    HOST_WIDE_INT size = tree_low_cst (TYPE_SIZE (type), 0);
+	    HOST_WIDE_INT bitpos = tree_to_shwi (TREE_OPERAND (e, 2));
+	    HOST_WIDE_INT size = tree_to_shwi (TYPE_SIZE (type));
 	    if ((bitpos % size) == 0)
 	      {
-		pp_c_left_paren (pp);
-		pp_c_left_paren (pp);
-		pp_type_id (pp, type);
-		pp_c_star (pp);
-		pp_c_right_paren (pp);
-		pp_c_ampersand (pp);
-		pp_expression (pp, TREE_OPERAND (e, 0));
-		pp_c_right_paren (pp);
-		pp_c_left_bracket (pp);
-		pp_wide_integer (pp, bitpos / size);
-		pp_c_right_bracket (pp);
+		pp_c_left_paren (this);
+		pp_c_left_paren (this);
+		type_id (type);
+		pp_c_star (this);
+		pp_c_right_paren (this);
+		pp_c_ampersand (this);
+		expression (TREE_OPERAND (e, 0));
+		pp_c_right_paren (this);
+		pp_c_left_bracket (this);
+		pp_wide_integer (this, bitpos / size);
+		pp_c_right_bracket (this);
 		break;
 	      }
 	  }
-	pp_unsupported_tree (pp, e);
+	pp_unsupported_tree (this, e);
       }
       break;
 
     case MEM_REF:
-      pp_c_expression (pp, e);
+      expression (e);
       break;
 
     case COMPLEX_CST:
     case VECTOR_CST:
-      pp_c_compound_literal (pp, e);
+      pp_c_compound_literal (this, e);
       break;
 
     case COMPLEX_EXPR:
-      pp_c_complex_expr (pp, e);
+      pp_c_complex_expr (this, e);
       break;
 
     case COMPOUND_LITERAL_EXPR:
       e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e));
       /* Fall through.  */
     case CONSTRUCTOR:
-      pp_initializer (pp, e);
+      initializer (e);
       break;
 
     case VA_ARG_EXPR:
-      pp_c_ws_string (pp, "__builtin_va_arg");
-      pp_c_left_paren (pp);
-      pp_assignment_expression (pp, TREE_OPERAND (e, 0));
-      pp_separate_with (pp, ',');
-      pp_type_id (pp, TREE_TYPE (e));
-      pp_c_right_paren (pp);
+      pp_c_ws_string (this, "__builtin_va_arg");
+      pp_c_left_paren (this);
+      assignment_expression (TREE_OPERAND (e, 0));
+      pp_separate_with (this, ',');
+      type_id (TREE_TYPE (e));
+      pp_c_right_paren (this);
       break;
 
     case ADDR_EXPR:
       if (TREE_CODE (TREE_OPERAND (e, 0)) == FUNCTION_DECL)
 	{
-	  pp_c_id_expression (pp, TREE_OPERAND (e, 0));
+          id_expression (TREE_OPERAND (e, 0));
 	  break;
 	}
-      /* else fall through.  */
+      /* fall through.  */
 
     default:
-      pp_primary_expression (pp, e);
+      primary_expression (e);
       break;
     }
 }
@@ -1581,7 +1677,7 @@
 {
   for (; e != NULL_TREE; e = TREE_CHAIN (e))
     {
-      pp_expression (pp, TREE_VALUE (e));
+      pp->expression (TREE_VALUE (e));
       if (TREE_CHAIN (e))
 	pp_separate_with (pp, ',');
     }
@@ -1590,15 +1686,15 @@
 /* Print out V, which contains the elements of a constructor.  */
 
 void
-pp_c_constructor_elts (c_pretty_printer *pp, VEC(constructor_elt,gc) *v)
+pp_c_constructor_elts (c_pretty_printer *pp, vec<constructor_elt, va_gc> *v)
 {
   unsigned HOST_WIDE_INT ix;
   tree value;
 
   FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value)
     {
-      pp_expression (pp, value);
-      if (ix != VEC_length (constructor_elt, v) - 1)
+      pp->expression (value);
+      if (ix != vec_safe_length (v) - 1)
 	pp_separate_with (pp, ',');
     }
 }
@@ -1634,15 +1730,15 @@
       __imag__ unary-expression  */
 
 void
-pp_c_unary_expression (c_pretty_printer *pp, tree e)
+c_pretty_printer::unary_expression (tree e)
 {
   enum tree_code code = TREE_CODE (e);
   switch (code)
     {
     case PREINCREMENT_EXPR:
     case PREDECREMENT_EXPR:
-      pp_string (pp, code == PREINCREMENT_EXPR ? "++" : "--");
-      pp_c_unary_expression (pp, TREE_OPERAND (e, 0));
+      pp_string (this, code == PREINCREMENT_EXPR ? "++" : "--");
+      unary_expression (TREE_OPERAND (e, 0));
       break;
 
     case ADDR_EXPR:
@@ -1653,53 +1749,59 @@
     case CONJ_EXPR:
       /* String literal are used by address.  */
       if (code == ADDR_EXPR && TREE_CODE (TREE_OPERAND (e, 0)) != STRING_CST)
-	pp_ampersand (pp);
+	pp_ampersand (this);
       else if (code == INDIRECT_REF)
-	pp_c_star (pp);
+	{
+	  tree type = TREE_TYPE (TREE_OPERAND (e, 0));
+	  if (type && TREE_CODE (type) == REFERENCE_TYPE)
+	    /* Reference decay is implicit, don't print anything.  */;
+	  else
+	    pp_c_star (this);
+	}
       else if (code == NEGATE_EXPR)
-	pp_minus (pp);
+	pp_minus (this);
       else if (code == BIT_NOT_EXPR || code == CONJ_EXPR)
-	pp_complement (pp);
+	pp_complement (this);
       else if (code == TRUTH_NOT_EXPR)
-	pp_exclamation (pp);
-      pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
+	pp_exclamation (this);
+      pp_c_cast_expression (this, TREE_OPERAND (e, 0));
       break;
 
     case MEM_REF:
       if (TREE_CODE (TREE_OPERAND (e, 0)) == ADDR_EXPR
 	  && integer_zerop (TREE_OPERAND (e, 1)))
-	pp_c_expression (pp, TREE_OPERAND (TREE_OPERAND (e, 0), 0));
+	expression (TREE_OPERAND (TREE_OPERAND (e, 0), 0));
       else
 	{
-	  pp_c_star (pp);
+	  pp_c_star (this);
 	  if (!integer_zerop (TREE_OPERAND (e, 1)))
 	    {
-	      pp_c_left_paren (pp);
+	      pp_c_left_paren (this);
 	      if (!integer_onep (TYPE_SIZE_UNIT
 				 (TREE_TYPE (TREE_TYPE (TREE_OPERAND (e, 0))))))
-		pp_c_type_cast (pp, ptr_type_node);
+		pp_c_type_cast (this, ptr_type_node);
 	    }
-	  pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
+	  pp_c_cast_expression (this, TREE_OPERAND (e, 0));
 	  if (!integer_zerop (TREE_OPERAND (e, 1)))
 	    {
-	      pp_plus (pp);
-	      pp_c_integer_constant (pp,
+	      pp_plus (this);
+	      pp_c_integer_constant (this,
 				     fold_convert (ssizetype,
 						   TREE_OPERAND (e, 1)));
-	      pp_c_right_paren (pp);
+	      pp_c_right_paren (this);
 	    }
 	}
       break;
 
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      pp_c_ws_string (pp, code == REALPART_EXPR ? "__real__" : "__imag__");
-      pp_c_whitespace (pp);
-      pp_unary_expression (pp, TREE_OPERAND (e, 0));
+      pp_c_ws_string (this, code == REALPART_EXPR ? "__real__" : "__imag__");
+      pp_c_whitespace (this);
+      unary_expression (TREE_OPERAND (e, 0));
       break;
 
     default:
-      pp_postfix_expression (pp, e);
+      postfix_expression (e);
       break;
     }
 }
@@ -1722,7 +1824,7 @@
       break;
 
     default:
-      pp_unary_expression (pp, e);
+      pp->unary_expression (e);
     }
 }
 
@@ -1732,8 +1834,8 @@
       multiplicative-expression / cast-expression
       multiplicative-expression % cast-expression   */
 
-static void
-pp_c_multiplicative_expression (c_pretty_printer *pp, tree e)
+void
+c_pretty_printer::multiplicative_expression (tree e)
 {
   enum tree_code code = TREE_CODE (e);
   switch (code)
@@ -1741,20 +1843,22 @@
     case MULT_EXPR:
     case TRUNC_DIV_EXPR:
     case TRUNC_MOD_EXPR:
-      pp_multiplicative_expression (pp, TREE_OPERAND (e, 0));
-      pp_c_whitespace (pp);
+    case EXACT_DIV_EXPR:
+    case RDIV_EXPR:
+      multiplicative_expression (TREE_OPERAND (e, 0));
+      pp_c_whitespace (this);
       if (code == MULT_EXPR)
-	pp_c_star (pp);
+	pp_c_star (this);
       else if (code == TRUNC_DIV_EXPR)
-	pp_slash (pp);
+	pp_slash (this);
       else
-	pp_modulo (pp);
-      pp_c_whitespace (pp);
-      pp_c_cast_expression (pp, TREE_OPERAND (e, 1));
+	pp_modulo (this);
+      pp_c_whitespace (this);
+      pp_c_cast_expression (this, TREE_OPERAND (e, 1));
       break;
 
     default:
-      pp_c_cast_expression (pp, e);
+      pp_c_cast_expression (this, e);
       break;
     }
 }
@@ -1780,11 +1884,11 @@
       else
 	pp_minus (pp);
       pp_c_whitespace (pp);
-      pp_multiplicative_expression (pp, TREE_OPERAND (e, 1));
+      pp->multiplicative_expression (TREE_OPERAND (e, 1));
       break;
 
     default:
-      pp_multiplicative_expression (pp, e);
+      pp->multiplicative_expression (e);
       break;
     }
 }
@@ -1802,9 +1906,13 @@
     {
     case LSHIFT_EXPR:
     case RSHIFT_EXPR:
+    case LROTATE_EXPR:
+    case RROTATE_EXPR:
       pp_c_shift_expression (pp, TREE_OPERAND (e, 0));
       pp_c_whitespace (pp);
-      pp_string (pp, code == LSHIFT_EXPR ? "<<" : ">>");
+      pp_string (pp, code == LSHIFT_EXPR ? "<<" :
+		     code == RSHIFT_EXPR ? ">>" :
+		     code == LROTATE_EXPR ? "<<<" : ">>>");
       pp_c_whitespace (pp);
       pp_c_additive_expression (pp, TREE_OPERAND (e, 1));
       break;
@@ -1838,9 +1946,9 @@
       else if (code == GT_EXPR)
 	pp_greater (pp);
       else if (code == LE_EXPR)
-	pp_string (pp, "<=");
+	pp_less_equal (pp);
       else if (code == GE_EXPR)
-	pp_string (pp, ">=");
+	pp_greater_equal (pp);
       pp_c_whitespace (pp);
       pp_c_shift_expression (pp, TREE_OPERAND (e, 1));
       break;
@@ -1950,7 +2058,7 @@
     {
       pp_c_logical_and_expression (pp, TREE_OPERAND (e, 0));
       pp_c_whitespace (pp);
-      pp_string (pp, "&&");
+      pp_ampersand_ampersand (pp);
       pp_c_whitespace (pp);
       pp_c_inclusive_or_expression (pp, TREE_OPERAND (e, 1));
     }
@@ -1970,7 +2078,7 @@
     {
       pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
       pp_c_whitespace (pp);
-      pp_string (pp, "||");
+      pp_bar_bar (pp);
       pp_c_whitespace (pp);
       pp_c_logical_and_expression (pp, TREE_OPERAND (e, 1));
     }
@@ -1982,23 +2090,23 @@
       logical-OR-expression
       logical-OR-expression ? expression : conditional-expression  */
 
-static void
-pp_c_conditional_expression (c_pretty_printer *pp, tree e)
+void
+c_pretty_printer::conditional_expression (tree e)
 {
   if (TREE_CODE (e) == COND_EXPR)
     {
-      pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
-      pp_c_whitespace (pp);
-      pp_question (pp);
-      pp_c_whitespace (pp);
-      pp_expression (pp, TREE_OPERAND (e, 1));
-      pp_c_whitespace (pp);
-      pp_colon (pp);
-      pp_c_whitespace (pp);
-      pp_c_conditional_expression (pp, TREE_OPERAND (e, 2));
+      pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
+      pp_c_whitespace (this);
+      pp_question (this);
+      pp_c_whitespace (this);
+      expression (TREE_OPERAND (e, 1));
+      pp_c_whitespace (this);
+      pp_colon (this);
+      pp_c_whitespace (this);
+      conditional_expression (TREE_OPERAND (e, 2));
     }
   else
-    pp_c_logical_or_expression (pp, e);
+    pp_c_logical_or_expression (this, e);
 }
 
 
@@ -2009,20 +2117,20 @@
    assignment-expression: one of
       =    *=    /=    %=    +=    -=    >>=    <<=    &=    ^=    |=  */
 
-static void
-pp_c_assignment_expression (c_pretty_printer *pp, tree e)
+void
+c_pretty_printer::assignment_expression (tree e)
 {
   if (TREE_CODE (e) == MODIFY_EXPR
       || TREE_CODE (e) == INIT_EXPR)
     {
-      pp_c_unary_expression (pp, TREE_OPERAND (e, 0));
-      pp_c_whitespace (pp);
-      pp_equal (pp);
-      pp_space (pp);
-      pp_c_expression (pp, TREE_OPERAND (e, 1));
+      unary_expression (TREE_OPERAND (e, 0));
+      pp_c_whitespace (this);
+      pp_equal (this);
+      pp_space (this);
+      expression (TREE_OPERAND (e, 1));
     }
   else
-    pp_c_conditional_expression (pp, e);
+    conditional_expression (e);
 }
 
 /* expression:
@@ -2032,28 +2140,32 @@
   Implementation note:  instead of going through the usual recursion
   chain, I take the liberty of dispatching nodes to the appropriate
   functions.  This makes some redundancy, but it worths it. That also
-  prevents a possible infinite recursion between pp_c_primary_expression ()
-  and pp_c_expression ().  */
+  prevents a possible infinite recursion between primary_expression ()
+  and expression ().  */
 
 void
-pp_c_expression (c_pretty_printer *pp, tree e)
+c_pretty_printer::expression (tree e)
 {
   switch (TREE_CODE (e))
     {
+    case VOID_CST:
+      pp_c_void_constant (this);
+      break;
+
     case INTEGER_CST:
-      pp_c_integer_constant (pp, e);
+      pp_c_integer_constant (this, e);
       break;
 
     case REAL_CST:
-      pp_c_floating_constant (pp, e);
+      pp_c_floating_constant (this, e);
       break;
 
     case FIXED_CST:
-      pp_c_fixed_constant (pp, e);
+      pp_c_fixed_constant (this, e);
       break;
 
     case STRING_CST:
-      pp_c_string_literal (pp, e);
+      pp_c_string_literal (this, e);
       break;
 
     case IDENTIFIER_NODE:
@@ -2065,12 +2177,21 @@
     case FIELD_DECL:
     case LABEL_DECL:
     case ERROR_MARK:
-      pp_primary_expression (pp, e);
+      primary_expression (e);
+      break;
+
+    case SSA_NAME:
+      if (SSA_NAME_VAR (e)
+	  && !DECL_ARTIFICIAL (SSA_NAME_VAR (e)))
+	expression (SSA_NAME_VAR (e));
+      else
+	translate_string ("<unknown>");
       break;
 
     case POSTINCREMENT_EXPR:
     case POSTDECREMENT_EXPR:
     case ARRAY_REF:
+    case ARRAY_NOTATION_REF:
     case CALL_EXPR:
     case COMPONENT_REF:
     case BIT_FIELD_REF:
@@ -2085,11 +2206,13 @@
     case UNLT_EXPR:
     case UNGE_EXPR:
     case UNGT_EXPR:
+    case MAX_EXPR:
+    case MIN_EXPR:
     case ABS_EXPR:
     case CONSTRUCTOR:
     case COMPOUND_LITERAL_EXPR:
     case VA_ARG_EXPR:
-      pp_postfix_expression (pp, e);
+      postfix_expression (e);
       break;
 
     case CONJ_EXPR:
@@ -2103,107 +2226,111 @@
     case PREDECREMENT_EXPR:
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      pp_c_unary_expression (pp, e);
+      unary_expression (e);
       break;
 
     case FLOAT_EXPR:
     case FIX_TRUNC_EXPR:
     CASE_CONVERT:
     case VIEW_CONVERT_EXPR:
-      pp_c_cast_expression (pp, e);
+      pp_c_cast_expression (this, e);
       break;
 
     case MULT_EXPR:
     case TRUNC_MOD_EXPR:
     case TRUNC_DIV_EXPR:
-      pp_multiplicative_expression (pp, e);
+    case EXACT_DIV_EXPR:
+    case RDIV_EXPR:
+      multiplicative_expression (e);
       break;
 
     case LSHIFT_EXPR:
     case RSHIFT_EXPR:
-      pp_c_shift_expression (pp, e);
+    case LROTATE_EXPR:
+    case RROTATE_EXPR:
+      pp_c_shift_expression (this, e);
       break;
 
     case LT_EXPR:
     case GT_EXPR:
     case LE_EXPR:
     case GE_EXPR:
-      pp_c_relational_expression (pp, e);
+      pp_c_relational_expression (this, e);
       break;
 
     case BIT_AND_EXPR:
-      pp_c_and_expression (pp, e);
+      pp_c_and_expression (this, e);
       break;
 
     case BIT_XOR_EXPR:
     case TRUTH_XOR_EXPR:
-      pp_c_exclusive_or_expression (pp, e);
+      pp_c_exclusive_or_expression (this, e);
       break;
 
     case BIT_IOR_EXPR:
-      pp_c_inclusive_or_expression (pp, e);
+      pp_c_inclusive_or_expression (this, e);
       break;
 
     case TRUTH_ANDIF_EXPR:
     case TRUTH_AND_EXPR:
-      pp_c_logical_and_expression (pp, e);
+      pp_c_logical_and_expression (this, e);
       break;
 
     case TRUTH_ORIF_EXPR:
     case TRUTH_OR_EXPR:
-      pp_c_logical_or_expression (pp, e);
+      pp_c_logical_or_expression (this, e);
       break;
 
     case EQ_EXPR:
     case NE_EXPR:
-      pp_c_equality_expression (pp, e);
+      pp_c_equality_expression (this, e);
       break;
 
     case COND_EXPR:
-      pp_conditional_expression (pp, e);
+      conditional_expression (e);
       break;
 
     case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
-      pp_c_additive_expression (pp, e);
+      pp_c_additive_expression (this, e);
       break;
 
     case MODIFY_EXPR:
     case INIT_EXPR:
-      pp_assignment_expression (pp, e);
+      assignment_expression (e);
       break;
 
     case COMPOUND_EXPR:
-      pp_c_left_paren (pp);
-      pp_expression (pp, TREE_OPERAND (e, 0));
-      pp_separate_with (pp, ',');
-      pp_assignment_expression (pp, TREE_OPERAND (e, 1));
-      pp_c_right_paren (pp);
+      pp_c_left_paren (this);
+      expression (TREE_OPERAND (e, 0));
+      pp_separate_with (this, ',');
+      assignment_expression (TREE_OPERAND (e, 1));
+      pp_c_right_paren (this);
       break;
 
     case NON_LVALUE_EXPR:
     case SAVE_EXPR:
-      pp_expression (pp, TREE_OPERAND (e, 0));
+      expression (TREE_OPERAND (e, 0));
       break;
 
     case TARGET_EXPR:
-      pp_postfix_expression (pp, TREE_OPERAND (e, 1));
+      postfix_expression (TREE_OPERAND (e, 1));
       break;
 
     case BIND_EXPR:
     case GOTO_EXPR:
       /* We don't yet have a way of dumping statements in a
          human-readable format.  */
-      pp_string (pp, "({...})");
+      pp_string (this, "({...})");
       break;
 
     case C_MAYBE_CONST_EXPR:
-      pp_c_expression (pp, C_MAYBE_CONST_EXPR_EXPR (e));
+      expression (C_MAYBE_CONST_EXPR_EXPR (e));
       break;
 
     default:
-      pp_unsupported_tree (pp, e);
+      pp_unsupported_tree (this, e);
       break;
     }
 }
@@ -2213,51 +2340,28 @@
 /* Statements.  */
 
 void
-pp_c_statement (c_pretty_printer *pp, tree stmt)
+c_pretty_printer::statement (tree stmt)
 {
   if (stmt == NULL)
     return;
 
-  if (pp_needs_newline (pp))
-    pp_newline_and_indent (pp, 0);
+  if (pp_needs_newline (this))
+    pp_newline_and_indent (this, 0);
 
-  dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true);
+  dump_generic_node (this, stmt, pp_indentation (this), 0, true);
 }
 
 
 /* Initialize the PRETTY-PRINTER for handling C codes.  */
 
-void
-pp_c_pretty_printer_init (c_pretty_printer *pp)
+c_pretty_printer::c_pretty_printer ()
+  : pretty_printer (),
+    offset_list (),
+    flags ()
 {
-  pp->offset_list               = 0;
-
-  pp->declaration               = pp_c_declaration;
-  pp->declaration_specifiers    = pp_c_declaration_specifiers;
-  pp->declarator                = pp_c_declarator;
-  pp->direct_declarator         = pp_c_direct_declarator;
-  pp->type_specifier_seq        = pp_c_specifier_qualifier_list;
-  pp->abstract_declarator       = pp_c_abstract_declarator;
-  pp->direct_abstract_declarator = pp_c_direct_abstract_declarator;
-  pp->ptr_operator              = pp_c_pointer;
-  pp->parameter_list            = pp_c_parameter_type_list;
-  pp->type_id                   = pp_c_type_id;
-  pp->simple_type_specifier     = pp_c_type_specifier;
-  pp->function_specifier        = pp_c_function_specifier;
-  pp->storage_class_specifier   = pp_c_storage_class_specifier;
-
-  pp->statement                 = pp_c_statement;
-
-  pp->constant                  = pp_c_constant;
-  pp->id_expression             = pp_c_id_expression;
-  pp->primary_expression        = pp_c_primary_expression;
-  pp->postfix_expression        = pp_c_postfix_expression;
-  pp->unary_expression          = pp_c_unary_expression;
-  pp->initializer               = pp_c_initializer;
-  pp->multiplicative_expression = pp_c_multiplicative_expression;
-  pp->conditional_expression    = pp_c_conditional_expression;
-  pp->assignment_expression     = pp_c_assignment_expression;
-  pp->expression                = pp_c_expression;
+  type_specifier_seq        = pp_c_specifier_qualifier_list;
+  ptr_operator              = pp_c_pointer;
+  parameter_list            = pp_c_parameter_type_list;
 }
 
 
@@ -2266,23 +2370,12 @@
 void
 print_c_tree (FILE *file, tree t)
 {
-  static c_pretty_printer pp_rec;
-  static bool initialized = 0;
-  c_pretty_printer *pp = &pp_rec;
+  c_pretty_printer pp;
 
-  if (!initialized)
-    {
-      initialized = 1;
-      pp_construct (pp_base (pp), NULL, 0);
-      pp_c_pretty_printer_init (pp);
-      pp_needs_newline (pp) = true;
-    }
-  pp_base (pp)->buffer->stream = file;
-
-  pp_statement (pp, t);
-
-  pp_newline (pp);
-  pp_flush (pp);
+  pp_needs_newline (&pp) = true;
+  pp.buffer->stream = file;
+  pp.statement (t);
+  pp_newline_and_flush (&pp);
 }
 
 /* Print the tree T in full, on stderr.  */
@@ -2309,7 +2402,8 @@
   else
     {
       static char xname[8];
-      sprintf (xname, "<U%4x>", ((unsigned)((uintptr_t)(t) & 0xffff)));
+      sprintf (xname, "<U%4hx>", ((unsigned short) ((uintptr_t) (t)
+						    & 0xffff)));
       name = xname;
     }