]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/go/gofrontend/statements.cc
gccgo: Added code to dump the AST tree.
[thirdparty/gcc.git] / gcc / go / gofrontend / statements.cc
index dd2aef6f10a04b8c01111a9065c14f9aeb59a917..c6d2ace91f841ce5983254c75bc5f534c198c480 100644 (file)
@@ -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* 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_backend(Translate_context* context)
   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_variable(Translate_context* context) const
   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 Statement
   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(Translate_context* context)
                                                  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 : public Statement
   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(Gogo*, Named_object*,
     }
 }
 
+// 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 : public Statement
   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(Gogo*, Named_object*, Block* enclosing,
   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(Gogo*, Named_object*, Block* enclosing,
   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(Gogo*, Named_object*,
   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 Statement
   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*, Named_object*, Block* enclosing,
   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 : public 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_lower(Gogo*, Named_object*,
   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_statement : public Statement
   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::lower_to_object_type(
   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 Statement
   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(Translate_context* context)
   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(Translate_context* context)
   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 Statement
   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_object*, Block*, Statement_inserter*)
   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_context* context)
   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(Translate_context* context)
   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(Translate_context* context)
                                              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_context* context)
   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 Statement
   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(Translate_context* context)
   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 Statement
   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_context* context)
                                          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(Translate_context* context,
     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_context* context,
     }
 }
 
+// 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 Statement
   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_backend(Translate_context* context)
   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::lower(Block* b,
     }
 }
 
+// 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, Temporary_statement* descriptor_temp,
     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_context* context)
     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_statements_backend(
   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(Translate_context* context)
                                     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(Unnamed_label* break_label,
   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*