// names.cc -- Names used by gofrontend generated code.

// Copyright 2017 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 "gogo.h"
#include "go-encode-id.h"
#include "types.h"
#include "expressions.h"

// This file contains functions that generate names that appear in the
// assembly code.  This is not used for names that appear only in the
// debug info.

// Our external names may contain only ASCII alphanumeric characters,
// underscore, and dot.  (According to the GCC sources, dot is not
// permitted in assembler symbols on VxWorks and MMIX.  We will not
// support those systems.)  Go identifiers cannot contain dot, but Go
// package paths can.  Both Go identifiers and package paths can, of
// course, contain all sorts of Unicode characters.
//
// The gc compiler uses names like "pkg.F", and it seems convenient to
// emulate that.  Therefore, we will use dot to separate different
// components of names.
//
// Since package paths can contain dot, to avoid ambiguity we must
// encode package paths such that they do not contain any dot.  The
// natural way to do this is to encode forbidden characters, including
// dot, using a notation based on underscore.  We will, of course,
// have to encode underscore itself.
//
// Since we will be using an underscore encoding for the package path,
// it seems reasonable to use the same encoding for Go identifiers.
// This has the disadvantage that encoded Go identifiers will appear
// to be valid Go identifiers with funny spellings, but it seems like
// the best available approach.
//
// Therefore, in the following discussion we may assume that none of
// the names under discussion contain a dot.  All of the names we
// generate for Go identifiers (that don't use //export or
// //go:linkname) will contain at least one dot, as discussed below.
// We assume that none of the non-Go symbols in the final link will
// contain a dot, so we don't worry about conflicts.
//
// We first describe the basic symbol names, used to represent Go
// functions and variables.
//
// The external name for a normal Go symbol NAME, a function or
// variable, is simply "PKGPATH.NAME".  Note that NAME is not the
// packed form used for the "hidden" name internally in the compiler;
// it is the name that appears in the source code.  Both PKGPATH and
// NAME will be encoded as described below.  The encoding process
// ensures that neither encoded string can contain a dot, and neither
// will start with a digit (NAME is a Go identifier that can't contain
// a dot or start with a digit anyhow).  The encoding process means
// that these external names contain exactly one dot and do not start
// with a dot.
//
// The external name for a method NAME for a named type TYPE is
// "PKGPATH.TYPE.NAME".  Both NAME and TYPE are simple Go identifiers.
// Unlike the gc compiler, the external name does not indicate whether
// this is a pointer method or a value method; a named type can not
// have both a pointer and value method with the same name, so there
// is no ambiguity.  PKGPATH is the package path of the package in
// which TYPE is defined.  PKGPATH, TYPE, and NAME are encoded, and
// cannot be empty or contain a dot or start with a digit.  These
// external names contain exactly two dots, not consecutive, and they
// do not start with a dot.
//
// It's uncommon, but the use of type literals with embedded fields
// can cause us to have methods on unnamed types.  The external names
// for these are also PKGPATH.TYPELIT.NAME, where TYPELIT is an
// approximately readable version of the type literal, described
// below.  A TYPELIT will always contain characters that cannot appear
// in a Go identifier, so TYPELIT can never be confused with a TYPE
// name.  There is no ambiguity as long as encoded type literals are
// unambiguous.
//
// Also uncommon is an external name that must refer to a named type
// defined within a function.  While such a type can not have methods
// itself, it can pick up embedded methods, and those methods need
// names.  These are treated as a kind of type literal written as,
// before type literal encoding, FNNAME.TYPENAME(INDEX) or, for a
// method, TYPE.MNAME.TYPENAME(INDEX).  INDEX is the index of that
// named type within the function, as a single function can have
// multiple types with the same name.  This is unambiguous as
// parentheses can not appear in a type literal in this form (they can
// only appear in interface method declarations).
//
// That is the end of the list of basic names.  The remaining names
// exist for special purposes, and are differentiated from the basic
// names by containing two consecutive dots.
//
// The hash function for a type is treated as a method whose name is
// ".hash".  That is, the method name begins with a dot.  The effect
// is that there will be two consecutive dots in the name; the name
// will always end with "..hash".
//
// Similarly the equality function for a type is treated as a method
// whose name is ".eq".
//
// The function descriptor for a function is the same as the name of
// the function with an added suffix "..f".
//
// A thunk for a go or defer statement is treated as a function whose
// name is ".thunkNN", unencoded, where NN is a sequence of digits
// (these functions are never globally visible).  Thus the final name
// of a thunk will be PKGPATH..thunkNN (PKGPATH is encoded).
//
// An init function is treated as a function whose name is ".initNN",
// unencoded, where NN is a sequence of digits (these functions are
// never globally visible).  Thus the final name of an init function
// will be PKGPATH..initNN (PKGPATH is encoded).
//
// A nested function is given the name of outermost enclosing function
// or method with an added suffix "..funcNN", unencoded, where NN is a
// sequence of digits.  Note that the function descriptor of a nested
// function, if needed, will end with "..funcNN..f".
//
// A recover thunk is the same as the name of the function with an
// added suffix "..r".
//
// The name of a type descriptor for a named type is
// PKGPATH.TYPENAME..d (PKGPATH and TYPENAME are encoded).
//
// The name of a type descriptor for a pointer to a named type is
// PKGPATH.TYPENAME..p (PKGPATH and TYPENAME are encoded).
//
// The name of a type descriptor for an unnamed type is type..TYPELIT.
// That is, the string "type.." followed by the encoded type literal.
// These names are common symbols, in the linker's sense of the word
// common: in the final executable there is only one instance of the
// type descriptor for a given unnamed type.
//
// The name of the GC symbol for a named type is PKGPATH.TYPE..g
// (PKGPATH and TYPE are encoded).
//
// The name of the GC symbol for an unnamed type is type..TYPELIT..g.
// These are common symbols.
//
// The name of a ptrmask symbol is gcbits..B32 where B32 is an
// encoding of the ptrmask bits using only ASCII letters.  These are
// common symbols.
//
// An interface method table for assigning the non-interface type TYPE
// to the interface type ITYPE is named imt..ITYPE..TYPE.  If ITYPE or
// TYPE is a named type, they are written as PKGPATH.TYPE (where both
// PKGPATH and TYPE are encoded).  Otherwise they are written as a
// type literal.  An interface method table for a pointer method set
// uses pimt instead of imt.
//
// The names of composite literal initializers, including the GC root
// variable, are not referenced.  They must not conflict with any C
// language names, but the names are otherwise unimportant.  They are
// named "go..CNN" where NN is a sequence of digits.  The names do not
// include the PKGPATH.
//
// The map zero value, a common symbol that represents the zero value
// of a map, is named simply "go..zerovalue".  The name does not
// include the PKGPATH.
//
// The import function for the main package is referenced by C code,
// and is named __go_init_main.  For other packages it is
// PKGPATH..import.  If a package doesn't need an init function, it
// will have a dummy one, named ~PKGPATH.
//
// In each package there is a list of all the type descriptors defined
// in this package.  The name of the list is PKGPATH..types.
//
// In the main package it gathers all the type descriptor lists in a
// single list, named go..typelists.
//
// The type literal encoding is essentially a single line version of
// the type literal, such as "struct { pkgpath.i int; J int }".  In
// this representation unexported names use their pkgpath, exported
// names omit it.
//
// The type literal encoding is not quite valid Go, as some aspects of
// compiler generated types can not be represented.  For example,
// incomparable struct types have an extra field "{x}".  Struct tags
// can contain any character, which will be underscore encoded as
// usual.  In the unusual case of a curly brace or a backslash in a
// struct tag, the brace or backslash will be backslash quoted, before
// underscore encoding.
//
// The underscore encoding is, naturally, an underscore followed by
// other characters.  As there are various characters that commonly
// appear in type literals and in package paths, we have a set of
// short encodings.  Then we have general encodings for other
// characters.
//
//   __ - '_'
//   _0 - '.'
//   _1 - '/'
//   _2 - '*'
//   _3 - ','
//   _4 - '{'
//   _5 - '}'
//   _6 - '['
//   _7 - ']'
//   _8 - '('
//   _9 - ')'
//   _a - '"'
//   _b - ' '
//   _c - ';'
//
// Other non-alphanumeric ASCII characters are encoded as _xNN, where
// NN is the hex value for the character.  If an encoded name would
// otherwise start with a digit, this encoding is also used for the
// leading digit.
//
// Non-ASCII Unicode characters are encoded as _u and four hex digits
// or _U and eight digits, just as in the language only using _u and
// _U instead of \u and \U.
//
// Demangling these names is straightforward:
//  - replace _xXX with an ASCII character
//  - replace _uXXXX with a unicode character
//  - replace _UXXXXXXXX with a unicode character
//  - replace _C per the table above
// That will get you as close as possible to a readable name.

// Set BNAME to the name to use for an exported function, a method, or
// a function/method declaration.  GO_NAME is the name that appears in
// the Go code.  PACKAGE is the package where the function is defined,
// and is NULL for the package being compiled.  For a method, RTYPE is
// the method's receiver type; for a function, RTYPE is NULL.

void
Gogo::function_backend_name(const std::string& go_name,
			    const Package* package, const Type* rtype,
			    Backend_name* bname)
{
  if (rtype != NULL)
    rtype->deref()->backend_name(this, bname);
  else if (package == NULL)
    bname->add(this->pkgpath());
  else
    bname->add(package->pkgpath());

  size_t pos = Gogo::special_name_pos(go_name);
  if (pos == std::string::npos)
    bname->add(Gogo::unpack_hidden_name(go_name));
  else
    {
      if (pos > 0)
	bname->add(go_name.substr(0, pos));
      bname->set_suffix(go_name.substr(pos));
    }
}

// Set BNAME to the name to use for a function descriptor.  These
// symbols are globally visible.

void
Gogo::function_descriptor_backend_name(Named_object* no,
				       Backend_name* bname)
{
  if (no->is_function())
    no->func_value()->backend_name(this, no, bname);
  else if (no->is_function_declaration())
    no->func_declaration_value()->backend_name(this, no, bname);
  else
    go_unreachable();
  bname->append_suffix("..f");
}

// Return the name to use for a generated stub method.  A stub method
// is used as the method table entry for a promoted method of an
// embedded type.  MNAME is the method name.  PACKAGE is the package
// where the type that needs this stub method is defined.  These
// functions are globally visible.
//
// This returns a name that acts like a Go identifier, as though the
// stub method were written in Go as an explicitly defined method that
// simply calls the promoted method.  The name we return here will
// eventually be passed to function_backend_name, which will return a
// name that includes the receiver type.
//
// We construct a unique method name and append "..stub".
// function_backend_name will look for the "..stub" and turn that into
// an unencoded suffix.  The rest of the name will be encoded as
// usual.

std::string
Gogo::stub_method_name(const Package* package, const std::string& mname)
{
  if (!Gogo::is_hidden_name(mname))
    return mname + "..stub";

  const std::string& ppkgpath(package == NULL
			      ? this->pkgpath()
			      : package->pkgpath());
  std::string mpkgpath = Gogo::hidden_name_pkgpath(mname);
  if (mpkgpath == ppkgpath)
    return Gogo::unpack_hidden_name(mname) + "..stub";

  // We are creating a stub method for an unexported method of an
  // imported embedded type.  A single type can have multiple promoted
  // methods with the same unexported name, if it embeds types from
  // different packages.  We need to disambiguate the method name.
  // This produces an unambiguous name because even though MPKGPATH
  // can be anything, we know that MNAME does not contain a dot.  The
  // dot we return here, between MPKGPATH and MNAME, will wind up
  // being underscore encoded.
  std::string ret(mpkgpath);
  ret.push_back('.');
  ret.append(Gogo::unpack_hidden_name(mname));
  ret.append("..stub");
  return ret;
}

// Set BNAME to the name of the hash function for TYPE.

void
Gogo::hash_function_name(const Type* type, Backend_name* bname)
{
  if (type->named_type() != NULL)
    type->backend_name(this, bname);
  else
    {
      bname->add(this->pkgpath());
      type->backend_name(this, bname);
    }
  bname->set_suffix("..hash");
}

// Set BNAME to the name of the equal function for TYPE.  If NAME is
// not NULL it is the name of the type.

void
Gogo::equal_function_name(const Type* type, const Named_type* name,
			  Backend_name* bname)
{
  if (name != NULL)
    name->backend_name(this, bname);
  else
    {
      bname->add(this->pkgpath());
      type->backend_name(this, bname);
    }
  bname->set_suffix("..eq");
}

// Set BNAME to the name to use for a global variable.  GO_NAME is the
// name that appears in the Go code.  PACKAGE is the package where the
// variable is defined, and is NULL for the package being compiled.

void
Gogo::global_var_backend_name(const std::string& go_name,
			      const Package* package,
			      Backend_name* bname)
{
  if (package == NULL)
    bname->add(this->pkgpath());
  else
    bname->add(package->pkgpath());
  bname->add(Gogo::unpack_hidden_name(go_name));
}

// Return an erroneous name that indicates that an error has already
// been reported.  This name will act like a Go identifier.

std::string
Gogo::erroneous_name()
{
  go_assert(saw_errors());
  static int erroneous_count;
  char name[50];
  snprintf(name, sizeof name, ".erroneous%d", erroneous_count);
  ++erroneous_count;
  return name;
}

// Return whether a name is an erroneous name.

bool
Gogo::is_erroneous_name(const std::string& name)
{
  return name.compare(0, 10, ".erroneous") == 0;
}

// Return a name for a thunk object.  This name will act like a Go
// identifier.  The name returned here will eventually be passed to
// function_backend_name, which will pull off the ..thunk as an
// unencoded suffix.

std::string
Gogo::thunk_name()
{
  static int thunk_count;
  char thunk_name[50];
  snprintf(thunk_name, sizeof thunk_name, "..thunk%d", thunk_count);
  ++thunk_count;
  // We don't want to return a name that starts with a dot, as that
  // will confuse Gogo::is_hidden_name.  And we don't want to change
  // ..thunk, which fits our general theme and is used by code like
  // runtime.Callers.  But the prefix doesn't matter, as the actual
  // name will include the package path.
  std::string ret = "go";
  return ret + thunk_name;
}

// Return whether a function is a thunk.

bool
Gogo::is_thunk(const Named_object* no)
{
  const std::string& name(no->name());
  size_t i = name.rfind("..thunk");
  if (i == std::string::npos)
    return false;
  return Gogo::is_digits(name.substr(i + 7));
}

// Return the name to use for an init function.  There can be multiple
// functions named "init" so each one needs a different name.

std::string
Gogo::init_function_name()
{
  static int init_count;
  char buf[30];
  snprintf(buf, sizeof buf, "..init%d", init_count);
  ++init_count;
  return this->pkgpath() + buf;
}

// Return the name to use for a nested function.  This name acts like
// a Go identifier.  This name will be rewritten by
// Function::backend_name.

std::string
Gogo::nested_function_name(Named_object* enclosing)
{
  std::string prefix;
  unsigned int index;
  if (enclosing == NULL)
    {
      // A function literal at top level, as in
      // var f = func() {}
      static unsigned int toplevel_index;
      ++toplevel_index;
      index = toplevel_index;
      prefix = ".go";
    }
  else
    {
      while (true)
	{
	  Named_object* parent = enclosing->func_value()->enclosing();
	  if (parent == NULL)
	    break;
	  enclosing = parent;
	}
      const Typed_identifier* rcvr =
	enclosing->func_value()->type()->receiver();
      if (rcvr != NULL)
	{
	  Backend_name bname;
	  rcvr->type()->backend_name(this, &bname);
	  prefix = bname.name();
	  prefix.push_back('.');
	}
      prefix.append(Gogo::unpack_hidden_name(enclosing->name()));
      index = enclosing->func_value()->next_nested_function_index();
    }
  char buf[30];
  snprintf(buf, sizeof buf, "..func%u", index);
  return prefix + buf;
}

// Return the name to use for a sink function, a function whose name
// is simply underscore.  We don't really need these functions but we
// do have to generate them for error checking.

std::string
Gogo::sink_function_name()
{
  static int sink_count;
  char buf[30];
  snprintf(buf, sizeof buf, ".sink%d", sink_count);
  ++sink_count;
  return buf;
}

// Return the name to use for a redefined function.  These functions
// are erroneous but we still generate them for further error
// checking.

std::string
Gogo::redefined_function_name()
{
  static int redefinition_count;
  char buf[30];
  snprintf(buf, sizeof buf, ".redefined%d", redefinition_count);
  ++redefinition_count;
  return buf;
}

// Return the name to use for a recover thunk for the function NAME.
// If the function is a method, RTYPE is the receiver type.  This is a
// name that acts like a Go identifier.

std::string
Gogo::recover_thunk_name(const std::string& name, const Type* rtype)
{
  std::string ret;
  if (rtype != NULL)
    {
      Backend_name bname;
      rtype->backend_name(this, &bname);
      ret = bname.name();
      ret.append(1, '.');
    }
  if (Gogo::special_name_pos(name) != std::string::npos)
    ret.append(name);
  else
    ret.append(Gogo::unpack_hidden_name(name));
  ret.append("..r");
  return ret;
}

// Return the name to use for a GC root variable.  The GC root
// variable is a composite literal that is passed to
// runtime.registerGCRoots.  There is at most one of these variables
// per compilation.

std::string
Gogo::gc_root_name()
{
  return "go..C0";
}

// Return the name to use for a composite literal or string
// initializer.  This is a local name never referenced outside of this
// file.

std::string
Gogo::initializer_name()
{
  static unsigned int counter;
  char buf[30];
  ++counter;
  snprintf(buf, sizeof buf, "go..C%u", counter);
  return buf;
}

// Return the assembler name of the variable used to represent the
// zero value of a map.  This is a globally visible common symbol.

std::string
Gogo::map_zero_value_name()
{
  return "go..zerovalue";
}

// Return the name to use for the import control function.  This name
// is handled specially by Function::backend_name.  It is not encoded
// further.

const std::string&
Gogo::get_init_fn_name()
{
  if (this->init_fn_name_.empty())
    {
      go_assert(this->package_ != NULL);
      if (this->is_main_package())
	{
	  // Use a name that the runtime knows.
	  this->init_fn_name_ = "__go_init_main";
	}
      else
	{
	  std::string s = this->pkgpath_symbol();
	  s.append("..import");
	  this->init_fn_name_ = s;
	}
    }

  return this->init_fn_name_;
}

// Return the name for a dummy init function, which is not a real
// function but only for tracking transitive import.

std::string
Gogo::dummy_init_fn_name()
{
  return "~" + this->pkgpath_symbol();
}

// Return the package path symbol from an init function name, which
// can be a real init function or a dummy one.

std::string
Gogo::pkgpath_symbol_from_init_fn_name(std::string name)
{
  go_assert(!name.empty());
  if (name[0] == '~')
    return name.substr(1);
  size_t pos = name.find("..import");
  if (pos != std::string::npos)
    return name.substr(0, pos);
  go_unreachable();
}

// Set BNAME to a name for a type to use in a symbol.  Return a name
// for a type to use in a symbol.  These names appear in symbol names
// in the assembler file for things like type descriptors and methods.

void
Type::backend_name(Gogo* gogo, Backend_name* bname) const
{
  // Special case top level named types to get nicer name encodings
  // for this common case.
  const Named_type* nt = this->unalias()->named_type();
  if (nt != NULL && !nt->is_builtin())
    {
      unsigned int index;
      if (nt->in_function(&index) == NULL)
	{
	  const Named_object* no = nt->named_object();
	  if (no->package() == NULL)
	    bname->add(gogo->pkgpath());
	  else
	    bname->add(no->package()->pkgpath());
	  bname->add(Gogo::unpack_hidden_name(no->name()));
	  return;
	}
    }

  std::string name;

  // The do_symbol_name virtual function will set RET to the mangled
  // name before encoding.
  this->do_mangled_name(gogo, &name);

  bname->add(name);
}

// The mangled name is implemented as a method on each instance of
// Type.

void
Error_type::do_mangled_name(Gogo*, std::string* ret) const
{
  ret->append("{error}");
}

void
Void_type::do_mangled_name(Gogo*, std::string* ret) const
{
  ret->append("{void}");
}

void
Boolean_type::do_mangled_name(Gogo*, std::string* ret) const
{
  ret->append("bool");
}

void
Integer_type::do_mangled_name(Gogo*, std::string* ret) const
{
  char buf[100];
  snprintf(buf, sizeof buf, "%s%si%d",
	   this->is_abstract_ ? "{abstract}" : "",
	   this->is_unsigned_ ? "u" : "",
	   this->bits_);
  ret->append(buf);
}

void
Float_type::do_mangled_name(Gogo*, std::string* ret) const
{
  char buf[100];
  snprintf(buf, sizeof buf, "%sfloat%d",
	   this->is_abstract_ ? "{abstract}" : "",
	   this->bits_);
  ret->append(buf);
}

void
Complex_type::do_mangled_name(Gogo*, std::string* ret) const
{
  char buf[100];
  snprintf(buf, sizeof buf, "%sc%d",
	   this->is_abstract_ ? "{abstract}" : "",
	   this->bits_);
  ret->append(buf);
}

void
String_type::do_mangled_name(Gogo*, std::string* ret) const
{
  ret->append("string");
}

void
Function_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  ret->append("func");

  if (this->receiver_ != NULL)
    {
      ret->push_back('(');
      this->append_mangled_name(this->receiver_->type(), gogo, ret);
      ret->append(")");
    }

  ret->push_back('(');
  const Typed_identifier_list* params = this->parameters();
  if (params != NULL)
    {
      bool first = true;
      for (Typed_identifier_list::const_iterator p = params->begin();
	   p != params->end();
	   ++p)
	{
	  if (first)
	    first = false;
	  else
	    ret->push_back(',');
	  if (this->is_varargs_ && p + 1 == params->end())
	    ret->append("...");
	  this->append_mangled_name(p->type(), gogo, ret);
	}
    }
  ret->push_back(')');

  ret->push_back('(');
  const Typed_identifier_list* results = this->results();
  if (results != NULL)
    {
      bool first = true;
      for (Typed_identifier_list::const_iterator p = results->begin();
	   p != results->end();
	   ++p)
	{
	  if (first)
	    first = false;
	  else
	    ret->append(",");
	  this->append_mangled_name(p->type(), gogo, ret);
	}
    }
  ret->push_back(')');
}

void
Pointer_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  ret->push_back('*');
  this->append_mangled_name(this->to_type_, gogo, ret);
}

void
Nil_type::do_mangled_name(Gogo*, std::string* ret) const
{
  ret->append("{nil}");
}

void
Struct_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  ret->append("struct{");

  if (this->is_struct_incomparable_)
    ret->append("{x}");

  const Struct_field_list* fields = this->fields_;
  if (fields != NULL)
    {
      bool first = true;
      for (Struct_field_list::const_iterator p = fields->begin();
	   p != fields->end();
	   ++p)
	{
	  if (first)
	    first = false;
	  else
	    ret->push_back(';');

	  if (!p->is_anonymous())
	    {
              Gogo::append_possibly_hidden_name(ret, p->field_name());
	      ret->push_back(' ');
	    }

	  // For an anonymous field with an alias type, the field name
	  // is the alias name.
	  if (p->is_anonymous()
	      && p->type()->named_type() != NULL
	      && p->type()->named_type()->is_alias())
	    p->type()->named_type()->append_symbol_type_name(gogo, true, ret);
	  else
	    this->append_mangled_name(p->type(), gogo, ret);

	  if (p->has_tag())
	    {
	      // Use curly braces around a struct tag, since they are
	      // unambiguous here and struct tags rarely contain curly
	      // braces.
	      ret->push_back('{');
	      ret->append(go_mangle_struct_tag(p->tag()));
	      ret->push_back('}');
	    }
	}
    }

  ret->push_back('}');
}

void
Array_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  ret->push_back('[');
  if (this->length_ != NULL)
    {
      Numeric_constant nc;
      if (!this->length_->numeric_constant_value(&nc))
	{
	  go_assert(saw_errors());
	  return;
	}
      mpz_t val;
      if (!nc.to_int(&val))
	{
	  go_assert(saw_errors());
	  return;
	}
      char *s = mpz_get_str(NULL, 10, val);
      ret->append(s);
      free(s);
      mpz_clear(val);
      if (this->is_array_incomparable_)
	ret->append("x");
    }
  ret->push_back(']');
  this->append_mangled_name(this->element_type_, gogo, ret);
}

void
Map_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  ret->append("map[");
  this->append_mangled_name(this->key_type_, gogo, ret);
  ret->push_back(']');
  this->append_mangled_name(this->val_type_, gogo, ret);
}

void
Channel_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  if (!this->may_send_)
    ret->append("<-");
  ret->append("chan");
  if (!this->may_receive_)
    ret->append("<-");
  ret->push_back(' ');
  this->append_mangled_name(this->element_type_, gogo, ret);
}

void
Interface_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  go_assert(this->methods_are_finalized_);

  ret->append("interface{");

  const Typed_identifier_list* methods = this->all_methods_;
  if (methods != NULL && !this->seen_)
    {
      this->seen_ = true;
      bool first = true;
      for (Typed_identifier_list::const_iterator p = methods->begin();
	   p != methods->end();
	   ++p)
	{
	  if (first)
	    first = false;
	  else
	    ret->push_back(';');

	  if (!p->name().empty())
	    {
              Gogo::append_possibly_hidden_name(ret, p->name());
	      ret->push_back(' ');
	    }

	  this->append_mangled_name(p->type(), gogo, ret);
	}
      this->seen_ = false;
    }

  ret->push_back('}');
}

void
Named_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  this->append_symbol_type_name(gogo, false, ret);
}

void
Forward_declaration_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  if (this->is_defined())
    this->append_mangled_name(this->real_type(), gogo, ret);
  else
    {
      const Named_object* no = this->named_object();
      if (no->package() == NULL)
	ret->append(gogo->pkgpath());
      else
	ret->append(no->package()->pkgpath());
      ret->push_back('.');
      ret->append(Gogo::unpack_hidden_name(no->name()));
    }
}

// Append the symbol name for a named type to RET.  For an alias we
// normally use the real name, but if USE_ALIAS is true we use the
// alias name itself.

void
Named_type::append_symbol_type_name(Gogo* gogo, bool use_alias,
				    std::string* ret) const
{
  if (this->is_error_)
    return;
  if (this->is_alias_ && !use_alias)
    {
      if (this->seen_alias_)
	return;
      this->seen_alias_ = true;
      this->append_mangled_name(this->type_, gogo, ret);
      this->seen_alias_ = false;
      return;
    }
  Named_object* no = this->named_object_;
  std::string name;
  if (this->is_builtin())
    go_assert(this->in_function_ == NULL);
  else
    {
      if (this->in_function_ != NULL)
	{
	  const Typed_identifier* rcvr =
	    this->in_function_->func_value()->type()->receiver();
	  if (rcvr != NULL)
	    {
	      Backend_name bname;
	      rcvr->type()->deref()->backend_name(gogo, &bname);
	      ret->append(bname.name());
	    }
	  else if (this->in_function_->package() == NULL)
	    ret->append(gogo->pkgpath());
	  else
	    ret->append(this->in_function_->package()->pkgpath());
	  ret->push_back('.');
	  ret->append(Gogo::unpack_hidden_name(this->in_function_->name()));
	}
      else
	{
	  if (no->package() == NULL)
	    ret->append(gogo->pkgpath());
	  else
	    ret->append(no->package()->pkgpath());
	}
      ret->push_back('.');
    }

  ret->append(Gogo::unpack_hidden_name(no->name()));

  if (this->in_function_ != NULL && this->in_function_index_ > 0)
    {
      char buf[30];
      snprintf(buf, sizeof buf, ".i%u", this->in_function_index_);
      ret->append(buf);
    }
}

// Given a name which may or may not have been hidden, append the
// appropriate version of the name to the result string.

void
Gogo::append_possibly_hidden_name(std::string *result, const std::string& name)
{
  if (!Gogo::is_hidden_name(name))
    *result += name;
  else
    *result += name.substr(1);
}

// Set BNAME to the name for the type descriptor symbol for TYPE.
// This can be a global, common, or local symbol, depending.  NT is
// not NULL if it is the name to use.

void
Gogo::type_descriptor_backend_name(const Type* type, Named_type* nt,
				   Backend_name* bname)
{
  // The type descriptor symbol for the unsafe.Pointer type is defined
  // in libgo/runtime/go-unsafe-pointer.c, so just use a reference to
  // that symbol for all unsafe pointer types.
  if (type->is_unsafe_pointer_type())
    {
      bname->set_asm_name("unsafe.Pointer..d");
      return;
    }

  bool is_pointer = false;
  if (nt == NULL && type->points_to() != NULL)
    {
      nt = type->points_to()->unalias()->named_type();
      is_pointer = true;
    }

  if (nt == NULL)
    {
      // Sanity check: we should never generate a type descriptor for
      // an unnamed primitive type.  For those we should always be
      // using a named type, like "int".
      go_assert(!type->is_basic_type());

      type->backend_name(this, bname);
      bname->set_prefix("type..");
    }
  else
    {
      nt->backend_name(this, bname);
      bname->set_suffix(is_pointer ? "..p" : "..d");
    }
}

// Return the name of the type descriptor list symbol of a package.
// This is passed directly to the backend without further encoding.

std::string
Gogo::type_descriptor_list_symbol(const std::string& pkgpath_symbol)
{
  return pkgpath_symbol + "..types";
}

// Return the name of the list of all type descriptor lists.  This is
// only used in the main package.  This is passed directly to the
// backend without further encoding.

std::string
Gogo::typelists_symbol()
{
  return "go..typelists";
}

// Return the assembler name for the GC symbol for a type.  This is
// used to initialize the gcdata field of a type descriptor.  This is
// a local name never referenced outside of this assembly file.  (Note
// that some type descriptors will initialize the gcdata field with a
// name generated by ptrmask_symbol_name rather than this method.)
// This is passed directly to the backend without further encoding.

std::string
Gogo::gc_symbol_name(Type* type)
{
  Backend_name bname;
  this->type_descriptor_backend_name(type, type->named_type(), &bname);
  bname.append_suffix("..g");
  return bname.asm_name();
}

// Return the assembler name for a ptrmask variable.  PTRMASK_SYM_NAME
// is a base32 string encoding the ptrmask (as returned by
// Ptrmask::symname in types.cc).  This name is used to intialize the
// gcdata field of a type descriptor.  These names are globally
// visible.  (Note that some type descriptors will initialize the
// gcdata field with a name generated by gc_symbol_name rather than
// this method.)  This is passed directly to the backend without
// further encoding.

std::string
Gogo::ptrmask_symbol_name(const std::string& ptrmask_sym_name)
{
  return "gcbits.." + ptrmask_sym_name;
}

// Return the assembler name to use for an interface method table used
// for the ordinary type TYPE converted to the interface type ITYPE.
// IS_POINTER is true if this is for the method set for a pointer
// receiver.  This is passed directly to the backend without further
// encoding.

std::string
Gogo::interface_method_table_name(Interface_type* itype, Type* type,
				  bool is_pointer)
{
  Backend_name iname;
  itype->backend_name(this, &iname);
  Backend_name tname;
  type->backend_name(this, &tname);
  return ((is_pointer ? "pimt.." : "imt..")
	  + iname.asm_name()
	  + ".."
	  + tname.asm_name());
}

// If NAME is a special name with a ".." suffix, return the position
// of that suffix.  This is needed because various special names use
// "..SUFFIX", but unpack_hidden_name just looks for '.', and because
// we don't want to encode the suffix.

size_t
Gogo::special_name_pos(const std::string& name)
{
  size_t pos = name.rfind("..");
  if (pos == std::string::npos)
    return pos;
  std::string suffix(name.substr(pos));
  if (suffix == "..hash"
      || suffix == "..eq"
      || suffix == "..stub"
      || suffix == "..d"
      || suffix == "..f"
      || suffix == "..r"
      || suffix == "..import")
    return pos;
  if ((suffix.compare(2, 4, "func") == 0
       || suffix.compare(2, 4, "init") == 0)
      && Gogo::is_digits(suffix.substr(6)))
    return pos;
  if (suffix.compare(2, 5, "thunk") == 0
      && Gogo::is_digits(suffix.substr(7)))
    return pos;
  return std::string::npos;
}

// Return whether the string is non-empty and contains only digits.

bool
Gogo::is_digits(const std::string& s)
{
  if (s.empty())
    return false;
  for (size_t i = 0; i < s.size(); ++i)
    if (s[i] < '0' || s[i] > '9')
      return false;
  return true;
}

// Class Backend_name.

// Get the user visible name.

std::string
Backend_name::name() const
{
  if (this->is_asm_name_)
    return this->components_[0];
  std::string ret;
  if (this->prefix_ != NULL)
    ret.append(this->prefix_);
  for (int i = 0; i < this->count_; i++)
    {
      if (i > 0)
	ret.push_back('.');
      ret.append(this->components_[i]);
    }
  if (!this->suffix_.empty())
    ret.append(this->suffix_);
  return ret;
}

// Get the assembler name.

std::string
Backend_name::asm_name() const
{
  if (this->is_asm_name_)
    return this->components_[0];
  std::string ret;
  if (this->prefix_ != NULL)
    ret.append(this->prefix_);
  for (int i = 0; i < this->count_; i++)
    {
      if (i > 0)
	ret.push_back('.');
      ret.append(go_encode_id(this->components_[i]));
    }
  if (!this->suffix_.empty())
    ret.append(this->suffix_);
  return ret;
}

// Get the assembler name, or the empty string if it is the same as
// the user visible name.

std::string
Backend_name::optional_asm_name() const
{
  if (this->is_asm_name_)
    return "";
  for (int i = 0; i < this->count_; i++)
    if (go_id_needs_encoding(this->components_[i]))
      return this->asm_name();
  return "";
}
