// 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.
//
// Many of these names will be visible in the debugger.  The debugger
// will be given these names before applying any underscore encoding.
// These user names do not have to be unique--they are only used by
// the debugger, not the linker--so this is OK.  However, there is an
// exception: if the name would otherwise include characters that
// can't normally appear in an identifier, then the user name will
// also be underscore encoded.  This avoids problems with
// communicating the debug info to the assembler and with handling the
// debug info in the debugger.  A Go-aware debugger will need to know
// whether to apply underscore decoding to a name before showing it to
// the user.  We indicate this by adding a prefix of "g.", and
// assuming that cases of a package path of "g" are unusual.  This
// prefix will only appear in the user name, not the assembler name.
//
// 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->deref()->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;
  bool is_non_identifier = false;

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

  bname->add(name);
  if (is_non_identifier)
    bname->set_is_non_identifier();
}

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

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

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

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

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

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

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

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

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

  if (this->receiver_ != NULL)
    {
      ret->push_back('(');
      this->append_mangled_name(this->receiver_->type(), gogo, ret,
				is_non_identifier);
      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,
				    is_non_identifier);
	}
    }
  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, is_non_identifier);
	}
    }
  ret->push_back(')');

  *is_non_identifier = true;
}

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

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

void
Struct_type::do_mangled_name(Gogo* gogo, std::string* ret,
			     bool* is_non_identifier) 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,
							     is_non_identifier);
	  else
	    this->append_mangled_name(p->type(), gogo, ret, is_non_identifier);

	  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('}');

  *is_non_identifier = true;
}

void
Array_type::do_mangled_name(Gogo* gogo, std::string* ret,
			    bool* is_non_identifier) 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, is_non_identifier);
  *is_non_identifier = true;
}

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

void
Channel_type::do_mangled_name(Gogo* gogo, std::string* ret,
			      bool* is_non_identifier) 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, is_non_identifier);
  *is_non_identifier = true;
}

void
Interface_type::do_mangled_name(Gogo* gogo, std::string* ret,
				bool* is_non_identifier) 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, is_non_identifier);
	}
      this->seen_ = false;
    }

  ret->push_back('}');

  *is_non_identifier = true;
}

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

void
Forward_declaration_type::do_mangled_name(Gogo* gogo, std::string* ret,
					  bool *is_non_identifier) const
{
  if (this->is_defined())
    this->append_mangled_name(this->real_type(), gogo, ret, is_non_identifier);
  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,
				    bool* is_non_identifier) 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, is_non_identifier);
      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());
	      if (bname.is_non_identifier())
		*is_non_identifier = true;
	    }
	  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];

  // If there is some character in the name that can't appear in an
  // identifier, use the assembler name as the user name.  This avoids
  // possible problems in the assembler or debugger.  The usual
  // demangling scheme will still work.  We use a prefix of "g." to
  // tell the debugger about this.
  if (this->is_non_identifier_)
    return "g." + this->asm_name();

  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 "";
  if (this->is_non_identifier_)
    return this->asm_name();
  for (int i = 0; i < this->count_; i++)
    if (go_id_needs_encoding(this->components_[i]))
      return this->asm_name();
  return "";
}
