// 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 constexpr 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(), NULL);
    }
  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);
}
