compiler: add debugger-callable AST dump functins
    
    Introduce a set debug_go_* global functions that can be used to emit
    AST dumps for Go statements and expressions from within GDB (for use
    by people developing gccgo).
    
    Reviewed-on: https://go-review.googlesource.com/c/162903


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@269027 138bc75d-0d04-0410-961f-82ee72b054a4
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index e3db885..12dd965 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-fe0382eabbf1e8b148dc8cb7733348bd9d887e10
+08cd59a502127da776e076a8a37016a668ef27fa
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/ast-dump.cc b/gcc/go/gofrontend/ast-dump.cc
index 1fbc890..9b4d708 100644
--- a/gcc/go/gofrontend/ast-dump.cc
+++ b/gcc/go/gofrontend/ast-dump.cc
@@ -482,7 +482,7 @@
   this->ostream() << s;
 }
 
-// Dump statment to stream.
+// Dump statement to stream.
 
 void
 Ast_dump_context::dump_to_stream(const Statement* stm, std::ostream* out)
@@ -499,3 +499,84 @@
   Ast_dump_context adc(out, false);
   expr->dump_expression(&adc);
 }
+
+// Dump an expression to std::cerr. This is intended to be used
+// from within a debugging session.
+
+void
+debug_go_expression(const Expression* expr)
+{
+  if (expr == NULL)
+    std::cerr << "<null>";
+  else
+    {
+      Ast_dump_context::dump_to_stream(expr, &std::cerr);
+      std::string lstr = Linemap::location_to_string(expr->location());
+      std::cerr << " // loc " << lstr << std::endl;
+    }
+}
+
+// Shallow dump of stmt to std::cerr. This is intended to be used
+// from within a debugging session.
+
+void
+debug_go_statement(const Statement* stmt)
+{
+  if (stmt == NULL)
+    std::cerr << "<null>\n";
+  else
+    {
+      std::string lstr = Linemap::location_to_string(stmt->location());
+      Statement *ncstmt = const_cast<Statement*>(stmt);
+      Block_statement* bs = ncstmt->block_statement();
+      if (bs != NULL)
+        std::cerr << "Block " << bs->block()
+                  << " // location: " << lstr << std::endl;
+      else
+        Ast_dump_context::dump_to_stream(stmt, &std::cerr);
+    }
+}
+
+// Deep dump of statement to std::cerr. This is intended to be used
+// from within a debugging session.
+
+void
+debug_go_statement_deep(const Statement* statement)
+{
+  Ast_dump_context adc(&std::cerr, true);
+  statement->dump_statement(&adc);
+}
+
+// Shallow dump of a block to std::cerr. This is intended to be used
+// from within a debugging session.
+
+void
+debug_go_block(const Block* block)
+{
+  if (block == NULL)
+    std::cerr << "<null>";
+  else
+    {
+      std::cerr << "Block " << block
+                << " (enclosing " << block->enclosing() << "):\n";
+      const std::vector<Statement*>* stmts = block->statements();
+      if (stmts != NULL)
+        {
+          for (size_t i = 0; i < stmts->size(); ++i)
+            {
+              debug_go_statement(stmts->at(i));
+            }
+        }
+    }
+}
+
+// Deep dump of a block to std:cerr. This is intended to be used
+// from within a debugging session.
+
+void
+debug_go_block_deep(const Block* block)
+{
+  Ast_dump_context adc(&std::cerr, true);
+  Block* ncblock = const_cast<Block*>(block);
+  adc.dump_block(ncblock);
+}