This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ast-optimizer-branch] Print trees in C syntax


On Tue, Nov 27, 2001 at 01:27:13PM +0100, Gabriel Dos Reis wrote:
> What about:
>   1) creating a new file -- say c-pretty-print.c
That was the simplest step.

>   2) move some bits from cp/errors.c into c-pretty-print.c
Hmm, I think I'll keep the big switch and avoid working with small specialized functions.
There're lot of interesting things in cp/error.c (like the handling template names, ...),
but I need some more time to finish...

>   3) make your routines take an 'output_buffer *'
Done.

>   4) make both C and C++ front-end aware of c-pretty-print.c
Hmm, here I need some more help : I don't want to break anything... 
For the moment I use this as a debugging tool (and thus I include the functions debug_c_node,
and debug_c_tree)
Here are some of possible places where to allow the user to dump the tree :
- dirrectly after the parser (like a -E option)
- before the RTL generation : that allows to see the overall effect of the tree optimizations.
- after each tree-optimisation pass ?
- Sugestions ?


Sebastian.


2001-11-26  Sebastian Pop  <s.pop@laposte.net>
	* Makefile.in (C_AND_OBJC_OBJS): Added c-pretty-print.o.
	(c-pretty-print.o): New target.
	* cp/Make-lang.in (CXX_C_OBJS): Added c-pretty-print.o.
        * tree.h (print_c_tree): Declare.
        (print_c_node): Declare.
        (debug_c_tree): Declare.
        (debug_c_node): Declare.
        * c-pretty-print.h: New file.
        (print_c_tree): Declare.
        (print_c_node): Declare.
        (debug_c_tree): Declare.
        (debug_c_node): Declare.
        (dump_c_tree): Declare.
        (dump_c_node): Declare.
        * c-pretty-print.c: New file.
	(dump_c_scope_vars): Declare static.
        (print_c_tree): New function.
        (print_c_node): New function.
        (debug_c_tree): New function.
        (debug_c_node): New function.
        (dump_c_tree): New function.
        (dump_c_node): New function.
	(dump_c_scope_vars): New function.

Index: gcc/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.701.2.6
diff -d -u -p -r1.701.2.6 Makefile.in
--- Makefile.in	2001/10/15 01:06:56	1.701.2.6
+++ Makefile.in	2001/12/04 20:20:39
@@ -726,7 +726,7 @@ CXX_TARGET_OBJS=@cxx_target_objs@
 C_AND_OBJC_OBJS = c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
   c-convert.o c-aux-info.o c-common.o c-format.o c-semantics.o c-dump.o \
   libcpp.a $(C_TARGET_OBJS)						\
-  tree-cfg.o tree-dfa.o tree-ssa.o tree-optimize.o
+  tree-cfg.o tree-dfa.o tree-ssa.o tree-optimize.o c-pretty-print.o
 
 # Language-specific object files for C.
 C_OBJS = c-parse.o c-lang.o $(C_AND_OBJC_OBJS)
@@ -1345,6 +1345,8 @@ tree-dfa.o : tree-dfa.c tree-optimize.h 
 tree-optimize.o : tree-optimize.c tree-optimize.h tree-flow.h $(CONFIG_H) \
    $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) $(EXPR_H) \
    $(C_COMMON_H) $(GGC_H) output.h diagnostic.h ssa.h errors.h flags.h
+c-pretty-print.o : c-pretty-print.c c-pretty-print.h $(CONFIG_H) $(SYSTEM_H) \
+   $(TREE_H) $(C_TREE_H) $(C_COMMON_H) diagnostic.h
 
 print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GGC_H)
 stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \
Index: gcc/cp/Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/Make-lang.in,v
retrieving revision 1.88.2.3
diff -d -u -p -r1.88.2.3 Make-lang.in
--- Make-lang.in	2001/08/27 15:52:14	1.88.2.3
+++ Make-lang.in	2001/12/04 20:20:39
@@ -94,7 +94,7 @@ $(DEMANGLER_PROG): cxxmain.o underscore.
 # The compiler itself.
 # Shared with C front end:
 CXX_C_OBJS = c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o c-dump.o $(CXX_TARGET_OBJS) \
-  tree-cfg.o tree-dfa.o tree-optimize.o tree-ssa.o
+  tree-cfg.o tree-dfa.o tree-optimize.o tree-ssa.o c-pretty-print.o
 
 # Language-specific object files.
 CXX_OBJS = cp/call.o cp/decl.o cp/errfn.o cp/expr.o cp/pt.o cp/typeck2.o \
Index: gcc/tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.257.2.1
diff -d -u -p -r1.257.2.1 tree.h
--- tree.h	2001/07/23 09:15:51	1.257.2.1
+++ tree.h	2001/12/04 21:02:44
@@ -2790,6 +2790,12 @@ extern void print_node_brief		PARAMS ((F
 extern void indent_to			PARAMS ((FILE *, int));
 #endif
 
+/* In c-pretty-print.c */
+extern void print_c_tree                PARAMS ((FILE*, tree));
+extern void print_c_node                PARAMS ((FILE*, tree));
+extern void debug_c_tree                PARAMS ((tree));
+extern void debug_c_node                PARAMS ((tree));
+
 /* In expr.c */
 extern int apply_args_register_offset		PARAMS ((int));
 extern struct rtx_def *expand_builtin_return_addr
Index: gcc/c-pretty-print.h
===================================================================
RCS file: gcc/c-pretty-print.h
diff -N gcc/c-pretty-print.h
--- /dev/null	Sat Mar 24 04:37:44 2001
+++ gcc/c-pretty-print.h	Tue Dec  4 20:34:12 2001
@@ -0,0 +1,30 @@
+/* Pretty formating of a tree in C syntax.
+   Copyright (C) 2001 Free Software Foundation, Inc.
+   Contributed by Sebastian Pop <s.pop@laposte.net>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+extern void print_c_tree                PARAMS ((FILE*, tree));
+extern void print_c_node                PARAMS ((FILE*, tree));
+extern void debug_c_tree                PARAMS ((tree));
+extern void debug_c_node                PARAMS ((tree));
+extern void dump_c_tree                 PARAMS ((output_buffer*, tree, HOST_WIDE_INT));
+extern int dump_c_node                  PARAMS ((output_buffer*, tree, HOST_WIDE_INT));
+
Index: gcc/c-pretty-print.c
===================================================================
RCS file: gcc/c-pretty-print.c
diff -N gcc/c-pretty-print.c
--- /dev/null	Sat Mar 24 04:37:44 2001
+++ gcc/c-pretty-print.c	Tue Dec  4 20:31:30 2001
@@ -0,0 +1,1066 @@
+/* Pretty formating of a tree in C syntax.
+   Copyright (C) 2001 Free Software Foundation, Inc.
+   Contributed by Sebastian Pop <s.pop@laposte.net>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "tree.h"
+#include "c-tree.h"
+#include "c-common.h"
+#include "diagnostic.h"
+#include "c-pretty-print.h"
+
+static void dump_c_scope_vars PARAMS ((output_buffer*, tree, HOST_WIDE_INT));
+
+
+/* Print the tree T in full, on file FILE.  */
+ 
+void 
+print_c_tree (file, t)
+     FILE *file;
+     tree t;
+{
+  output_buffer buffer_rec;
+  output_buffer *buffer = &buffer_rec;
+
+  init_output_buffer (buffer, /* prefix */NULL, /* line-width */0);
+  output_clear_message_text (buffer);
+  dump_c_tree (buffer, t, 0);
+  fprintf (file, "%s", output_finalize_message (buffer));
+}
+
+/* Print the node T on file FILE.  */
+
+void 
+print_c_node (file, t)
+     FILE *file;
+     tree t;
+{
+  output_buffer buffer_rec;
+  output_buffer *buffer = &buffer_rec;
+
+  init_output_buffer (buffer, /* prefix */NULL, /* line-width */0);
+  output_clear_message_text (buffer);
+  dump_c_node (buffer, t, 0);
+  fprintf (file, "%s", output_finalize_message (buffer));
+}
+
+/* Print the tree T in full, on stderr.  */
+
+void 
+debug_c_tree (t)
+     tree t;
+{
+  print_c_tree (stderr, t);
+}
+
+/* Print the node T on stderr.  */
+
+void 
+debug_c_node (t)
+     tree t;
+{
+  print_c_node (stderr, t);
+}
+
+/* Dump the tree T on the output_buffer OBUFF.  */
+ 
+void 
+dump_c_tree (buffer, t, spc)
+     output_buffer *buffer;
+     tree t;
+     HOST_WIDE_INT spc;
+{
+  tree node = t;
+  while (node && node != error_mark_node)
+    {
+      spc = dump_c_node (buffer, node, spc);
+      switch (TREE_CODE (node))
+	{
+	case TYPE_DECL:
+	case FIELD_DECL:
+	case VAR_DECL:
+	case PARM_DECL:
+	  /* Some nodes on which we need to stop the recursive printing,
+	     otherwise we print all declared vars in the scope.  */
+	  return;
+	default:
+	  break;
+	}
+      node = TREE_CHAIN (node);
+    }
+}
+
+/* Dump the node NODE on the output_buffer BUFFER, SPC spaces of indent.  */
+
+int
+dump_c_node (buffer, node, spc)
+     output_buffer *buffer;
+     tree node;
+     HOST_WIDE_INT spc;
+{
+  HOST_WIDE_INT i;
+  tree type;
+
+  if (node == NULL_TREE)
+    return spc;
+
+#define INDENT_PRINT_C_NODE(SPACE) for (i = 0; i<SPACE; i++) output_add_space (buffer)
+#define NIY output_add_string (buffer, "NIY "); break
+
+  /* Keep the following switch ordered as in 'tree.def' and 'c-common.def'.  */
+  switch (TREE_CODE (node))
+    {
+    case ERROR_MARK:
+      NIY;
+    case IDENTIFIER_NODE:
+      NIY;
+    case OP_IDENTIFIER:
+      NIY;
+    case TREE_LIST:
+      while (node && node != error_mark_node)
+	{
+	  dump_c_node (buffer, TREE_VALUE (node), spc);
+	  node = TREE_CHAIN (node);
+	  if (node && TREE_CODE (node) == TREE_LIST)
+	    {
+	      output_add_character (buffer, ',');
+	      output_add_space (buffer);
+	    }
+	}
+      break;
+    case TREE_VEC:
+      dump_c_node (buffer, BINFO_TYPE (node), spc);
+      break;
+    case BLOCK:
+      NIY;
+    case VOID_TYPE:
+    case INTEGER_TYPE:
+    case REAL_TYPE:
+    case COMPLEX_TYPE:
+    case VECTOR_TYPE:
+    case ENUMERAL_TYPE:
+    case BOOLEAN_TYPE:
+    case CHAR_TYPE:
+      output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
+      break;
+    case POINTER_TYPE:
+      dump_c_node (buffer, TREE_TYPE (node), spc);
+      output_add_character (buffer, '*');
+      break;
+    case OFFSET_TYPE:
+      NIY;
+    case REFERENCE_TYPE:
+      NIY;
+    case METHOD_TYPE:
+      output_add_string (buffer, IDENTIFIER_POINTER 
+			 (DECL_NAME (TYPE_NAME (TYPE_METHOD_BASETYPE (node)))));
+      output_add_string (buffer, "::");
+      break;
+    case FILE_TYPE:
+      NIY;
+    case ARRAY_TYPE:
+      NIY;
+    case SET_TYPE:
+      NIY;
+    case RECORD_TYPE:
+      /* I have to work a little more on this node... */
+
+      /* Print the name of the structure.  */
+      if (TYPE_NAME (node))
+	output_add_string (buffer, IDENTIFIER_POINTER (TYPE_NAME (node)));
+      output_add_newline (buffer);
+      INDENT_PRINT_C_NODE (spc);
+      output_add_character (buffer, '{');
+      output_add_newline (buffer);
+      
+      /* Print the fields of the structure.  */
+      {
+	tree tmp;
+	tmp = TYPE_FIELDS (node);
+	while (tmp)
+	  {
+	    /* Avoid to print recursively the structure.  */
+	    if (TREE_TYPE (tmp) == node)
+	      {
+		
+	      }
+	    else
+	      {
+		/* Print the type of the field.  */
+		INDENT_PRINT_C_NODE (spc+2);
+		dump_c_node (buffer, TREE_TYPE (tmp), spc+2);
+		output_add_space (buffer);
+		
+		/* Print the field.  */
+		dump_c_node (buffer, tmp, spc+2);
+		output_add_character (buffer, ';');
+		output_add_newline (buffer);
+	      }
+	    tmp = TREE_CHAIN (tmp);
+	  }
+      }
+
+      /* Print the methods of the structure.  */
+      /* dump_c_node (buffer, TYPE_METHODS (node), spc+2);  */
+      
+      INDENT_PRINT_C_NODE (spc);
+      output_add_character (buffer, '}');
+      break;
+    case UNION_TYPE:
+      NIY;
+    case QUAL_UNION_TYPE:
+      NIY;
+    case FUNCTION_TYPE:
+      break;
+    case LANG_TYPE:
+      NIY;
+    case INTEGER_CST:
+      if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
+	/* In the case of a pointer, divise by the size of the pointed type.  */
+	output_decimal (buffer,
+			TREE_INT_CST_LOW (node) / 
+			TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE 
+							  (TREE_TYPE (node)))) );
+      else
+	output_decimal (buffer, TREE_INT_CST_LOW (node));
+      break;
+    case REAL_CST:
+      /* Code copied from print_node.  */
+      {
+	REAL_VALUE_TYPE d;
+	if (TREE_OVERFLOW (node))
+	  output_add_string (buffer, " overflow");
+	
+#if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
+	d = TREE_REAL_CST (node);
+	if (REAL_VALUE_ISINF (d))
+	  output_add_string (buffer, " Inf");
+	else if (REAL_VALUE_ISNAN (d))
+	  output_add_string (buffer, " Nan");
+	else
+	  {
+	    char string[100];
+	    REAL_VALUE_TO_DECIMAL (d, "%e", string);
+	    output_add_string (buffer, string);
+	  }
+#else
+	{
+	  HOST_WIDE_INT i;
+	  unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
+	  output_add_string (buffer, "0x");
+	  for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
+	    output_formatted_integer (buffer, "%02x", *p++);
+	}
+#endif
+	break;
+      }
+    case COMPLEX_CST:
+      NIY;
+    case STRING_CST:
+      NIY;
+    case FUNCTION_DECL:
+
+      if (!DECL_INITIAL (node))
+	{
+	  /* Print the prototype of the function.  */
+	  INDENT_PRINT_C_NODE (spc);
+	  
+	  /* Print the return type.  */
+	  dump_c_node (buffer, TREE_TYPE (TREE_TYPE (node)), spc);
+	  output_add_space (buffer);
+
+	  /* Print the namespace.  */
+	  dump_c_node (buffer, TREE_TYPE (node), spc);
+	  	  
+	  /* Print the function name.  */
+	  output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (node)));
+	  output_add_space (buffer);
+	  output_add_character (buffer, '(');
+	  
+	  /* Print the argument types.  The last element in the list is a 
+	     VOID_TYPE.  The following avoid to print the last element.  */
+	  /* dump_c_node (buffer, TYPE_ARG_TYPES (TREE_TYPE (node)), spc);  */
+	  {
+	    tree tmp = TYPE_ARG_TYPES (TREE_TYPE (node));
+	    while (TREE_CHAIN (tmp) && tmp != error_mark_node)
+	      {
+		dump_c_node (buffer, TREE_VALUE (tmp), spc);
+		tmp = TREE_CHAIN (tmp);
+		if (TREE_CHAIN (tmp) && TREE_CODE (TREE_CHAIN (tmp)) == TREE_LIST)
+		  {
+		    output_add_character (buffer, ',');
+		    output_add_space (buffer);
+		  }
+	      }
+	  }
+
+	  output_add_character (buffer, ')');
+	  output_add_character (buffer, ';');
+	}
+      else
+	{
+	  /* Print the function, its arguments and its body.  */
+
+	  /* Print the return type of the function.  */
+	  INDENT_PRINT_C_NODE (spc);
+	  dump_c_node (buffer, DECL_RESULT (node), spc);
+	  output_add_space (buffer);
+	  
+	  /* In C++ TREE_TYPE (node) could be a METHOD_TYPE containing the namespace.
+	     Otherwise it's a FUNCTION_TYPE.  */
+	  dump_c_node (buffer, TREE_TYPE (node), spc);
+	  
+	  /* Print the name of the function.  */
+	  output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (node)));
+	  output_add_space (buffer);
+	  output_add_character (buffer, '(');
+	  
+	  /* Print the arguments.  */
+	  {
+	    tree tmp;
+	    tmp = DECL_ARGUMENTS (node);
+	    while (tmp && tmp != error_mark_node)
+	      {
+		/* In C++ the first argument of a method is the pointer (*this).
+		   This condition avoids to print it.  */
+		if (TREE_TYPE (node) == NULL_TREE ||
+		    TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE ||
+		    TREE_TYPE (TREE_TYPE (tmp)) != TYPE_METHOD_BASETYPE (TREE_TYPE (node)))
+		  {
+		    /* Print the type.  */
+		    dump_c_node (buffer, TREE_TYPE (tmp), spc);
+		    output_add_space (buffer);
+		    /* Print the argument.  */
+		    dump_c_node (buffer, tmp, spc);
+		    tmp = TREE_CHAIN (tmp);
+		    if (tmp)
+		      {
+			output_add_character (buffer, ',');
+			output_add_space (buffer);
+		      }
+		  }
+		else
+		  tmp = TREE_CHAIN (tmp);
+	      }
+	  }
+	  output_add_character (buffer, ')');
+	  
+	  /* And finally, print the body.  */
+	  output_add_newline (buffer);
+	  dump_c_node (buffer, DECL_SAVED_TREE (node), spc);
+	}
+      output_add_newline (buffer);
+      break;
+    case LABEL_DECL:
+      if (DECL_NAME (node))
+	output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (node)));
+      break;
+    case CONST_DECL:
+      if (DECL_NAME (node))
+	output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (node)));
+      break;
+    case TYPE_DECL:
+      if (strcmp (DECL_SOURCE_FILE (node), "<built-in>") == 0)
+	{
+	  /* Don't print the declaration of built-in types.  */
+	  break;
+	}
+      if (DECL_NAME (node))
+	{
+	  output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (node)));
+	}
+      else
+	{
+	  if (TYPE_METHODS (TREE_TYPE (node)))
+	    {
+	      /* The caller is a c++ function : all structures have at least 
+		 4 methods. */
+	      INDENT_PRINT_C_NODE (spc);
+	      output_add_string (buffer, "class ");
+	      dump_c_node (buffer, TREE_TYPE (node), spc);
+	    }
+	  else
+	    {
+	      INDENT_PRINT_C_NODE (spc);
+	      output_add_string (buffer, "struct ");
+	      dump_c_node (buffer, TREE_TYPE (node), spc);
+	      output_add_character (buffer, ';');
+	      output_add_newline (buffer);
+	    }
+	}
+      break;
+    case VAR_DECL:
+      if (DECL_NAME (node))
+	output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (node)));
+      break;
+    case PARM_DECL:
+      if (DECL_NAME (node))
+	output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (node)));
+      break;
+    case RESULT_DECL:
+      dump_c_node (buffer, TREE_TYPE (node), spc);      
+      break;
+    case FIELD_DECL:
+      if (DECL_NAME (node))
+	output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (node)));
+      break;
+    case NAMESPACE_DECL:
+      if (DECL_NAME (node))
+	output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (node)));
+      break;
+    case COMPONENT_REF:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_character (buffer, '.');
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case BIT_FIELD_REF:
+      NIY;
+    case INDIRECT_REF:
+      output_add_character (buffer, '(');
+      output_add_character (buffer, '*');
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_character (buffer, ')');
+      break;
+    case BUFFER_REF:
+      NIY;
+    case ARRAY_REF:
+      if (TREE_CODE (TREE_OPERAND (node, 0)) == ARRAY_REF)
+	{
+	  dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+	  output_add_character (buffer, '[');
+	}
+      else
+	{
+	  output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (node, 0))));
+	  output_add_character (buffer, '[');
+	}
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      output_add_character (buffer, ']');
+      break;
+    case ARRAY_RANGE_REF:
+      NIY;
+    case CONSTRUCTOR:
+      output_add_character (buffer, '{');
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      output_add_character (buffer, '}');
+      break;
+    case COMPOUND_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_character (buffer, ',');
+      output_add_space (buffer);
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case MODIFY_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_space (buffer);
+      output_add_character (buffer, '=');
+      output_add_space (buffer);
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case INIT_EXPR:
+      NIY;
+    case TARGET_EXPR:
+      NIY;
+    case COND_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_space (buffer);
+      output_add_character (buffer, '?');
+      output_add_space (buffer);
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      output_add_space (buffer);
+      output_add_character (buffer, ':');
+      output_add_space (buffer);
+      dump_c_node (buffer, TREE_OPERAND (node, 2), spc);
+      break;
+    case BIND_EXPR:
+      NIY;
+    case CALL_EXPR:
+      output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (TREE_OPERAND (node, 0), 0))));
+      output_add_character (buffer, '(');
+      if (TREE_OPERAND (node, 1))
+	dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      output_add_character (buffer, ')');
+      break;
+    case METHOD_CALL_EXPR:
+      NIY;
+    case WITH_CLEANUP_EXPR:
+      NIY;
+    case CLEANUP_POINT_EXPR:
+      NIY;
+    case PLACEHOLDER_EXPR:
+      NIY;
+    case WITH_RECORD_EXPR:
+      NIY;
+    case PLUS_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_space (buffer);
+      output_add_character (buffer, '+');
+      output_add_space (buffer);
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case MINUS_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_space (buffer);
+      output_add_character (buffer, '-');
+      output_add_space (buffer);
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case MULT_EXPR:
+      if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
+	dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      else
+	{
+	  if (TREE_CODE (TREE_OPERAND (node, 0)) == PLUS_EXPR || 
+	      TREE_CODE (TREE_OPERAND (node, 0)) == MINUS_EXPR )
+	    {
+	      /* When the operands are expressions with less priority, 
+		 keep semantics of the tree representation.  */
+	      output_add_character (buffer, '(');
+	      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+	      output_add_character (buffer, ')');
+	    }
+	  else
+	    dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+	  output_add_space (buffer);
+	  output_add_character (buffer, '*');
+	  output_add_space (buffer);
+	  if (TREE_CODE (TREE_OPERAND (node, 1)) == PLUS_EXPR || 
+	      TREE_CODE (TREE_OPERAND (node, 1)) == MINUS_EXPR )
+	    {
+	      /* When the operands are expressions with less priority, 
+		 keep semantics of the tree representation.  */
+	      output_add_character (buffer, '(');
+	      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+	      output_add_character (buffer, ')');
+	    }
+	  else
+	    dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+	}
+      break;
+    case TRUNC_DIV_EXPR:
+      if (TREE_CODE (TREE_OPERAND (node, 0)) == PLUS_EXPR || 
+	  TREE_CODE (TREE_OPERAND (node, 0)) == MINUS_EXPR )
+	{
+	  /* When the operands are expressions with less priority, 
+	     keep semantics of the tree representation.  */
+	  output_add_character (buffer, '(');
+	  dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+	  output_add_character (buffer, ')');
+	}
+      else
+	dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_space (buffer);
+      output_add_character (buffer, '/');
+      output_add_space (buffer);
+      if (TREE_CODE (TREE_OPERAND (node, 1)) == PLUS_EXPR || 
+	  TREE_CODE (TREE_OPERAND (node, 1)) == MINUS_EXPR )
+	{
+	  /* When the operands are expressions with less priority, 
+	     keep semantics of the tree representation.  */
+	  output_add_character (buffer, '(');
+	  dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+	  output_add_character (buffer, ')');
+	}
+      else
+	dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case CEIL_DIV_EXPR:
+      NIY;
+    case FLOOR_DIV_EXPR:
+      NIY;
+    case ROUND_DIV_EXPR:
+      NIY;
+    case TRUNC_MOD_EXPR:
+      NIY;
+    case CEIL_MOD_EXPR:
+      NIY;
+    case FLOOR_MOD_EXPR:
+      NIY;
+    case ROUND_MOD_EXPR:
+      NIY;
+    case RDIV_EXPR:
+      NIY;
+    case EXACT_DIV_EXPR:
+      NIY;
+    case FIX_TRUNC_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);	  
+      break;
+    case FIX_CEIL_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);	  
+      break;
+    case FIX_FLOOR_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);	  
+      break;
+    case FIX_ROUND_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);	  
+      break;
+    case FLOAT_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);	  
+      break;
+    case NEGATE_EXPR:
+      output_add_character (buffer, '-');
+      output_add_character (buffer, '(');
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_character (buffer, ')');
+      break;
+    case MIN_EXPR:
+      NIY;
+    case MAX_EXPR:
+      NIY;
+    case ABS_EXPR:
+      NIY;
+    case FFS_EXPR:
+      NIY;
+    case LSHIFT_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, " << ");
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case RSHIFT_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, " >> ");
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case LROTATE_EXPR:
+      NIY;
+    case RROTATE_EXPR:
+      NIY;
+    case BIT_IOR_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_space (buffer);
+      output_add_character (buffer, '|');
+      output_add_space (buffer);
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case BIT_XOR_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_space (buffer);
+      output_add_character (buffer, '^');
+      output_add_space (buffer);
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case BIT_AND_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_space (buffer);
+      output_add_character (buffer, '&');
+      output_add_space (buffer);
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case BIT_ANDTC_EXPR:
+      NIY;
+    case BIT_NOT_EXPR:
+      NIY;
+    case TRUTH_ANDIF_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, " && ");
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case TRUTH_ORIF_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, " || ");
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case TRUTH_AND_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, " && ");
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case TRUTH_OR_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, " || ");
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case TRUTH_XOR_EXPR:
+      NIY;
+    case TRUTH_NOT_EXPR:
+      output_add_space (buffer);
+      output_add_character (buffer, '!');
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      break;
+    case LT_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_space (buffer);
+      output_add_character (buffer, '<');
+      output_add_space (buffer);
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case LE_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, " <= ");
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case GT_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_space (buffer);
+      output_add_character (buffer, '>');
+      output_add_space (buffer);
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case GE_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, " >= ");
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case EQ_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, " == ");
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case NE_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, " != ");
+      dump_c_node (buffer, TREE_OPERAND (node, 1), spc);
+      break;
+    case UNORDERED_EXPR:
+      NIY;
+    case ORDERED_EXPR:
+      NIY;
+    case UNLT_EXPR:
+      NIY;
+    case UNLE_EXPR:
+      NIY;
+    case UNGT_EXPR:
+      NIY;
+    case UNGE_EXPR:
+      NIY;
+    case UNEQ_EXPR:
+      NIY;
+    case IN_EXPR:
+      NIY;
+    case SET_LE_EXPR:
+      NIY;
+    case CARD_EXPR:
+      NIY;
+    case RANGE_EXPR:
+      NIY;
+    case CONVERT_EXPR:
+      if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
+	dump_c_node (buffer, TREE_OPERAND (TREE_OPERAND (node, 0), 0), spc);
+      else
+	NIY;
+      break;
+    case NOP_EXPR:
+      type = TREE_TYPE (node);
+      if (type == ptr_type_node)
+	{
+	  type = TREE_TYPE (node);
+	  if (type == integer_type_node)
+	    {
+	      output_add_string (buffer, "(int*)");
+	      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+	    }
+	}
+      else
+	dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      break;
+    case NON_LVALUE_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      break;
+    case SAVE_EXPR:
+      NIY;
+    case UNSAVE_EXPR:
+      NIY;
+    case RTL_EXPR:
+      NIY;
+    case ADDR_EXPR:
+      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (node, 0))) != ARRAY_TYPE)
+	output_add_character (buffer, '&');
+      output_add_string (buffer, IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (node, 0))));
+      break;
+    case REFERENCE_EXPR:
+      NIY;
+    case ENTRY_VALUE_EXPR:
+      NIY;
+    case COMPLEX_EXPR:
+      NIY;
+    case CONJ_EXPR:
+      NIY;
+    case REALPART_EXPR:
+      NIY;
+    case IMAGPART_EXPR:
+      NIY;
+    case PREDECREMENT_EXPR:
+      output_add_string (buffer, " --");
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      break;
+    case PREINCREMENT_EXPR:
+      output_add_string (buffer, " ++");
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      break;
+    case POSTDECREMENT_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, "-- ");
+      break;
+    case POSTINCREMENT_EXPR:
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_string (buffer, "++ ");
+      break;
+    case VA_ARG_EXPR:
+      NIY;
+    case TRY_CATCH_EXPR:
+      NIY;
+    case TRY_FINALLY_EXPR:
+      NIY;
+    case GOTO_SUBROUTINE_EXPR:
+      NIY;
+    case LABEL_EXPR:
+      INDENT_PRINT_C_NODE (spc);
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_character (buffer, ':');
+      output_add_character (buffer, ';');
+      output_add_newline (buffer);
+      break;
+    case GOTO_EXPR:
+      NIY;
+      /*
+	case RETURN_EXPR:
+	NIY;
+      */
+    case EXIT_EXPR:
+      NIY;
+    case LOOP_EXPR:
+      NIY;
+    case LABELED_BLOCK_EXPR:
+      NIY;
+    case EXIT_BLOCK_EXPR:
+      NIY;
+    case EXPR_WITH_FILE_LOCATION:
+      NIY;
+    case SWITCH_EXPR:
+      NIY;
+    case EXC_PTR_EXPR:
+      NIY;
+
+      /* Nodes from 'c-common.def'.  */
+
+    case SRCLOC:
+      NIY;
+    case SIZEOF_EXPR:
+      NIY;
+    case ARROW_EXPR:
+      NIY;
+    case ALIGNOF_EXPR:
+      NIY;
+    case EXPR_STMT:
+      INDENT_PRINT_C_NODE (spc);
+      dump_c_node (buffer, EXPR_STMT_EXPR (node), spc);
+      output_add_character (buffer, ';');
+      output_add_newline (buffer);
+      break;
+    case COMPOUND_STMT:
+      dump_c_tree (buffer, COMPOUND_BODY (node), spc);
+      break;
+    case DECL_STMT:
+      break;
+    case IF_STMT:
+      INDENT_PRINT_C_NODE (spc);
+      output_add_string (buffer, "if (");
+      dump_c_node (buffer, IF_COND (node), spc);
+      output_add_character (buffer, ')');
+      output_add_newline (buffer);
+      dump_c_node (buffer, THEN_CLAUSE (node), spc+2);
+      if (ELSE_CLAUSE (node))
+	{
+	  INDENT_PRINT_C_NODE (spc);
+	  output_add_string (buffer, "else");
+	  output_add_newline (buffer);
+	  dump_c_node (buffer, ELSE_CLAUSE (node), spc+2);
+	}
+      break;
+    case FOR_STMT:
+      INDENT_PRINT_C_NODE (spc);
+      output_add_string (buffer, "for (");
+      if (FOR_INIT_STMT (node))
+	dump_c_node (buffer, EXPR_STMT_EXPR (FOR_INIT_STMT (node)), 0);
+      output_add_character (buffer, ';');
+      output_add_space (buffer);
+      dump_c_node (buffer, FOR_COND (node), 0);
+      output_add_character (buffer, ';');
+      output_add_space (buffer);
+      dump_c_node (buffer, FOR_EXPR (node), 0);
+      output_add_character (buffer, ')');
+      output_add_newline (buffer);
+      dump_c_node (buffer, FOR_BODY (node), spc+2);
+      break;
+    case WHILE_STMT:
+      INDENT_PRINT_C_NODE (spc);
+      output_add_string (buffer, "while (");
+      dump_c_node (buffer, WHILE_COND (node), spc);
+      output_add_character (buffer, ')');
+      output_add_newline (buffer);
+      dump_c_node (buffer, WHILE_BODY (node), spc+2);
+      break;
+    case DO_STMT:
+      INDENT_PRINT_C_NODE (spc);
+      output_add_string (buffer, "do");
+      output_add_newline (buffer);
+      dump_c_node (buffer, DO_BODY (node), spc+2);
+      INDENT_PRINT_C_NODE (spc);
+      output_add_string (buffer, "while (");
+      dump_c_node (buffer, DO_COND (node), spc);
+      output_add_character (buffer, ')');
+      output_add_character (buffer, ';');
+      output_add_newline (buffer);
+      break;
+    case RETURN_STMT:
+      INDENT_PRINT_C_NODE (spc);
+      output_add_string (buffer, "return ");
+      if (RETURN_EXPR (node))
+	dump_c_node (buffer, TREE_OPERAND (RETURN_EXPR (node), 1), spc);
+      output_add_character (buffer, ';');
+      output_add_newline (buffer);
+      break;
+    case BREAK_STMT:
+      INDENT_PRINT_C_NODE (spc);
+      output_add_string (buffer, "break;");
+      output_add_newline (buffer);
+      break;
+    case CONTINUE_STMT:
+      INDENT_PRINT_C_NODE (spc);
+      output_add_string (buffer, "continue;");
+      output_add_newline (buffer);
+      break;
+    case SWITCH_STMT:
+      INDENT_PRINT_C_NODE (spc);
+      output_add_string (buffer, "switch (");
+      dump_c_node (buffer, SWITCH_COND (node), spc);
+      output_add_character (buffer, ')');
+      output_add_newline (buffer);
+      dump_c_node (buffer, SWITCH_BODY (node), spc+2);
+      break;
+    case GOTO_STMT:
+      INDENT_PRINT_C_NODE (spc);
+      output_add_string (buffer, "goto ");
+      dump_c_node (buffer, GOTO_DESTINATION (node), spc);
+      output_add_character (buffer, ';');
+      output_add_newline (buffer);
+      break;
+    case LABEL_STMT:
+      INDENT_PRINT_C_NODE (spc);
+      dump_c_node (buffer, TREE_OPERAND (node, 0), spc);
+      output_add_character (buffer, ':');
+      output_add_character (buffer, ';');
+      output_add_newline (buffer);
+      break;
+    case ASM_STMT:
+      NIY;
+    case SCOPE_STMT:
+      if (SCOPE_BEGIN_P (node))
+	{
+	  INDENT_PRINT_C_NODE (spc);
+	  output_add_character (buffer, '{');
+	  output_add_newline (buffer);
+	  spc += 2;
+ 	  if (SCOPE_STMT_BLOCK (node))
+	    dump_c_scope_vars (buffer, node, spc);
+	}
+      else
+	{
+	  spc -= 2;
+	  INDENT_PRINT_C_NODE (spc);
+	  output_add_character (buffer, '}');
+	  output_add_newline (buffer);
+	}
+      break;
+    case CASE_LABEL:
+      INDENT_PRINT_C_NODE (spc-2);
+      if (CASE_LOW (node) && CASE_HIGH (node))
+	{
+	  output_add_string (buffer, "case ");
+	  dump_c_node (buffer, CASE_LOW (node), spc);
+	  output_add_string (buffer, " ... ");
+	  dump_c_node (buffer, CASE_HIGH (node), spc);
+	}
+      else if (CASE_LOW (node))
+	{
+	  output_add_string (buffer, "case ");
+	  dump_c_node (buffer, CASE_LOW (node), spc);
+	}
+      else
+	output_add_string (buffer, "default ");
+      output_add_character (buffer, ':');
+      output_add_newline (buffer);
+      break;
+    case STMT_EXPR:
+      output_add_character (buffer, '(');
+      output_add_newline (buffer);
+      dump_c_node (buffer, STMT_EXPR_STMT (node), spc);
+      INDENT_PRINT_C_NODE (spc);
+      output_add_character (buffer, ')');
+      break;
+      
+    default:
+      NIY;
+    }
+  return spc;
+}
+
+
+static void 
+dump_c_scope_vars (buffer, scope, spc)
+     output_buffer *buffer;
+     tree scope;
+     HOST_WIDE_INT spc;
+{
+  HOST_WIDE_INT i;
+  tree iter = BLOCK_VARS (SCOPE_STMT_BLOCK (scope));
+  tree context = BLOCK_SUPERCONTEXT (BLOCK_SUPERCONTEXT (TREE_OPERAND (scope, 0)));
+  
+  /* Walk through the BLOCK_VARS and print declarations.  */
+  while (iter)
+    {
+      INDENT_PRINT_C_NODE (spc);
+
+      /* Is the type declaration local?  
+	 The expansion of a RECORD_TYPE can be handled by looking at the context.  */
+      if (DECL_CONTEXT (iter) != context)
+	{
+	  /* The declaration of the type is not in the current context.
+	     Don't expand the declaration in this case : print just the name
+	     of the type.  */
+	  output_add_string (buffer, IDENTIFIER_POINTER 
+			     (TYPE_NAME (TREE_TYPE (iter))));
+	}
+      else
+	{
+	  /* Print the entire type declaration.  */
+	  dump_c_node (buffer, TREE_TYPE (iter), spc);
+	}
+
+      /* Print the name of the variable.  */
+      output_add_space (buffer);
+      dump_c_node (buffer, iter, spc);
+      
+      /* Print the initial value.  */
+      if (DECL_INITIAL (iter))
+	{
+	  output_add_space (buffer);
+	  output_add_character (buffer, '=');
+	  output_add_space (buffer);
+	  dump_c_node (buffer, DECL_INITIAL (iter), spc);
+	}
+      output_add_character (buffer, ';');
+      output_add_newline (buffer);
+      iter = TREE_CHAIN (iter);      
+    }
+}
+
+


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]