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]

Go patch committed: Add AST dumper


This patch, written by Roberto Lublinerman at Google, adds an option to
gccgo to dump the gccgo AST before converting to GENERIC.  Bootstrapped
and ran Go testsuite on x86_64-unknown-linux-gnu.  Committed to
mainline.

Ian


2011-08-02  Roberto Lublinerman  <rluble@gmail.com>

	* Make-lang.in (GO_OBJS): Add go/ast-dump.o.
	(go/ast-dump.o): New target.
	(go/expressions.o): Depend on go/gofrontend/ast-dump.h.
	(go/statements.o): Likewise.


Index: gcc/go/Make-lang.in
===================================================================
--- gcc/go/Make-lang.in	(revision 176626)
+++ gcc/go/Make-lang.in	(working copy)
@@ -45,6 +45,7 @@ gccgo$(exeext): $(GCCGO_OBJS) $(EXTRA_GC
 go-warn = $(STRICT_WARN)
 
 GO_OBJS = \
+	go/ast-dump.o \
 	go/dataflow.o \
 	go/export.o \
 	go/expressions.o \
@@ -247,6 +248,9 @@ go/go-gcc.o: go/go-gcc.cc $(GO_SYSTEM_H)
 go/%.o: go/gofrontend/%.cc
 	$(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION)
 
+go/ast-dump.o: go/gofrontend/ast-dump.cc $(GO_SYSTME_H) $(GO_GOGO_H) \
+	$(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) $(GO_TYPES_H) \
+	go/gofrontend/ast-dump.h $(GO_C_H) go/gofrontend/go-dump.h
 go/dataflow.o: go/gofrontend/dataflow.cc $(GO_SYSTEM_H) $(GO_GOGO_H) \
 	$(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) go/gofrontend/dataflow.h
 go/export.o: go/gofrontend/export.cc $(GO_SYSTEM_H) \
@@ -256,7 +260,8 @@ go/expressions.o: go/gofrontend/expressi
 	intl.h $(TREE_H) $(GIMPLE_H) tree-iterator.h convert.h $(REAL_H) \
 	realmpfr.h $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) \
 	go/gofrontend/export.h $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \
-	$(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_EXPRESSIONS_H)
+	$(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_EXPRESSIONS_H) \
+	go/gofrontend/ast-dump.h
 go/go.o: go/gofrontend/go.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_LEX_H) \
 	$(GO_PARSE_H) go/gofrontend/backend.h $(GO_GOGO_H)
 go/go-dump.o: go/gofrontend/go-dump.cc $(GO_SYSTEM_H) $(GO_C_H) \
@@ -285,7 +290,8 @@ go/runtime.o: go/gofrontend/runtime.cc $
 	go/gofrontend/runtime.def
 go/statements.o: go/gofrontend/statements.cc $(GO_SYSTEM_H) \
 	$(GO_C_H) $(GO_TYPES_H) $(GO_EXPRESSIONS_H) $(GO_GOGO_H) \
-	$(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_STATEMENTS_H)
+	$(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_STATEMENTS_H) \
+	go/gofrontend/ast-dump.h
 go/types.o: go/gofrontend/types.cc $(GO_SYSTEM_H) $(TOPLEV_H) intl.h $(TREE_H) \
 	$(GIMPLE_H) $(REAL_H) convert.h $(GO_C_H) $(GO_GOGO_H) \
 	go/gofrontend/operator.h $(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) \
Index: gcc/go/gofrontend/gogo.h
===================================================================
--- gcc/go/gofrontend/gogo.h	(revision 176998)
+++ gcc/go/gofrontend/gogo.h	(working copy)
@@ -422,6 +422,10 @@ class Gogo
   void
   simplify_thunk_statements();
 
+  // Dump AST if -fgo-dump-ast is set 
+  void
+  dump_ast(const char* basename);
+
   // Convert named types to the backend representation.
   void
   convert_named_types();
@@ -512,7 +516,6 @@ class Gogo
   receive_as_64bit_integer(tree type, tree channel, bool blocking,
 			   bool for_select);
 
-
   // Make a trampoline which calls FNADDR passing CLOSURE.
   tree
   make_trampoline(tree fnaddr, tree closure, source_location);
Index: gcc/go/gofrontend/go.cc
===================================================================
--- gcc/go/gofrontend/go.cc	(revision 176626)
+++ gcc/go/gofrontend/go.cc	(working copy)
@@ -133,6 +133,9 @@ go_parse_input_files(const char** filena
 
   // Convert complicated go and defer statements into simpler ones.
   ::gogo->simplify_thunk_statements();
+  
+  // Dump ast, use filename[0] as the base name
+  ::gogo->dump_ast(filenames[0]);
 }
 
 // Write out globals.
Index: gcc/go/gofrontend/expressions.h
===================================================================
--- gcc/go/gofrontend/expressions.h	(revision 176998)
+++ gcc/go/gofrontend/expressions.h	(working copy)
@@ -42,6 +42,7 @@ class Export;
 class Import;
 class Temporary_statement;
 class Label;
+class Ast_dump_context;
 
 // The base class for all expressions.
 
@@ -635,6 +636,10 @@ class Expression
   static tree
   check_bounds(tree val, tree bound_type, tree sofar, source_location);
 
+  // Dump an expression to a dump constext.
+  void
+  dump_expression(Ast_dump_context*) const;
+
  protected:
   // May be implemented by child class: traverse the expressions.
   virtual int
@@ -731,6 +736,10 @@ class Expression
   void
   report_error(const char*);
 
+  // Child class implements dumping to a dump context.
+  virtual void
+  do_dump_expression(Ast_dump_context*) const = 0;
+
  private:
   // Convert to the desired statement classification, or return NULL.
   // This is a controlled dynamic cast.
@@ -934,6 +943,9 @@ class Var_expression : public Expression
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The variable we are referencing.
   Named_object* variable_;
@@ -978,6 +990,9 @@ class Temporary_reference_expression : p
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The statement where the temporary variable is defined.
   Temporary_statement* statement_;
@@ -1031,6 +1046,9 @@ class String_expression : public Express
   void
   do_export(Export*) const;
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The string value.  This is immutable.
   const std::string val_;
@@ -1154,6 +1172,9 @@ class Binary_expression : public Express
   void
   do_export(Export*) const;
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The binary operator to apply.
   Operator op_;
@@ -1290,6 +1311,9 @@ class Call_expression : public Expressio
   bool
   determining_types();
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   bool
   check_argument_type(int, const Type*, const Type*, source_location, bool);
@@ -1384,6 +1408,9 @@ class Func_expression : public Expressio
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The function itself.
   Named_object* function_;
@@ -1432,6 +1459,9 @@ class Unknown_expression : public Parser
   do_copy()
   { return new Unknown_expression(this->named_object_, this->location()); }
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+  
  private:
   // The unknown name.
   Named_object* named_object_;
@@ -1456,6 +1486,12 @@ class Index_expression : public Parser_e
   set_is_lvalue()
   { this->is_lvalue_ = true; }
 
+  // Dump an index expression, i.e. an expression of the form
+  // expr[expr] or expr[expr:expr], to a dump context.
+  static void
+  dump_index_expression(Ast_dump_context*, const Expression* expr, 
+                        const Expression* start, const Expression* end);
+
  protected:
   int
   do_traverse(Traverse*);
@@ -1473,6 +1509,9 @@ class Index_expression : public Parser_e
 				this->location());
   }
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The expression being indexed.
   Expression* left_;
@@ -1572,6 +1611,9 @@ class Map_index_expression : public Expr
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The map we are looking into.
   Expression* map_;
@@ -1641,6 +1683,9 @@ class Bound_method_expression : public E
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The object used to find the method.  This is passed to the method
   // as the first argument.
@@ -1712,6 +1757,9 @@ class Field_reference_expression : publi
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The expression we are looking into.  This should have a type of
   // struct.
@@ -1777,6 +1825,9 @@ class Interface_field_reference_expressi
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The expression for the interface object.  This should have a type
   // of interface or pointer to interface.
@@ -1830,6 +1881,9 @@ class Type_guard_expression : public Exp
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The expression to convert.
   Expression* expr_;
@@ -1889,6 +1943,9 @@ class Receive_expression : public Expres
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The channel from which we are receiving.
   Expression* channel_;
Index: gcc/go/gofrontend/statements.cc
===================================================================
--- gcc/go/gofrontend/statements.cc	(revision 176998)
+++ gcc/go/gofrontend/statements.cc	(working copy)
@@ -15,6 +15,7 @@
 #include "runtime.h"
 #include "backend.h"
 #include "statements.h"
+#include "ast-dump.h"
 
 // Class Statement.
 
@@ -142,6 +143,14 @@ Statement::get_backend(Translate_context
   return this->do_get_backend(context);
 }
 
+// Dump AST representation for a statement to a dump context.
+
+void
+Statement::dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  this->do_dump_statement(ast_dump_context);
+}
+
 // Note that this statement is erroneous.  This is called by children
 // when they discover an error.
 
@@ -178,8 +187,20 @@ class Error_statement : public Statement
   Bstatement*
   do_get_backend(Translate_context*)
   { go_unreachable(); }
+
+  void
+  do_dump_statement(Ast_dump_context*) const;
 };
 
+// Dump the AST representation for an error statement.
+
+void
+Error_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "Error statement" << std::endl;
+}
+
 // Make an error statement.
 
 Statement*
@@ -280,6 +301,30 @@ Variable_declaration_statement::do_get_b
   return context->backend()->statement_list(stats);
 }
 
+// Dump the AST representation for a variable declaration.
+
+void
+Variable_declaration_statement::do_dump_statement(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  
+  go_assert(var_->is_variable());
+  ast_dump_context->ostream() << "var " << this->var_->name() <<  " ";
+  Variable* var = this->var_->var_value();
+  if (var->has_type()) 
+    {
+      ast_dump_context->dump_type(var->type());
+      ast_dump_context->ostream() << " ";
+    }
+  if (var->init() != NULL)
+    {
+      ast_dump_context->ostream() <<  "= ";
+      ast_dump_context->dump_expression(var->init());
+    }
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make a variable declaration.
 
 Statement*
@@ -422,6 +467,27 @@ Temporary_statement::get_backend_variabl
   return this->bvariable_;
 }
 
+// Dump the AST represemtation for a temporary statement
+
+void
+Temporary_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_temp_variable_name(this);
+  if (this->type_ != NULL)
+    {
+      ast_dump_context->ostream() << " ";
+      ast_dump_context->dump_type(this->type_);
+      
+    }
+  if (this->init_ != NULL)
+    {
+      ast_dump_context->ostream() << " = ";
+      ast_dump_context->dump_expression(this->init_);
+    }
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make and initialize a temporary variable in BLOCK.
 
 Temporary_statement*
@@ -458,6 +524,9 @@ class Assignment_statement : public Stat
   Bstatement*
   do_get_backend(Translate_context*);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // Left hand side--the lvalue.
   Expression* lhs_;
@@ -542,6 +611,19 @@ Assignment_statement::do_get_backend(Tra
 						  this->location());
 }
 
+// Dump the AST representation for an assignment statement.
+
+void
+Assignment_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
+    const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_expression(this->lhs_);
+  ast_dump_context->ostream() << " = " ;
+  ast_dump_context->dump_expression(this->rhs_);
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make an assignment statement.
 
 Statement*
@@ -614,6 +696,9 @@ class Assignment_operation_statement : p
   do_get_backend(Translate_context*)
   { go_unreachable(); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The operator (OPERATOR_PLUSEQ, etc.).
   Operator op_;
@@ -704,6 +789,19 @@ Assignment_operation_statement::do_lower
     }
 }
 
+// Dump the AST representation for an assignment operation statement
+
+void
+Assignment_operation_statement::do_dump_statement(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_expression(this->lhs_);
+  ast_dump_context->dump_operator(this->op_); 
+  ast_dump_context->dump_expression(this->rhs_);
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make an assignment operation statement.
 
 Statement*
@@ -741,6 +839,9 @@ class Tuple_assignment_statement : publi
   do_get_backend(Translate_context*)
   { go_unreachable(); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // Left hand side--a list of lvalues.
   Expression_list* lhs_;
@@ -768,7 +869,7 @@ Tuple_assignment_statement::do_lower(Gog
   source_location loc = this->location();
 
   Block* b = new Block(enclosing, loc);
-  
+
   // First move out any subexpressions on the left hand side.  The
   // right hand side will be evaluated in the required order anyhow.
   Move_ordered_evals moe(b);
@@ -832,6 +933,19 @@ Tuple_assignment_statement::do_lower(Gog
   return Statement::make_block_statement(b, loc);
 }
 
+// Dump the AST representation for a tuple assignment statement.
+
+void
+Tuple_assignment_statement::do_dump_statement(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_expression_list(this->lhs_);
+  ast_dump_context->ostream() << " = ";
+  ast_dump_context->dump_expression_list(this->rhs_);
+  ast_dump_context->ostream()  << std::endl;
+}
+
 // Make a tuple assignment statement.
 
 Statement*
@@ -869,6 +983,9 @@ public:
   do_get_backend(Translate_context*)
   { go_unreachable(); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // Lvalue which receives the value from the map.
   Expression* val_;
@@ -960,6 +1077,21 @@ Tuple_map_assignment_statement::do_lower
   return Statement::make_block_statement(b, loc);
 }
 
+// Dump the AST representation for a tuple map assignment statement.
+
+void
+Tuple_map_assignment_statement::do_dump_statement(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_expression(this->val_);
+  ast_dump_context->ostream() << ", ";
+  ast_dump_context->dump_expression(this->present_);
+  ast_dump_context->ostream() << " = ";
+  ast_dump_context->dump_expression(this->map_index_);
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make a map assignment statement which returns a pair of values.
 
 Statement*
@@ -998,6 +1130,9 @@ class Map_assignment_statement : public 
   do_get_backend(Translate_context*)
   { go_unreachable(); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // A reference to the map index which should be set or deleted.
   Expression* map_index_;
@@ -1076,6 +1211,21 @@ Map_assignment_statement::do_lower(Gogo*
   return Statement::make_block_statement(b, loc);
 }
 
+// Dump the AST representation for a map assignment statement.
+
+void
+Map_assignment_statement::do_dump_statement(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_expression(this->map_index_);
+  ast_dump_context->ostream() << " = ";
+  ast_dump_context->dump_expression(this->val_);
+  ast_dump_context->ostream() << ", ";
+  ast_dump_context->dump_expression(this->should_set_);
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make a statement which assigns a pair of entries to a map.
 
 Statement*
@@ -1113,6 +1263,9 @@ class Tuple_receive_assignment_statement
   do_get_backend(Translate_context*)
   { go_unreachable(); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // Lvalue which receives the value from the channel.
   Expression* val_;
@@ -1200,6 +1353,21 @@ Tuple_receive_assignment_statement::do_l
   return Statement::make_block_statement(b, loc);
 }
 
+// Dump the AST representation for a tuple receive statement.
+
+void
+Tuple_receive_assignment_statement::do_dump_statement(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_expression(this->val_);
+  ast_dump_context->ostream() << ", ";
+  ast_dump_context->dump_expression(this->closed_);
+  ast_dump_context->ostream() << " <- ";
+  ast_dump_context->dump_expression(this->channel_);
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make a nonblocking receive statement.
 
 Statement*
@@ -1240,6 +1408,9 @@ class Tuple_type_guard_assignment_statem
   do_get_backend(Translate_context*)
   { go_unreachable(); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   Call_expression*
   lower_to_type(Runtime::Function);
@@ -1375,6 +1546,23 @@ Tuple_type_guard_assignment_statement::l
   b->add_statement(s);
 }
 
+// Dump the AST representation for a tuple type guard statement.
+
+void 
+Tuple_type_guard_assignment_statement::do_dump_statement(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_expression(this->val_);
+  ast_dump_context->ostream() << ", ";
+  ast_dump_context->dump_expression(this->ok_);
+  ast_dump_context->ostream() << " = ";
+  ast_dump_context->dump_expression(this->expr_);
+  ast_dump_context->ostream() << " . ";
+  ast_dump_context->dump_type(this->type_);
+  ast_dump_context->ostream()  << std::endl;
+}
+
 // Make an assignment from a type guard to a pair of variables.
 
 Statement*
@@ -1415,6 +1603,9 @@ class Expression_statement : public Stat
   Bstatement*
   do_get_backend(Translate_context* context);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   Expression* expr_;
 };
@@ -1459,6 +1650,17 @@ Expression_statement::do_get_backend(Tra
   return context->backend()->expression_statement(tree_to_expr(expr_tree));
 }
 
+// Dump the AST representation for an expression statement
+
+void 
+Expression_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
+    const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_expression(expr_);
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make an expression statement from an Expression.
 
 Statement*
@@ -1494,6 +1696,9 @@ class Block_statement : public Statement
   Bstatement*
   do_get_backend(Translate_context* context);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   Block* block_;
 };
@@ -1507,6 +1712,14 @@ Block_statement::do_get_backend(Translat
   return context->backend()->block_statement(bblock);
 }
 
+// Dump the AST for a block statement
+
+void
+Block_statement::do_dump_statement(Ast_dump_context*) const
+{
+  // block statement braces are dumped when traversing.
+}
+
 // Make a block statement.
 
 Statement*
@@ -1541,6 +1754,9 @@ class Inc_dec_statement : public Stateme
   do_get_backend(Translate_context*)
   { go_unreachable(); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The l-value to increment or decrement.
   Expression* expr_;
@@ -1564,6 +1780,16 @@ Inc_dec_statement::do_lower(Gogo*, Named
   return Statement::make_assignment_operation(op, this->expr_, oexpr, loc);
 }
 
+// Dump the AST representation for a inc/dec statement.
+
+void
+Inc_dec_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_expression(expr_);
+  ast_dump_context->ostream() << (is_inc_? "++": "--") << std::endl;
+}
+
 // Make an increment statement.
 
 Statement*
@@ -2233,6 +2459,17 @@ Go_statement::do_get_backend(Translate_c
   return context->backend()->expression_statement(call_bexpr);
 }
 
+// Dump the AST representation for go statement.
+
+void
+Go_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "go ";
+  ast_dump_context->dump_expression(this->call());
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make a go statement.
 
 Statement*
@@ -2261,6 +2498,17 @@ Defer_statement::do_get_backend(Translat
   return context->backend()->expression_statement(call_bexpr);
 }
 
+// Dump the AST representation for defer statement.
+
+void
+Defer_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "defer ";
+  ast_dump_context->dump_expression(this->call());
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make a defer statement.
 
 Statement*
@@ -2445,6 +2693,17 @@ Return_statement::do_get_backend(Transla
 					      retvals, loc);
 }
 
+// Dump the AST representation for a return statement.
+
+void
+Return_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "return " ;
+  ast_dump_context->dump_expression_list(this->vals_);
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make a return statement.
 
 Statement*
@@ -2481,6 +2740,9 @@ class Bc_statement : public Statement
   do_get_backend(Translate_context* context)
   { return this->label_->get_goto(context, this->location()); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The label that this branches to.
   Unnamed_label* label_;
@@ -2488,6 +2750,21 @@ class Bc_statement : public Statement
   bool is_break_;
 };
 
+// Dump the AST representation for a break/continue statement
+
+void
+Bc_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << (this->is_break_ ? "break" : "continue");
+  if (this->label_ != NULL) 
+    {
+      ast_dump_context->ostream() << " "; 
+      ast_dump_context->dump_label_name(this->label_);
+    }
+  ast_dump_context->ostream() << std::endl; 
+}
+
 // Make a break statement.
 
 Statement*
@@ -2530,6 +2807,9 @@ class Goto_statement : public Statement
   Bstatement*
   do_get_backend(Translate_context*);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   Label* label_;
 };
@@ -2557,6 +2837,15 @@ Goto_statement::do_get_backend(Translate
   return context->backend()->goto_statement(blabel, this->location());
 }
 
+// Dump the AST representation for a goto statement.
+
+void
+Goto_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "goto " << this->label_->name() << std::endl;
+}
+
 // Make a goto statement.
 
 Statement*
@@ -2588,10 +2877,25 @@ class Goto_unnamed_statement : public St
   do_get_backend(Translate_context* context)
   { return this->label_->get_goto(context, this->location()); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   Unnamed_label* label_;
 };
 
+// Dump the AST representation for an unnamed goto statement
+
+void
+Goto_unnamed_statement::do_dump_statement(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "goto ";
+  ast_dump_context->dump_label_name(this->label_);
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make a goto statement to an unnamed label.
 
 Statement*
@@ -2621,6 +2925,15 @@ Label_statement::do_get_backend(Translat
   return context->backend()->label_definition_statement(blabel);
 }
 
+// Dump the AST for a label definition statement.
+
+void
+Label_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << this->label_->name() << ":" << std::endl;
+}
+
 // Make a label statement.
 
 Statement*
@@ -2648,11 +2961,25 @@ class Unnamed_label_statement : public S
   do_get_backend(Translate_context* context)
   { return this->label_->get_definition(context); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The label.
   Unnamed_label* label_;
 };
 
+// Dump the AST representation for an unnamed label definition statement.
+
+void
+Unnamed_label_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
+    const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_label_name(this->label_);
+  ast_dump_context->ostream() << ":" << std::endl;
+}
+
 // Make an unnamed label statement.
 
 Statement*
@@ -2688,6 +3015,9 @@ class If_statement : public Statement
   Bstatement*
   do_get_backend(Translate_context*);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   Expression* cond_;
   Block* then_block_;
@@ -2759,6 +3089,24 @@ If_statement::do_get_backend(Translate_c
 					  else_block, this->location());
 }
 
+// Dump the AST representation for an if statement
+
+void
+If_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "if ";
+  ast_dump_context->dump_expression(this->cond_);
+  ast_dump_context->ostream() << std::endl;
+  ast_dump_context->dump_block(this->then_block_);
+  if (this->else_block_ != NULL) 
+    {
+      ast_dump_context->print_indent();
+      ast_dump_context->ostream() << "else" << std::endl;
+      ast_dump_context->dump_block(this->else_block_);
+    }
+}
+
 // Make an if statement.
 
 Statement*
@@ -3050,6 +3398,31 @@ Case_clauses::Case_clause::get_backend(T
     return context->backend()->compound_statement(statements, break_stat);
 }
 
+// Dump the AST representation for a case clause
+
+void
+Case_clauses::Case_clause::dump_clause(Ast_dump_context* ast_dump_context) 
+    const
+{
+  ast_dump_context->print_indent();
+  if (this->is_default_)
+    {
+      ast_dump_context->ostream() << "default:";
+    }
+  else
+    {
+      ast_dump_context->ostream() << "case ";
+      ast_dump_context->dump_expression_list(this->cases_);
+      ast_dump_context->ostream() << ":" ;
+    }
+  ast_dump_context->dump_block(this->statements_);
+  if (this->is_fallthrough_)
+    {
+      ast_dump_context->print_indent();
+      ast_dump_context->ostream() <<  " (fallthrough)" << std::endl;
+    }
+}
+
 // Class Case_clauses.
 
 // Traversal.
@@ -3212,6 +3585,17 @@ Case_clauses::get_backend(Translate_cont
     }
 }
 
+// Dump the AST representation for case clauses (from a switch statement)
+
+void
+Case_clauses::dump_clauses(Ast_dump_context* ast_dump_context) const
+{
+  for (Clauses::const_iterator p = this->clauses_.begin();
+       p != this->clauses_.end();
+       ++p)    
+    p->dump_clause(ast_dump_context);
+}
+
 // A constant switch statement.  A Switch_statement is lowered to this
 // when all the cases are constants.
 
@@ -3241,6 +3625,9 @@ class Constant_switch_statement : public
   Bstatement*
   do_get_backend(Translate_context*);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The value to switch on.
   Expression* val_;
@@ -3320,6 +3707,20 @@ Constant_switch_statement::do_get_backen
   return context->backend()->compound_statement(switch_statement, ldef);
 }
 
+// Dump the AST representation for a constant switch statement.
+
+void
+Constant_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
+    const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "switch ";
+  ast_dump_context->dump_expression(this->val_);
+  ast_dump_context->ostream() << " {" << std::endl;
+  this->clauses_->dump_clauses(ast_dump_context);
+  ast_dump_context->ostream() << "}" << std::endl;
+}
+
 // Class Switch_statement.
 
 // Traversal.
@@ -3395,6 +3796,24 @@ Switch_statement::break_label()
   return this->break_label_;
 }
 
+// Dump the AST representation for a switch statement.
+
+void
+Switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "switch ";
+  if (this->val_ != NULL)
+    {
+      ast_dump_context->dump_expression(this->val_);
+      ast_dump_context->ostream() << " ";
+    }
+  ast_dump_context->ostream() << "{" << std::endl;
+  this->clauses_->dump_clauses(ast_dump_context);
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "}" << std::endl;
+}
+
 // Make a switch statement.
 
 Switch_statement*
@@ -3519,6 +3938,31 @@ Type_case_clauses::Type_case_clause::low
     }
 }
 
+// Dump the AST representation for a type case clause
+
+void
+Type_case_clauses::Type_case_clause::dump_clause(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  if (this->is_default_)
+    {
+      ast_dump_context->ostream() << "default:";
+    }
+  else
+    {
+      ast_dump_context->ostream() << "case "; 
+      ast_dump_context->dump_type(this->type_);
+      ast_dump_context->ostream() << ":" ;
+    }
+  ast_dump_context->dump_block(this->statements_);
+  if (this->is_fallthrough_)
+    {
+      ast_dump_context->print_indent();
+      ast_dump_context->ostream() <<  " (fallthrough)" << std::endl;
+    }
+}
+
 // Class Type_case_clauses.
 
 // Traversal.
@@ -3589,6 +4033,17 @@ Type_case_clauses::lower(Block* b, Tempo
     default_case->lower(b, descriptor_temp, break_label, NULL);
 }
 
+// Dump the AST representation for case clauses (from a switch statement)
+
+void
+Type_case_clauses::dump_clauses(Ast_dump_context* ast_dump_context) const
+{
+  for (Type_clauses::const_iterator p = this->clauses_.begin();
+       p != this->clauses_.end();
+       ++p)    
+    p->dump_clause(ast_dump_context);
+}
+
 // Class Type_switch_statement.
 
 // Traversal.
@@ -3692,6 +4147,20 @@ Type_switch_statement::break_label()
   return this->break_label_;
 }
 
+// Dump the AST representation for a type switch statement
+
+void
+Type_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context) 
+    const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "switch " << this->var_->name() << " = ";
+  ast_dump_context->dump_expression(this->expr_);
+  ast_dump_context->ostream() << " .(type) {" << std::endl;
+  this->clauses_->dump_clauses(ast_dump_context);
+  ast_dump_context->ostream() << "}" << std::endl;
+}
+
 // Make a type switch statement.
 
 Type_switch_statement*
@@ -3862,6 +4331,18 @@ Send_statement::do_get_backend(Translate
     return context->backend()->compound_statement(btemp, s);
 }
 
+// Dump the AST representation for a send statement
+
+void
+Send_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->dump_expression(this->channel_);
+  ast_dump_context->ostream() << " <- ";
+  ast_dump_context->dump_expression(this->val_);
+  ast_dump_context->ostream() << std::endl;
+}
+
 // Make a send statement.
 
 Send_statement*
@@ -4053,6 +4534,48 @@ Select_clauses::Select_clause::get_state
   return context->backend()->block_statement(bblock);
 }
 
+// Dump the AST representation for a select case clause
+
+void
+Select_clauses::Select_clause::dump_clause(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  if (this->is_default_)
+    {
+      ast_dump_context->ostream() << "default:";
+    }
+  else
+    {
+      ast_dump_context->ostream() << "case "  ;
+      if (this->is_send_)
+        {
+          ast_dump_context->dump_expression(this->channel_);
+          ast_dump_context->ostream() << " <- " ;
+          ast_dump_context->dump_expression(this->val_);
+        }
+      else 
+        {
+	  if (this->val_ != NULL)
+	    ast_dump_context->dump_expression(this->val_);
+          if (this->closed_ != NULL)
+            {
+	      // FIXME: can val_ == NULL and closed_ ! = NULL?
+              ast_dump_context->ostream() << " , " ;
+              ast_dump_context->dump_expression(this->closed_);
+            }
+          if (this->closedvar_ != NULL ||
+              this->var_ != NULL)
+            ast_dump_context->ostream() << " := " ;
+            
+          ast_dump_context->ostream() << " <- " ;
+          ast_dump_context->dump_expression(this->channel_);
+        }
+      ast_dump_context->ostream() << ":" ;
+    }
+  ast_dump_context->dump_block(this->statements_);
+}
+
 // Class Select_clauses.
 
 // Traversal.
@@ -4326,6 +4849,17 @@ Select_clauses::add_clause_backend(
     (*clauses)[index] = context->backend()->compound_statement(s, g);
 }
 
+// Dump the AST representation for select clauses.
+
+void
+Select_clauses::dump_clauses(Ast_dump_context* ast_dump_context) const
+{
+  for (Clauses::const_iterator p = this->clauses_.begin();
+       p != this->clauses_.end();
+       ++p)    
+    p->dump_clause(ast_dump_context);
+}
+
 // Class Select_statement.
 
 // Return the break label for this switch statement, creating it if
@@ -4366,6 +4900,17 @@ Select_statement::do_get_backend(Transla
 				     this->location());
 }
 
+// Dump the AST representation for a select statement.
+
+void 
+Select_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "select {" << std::endl;
+  this->clauses_->dump_clauses(ast_dump_context);
+  ast_dump_context->ostream() << "}" << std::endl;
+}
+
 // Make a select statement.
 
 Select_statement*
@@ -4501,6 +5046,38 @@ For_statement::set_break_continue_labels
   this->continue_label_ = continue_label;
 }
 
+// Dump the AST representation for a for statement.
+
+void
+For_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  if (this->init_ != NULL)
+    {
+      ast_dump_context->print_indent();
+      ast_dump_context->indent();
+      ast_dump_context->ostream() << "// INIT  " << std::endl;
+      ast_dump_context->dump_block(this->init_);
+      ast_dump_context->unindent();
+    }
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "for ";
+  if (this->cond_ != NULL)
+    ast_dump_context->dump_expression(this->cond_);
+  ast_dump_context->ostream() << " {" << std::endl;
+  ast_dump_context->indent();
+
+  ast_dump_context->dump_block(this->statements_);
+  if (this->init_ != NULL)
+    {
+      ast_dump_context->print_indent();
+      ast_dump_context->ostream() << "// POST " << std::endl;
+      ast_dump_context->dump_block(this->post_);
+    }
+  ast_dump_context->unindent();
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "}" << std::endl;
+}
+
 // Make a for statement.
 
 For_statement*
@@ -5119,6 +5696,33 @@ For_range_statement::continue_label()
   return this->continue_label_;
 }
 
+// Dump the AST representation for a for range statement.
+
+void
+For_range_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
+{
+  
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "for ";
+  ast_dump_context->dump_expression(this->index_var_);
+  if (this->value_var_ != NULL)
+    {
+      ast_dump_context->ostream() << ", ";
+      ast_dump_context->dump_expression(this->value_var_);
+    }
+    
+  ast_dump_context->ostream() << " = range ";      
+  ast_dump_context->dump_expression(this->range_);
+  ast_dump_context->ostream() << " {" << std::endl;
+  ast_dump_context->indent();
+
+  ast_dump_context->dump_block(this->statements_);
+
+  ast_dump_context->unindent();
+  ast_dump_context->print_indent();
+  ast_dump_context->ostream() << "}" << std::endl;
+}
+
 // Make a for statement with a range clause.
 
 For_range_statement*
Index: gcc/go/gofrontend/statements.h
===================================================================
--- gcc/go/gofrontend/statements.h	(revision 176998)
+++ gcc/go/gofrontend/statements.h	(working copy)
@@ -43,6 +43,7 @@ class Typed_identifier_list;
 class Bexpression;
 class Bstatement;
 class Bvariable;
+class Ast_dump_context;
 
 // This class is used to traverse assignments made by a statement
 // which makes assignments.
@@ -374,6 +375,10 @@ class Statement
   Bstatement*
   get_backend(Translate_context*);
 
+  // Dump AST representation of a statement to a dump context.
+  void
+  dump_statement(Ast_dump_context*) const;
+
  protected:
   // Implemented by child class: traverse the tree.
   virtual int
@@ -414,6 +419,10 @@ class Statement
   virtual Bstatement*
   do_get_backend(Translate_context*) = 0;
 
+  // Implemented by child class: dump ast representation.
+  virtual void
+  do_dump_statement(Ast_dump_context*) const = 0;
+
   // Traverse an expression in a statement.
   int
   traverse_expression(Traverse*, Expression**);
@@ -507,6 +516,9 @@ class Temporary_statement : public State
   Bstatement*
   do_get_backend(Translate_context*);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The type of the temporary variable.
   Type* type_;
@@ -544,6 +556,9 @@ class Variable_declaration_statement : p
   Bstatement*
   do_get_backend(Translate_context*);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   Named_object* var_;
 };
@@ -581,6 +596,9 @@ class Return_statement : public Statemen
   Bstatement*
   do_get_backend(Translate_context*);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // Return values.  This may be NULL.
   Expression_list* vals_;
@@ -617,6 +635,9 @@ class Send_statement : public Statement
   Bstatement*
   do_get_backend(Translate_context*);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The channel on which to send the value.
   Expression* channel_;
@@ -678,6 +699,10 @@ class Select_clauses
   Bstatement*
   get_backend(Translate_context*, Unnamed_label* break_label, source_location);
 
+  // Dump AST representation.
+  void
+  dump_clauses(Ast_dump_context*) const;
+
  private:
   // A single clause.
   class Select_clause
@@ -748,6 +773,10 @@ class Select_clauses
     Bstatement*
     get_statements_backend(Translate_context*);
 
+    // Dump AST representation.
+    void
+    dump_clause(Ast_dump_context*) const;
+
    private:
     // The channel.
     Expression* channel_;
@@ -825,6 +854,9 @@ class Select_statement : public Statemen
   Bstatement*
   do_get_backend(Translate_context*);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The select clauses.
   Select_clauses* clauses_;
@@ -844,7 +876,7 @@ class Thunk_statement : public Statement
 
   // Return the call expression.
   Expression*
-  call()
+  call() const
   { return this->call_; }
 
   // Simplify a go or defer statement so that it only uses a single
@@ -914,6 +946,9 @@ class Go_statement : public Thunk_statem
  protected:
   Bstatement*
   do_get_backend(Translate_context*);
+
+  void
+  do_dump_statement(Ast_dump_context*) const;
 };
 
 // A defer statement.
@@ -928,6 +963,9 @@ class Defer_statement : public Thunk_sta
  protected:
   Bstatement*
   do_get_backend(Translate_context*);
+
+  void
+  do_dump_statement(Ast_dump_context*) const;
 };
 
 // A label statement.
@@ -952,6 +990,9 @@ class Label_statement : public Statement
   Bstatement*
   do_get_backend(Translate_context*);
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The label.
   Label* label_;
@@ -1005,6 +1046,9 @@ class For_statement : public Statement
   do_get_backend(Translate_context*)
   { go_unreachable(); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The initialization statements.  This may be NULL.
   Block* init_;
@@ -1063,6 +1107,9 @@ class For_range_statement : public State
   do_get_backend(Translate_context*)
   { go_unreachable(); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   Expression*
   make_range_ref(Named_object*, Temporary_statement*, source_location);
@@ -1167,6 +1214,10 @@ class Case_clauses
 	      std::vector<std::vector<Bexpression*> >* all_cases,
 	      std::vector<Bstatement*>* all_statements) const;
 
+  // Dump the AST representation to a dump context.
+  void
+  dump_clauses(Ast_dump_context*) const;
+  
  private:
   // For a constant switch we need to keep a record of constants we
   // have already seen.
@@ -1237,6 +1288,10 @@ class Case_clauses
     get_backend(Translate_context*, Unnamed_label* break_label,
 		Case_constants*, std::vector<Bexpression*>* cases) const;
 
+    // Dump the AST representation to a dump context.
+    void
+    dump_clause(Ast_dump_context*) const;
+  
    private:
     // The list of case expressions.
     Expression_list* cases_;
@@ -1292,6 +1347,9 @@ class Switch_statement : public Statemen
   do_get_backend(Translate_context*)
   { go_unreachable(); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The value to switch on.  This may be NULL.
   Expression* val_;
@@ -1342,6 +1400,10 @@ class Type_case_clauses
   lower(Block*, Temporary_statement* descriptor_temp,
 	Unnamed_label* break_label) const;
 
+  // Dump the AST representation to a dump context.
+  void
+  dump_clauses(Ast_dump_context*) const;
+
  private:
   // One type case clause.
   class Type_case_clause
@@ -1382,6 +1444,10 @@ class Type_case_clauses
     lower(Block*, Temporary_statement* descriptor_temp,
 	  Unnamed_label* break_label, Unnamed_label** stmts_label) const;
 
+    // Dump the AST representation to a dump context.
+    void
+    dump_clause(Ast_dump_context*) const;
+
    private:
     // The type for this type clause.
     Type* type_;
@@ -1438,6 +1504,9 @@ class Type_switch_statement : public Sta
   do_get_backend(Translate_context*)
   { go_unreachable(); }
 
+  void
+  do_dump_statement(Ast_dump_context*) const;
+
  private:
   // The variable holding the value we are switching on.
   Named_object* var_;
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 176998)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -36,6 +36,7 @@ extern "C"
 #include "runtime.h"
 #include "backend.h"
 #include "expressions.h"
+#include "ast-dump.h"
 
 // Class Expression.
 
@@ -790,6 +791,12 @@ Expression::check_bounds(tree val, tree 
 			   sofar, ret);
 }
 
+void
+Expression::dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  this->do_dump_expression(ast_dump_context);
+}
+
 // Error expressions.  This are used to avoid cascading errors.
 
 class Error_expression : public Expression
@@ -849,8 +856,19 @@ class Error_expression : public Expressi
   tree
   do_get_tree(Translate_context*)
   { return error_mark_node; }
+
+  void
+  do_dump_expression(Ast_dump_context*) const;
 };
 
+// Dump the ast representation for an error expression to a dump context.
+
+void
+Error_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << "_Error_" ;
+}
+
 Expression*
 Expression::make_error(source_location location)
 {
@@ -894,11 +912,19 @@ Type_expression : public Expression
   do_get_tree(Translate_context*)
   { go_unreachable(); }
 
+  void do_dump_expression(Ast_dump_context*) const;
+ 
  private:
   // The type which we are representing as an expression.
   Type* type_;
 };
 
+void
+Type_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->dump_type(this->type_);
+}
+
 Expression*
 Expression::make_type(Type* type, source_location location)
 {
@@ -1018,6 +1044,14 @@ Var_expression::do_get_tree(Translate_co
   return ret;
 }
 
+// Ast dump for variable expression.
+
+void
+Var_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << this->variable_->name() ;
+}
+
 // Make a reference to a variable in an expression.
 
 Expression*
@@ -1076,6 +1110,15 @@ Temporary_reference_expression::do_get_t
   return ret;
 }
 
+// Ast dump for temporary reference.
+
+void
+Temporary_reference_expression::do_dump_expression(
+                                Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->dump_temp_variable_name(this->statement_);
+}
+
 // Make a reference to a temporary variable.
 
 Temporary_reference_expression*
@@ -1113,6 +1156,9 @@ class Sink_expression : public Expressio
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The type of this sink variable.
   Type* type_;
@@ -1154,6 +1200,14 @@ Sink_expression::do_get_tree(Translate_c
   return this->var_;
 }
 
+// Ast dump for sink expression.
+
+void
+Sink_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << "_" ;
+}
+
 // Make a sink expression.
 
 Expression*
@@ -1286,6 +1340,14 @@ Func_expression::do_get_tree(Translate_c
   return gogo->make_trampoline(fnaddr, closure_tree, this->location());
 }
 
+// Ast dump for function.
+
+void
+Func_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << this->function_->name() ;
+}
+
 // Make a reference to a function in an expression.
 
 Expression*
@@ -1354,6 +1416,16 @@ Unknown_expression::do_lower(Gogo*, Name
     }
 }
 
+// Dump the ast representation for an unknown expression to a dump context.
+
+void
+Unknown_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << "_Unknown_(" << this->named_object_->name()
+			      << ")";
+   
+}
+
 // Make a reference to an unknown name.
 
 Expression*
@@ -1399,6 +1471,10 @@ class Boolean_expression : public Expres
   do_export(Export* exp) const
   { exp->write_c_string(this->val_ ? "true" : "false"); }
 
+  void
+  do_dump_expression(Ast_dump_context* ast_dump_context) const
+  { ast_dump_context->ostream() << (this->val_ ? "true" : "false"); }
+  
  private:
   // The constant.
   bool val_;
@@ -1566,6 +1642,15 @@ String_expression::do_import(Import* imp
   return Expression::make_string(val, imp->location());
 }
 
+// Ast dump for string expression.
+
+void
+String_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  // FIXME: Do proper backshlash quoting for this->val_
+  ast_dump_context->ostream() << "\"" << this->val_ << "\"";
+}
+
 // Make a string expression.
 
 Expression*
@@ -1595,6 +1680,10 @@ class Integer_expression : public Expres
   static void
   export_integer(Export* exp, const mpz_t val);
 
+  // Write VAL to dump context.
+  static void
+  dump_integer(Ast_dump_context* ast_dump_context, const mpz_t val);
+
  protected:
   bool
   do_is_constant() const
@@ -1623,6 +1712,9 @@ class Integer_expression : public Expres
   void
   do_export(Export*) const;
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The integer value.
   mpz_t val_;
@@ -1871,6 +1963,28 @@ Integer_expression::do_import(Import* im
     }
 }
 
+// Write integer to dump context.
+
+void
+Integer_expression::dump_integer(Ast_dump_context* ast_dump_context, 
+                                 const mpz_t val)
+{
+  // FIXME: refactor this code so that is used both by dump and export. Extract
+  // a common interface for Ast_dump_context and Export.
+  char* s = mpz_get_str(NULL, 10, val);
+  ast_dump_context->ostream() << s ;
+  free(s);
+}
+
+
+// Ast dump for integer expression.
+
+void
+Integer_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  Integer_expression::dump_integer(ast_dump_context, this->val_);
+}
+
 // Build a new integer value.
 
 Expression*
@@ -1903,6 +2017,10 @@ class Float_expression : public Expressi
   // Write VAL to export data.
   static void
   export_float(Export* exp, const mpfr_t val);
+  
+  // Write VAL to dump file.
+  static void
+  dump_float(Ast_dump_context* ast_dump_context, const mpfr_t val);
 
  protected:
   bool
@@ -1932,6 +2050,9 @@ class Float_expression : public Expressi
   void
   do_export(Export*) const;
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The floating point value.
   mpfr_t val_;
@@ -2109,6 +2230,35 @@ Float_expression::do_export(Export* exp)
   exp->write_c_string(" ");
 }
 
+// Write  a floating point number to a dump context.
+
+void
+Float_expression::dump_float(Ast_dump_context* ast_dump_context, 
+                                  const mpfr_t val)
+{
+  // FIXME: this code should be refactored so that the same code is used here
+  // and in export_float.
+
+  mp_exp_t exponent;
+  char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, GMP_RNDN);
+  if (*s == '-')
+    ast_dump_context->ostream() << "-";
+  ast_dump_context->ostream() << "0.";
+  ast_dump_context->ostream() << (*s == '-' ? s + 1 : s);
+  mpfr_free_str(s);
+  char buf[30];
+  snprintf(buf, sizeof buf, "E%ld", exponent);
+  ast_dump_context->ostream()  << buf;
+}
+
+// Dump a floating point number to the dump file.
+
+void
+Float_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  Float_expression::dump_float(ast_dump_context, this->val_);
+}
+
 // Make a float expression.
 
 Expression*
@@ -2143,6 +2293,11 @@ class Complex_expression : public Expres
   static void
   export_complex(Export* exp, const mpfr_t real, const mpfr_t val);
 
+  // Write REAL/IMAG to dump context.
+  static void
+  dump_complex(Ast_dump_context* ast_dump_context, 
+	       const mpfr_t real, const mpfr_t val);
+  
  protected:
   bool
   do_is_constant() const
@@ -2173,6 +2328,9 @@ class Complex_expression : public Expres
   void
   do_export(Export*) const;
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+  
  private:
   // The real part.
   mpfr_t real_;
@@ -2342,6 +2500,34 @@ Complex_expression::do_export(Export* ex
   exp->write_c_string(" ");
 }
 
+// Write a complex number to a dump context.
+
+void
+Complex_expression::dump_complex(Ast_dump_context* ast_dump_context,
+                                    const mpfr_t real, const mpfr_t imag) 
+{
+  // FIXME: this code should be refactored so that it is used both here
+  // and by export _complex
+  if (!mpfr_zero_p(real))
+    {
+      Float_expression::dump_float(ast_dump_context, real);
+      if (mpfr_sgn(imag) > 0)
+        ast_dump_context->ostream() << "+";
+    }
+  Float_expression::dump_float(ast_dump_context, imag);
+  ast_dump_context->ostream() << "i";
+}
+
+// Dump a complex expression to the dump file.
+
+void
+Complex_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  Complex_expression::dump_complex(ast_dump_context, 
+                                      this->real_,
+                                      this->imag_);
+}
+
 // Make a complex expression.
 
 Expression*
@@ -2443,6 +2629,9 @@ class Const_expression : public Expressi
   do_export(Export* exp) const
   { this->constant_->const_value()->expr()->export_expression(exp); }
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The constant.
   Named_object* constant_;
@@ -2824,6 +3013,14 @@ Const_expression::do_get_tree(Translate_
   return ret;
 }
 
+// Dump ast representation for constant expression.
+
+void
+Const_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << this->constant_->name();
+}
+
 // Make a reference to a constant in an expression.
 
 Expression*
@@ -2905,6 +3102,10 @@ class Nil_expression : public Expression
   void
   do_export(Export* exp) const
   { exp->write_c_string("nil"); }
+
+  void
+  do_dump_expression(Ast_dump_context* ast_dump_context) const
+  { ast_dump_context->ostream() << "nil"; }
 };
 
 // Import a nil expression.
@@ -2945,6 +3146,10 @@ class Iota_expression : public Parser_ex
   Expression*
   do_copy()
   { go_unreachable(); }
+  
+  void
+  do_dump_expression(Ast_dump_context* ast_dump_context) const
+  { ast_dump_context->ostream() << "iota"; } 
 };
 
 // Make an iota expression.  This is only called for one case: the
@@ -3040,6 +3245,9 @@ class Type_conversion_expression : publi
   void
   do_export(Export*) const;
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The type to convert to.
   Type* type_;
@@ -3570,6 +3778,18 @@ Type_conversion_expression::do_import(Im
   return Expression::make_cast(type, val, imp->location());
 }
 
+// Dump ast representation for a type conversion expression.
+
+void
+Type_conversion_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->dump_type(this->type_);
+  ast_dump_context->ostream() << "(";
+  ast_dump_context->dump_expression(this->expr_);
+  ast_dump_context->ostream() << ") ";
+}
+
 // Make a type cast expression.
 
 Expression*
@@ -3614,6 +3834,9 @@ class Unsafe_type_conversion_expression 
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The type to convert to.
   Type* type_;
@@ -3698,6 +3921,18 @@ Unsafe_type_conversion_expression::do_ge
     return fold_convert_loc(loc, type_tree, expr_tree);
 }
 
+// Dump ast representation for an unsafe type conversion expression.
+
+void
+Unsafe_type_conversion_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->dump_type(this->type_);
+  ast_dump_context->ostream() << "(";
+  ast_dump_context->dump_expression(this->expr_);
+  ast_dump_context->ostream() << ") ";
+}
+
 // Make an unsafe type conversion expression.
 
 Expression*
@@ -3801,6 +4036,9 @@ class Unary_expression : public Expressi
   void
   do_export(Export*) const;
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The unary operator to apply.
   Operator op_;
@@ -4412,6 +4650,17 @@ Unary_expression::do_import(Import* imp)
   return Expression::make_unary(op, expr, imp->location());
 }
 
+// Dump ast representation of an unary expression.
+
+void
+Unary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->dump_operator(this->op_);
+  ast_dump_context->ostream() << "(";
+  ast_dump_context->dump_expression(this->expr_);
+  ast_dump_context->ostream() << ") ";
+}
+
 // Make a unary expression.
 
 Expression*
@@ -6311,6 +6560,20 @@ Binary_expression::do_import(Import* imp
   return Expression::make_binary(op, left, right, imp->location());
 }
 
+// Dump ast representation of a binary expression.
+
+void
+Binary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << "(";
+  ast_dump_context->dump_expression(this->left_);
+  ast_dump_context->ostream() << " ";
+  ast_dump_context->dump_operator(this->op_);
+  ast_dump_context->ostream() << " ";
+  ast_dump_context->dump_expression(this->right_);
+  ast_dump_context->ostream() << ") ";
+}
+
 // Make a binary expression.
 
 Expression*
@@ -6643,6 +6906,26 @@ Bound_method_expression::do_get_tree(Tra
   return error_mark_node;
 }
 
+// Dump ast representation of a bound method expression.
+
+void
+Bound_method_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
+    const
+{
+  if (this->expr_type_ != NULL)
+    ast_dump_context->ostream() << "(";
+  ast_dump_context->dump_expression(this->expr_); 
+  if (this->expr_type_ != NULL) 
+    {
+      ast_dump_context->ostream() << ":";
+      ast_dump_context->dump_type(this->expr_type_);
+      ast_dump_context->ostream() << ")";
+    }
+    
+  ast_dump_context->ostream() << ".";
+  ast_dump_context->dump_expression(method_);
+}
+
 // Make a method expression.
 
 Bound_method_expression*
@@ -9298,6 +9581,19 @@ Call_expression::set_results(Translate_c
   return save_expr(stmt_list);
 }
 
+// Dump ast representation for a call expressin.
+
+void
+Call_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  this->fn_->dump_expression(ast_dump_context);
+  ast_dump_context->ostream() << "(";
+  if (args_ != NULL)
+    ast_dump_context->dump_expression_list(this->args_);
+
+  ast_dump_context->ostream() << ") ";
+}
+
 // Make a call expression.
 
 Call_expression*
@@ -9344,6 +9640,9 @@ class Call_result_expression : public Ex
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The underlying call expression.
   Expression* call_;
@@ -9443,6 +9742,19 @@ Call_result_expression::do_get_tree(Tran
   return ref->get_tree(context);
 }
 
+// Dump ast representation for a call result expression.
+
+void
+Call_result_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
+    const
+{
+  // FIXME: Wouldn't it be better if the call is assigned to a temporary 
+  // (struct) and the fields are referenced instead.
+  ast_dump_context->ostream() << this->index_ << "@(";
+  ast_dump_context->dump_expression(this->call_);
+  ast_dump_context->ostream() << ")";
+}
+
 // Make a reference to a single result of a call which returns
 // multiple results.
 
@@ -9519,6 +9831,36 @@ Index_expression::do_lower(Gogo*, Named_
     }
 }
 
+// Write an indexed expression (expr[expr:expr] or expr[expr]) to a
+// dump context
+
+void
+Index_expression::dump_index_expression(Ast_dump_context* ast_dump_context, 
+					const Expression* expr, 
+					const Expression* start,
+					const Expression* end)
+{
+  expr->dump_expression(ast_dump_context);
+  ast_dump_context->ostream() << "[";
+  start->dump_expression(ast_dump_context);
+  if (end != NULL)
+    {
+      ast_dump_context->ostream() << ":";
+      end->dump_expression(ast_dump_context);
+    }
+  ast_dump_context->ostream() << "]";
+}
+
+// Dump ast representation for an index expression.
+
+void
+Index_expression::do_dump_expression(Ast_dump_context* ast_dump_context) 
+    const
+{
+  Index_expression::dump_index_expression(ast_dump_context, this->left_, 
+                                          this->start_, this->end_);
+}
+
 // Make an index expression.
 
 Expression*
@@ -9573,6 +9915,9 @@ class Array_index_expression : public Ex
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+  
  private:
   // The array we are getting a value from.
   Expression* array_;
@@ -9922,6 +10267,16 @@ Array_index_expression::do_get_tree(Tran
 			 constructor);
 }
 
+// Dump ast representation for an array index expression.
+
+void
+Array_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context) 
+    const
+{
+  Index_expression::dump_index_expression(ast_dump_context, this->array_, 
+                                          this->start_, this->end_);
+}
+
 // Make an array index expression.  END may be NULL.
 
 Expression*
@@ -9976,6 +10331,9 @@ class String_index_expression : public E
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The string we are getting a value from.
   Expression* string_;
@@ -10176,6 +10534,16 @@ String_index_expression::do_get_tree(Tra
     }
 }
 
+// Dump ast representation for a string index expression.
+
+void
+String_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
+    const
+{
+  Index_expression::dump_index_expression(ast_dump_context, this->string_, 
+					  this->start_, this->end_);
+}
+
 // Make a string index expression.  END may be NULL.
 
 Expression*
@@ -10390,6 +10758,16 @@ Map_index_expression::get_value_pointer(
   return ret;
 }
 
+// Dump ast representation for a map index expression
+
+void
+Map_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context) 
+    const
+{
+  Index_expression::dump_index_expression(ast_dump_context, 
+                                          this->map_, this->index_, NULL);
+}
+
 // Make a map index expression.
 
 Map_index_expression*
@@ -10456,6 +10834,16 @@ Field_reference_expression::do_get_tree(
 		NULL_TREE);
 }
 
+// Dump ast representation for a field reference expression.
+
+void
+Field_reference_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  this->expr_->dump_expression(ast_dump_context);
+  ast_dump_context->ostream() << "." <<  this->field_index_;
+}
+
 // Make a reference to a qualified identifier in an expression.
 
 Field_reference_expression*
@@ -10602,6 +10990,16 @@ Interface_field_reference_expression::do
   go_unreachable();
 }
 
+// Dump ast representation for an interface field reference.
+
+void
+Interface_field_reference_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  this->expr_->dump_expression(ast_dump_context);
+  ast_dump_context->ostream() << "." << this->name_;
+}
+
 // Make a reference to a field in an interface.
 
 Expression*
@@ -10639,6 +11037,9 @@ class Selector_expression : public Parse
 				   this->location());
   }
 
+  void
+  do_dump_expression(Ast_dump_context* ast_dump_context) const;
+
  private:
   Expression*
   lower_method_expression(Gogo*);
@@ -10859,6 +11260,17 @@ Selector_expression::lower_method_expres
   return Expression::make_func_reference(no, NULL, location);
 }
 
+// Dump the ast for a selector expression.
+
+void
+Selector_expression::do_dump_expression(Ast_dump_context* ast_dump_context) 
+    const
+{
+  ast_dump_context->dump_expression(this->left_);
+  ast_dump_context->ostream() << ".";
+  ast_dump_context->ostream() << this->name_;
+}
+                      
 // Make a selector expression.
 
 Expression*
@@ -10898,6 +11310,9 @@ class Allocation_expression : public Exp
   tree
   do_get_tree(Translate_context*);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+  
  private:
   // The type we are allocating.
   Type* type_;
@@ -10919,6 +11334,17 @@ Allocation_expression::do_get_tree(Trans
   return fold_convert(build_pointer_type(type_tree), space);
 }
 
+// Dump ast representation for an allocation expression.
+
+void
+Allocation_expression::do_dump_expression(Ast_dump_context* ast_dump_context) 
+    const
+{
+  ast_dump_context->ostream() << "new(";
+  ast_dump_context->dump_type(this->type_);
+  ast_dump_context->ostream() << ")";
+}
+
 // Make an allocation expression.
 
 Expression*
@@ -10973,6 +11399,9 @@ class Struct_construction_expression : p
   void
   do_export(Export*) const;
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The type of the struct to construct.
   Type* type_;
@@ -11185,6 +11614,19 @@ Struct_construction_expression::do_expor
   exp->write_c_string(")");
 }
 
+// Dump ast representation of a struct construction expression.
+
+void
+Struct_construction_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+
+  ast_dump_context->dump_type(this->type_);
+  ast_dump_context->ostream() << "{";
+  ast_dump_context->dump_expression_list(this->vals_);
+  ast_dump_context->ostream() << "}";
+}
+
 // Make a struct composite literal.  This used by the thunk code.
 
 Expression*
@@ -11249,6 +11691,9 @@ protected:
   tree
   get_constructor_tree(Translate_context* context, tree type_tree);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The type of the array to construct.
   Type* type_;
@@ -11422,6 +11867,19 @@ Array_construction_expression::do_export
   exp->write_c_string(")");
 }
 
+// Dump ast representation of an array construction expressin.
+
+void
+Array_construction_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->dump_type(this->type_);
+  ast_dump_context->ostream() << "{" ;
+  ast_dump_context->dump_expression_list(this->vals_);
+  ast_dump_context->ostream() << "}" ;
+
+}
+
 // Construct a fixed array.
 
 class Fixed_array_construction_expression :
@@ -11688,6 +12146,9 @@ class Map_construction_expression : publ
   void
   do_export(Export*) const;
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+  
  private:
   // The type of the map to construct.
   Type* type_;
@@ -11941,6 +12402,18 @@ Map_construction_expression::do_export(E
   exp->write_c_string(")");
 }
 
+// Dump ast representation for a map construction expression.
+
+void
+Map_construction_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  // FIXME: We should print key:value pairs here.
+  ast_dump_context->ostream() << "{" ;
+  ast_dump_context->dump_expression_list(this->vals_);
+  ast_dump_context->ostream() << "}";
+}
+
 // A general composite literal.  This is lowered to a type specific
 // version.
 
@@ -11971,6 +12444,9 @@ class Composite_literal_expression : pub
 					    this->location());
   }
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+  
  private:
   Expression*
   lower_struct(Gogo*, Type*);
@@ -12382,6 +12858,20 @@ Composite_literal_expression::lower_map(
   return new Map_construction_expression(type, this->vals_, location);
 }
 
+// Dump ast representation for a composite literal expression.
+
+void
+Composite_literal_expression::do_dump_expression(
+                               Ast_dump_context* ast_dump_context) const
+{
+  // FIXME: We should print colons if this->has_keys_ is true
+  ast_dump_context->ostream() << "composite_literal(" ;
+  ast_dump_context->dump_type(this->type_);
+  ast_dump_context->ostream() << ", {";
+  ast_dump_context->dump_expression_list(this->vals_);
+  ast_dump_context->ostream() << "})";
+}
+
 // Make a composite literal expression.
 
 Expression*
@@ -12556,6 +13046,17 @@ Type_guard_expression::do_get_tree(Trans
 					      this->location());
 }
 
+// Dump ast representation for a type guard expression.
+
+void
+Type_guard_expression::do_dump_expression(Ast_dump_context* ast_dump_context) 
+    const
+{
+  this->expr_->dump_expression(ast_dump_context);
+  ast_dump_context->ostream() <<  ".";
+  ast_dump_context->dump_type(this->type_);
+}
+
 // Make a type guard expression.
 
 Expression*
@@ -12607,6 +13108,9 @@ class Heap_composite_expression : public
   do_export(Export*) const
   { go_unreachable(); }
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The composite literal which is being put on the heap.
   Expression* expr_;
@@ -12635,6 +13139,17 @@ Heap_composite_expression::do_get_tree(T
   return ret;
 }
 
+// Dump ast representation for a heap composite expression.
+
+void
+Heap_composite_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << "&(";
+  ast_dump_context->dump_expression(this->expr_);
+  ast_dump_context->ostream() << ")";
+}
+
 // Allocate a composite literal on the heap.
 
 Expression*
@@ -12702,6 +13217,15 @@ Receive_expression::do_get_tree(Translat
 				    this->for_select_, this->location());
 }
 
+// Dump ast representation for a receive expression.
+
+void
+Receive_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << " <- " ;
+  ast_dump_context->dump_expression(channel_);
+}
+
 // Make a receive expression.
 
 Receive_expression*
@@ -12741,11 +13265,23 @@ class Type_descriptor_expression : publi
 						this->location());
   }
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The type for which this is the descriptor.
   Type* type_;
 };
 
+// Dump ast representation for a type descriptor expression.
+
+void
+Type_descriptor_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->dump_type(this->type_);
+}
+
 // Make a type descriptor expression.
 
 Expression*
@@ -12783,6 +13319,9 @@ class Type_info_expression : public Expr
   tree
   do_get_tree(Translate_context* context);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+
  private:
   // The type for which we are getting information.
   Type* type_;
@@ -12834,6 +13373,23 @@ Type_info_expression::do_get_tree(Transl
     }
 }
 
+// Dump ast representation for a type info expression.
+
+void
+Type_info_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << "typeinfo(";
+  ast_dump_context->dump_type(this->type_);
+  ast_dump_context->ostream() << ",";
+  ast_dump_context->ostream() << 
+    (this->type_info_ == TYPE_INFO_ALIGNMENT ? "alignment" 
+    : this->type_info_ == TYPE_INFO_FIELD_ALIGNMENT ? "field alignment"
+    : this->type_info_ == TYPE_INFO_SIZE ? "size "
+    : "unknown");
+  ast_dump_context->ostream() << ")";
+}
+
 // Make a type info expression.
 
 Expression*
@@ -12870,6 +13426,9 @@ class Struct_field_offset_expression : p
   tree
   do_get_tree(Translate_context* context);
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+  
  private:
   // The type of the struct.
   Struct_type* type_;
@@ -12906,6 +13465,17 @@ Struct_field_offset_expression::do_get_t
 			  byte_position(struct_field_tree));
 }
 
+// Dump ast representation for a struct field offset expression.
+
+void
+Struct_field_offset_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() <<  "unsafe.Offsetof(";
+  ast_dump_context->ostream() << this->field_->field_name();
+  ast_dump_context->ostream() << ")";
+}
+
 // Make an expression for a struct field offset.
 
 Expression*
@@ -12946,11 +13516,25 @@ class Map_descriptor_expression : public
 					       this->location());
   }
 
+  void
+  do_dump_expression(Ast_dump_context*) const;
+ 
  private:
   // The type for which this is the descriptor.
   Map_type* type_;
 };
 
+// Dump ast representation for a map descriptor expression.
+
+void
+Map_descriptor_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context) const
+{
+  ast_dump_context->ostream() << "map_descriptor(";
+  ast_dump_context->dump_type(this->type_);
+  ast_dump_context->ostream() << ")";
+}
+
 // Make a map descriptor expression.
 
 Expression*
@@ -12988,6 +13572,10 @@ class Label_addr_expression : public Exp
     return expr_to_tree(this->label_->get_addr(context, this->location()));
   }
 
+  void
+  do_dump_expression(Ast_dump_context* ast_dump_context) const
+  { ast_dump_context->ostream() << this->label_->name(); }
+  
  private:
   // The label whose address we are taking.
   Label* label_;

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