// 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.

// Return the assembler name to use for an exported function, a
// method, or a function/method declaration.  This is not called if
// the function has been given an explicit name via a magic //extern
// or //go:linkname comment.  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.

std::string
Gogo::function_asm_name(const std::string& go_name, const Package* package,
			const Type* rtype)
{
  std::string ret = (package == NULL
		     ? this->pkgpath_symbol()
		     : package->pkgpath_symbol());

  if (rtype != NULL
      && Gogo::is_hidden_name(go_name)
      && Gogo::hidden_name_pkgpath(go_name) != this->pkgpath())
    {
      // This is a method created for an unexported method of an
      // imported embedded type.  Use the pkgpath of the imported
      // package.
      std::string p = Gogo::hidden_name_pkgpath(go_name);
      ret = this->pkgpath_symbol_for_package(p);
    }

  ret.append(1, '.');
  ret.append(Gogo::unpack_hidden_name(go_name));

  if (rtype != NULL)
    {
      ret.append(1, '.');
      ret.append(rtype->mangled_name(this));
    }

  return go_encode_id(ret);
}

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

std::string
Gogo::function_descriptor_name(Named_object* no)
{
  std::string var_name;
  if (no->is_function_declaration()
      && !no->func_declaration_value()->asm_name().empty()
      && Linemap::is_predeclared_location(no->location()))
    {
      if (no->func_declaration_value()->asm_name().substr(0, 8) != "runtime.")
	var_name = no->func_declaration_value()->asm_name() + "_descriptor";
      else
	var_name = no->func_declaration_value()->asm_name() + "$descriptor";
    }
  else
    {
      if (no->package() == NULL)
	var_name = this->pkgpath_symbol();
      else
	var_name = no->package()->pkgpath_symbol();
      var_name.push_back('.');
      var_name.append(Gogo::unpack_hidden_name(no->name()));
      var_name.append("$descriptor");
    }
  return var_name;
}

// Return the name to use for a generated stub method.  MNAME is the
// method name.  These functions are globally visible.  Note that this
// is the function name that corresponds to the name used for the
// method in Go source code, if this stub method were written in Go.
// The assembler name will be generated by Gogo::function_asm_name,
// and because this is a method that name will include the receiver
// type.

std::string
Gogo::stub_method_name(const std::string& mname)
{
  return mname + "$stub";
}

// Return the names of the hash and equality functions for TYPE.  If
// NAME is not NULL it is the name of the type.  Set *HASH_NAME and
// *EQUAL_NAME.

void
Gogo::specific_type_function_names(const Type* type, const Named_type* name,
				   std::string *hash_name,
				   std::string *equal_name)
{
  std::string base_name;
  if (name == NULL)
    {
      // Mangled names can have '.' if they happen to refer to named
      // types in some way.  That's fine if this is simply a named
      // type, but otherwise it will confuse the code that builds
      // function identifiers.  Remove '.' when necessary.
      base_name = type->mangled_name(this);
      size_t i;
      while ((i = base_name.find('.')) != std::string::npos)
	base_name[i] = '$';
      base_name = this->pack_hidden_name(base_name, false);
    }
  else
    {
      // This name is already hidden or not as appropriate.
      base_name = name->name();
      unsigned int index;
      const Named_object* in_function = name->in_function(&index);
      if (in_function != NULL)
	{
	  base_name.append(1, '$');
	  const Typed_identifier* rcvr =
	    in_function->func_value()->type()->receiver();
	  if (rcvr != NULL)
	    {
	      Named_type* rcvr_type = rcvr->type()->deref()->named_type();
	      base_name.append(Gogo::unpack_hidden_name(rcvr_type->name()));
	      base_name.append(1, '$');
	    }
	  base_name.append(Gogo::unpack_hidden_name(in_function->name()));
	  if (index > 0)
	    {
	      char buf[30];
	      snprintf(buf, sizeof buf, "%u", index);
	      base_name += '$';
	      base_name += buf;
	    }
	}
    }
  *hash_name = base_name + "$hash";
  *equal_name = base_name + "$equal";
}

// Return the assembler 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.

std::string
Gogo::global_var_asm_name(const std::string& go_name, const Package* package)
{
  std::string ret = (package != NULL
		     ? package->pkgpath_symbol()
		     : this->pkgpath_symbol());
  ret.push_back('.');
  ret.append(Gogo::unpack_hidden_name(go_name));
  return go_encode_id(ret);
}

// Return an erroneous name that indicates that an error has already
// been reported.

std::string
Gogo::erroneous_name()
{
  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.

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;
  return thunk_name;
}

// Return whether a function is a thunk.

bool
Gogo::is_thunk(const Named_object* no)
{
  return no->name().compare(0, 6, "$thunk") == 0;
}

// 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 buf;
}

// Return the name to use for a nested function.

std::string
Gogo::nested_function_name()
{
  static int nested_count;
  char buf[30];
  snprintf(buf, sizeof buf, ".$nested%d", nested_count);
  ++nested_count;
  return buf;
}

// Return the index of a nested function name.

int
Gogo::nested_function_num(const std::string& name)
{
  std::string n(Gogo::unpack_hidden_name(name));
  go_assert(n.compare(0, 8, ".$nested") == 0);
  return strtol(n.substr(8).c_str(), NULL, 0);
}

// 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.

std::string
Gogo::recover_thunk_name(const std::string& name, const Type* rtype)
{
  std::string ret(name);
  if (rtype != NULL)
    {
      ret.push_back('$');
      ret.append(rtype->mangled_name(this));
    }
  ret.append("$recover");
  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 "gc0";
}

// 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];
  snprintf(buf, sizeof buf, "C%u", counter);
  ++counter;
  return buf;
}

// Return the 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.

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 a mangled name for a type.  These names appear in symbol
// names in the assembler file for things like type descriptors and
// methods.

std::string
Type::mangled_name(Gogo* gogo) const
{
  std::string ret;

  // The do_mangled_name virtual function should set RET to the
  // mangled name.  For a composite type it should append a code for
  // the composition and then call do_mangled_name on the components.
  this->do_mangled_name(gogo, &ret);

  return ret;
}

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

void
Void_type::do_mangled_name(Gogo*, std::string* ret) const
{
  ret->push_back('v');
}

void
Boolean_type::do_mangled_name(Gogo*, std::string* ret) const
{
  ret->push_back('b');
}

void
Integer_type::do_mangled_name(Gogo*, std::string* ret) const
{
  char buf[100];
  snprintf(buf, sizeof buf, "i%s%s%de",
	   this->is_abstract_ ? "a" : "",
	   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, "f%s%de",
	   this->is_abstract_ ? "a" : "",
	   this->bits_);
  ret->append(buf);
}

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

void
String_type::do_mangled_name(Gogo*, std::string* ret) const
{
  ret->push_back('z');
}

void
Function_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  ret->push_back('F');

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

  const Typed_identifier_list* params = this->parameters();
  if (params != NULL)
    {
      ret->push_back('p');
      for (Typed_identifier_list::const_iterator p = params->begin();
	   p != params->end();
	   ++p)
	this->append_mangled_name(p->type(), gogo, ret);
      if (this->is_varargs_)
	ret->push_back('V');
      ret->push_back('e');
    }

  const Typed_identifier_list* results = this->results();
  if (results != NULL)
    {
      ret->push_back('r');
      for (Typed_identifier_list::const_iterator p = results->begin();
	   p != results->end();
	   ++p)
	this->append_mangled_name(p->type(), gogo, ret);
      ret->push_back('e');
    }

  ret->push_back('e');
}

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

void
Nil_type::do_mangled_name(Gogo*, std::string* ret) const
{
  ret->push_back('n');
}

void
Struct_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  ret->push_back('S');

  const Struct_field_list* fields = this->fields_;
  if (fields != NULL)
    {
      for (Struct_field_list::const_iterator p = fields->begin();
	   p != fields->end();
	   ++p)
	{
	  if (p->is_anonymous())
	    ret->append("0_");
	  else
            {

              std::string n(Gogo::mangle_possibly_hidden_name(p->field_name()));
	      char buf[20];
	      snprintf(buf, sizeof buf, "%u_",
		       static_cast<unsigned int>(n.length()));
	      ret->append(buf);
	      ret->append(n);
	    }

	  // 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_mangled_type_name(gogo, true, ret);
	  else
	    this->append_mangled_name(p->type(), gogo, ret);
	  if (p->has_tag())
	    {
	      const std::string& tag(p->tag());
	      std::string out;
	      for (std::string::const_iterator p = tag.begin();
		   p != tag.end();
		   ++p)
		{
		  if (ISALNUM(*p) || *p == '_')
		    out.push_back(*p);
		  else
		    {
		      char buf[20];
		      snprintf(buf, sizeof buf, ".%x.",
			       static_cast<unsigned int>(*p));
		      out.append(buf);
		    }
		}
	      char buf[20];
	      snprintf(buf, sizeof buf, "T%u_",
		       static_cast<unsigned int>(out.length()));
	      ret->append(buf);
	      ret->append(out);
	    }
	}
    }

  if (this->is_struct_incomparable_)
    ret->push_back('x');

  ret->push_back('e');
}

void
Array_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  ret->push_back('A');
  this->append_mangled_name(this->element_type_, gogo, ret);
  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->push_back('x');
    }
  ret->push_back('e');
}

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

void
Channel_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  ret->push_back('C');
  this->append_mangled_name(this->element_type_, gogo, ret);
  if (this->may_send_)
    ret->push_back('s');
  if (this->may_receive_)
    ret->push_back('r');
  ret->push_back('e');
}

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

  ret->push_back('I');

  const Typed_identifier_list* methods = this->all_methods_;
  if (methods != NULL && !this->seen_)
    {
      this->seen_ = true;
      for (Typed_identifier_list::const_iterator p = methods->begin();
	   p != methods->end();
	   ++p)
	{
	  if (!p->name().empty())
	    {
	      std::string n(Gogo::mangle_possibly_hidden_name(p->name()));
	      char buf[20];
	      snprintf(buf, sizeof buf, "%u_",
		       static_cast<unsigned int>(n.length()));
	      ret->append(buf);
	      ret->append(n);
	    }
	  this->append_mangled_name(p->type(), gogo, ret);
	}
      this->seen_ = false;
    }

  ret->push_back('e');
}

void
Named_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
  this->append_mangled_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();
      std::string name;
      if (no->package() == NULL)
	name = gogo->pkgpath_symbol();
      else
	name = no->package()->pkgpath_symbol();
      name += '.';
      name += Gogo::unpack_hidden_name(no->name());
      char buf[20];
      snprintf(buf, sizeof buf, "N%u_",
	       static_cast<unsigned int>(name.length()));
      ret->append(buf);
      ret->append(name);
    }
}

// Append the mangled 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_mangled_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
    {
      const std::string& pkgpath(no->package() == NULL
				 ? gogo->pkgpath_symbol()
				 : no->package()->pkgpath_symbol());
      name = pkgpath;
      name.append(1, '.');
      if (this->in_function_ != NULL)
	{
	  const Typed_identifier* rcvr =
	    this->in_function_->func_value()->type()->receiver();
	  if (rcvr != NULL)
	    {
	      Named_type* rcvr_type = rcvr->type()->deref()->named_type();
	      name.append(Gogo::unpack_hidden_name(rcvr_type->name()));
	      name.append(1, '.');
	    }
	  name.append(Gogo::unpack_hidden_name(this->in_function_->name()));
	  name.append(1, '$');
	  if (this->in_function_index_ > 0)
	    {
	      char buf[30];
	      snprintf(buf, sizeof buf, "%u", this->in_function_index_);
	      name.append(buf);
	      name.append(1, '$');
	    }
	}
    }
  name.append(Gogo::unpack_hidden_name(no->name()));
  char buf[20];
  snprintf(buf, sizeof buf, "N%u_", static_cast<unsigned int>(name.length()));
  ret->append(buf);
  ret->append(name);
}

// Return 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.

std::string
Gogo::type_descriptor_name(Type* type, Named_type* nt)
{
  // 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.
  if (type->is_unsafe_pointer_type())
    return "__go_tdn_unsafe.Pointer";

  if (nt == NULL)
    return "__go_td_" + type->mangled_name(this);

  Named_object* no = nt->named_object();
  unsigned int index;
  const Named_object* in_function = nt->in_function(&index);
  std::string ret = "__go_tdn_";
  if (nt->is_builtin())
    go_assert(in_function == NULL);
  else
    {
      const std::string& pkgpath(no->package() == NULL
				 ? this->pkgpath_symbol()
				 : no->package()->pkgpath_symbol());
      ret.append(pkgpath);
      ret.append(1, '.');
      if (in_function != NULL)
	{
	  const Typed_identifier* rcvr =
	    in_function->func_value()->type()->receiver();
	  if (rcvr != NULL)
	    {
	      Named_type* rcvr_type = rcvr->type()->deref()->named_type();
	      ret.append(Gogo::unpack_hidden_name(rcvr_type->name()));
	      ret.append(1, '.');
	    }
	  ret.append(Gogo::unpack_hidden_name(in_function->name()));
	  ret.append(1, '.');
	  if (index > 0)
	    {
	      char buf[30];
	      snprintf(buf, sizeof buf, "%u", index);
	      ret.append(buf);
	      ret.append(1, '.');
	    }
	}
    }

  std::string mname(Gogo::mangle_possibly_hidden_name(no->name()));
  ret.append(mname);

  return ret;
}

// Return the 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.)

std::string
Gogo::gc_symbol_name(Type* type)
{
  return this->type_descriptor_name(type, type->named_type()) + "$gc";
}

// Return the name for a ptrmask variable.  PTRMASK_SYM_NAME is a
// base64 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.)

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

// Return the 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.

std::string
Gogo::interface_method_table_name(Interface_type* itype, Type* type,
				  bool is_pointer)
{
  return ((is_pointer ? "__go_pimt__" : "__go_imt_")
	  + itype->mangled_name(this)
	  + "__"
	  + type->mangled_name(this));
}
