// ast-dump.cc -- AST debug dump.    -*- C++ -*-

// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go-system.h"

#include <iostream>
#include <fstream>
#include <sstream>

#include "gogo.h"
#include "expressions.h"
#include "statements.h"
#include "types.h"
#include "ast-dump.h"
#include "go-c.h"
#include "go-dump.h"
#include "go-diagnostics.h"

// The -fgo-dump-ast flag to activate AST dumps.

Go_dump ast_dump_flag("ast");

// This class is used to traverse the tree to look for blocks and
// function headers.

class Ast_dump_traverse_blocks_and_functions : public Traverse
{
 public:
  Ast_dump_traverse_blocks_and_functions(Ast_dump_context* ast_dump_context)
      : Traverse(traverse_blocks | traverse_functions | traverse_variables),
      ast_dump_context_(ast_dump_context)
  { }

 protected:
  int
  block(Block*);

  int
  function(Named_object*);

  int
  variable(Named_object*);

 private:
  Ast_dump_context* ast_dump_context_;
};

// This class is used to traverse the tree to look for statements.

class Ast_dump_traverse_statements : public Traverse
{
 public:
  Ast_dump_traverse_statements(Ast_dump_context* ast_dump_context)
      : Traverse(traverse_statements),
      ast_dump_context_(ast_dump_context)
  { }

 protected:
  int
  statement(Block*, size_t* pindex, Statement*);

 private:
  Ast_dump_context* ast_dump_context_;
};

// For each block we enclose it in brackets.

int Ast_dump_traverse_blocks_and_functions::block(Block * block)
{
  if (block == NULL)
    {
      this->ast_dump_context_->ostream() << std::endl;
      return TRAVERSE_EXIT;
    }

  this->ast_dump_context_->print_indent();
  this->ast_dump_context_->ostream() << "{" << std::endl;
  this->ast_dump_context_->indent();

  // Dump statememts.
  Ast_dump_traverse_statements adts(this->ast_dump_context_);
  block->traverse(&adts);

  this->ast_dump_context_->unindent();
  this->ast_dump_context_->print_indent();
  this->ast_dump_context_->ostream() << "}" << std::endl;

  return TRAVERSE_SKIP_COMPONENTS;
}

// Dump each traversed statement.

int
Ast_dump_traverse_statements::statement(Block* block, size_t* pindex,
                                        Statement* statement)
{
  statement->dump_statement(this->ast_dump_context_);

  if (statement->is_block_statement())
    {
      Ast_dump_traverse_blocks_and_functions adtbf(this->ast_dump_context_);
      statement->traverse(block, pindex, &adtbf);
    }

  return TRAVERSE_SKIP_COMPONENTS;
}

// Dump the function header.

int
Ast_dump_traverse_blocks_and_functions::function(Named_object* no)
{
  this->ast_dump_context_->ostream() << no->name();

  go_assert(no->is_function());
  Function* func = no->func_value();

  this->ast_dump_context_->ostream() << "(";
  this->ast_dump_context_->dump_typed_identifier_list(
                              func->type()->parameters());

  this->ast_dump_context_->ostream() << ")";

  Function::Results* res = func->result_variables();
  if (res != NULL && !res->empty())
    {
      this->ast_dump_context_->ostream() << " (";

      for (Function::Results::const_iterator it = res->begin();
          it != res->end();
          it++)
        {
          if (it != res->begin())
            this->ast_dump_context_->ostream() << ",";
          Named_object* no = (*it);

          this->ast_dump_context_->ostream() << no->name() << " ";
          go_assert(no->is_result_variable());
          Result_variable* resvar = no->result_var_value();

          this->ast_dump_context_->dump_type(resvar->type());

        }
      this->ast_dump_context_->ostream() << ")";
    }

  this->ast_dump_context_->ostream() << " : ";
  this->ast_dump_context_->dump_type(func->type());
  this->ast_dump_context_->ostream() << std::endl;

  return TRAVERSE_CONTINUE;
}

// Dump variable preinits

int
Ast_dump_traverse_blocks_and_functions::variable(Named_object* no)
{
  if (!no->is_variable())
    return TRAVERSE_CONTINUE;

  Variable* var = no->var_value();
  if (var->has_pre_init())
    {
      this->ast_dump_context_->ostream() << "// preinit block for var "
                                         << no->message_name() << "\n";
      var->preinit()->traverse(this);
    }

  return TRAVERSE_CONTINUE;
}



// Class Ast_dump_context.

Ast_dump_context::Ast_dump_context(std::ostream* out /* = NULL */,
				   bool dump_subblocks /* = true */)
  :  indent_(0), dump_subblocks_(dump_subblocks), ostream_(out), gogo_(NULL)
{
}

// Dump files will be named %basename%.dump.ast

const char* kAstDumpFileExtension = ".dump.ast";

// Dump the internal representation.

void
Ast_dump_context::dump(Gogo* gogo, const char* basename)
{
  std::ofstream out;
  std::string dumpname(basename);
  dumpname += ".dump.ast";
  out.open(dumpname.c_str());

  if (out.fail())
    {
      go_error_at(Linemap::unknown_location(),
		  "cannot open %s:%m; %<-fgo-dump-ast%> ignored",
		  dumpname.c_str());
      return;
    }

  this->gogo_ = gogo;
  this->ostream_ = &out;

  Ast_dump_traverse_blocks_and_functions adtbf(this);
  gogo->traverse(&adtbf);

  out.close();
}

// Dump a textual representation of a type to the
// the dump file.

void
Ast_dump_context::dump_type(const Type* t)
{
  if (t == NULL)
    this->ostream() << "(nil type)";
  else
    // FIXME: write a type pretty printer instead of
    // using mangled names.
    if (this->gogo_ != NULL)
      this->ostream() << "(" << t->mangled_name(this->gogo_) <<  ")";
}

// Dump a textual representation of a block to the
// the dump file.

void
Ast_dump_context::dump_block(Block* b)
{
  Ast_dump_traverse_blocks_and_functions adtbf(this);
  b->traverse(&adtbf);
}

// Dump a textual representation of an expression to the
// the dump file.

void
Ast_dump_context::dump_expression(const Expression* e)
{
  e->dump_expression(this);
}

// Dump a textual representation of an expression list to the
// the dump file.

void
Ast_dump_context::dump_expression_list(const Expression_list* el,
				       bool as_pairs /* = false */)
{
  if (el == NULL)
    return;

  for (std::vector<Expression*>::const_iterator it = el->begin();
       it != el->end();
       it++)
    {
      if ( it != el->begin())
        this->ostream() << ",";
      if (*it != NULL)
	(*it)->dump_expression(this);
      else
        this->ostream() << "NULL";
      if (as_pairs)
        {
	  this->ostream() << ":";
	  ++it;
	  (*it)->dump_expression(this);
        }
    }
}

// Dump a textual representation of a typed identifier to the
// the dump file.

void
Ast_dump_context::dump_typed_identifier(const Typed_identifier* ti)
{
  this->ostream() << ti->name() << " ";
  this->dump_type(ti->type());
}

// Dump a textual representation of a typed identifier list to the
// the dump file.

void
Ast_dump_context::dump_typed_identifier_list(
    const Typed_identifier_list* ti_list)
{
  if (ti_list == NULL)
    return;

  for (Typed_identifier_list::const_iterator it = ti_list->begin();
       it != ti_list->end();
       it++)
    {
      if (it != ti_list->begin())
        this->ostream() << ",";
      this->dump_typed_identifier(&(*it));
    }
}

// Dump a textual representation of a temporary variable to the
// the dump file.

void
Ast_dump_context::dump_temp_variable_name(const Statement* s)
{
  go_assert(s->classification() == Statement::STATEMENT_TEMPORARY);
  // Use the statement address as part of the name for the temporary variable.
  this->ostream() << "tmp." << (uintptr_t) s;
}

// Dump a textual representation of a label to the
// the dump file.

void
Ast_dump_context::dump_label_name(const Unnamed_label* l)
{
  // Use the unnamed label address as part of the name for the temporary
  // variable.
  this->ostream() << "label." << (uintptr_t) l;
}

// Produce a textual representation of an operator symbol.

static const char*
op_string(Operator op)
{
// FIXME: This should be in line with symbols that are parsed,
// exported and/or imported.
  switch (op)
    {
    case OPERATOR_PLUS:
      return "+";
    case OPERATOR_MINUS:
      return "-";
    case OPERATOR_NOT:
      return "!";
    case OPERATOR_XOR:
      return "^";
    case OPERATOR_OR:
      return "|";
    case OPERATOR_AND:
      return "&";
    case OPERATOR_MULT:
      return "*";
    case OPERATOR_OROR:
      return "||";
    case OPERATOR_ANDAND:
      return "&&";
    case OPERATOR_EQEQ:
      return "==";
    case OPERATOR_NOTEQ:
      return "!=";
    case OPERATOR_LT:
      return "<";
    case OPERATOR_LE:
      return "<=";
    case OPERATOR_GT:
      return ">";
    case OPERATOR_GE:
      return ">=";
    case OPERATOR_DIV:
      return "/";
    case OPERATOR_MOD:
      return "%";
    case OPERATOR_LSHIFT:
      return "<<";
    case OPERATOR_RSHIFT:
      return "//";
    case OPERATOR_BITCLEAR:
      return "&^";
    case OPERATOR_CHANOP:
      return "<-";
    case OPERATOR_PLUSEQ:
      return "+=";
    case OPERATOR_MINUSEQ:
      return "-=";
    case OPERATOR_OREQ:
      return "|=";
    case OPERATOR_XOREQ:
      return "^=";
    case OPERATOR_MULTEQ:
      return "*=";
    case OPERATOR_DIVEQ:
      return "/=";
    case OPERATOR_MODEQ:
      return "%=";
    case OPERATOR_LSHIFTEQ:
      return "<<=";
    case OPERATOR_RSHIFTEQ:
      return ">>=";
    case OPERATOR_ANDEQ:
      return "&=";
    case OPERATOR_BITCLEAREQ:
      return "&^=";
    case OPERATOR_PLUSPLUS:
      return "++";
    case OPERATOR_MINUSMINUS:
      return "--";
    case OPERATOR_COLON:
      return ":";
    case OPERATOR_COLONEQ:
      return ":=";
    case OPERATOR_SEMICOLON:
      return ";";
    case OPERATOR_DOT:
      return ".";
    case OPERATOR_ELLIPSIS:
      return "...";
    case OPERATOR_COMMA:
      return ",";
    case OPERATOR_LPAREN:
      return "(";
    case OPERATOR_RPAREN:
      return ")";
    case OPERATOR_LCURLY:
      return "{";
    case OPERATOR_RCURLY:
      return "}";
    case OPERATOR_LSQUARE:
      return "[";
    case OPERATOR_RSQUARE:
      return "]";
    default:
      go_unreachable();
    }
  return NULL;
}

// Dump a textual representation of an operator to the
// the dump file.

void
Ast_dump_context::dump_operator(Operator op)
{
  this->ostream() << op_string(op);
}

// Size of a single indent.

const int Ast_dump_context::offset_ = 2;

// Print indenting spaces to dump file.

void
Ast_dump_context::print_indent()
{
  for (int i = 0; i < this->indent_ * this->offset_; i++)
    this->ostream() << " ";
}

// Dump a textual representation of the ast to the
// the dump file.

void Gogo::dump_ast(const char* basename)
{
  if (::ast_dump_flag.is_enabled())
    {
      Ast_dump_context adc;
      adc.dump(this, basename);
    }
}

// Implementation of String_dump interface.

void
Ast_dump_context::write_c_string(const char* s)
{
  this->ostream() << s;
}

void
Ast_dump_context::write_string(const std::string& s)
{
  this->ostream() << s;
}

// Dump statement to stream.

void
Ast_dump_context::dump_to_stream(const Statement* stm, std::ostream* out)
{
  Ast_dump_context adc(out, false);
  stm->dump_statement(&adc);
}

// Dump expression to stream.

void
Ast_dump_context::dump_to_stream(const Expression* expr, std::ostream* out)
{
  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);
}

class Type_dumper
{
  typedef Unordered_map(const Type*, unsigned) idx_map;
 public:
  Type_dumper(const Type* type)
      : top_(type), ntypes_(0)
  {
    this->worklist_.push_back(type);
  }

  void visit();

  std::string stringResult() { return ss_.str(); }

 private:
  void emitpre(unsigned tag, const Type* addr);
  void typeref(const char*, const Type*, const char *);
  void visit_forward_declaration_type(const Forward_declaration_type* fdt);
  void visit_function_type(const Function_type* ft);
  void visit_struct_type(const Struct_type* st);
  void visit_array_type(const Array_type* at);
  void visit_map_type(const Map_type* mt);
  void visit_channel_type(const Channel_type* mt);
  void visit_interface_type(const Interface_type* mt);
  void visit_methods(const Typed_identifier_list* methods,
                     const char *tag);
  std::pair<bool, unsigned> lookup(const Type*);

  static const unsigned notag = 0xffffffff;

 private:
  const Type* top_;
  idx_map types_;
  unsigned ntypes_;
  std::list<const Type*> worklist_;
  std::ostringstream ss_;
};

// Look up a type, installing it in 'types_'. Return is <found, N>
// where 'found' is true if type had been previously recorded, and N
// is the index/tag assigned to N.  The input argument is appended to
// the work list if this is the first time we've seen it.

std::pair<bool, unsigned> Type_dumper::lookup(const Type* t)
{
  std::pair<const Type*, unsigned> entry = std::make_pair(t, this->ntypes_);
  std::pair<idx_map::iterator, bool> ins = this->types_.insert(entry);
  if (ins.second)
    {
      this->ntypes_++;
      if (t != this->top_)
        this->worklist_.push_back(t);
    }
  return std::make_pair(ins.second, ins.first->second);
}

// Emit preamble prior to dumping a type, including the type
// pointer itself and the tag we've assigned it.  If no
// tag is specified (via special "notag" value) and/or the
// pointer is null, then just emit an equivalent amount
// of spaces.

void Type_dumper::emitpre(unsigned tag, const Type* ptr)
{
  char tbuf[50], pbuf[50], buf[200];

  tbuf[0] = '\0';
  if (tag != notag)
    snprintf(tbuf, sizeof tbuf, "T%u", tag);

  pbuf[0] = '\0';
  if (ptr != NULL)
    snprintf(pbuf, sizeof pbuf, "%p", (const void*) ptr);

  snprintf(buf, sizeof buf, "%8s %16s  ", tbuf, pbuf);
  this->ss_ << buf;
}

// Emit a reference to a type into the dump buffer. In most cases this means
// just the type tag, but for named types we also emit the name, and for
// simple/primitive types (ex: int64) we emit the type itself. If "pref" is
// non-NULL, emit the string prior to the reference, and if "suf" is non-NULL,
// emit it following the reference.

void Type_dumper::typeref(const char* pref, const Type* t, const char* suf)
{
  if (pref != NULL)
    this->ss_ << pref;
  std::pair<bool, unsigned> p = this->lookup(t);
  unsigned tag = p.second;
  switch (t->classification())
    {
      case Type::TYPE_NAMED:
        {
          const Named_type* nt = t->named_type();
          const Named_object* no = nt->named_object();
          this->ss_ << "'" << no->message_name() << "' -> ";
          const Type* underlying = nt->real_type();
          this->typeref(NULL, underlying, NULL);
          break;
        }
      case Type::TYPE_POINTER:
        this->typeref("*", t->points_to(), NULL);
        break;
      case Type::TYPE_ERROR:
        this->ss_ << "error_type";
        break;
      case Type::TYPE_INTEGER:
        {
          const Integer_type* it = t->integer_type();
          if (it->is_abstract())
            this->ss_ << "abstract_int";
          else
            this->ss_ << (it->is_unsigned() ? "u" : "") << "int" << it->bits();
          break;
        }
      case Type::TYPE_FLOAT:
        {
          const Float_type* ft = t->float_type();
          if (ft->is_abstract())
            this->ss_ << "abstract_float";
          else
            this->ss_ << "float" << ft->bits();
          break;
        }
      case Type::TYPE_COMPLEX:
        {
          const Complex_type* ct = t->complex_type();
          if (ct->is_abstract())
            this->ss_ << "abstract_complex";
          else
            this->ss_ << "complex" << ct->bits();
          break;
        }
      case Type::TYPE_BOOLEAN:
        this->ss_ << "bool";
        break;
      case Type::TYPE_STRING:
        this->ss_ << "string";
        break;
      case Type::TYPE_NIL:
        this->ss_ << "nil_type";
        break;
    case Type::TYPE_VOID:
        this->ss_ << "void_type";
        break;
    case Type::TYPE_FUNCTION:
    case Type::TYPE_STRUCT:
    case Type::TYPE_ARRAY:
    case Type::TYPE_MAP:
    case Type::TYPE_CHANNEL:
    case Type::TYPE_FORWARD:
    case Type::TYPE_INTERFACE:
      this->ss_ << "T" << tag;
      break;

    default:
      // This is a debugging routine, so instead of a go_unreachable()
      // issue a warning/error, to allow for the possibility that the
      // compiler we're debugging is in a bad state.
      this->ss_ << "<??? " << ((unsigned)t->classification()) << "> "
                << "T" << tag;
    }
  if (suf != NULL)
    this->ss_ << suf;
}

void Type_dumper::visit_forward_declaration_type(const Forward_declaration_type* fdt)
{
  this->ss_ << "forward_declaration_type ";
  if (fdt->is_defined())
    this->typeref("-> ", fdt->real_type(), NULL);
  else
    this->ss_ << "'" << fdt->name() << "'";
  this->ss_ << "\n";
}

void Type_dumper::visit_function_type(const Function_type* ft)
{
  this->ss_ << "function\n";
  const Typed_identifier* rec = ft->receiver();
  if (rec != NULL)
    {
      this->emitpre(notag, NULL);
      this->typeref("receiver ", rec->type(), "\n");
    }
  const Typed_identifier_list* parameters = ft->parameters();
  if (parameters != NULL)
    {
      for (Typed_identifier_list::const_iterator p = parameters->begin();
	   p != parameters->end();
	   ++p)
        {
          this->emitpre(notag, NULL);
          this->typeref(" param ", p->type(), "\n");
        }
    }
  const Typed_identifier_list* results = ft->results();
  if (results != NULL)
    {
      for (Typed_identifier_list::const_iterator p = results->begin();
	   p != results->end();
	   ++p)
        {
          this->emitpre(notag, NULL);
          this->typeref(" result ", p->type(), "\n");
        }
    }
}

void Type_dumper::visit_struct_type(const Struct_type* st)
{
  this->ss_ << "struct\n";
  const Struct_field_list* fields = st->fields();
  if (fields != NULL)
    {
      for (Struct_field_list::const_iterator p = fields->begin();
           p != fields->end();
           ++p)
        {
          this->emitpre(notag, NULL);
          this->typeref(" field ", p->type(), "\n");
        }
    }
}

void Type_dumper::visit_array_type(const Array_type* at)
{
  this->ss_ << "array [";
  if (at->length() != NULL)
    {
      int64_t len = 0;
      if (at->int_length(&len))
        this->ss_ << len;
    }
  this->typeref("] ", at->element_type(), "\n");
}

void Type_dumper::visit_map_type(const Map_type* mt)
{
  this->ss_ << "map [";
  this->typeref(NULL, mt->key_type(), NULL);
  this->typeref("] ", mt->val_type(), "\n");
}

void Type_dumper::visit_methods(const Typed_identifier_list* methods,
                                const char *tag)
{
  if (tag != NULL)
    {
      this->emitpre(notag, NULL);
      this->ss_ << tag << "\n";
    }
  for (Typed_identifier_list::const_iterator p = methods->begin();
       p != methods->end();
       ++p)
    {
      this->emitpre(notag, NULL);
      if (p->name().empty())
        this->typeref("  embedded method ", p->type(), "\n");
      else
        {
          this->ss_ << "  method '" << p->name() << "' ";
          this->typeref(NULL, p->type(), "\n");
        }
    }
}

void Type_dumper::visit_interface_type(const Interface_type* it)
{
  const Typed_identifier_list* methods =
      (it->methods_are_finalized() ? it->methods() : it->local_methods());
  if (methods == NULL)
    {
      this->ss_ << "empty_interface\n";
      return;
    }
  this->ss_ << "interface";
  if (! it->methods_are_finalized())
    {
      this->ss_ << " [unfinalized]\n";
      visit_methods(it->local_methods(), NULL);
    }
  else
    {
      this->ss_ << "\n";
      visit_methods(it->local_methods(), "[parse_methods]");
      visit_methods(it->methods(), "[all_methods]");
    }
}

void Type_dumper::visit_channel_type(const Channel_type* ct)
{
  this->ss_ << "channel {";
  if (ct->may_send())
    this->ss_ << " send";
  if (ct->may_receive())
    this->ss_ << " receive";
  this->typeref(" } ", ct->element_type(), "\n");
}

void Type_dumper::visit()
{
  while (! this->worklist_.empty()) {
    const Type* t = this->worklist_.front();
    this->worklist_.pop_front();

    std::pair<bool, unsigned> p = this->lookup(t);
    unsigned tag = p.second;
    this->emitpre(tag, t);

    switch(t->classification())
      {
        case Type::TYPE_ERROR:
        case Type::TYPE_INTEGER:
        case Type::TYPE_FLOAT:
        case Type::TYPE_COMPLEX:
        case Type::TYPE_BOOLEAN:
        case Type::TYPE_STRING:
        case Type::TYPE_VOID:
        case Type::TYPE_POINTER:
        case Type::TYPE_NIL:
        case Type::TYPE_NAMED:
          this->typeref(NULL, t, "\n");
          break;
        case Type::TYPE_FORWARD:
          this->visit_forward_declaration_type(t->forward_declaration_type());
          break;

        case Type::TYPE_FUNCTION:
          this->visit_function_type(t->function_type());
          break;
        case Type::TYPE_STRUCT:
          this->visit_struct_type(t->struct_type());
          break;
        case Type::TYPE_ARRAY:
          this->visit_array_type(t->array_type());
          break;
        case Type::TYPE_MAP:
          this->visit_map_type(t->map_type());
          break;
        case Type::TYPE_CHANNEL:
          this->visit_channel_type(t->channel_type());
          break;
        case Type::TYPE_INTERFACE:
          this->visit_interface_type(t->interface_type());
          break;
        default:
          // This is a debugging routine, so instead of a go_unreachable()
          // issue a warning/error, to allow for the possibility that the
          // compiler we're debugging is in a bad state.
          this->ss_ << "<unknown/unrecognized classification "
                    << ((unsigned)t->classification()) << ">\n";
      }
  }
}

// Dump a Go type for debugging purposes. This is a deep as opposed
// to shallow dump; all of the types reachable from the specified
// type will be dumped in addition to the type itself.

void debug_go_type(const Type* type)
{
  if (type == NULL)
    {
      std::cerr << "<NULL type>\n";
      return;
    }
  Type_dumper dumper(type);
  dumper.visit();
  std::cerr << dumper.stringResult();
}

void debug_go_type(Type* type)
{
  const Type* ctype = type;
  debug_go_type(ctype);
}
