LCOV - code coverage report
Current view: top level - gcc/go/gofrontend - names.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 90.1 % 504 454
Test Date: 2026-02-28 14:20:25 Functions: 88.5 % 52 46
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // names.cc -- Names used by gofrontend generated code.
       2              : 
       3              : // Copyright 2017 The Go Authors. All rights reserved.
       4              : // Use of this source code is governed by a BSD-style
       5              : // license that can be found in the LICENSE file.
       6              : 
       7              : #include "go-system.h"
       8              : 
       9              : #include "gogo.h"
      10              : #include "go-encode-id.h"
      11              : #include "types.h"
      12              : #include "expressions.h"
      13              : 
      14              : // This file contains functions that generate names that appear in the
      15              : // assembly code.  This is not used for names that appear only in the
      16              : // debug info.
      17              : 
      18              : // Our external names may contain only ASCII alphanumeric characters,
      19              : // underscore, and dot.  (According to the GCC sources, dot is not
      20              : // permitted in assembler symbols on VxWorks and MMIX.  We will not
      21              : // support those systems.)  Go identifiers cannot contain dot, but Go
      22              : // package paths can.  Both Go identifiers and package paths can, of
      23              : // course, contain all sorts of Unicode characters.
      24              : //
      25              : // The gc compiler uses names like "pkg.F", and it seems convenient to
      26              : // emulate that.  Therefore, we will use dot to separate different
      27              : // components of names.
      28              : //
      29              : // Since package paths can contain dot, to avoid ambiguity we must
      30              : // encode package paths such that they do not contain any dot.  The
      31              : // natural way to do this is to encode forbidden characters, including
      32              : // dot, using a notation based on underscore.  We will, of course,
      33              : // have to encode underscore itself.
      34              : //
      35              : // Since we will be using an underscore encoding for the package path,
      36              : // it seems reasonable to use the same encoding for Go identifiers.
      37              : // This has the disadvantage that encoded Go identifiers will appear
      38              : // to be valid Go identifiers with funny spellings, but it seems like
      39              : // the best available approach.
      40              : //
      41              : // Therefore, in the following discussion we may assume that none of
      42              : // the names under discussion contain a dot.  All of the names we
      43              : // generate for Go identifiers (that don't use //export or
      44              : // //go:linkname) will contain at least one dot, as discussed below.
      45              : // We assume that none of the non-Go symbols in the final link will
      46              : // contain a dot, so we don't worry about conflicts.
      47              : //
      48              : // We first describe the basic symbol names, used to represent Go
      49              : // functions and variables.
      50              : //
      51              : // The external name for a normal Go symbol NAME, a function or
      52              : // variable, is simply "PKGPATH.NAME".  Note that NAME is not the
      53              : // packed form used for the "hidden" name internally in the compiler;
      54              : // it is the name that appears in the source code.  Both PKGPATH and
      55              : // NAME will be encoded as described below.  The encoding process
      56              : // ensures that neither encoded string can contain a dot, and neither
      57              : // will start with a digit (NAME is a Go identifier that can't contain
      58              : // a dot or start with a digit anyhow).  The encoding process means
      59              : // that these external names contain exactly one dot and do not start
      60              : // with a dot.
      61              : //
      62              : // The external name for a method NAME for a named type TYPE is
      63              : // "PKGPATH.TYPE.NAME".  Both NAME and TYPE are simple Go identifiers.
      64              : // Unlike the gc compiler, the external name does not indicate whether
      65              : // this is a pointer method or a value method; a named type can not
      66              : // have both a pointer and value method with the same name, so there
      67              : // is no ambiguity.  PKGPATH is the package path of the package in
      68              : // which TYPE is defined.  PKGPATH, TYPE, and NAME are encoded, and
      69              : // cannot be empty or contain a dot or start with a digit.  These
      70              : // external names contain exactly two dots, not consecutive, and they
      71              : // do not start with a dot.
      72              : //
      73              : // It's uncommon, but the use of type literals with embedded fields
      74              : // can cause us to have methods on unnamed types.  The external names
      75              : // for these are also PKGPATH.TYPELIT.NAME, where TYPELIT is an
      76              : // approximately readable version of the type literal, described
      77              : // below.  A TYPELIT will always contain characters that cannot appear
      78              : // in a Go identifier, so TYPELIT can never be confused with a TYPE
      79              : // name.  There is no ambiguity as long as encoded type literals are
      80              : // unambiguous.
      81              : //
      82              : // Also uncommon is an external name that must refer to a named type
      83              : // defined within a function.  While such a type can not have methods
      84              : // itself, it can pick up embedded methods, and those methods need
      85              : // names.  These are treated as a kind of type literal written as,
      86              : // before type literal encoding, FNNAME.TYPENAME(INDEX) or, for a
      87              : // method, TYPE.MNAME.TYPENAME(INDEX).  INDEX is the index of that
      88              : // named type within the function, as a single function can have
      89              : // multiple types with the same name.  This is unambiguous as
      90              : // parentheses can not appear in a type literal in this form (they can
      91              : // only appear in interface method declarations).
      92              : //
      93              : // That is the end of the list of basic names.  The remaining names
      94              : // exist for special purposes, and are differentiated from the basic
      95              : // names by containing two consecutive dots.
      96              : //
      97              : // The hash function for a type is treated as a method whose name is
      98              : // ".hash".  That is, the method name begins with a dot.  The effect
      99              : // is that there will be two consecutive dots in the name; the name
     100              : // will always end with "..hash".
     101              : //
     102              : // Similarly the equality function for a type is treated as a method
     103              : // whose name is ".eq".
     104              : //
     105              : // The function descriptor for a function is the same as the name of
     106              : // the function with an added suffix "..f".
     107              : //
     108              : // A thunk for a go or defer statement is treated as a function whose
     109              : // name is ".thunkNN", unencoded, where NN is a sequence of digits
     110              : // (these functions are never globally visible).  Thus the final name
     111              : // of a thunk will be PKGPATH..thunkNN (PKGPATH is encoded).
     112              : //
     113              : // An init function is treated as a function whose name is ".initNN",
     114              : // unencoded, where NN is a sequence of digits (these functions are
     115              : // never globally visible).  Thus the final name of an init function
     116              : // will be PKGPATH..initNN (PKGPATH is encoded).
     117              : //
     118              : // A nested function is given the name of outermost enclosing function
     119              : // or method with an added suffix "..funcNN", unencoded, where NN is a
     120              : // sequence of digits.  Note that the function descriptor of a nested
     121              : // function, if needed, will end with "..funcNN..f".
     122              : //
     123              : // A recover thunk is the same as the name of the function with an
     124              : // added suffix "..r".
     125              : //
     126              : // The name of a type descriptor for a named type is
     127              : // PKGPATH.TYPENAME..d (PKGPATH and TYPENAME are encoded).
     128              : //
     129              : // The name of a type descriptor for a pointer to a named type is
     130              : // PKGPATH.TYPENAME..p (PKGPATH and TYPENAME are encoded).
     131              : //
     132              : // The name of a type descriptor for an unnamed type is type..TYPELIT.
     133              : // That is, the string "type.." followed by the encoded type literal.
     134              : // These names are common symbols, in the linker's sense of the word
     135              : // common: in the final executable there is only one instance of the
     136              : // type descriptor for a given unnamed type.
     137              : //
     138              : // The name of the GC symbol for a named type is PKGPATH.TYPE..g
     139              : // (PKGPATH and TYPE are encoded).
     140              : //
     141              : // The name of the GC symbol for an unnamed type is type..TYPELIT..g.
     142              : // These are common symbols.
     143              : //
     144              : // The name of a ptrmask symbol is gcbits..B32 where B32 is an
     145              : // encoding of the ptrmask bits using only ASCII letters.  These are
     146              : // common symbols.
     147              : //
     148              : // An interface method table for assigning the non-interface type TYPE
     149              : // to the interface type ITYPE is named imt..ITYPE..TYPE.  If ITYPE or
     150              : // TYPE is a named type, they are written as PKGPATH.TYPE (where both
     151              : // PKGPATH and TYPE are encoded).  Otherwise they are written as a
     152              : // type literal.  An interface method table for a pointer method set
     153              : // uses pimt instead of imt.
     154              : //
     155              : // The names of composite literal initializers, including the GC root
     156              : // variable, are not referenced.  They must not conflict with any C
     157              : // language names, but the names are otherwise unimportant.  They are
     158              : // named "go..CNN" where NN is a sequence of digits.  The names do not
     159              : // include the PKGPATH.
     160              : //
     161              : // The map zero value, a common symbol that represents the zero value
     162              : // of a map, is named simply "go..zerovalue".  The name does not
     163              : // include the PKGPATH.
     164              : //
     165              : // The import function for the main package is referenced by C code,
     166              : // and is named __go_init_main.  For other packages it is
     167              : // PKGPATH..import.  If a package doesn't need an init function, it
     168              : // will have a dummy one, named ~PKGPATH.
     169              : //
     170              : // In each package there is a list of all the type descriptors defined
     171              : // in this package.  The name of the list is PKGPATH..types.
     172              : //
     173              : // In the main package it gathers all the type descriptor lists in a
     174              : // single list, named go..typelists.
     175              : //
     176              : // The type literal encoding is essentially a single line version of
     177              : // the type literal, such as "struct { pkgpath.i int; J int }".  In
     178              : // this representation unexported names use their pkgpath, exported
     179              : // names omit it.
     180              : //
     181              : // The type literal encoding is not quite valid Go, as some aspects of
     182              : // compiler generated types can not be represented.  For example,
     183              : // incomparable struct types have an extra field "{x}".  Struct tags
     184              : // can contain any character, which will be underscore encoded as
     185              : // usual.  In the unusual case of a curly brace or a backslash in a
     186              : // struct tag, the brace or backslash will be backslash quoted, before
     187              : // underscore encoding.
     188              : //
     189              : // Many of these names will be visible in the debugger.  The debugger
     190              : // will be given these names before applying any underscore encoding.
     191              : // These user names do not have to be unique--they are only used by
     192              : // the debugger, not the linker--so this is OK.  However, there is an
     193              : // exception: if the name would otherwise include characters that
     194              : // can't normally appear in an identifier, then the user name will
     195              : // also be underscore encoded.  This avoids problems with
     196              : // communicating the debug info to the assembler and with handling the
     197              : // debug info in the debugger.  A Go-aware debugger will need to know
     198              : // whether to apply underscore decoding to a name before showing it to
     199              : // the user.  We indicate this by adding a prefix of "g.", and
     200              : // assuming that cases of a package path of "g" are unusual.  This
     201              : // prefix will only appear in the user name, not the assembler name.
     202              : //
     203              : // The underscore encoding is, naturally, an underscore followed by
     204              : // other characters.  As there are various characters that commonly
     205              : // appear in type literals and in package paths, we have a set of
     206              : // short encodings.  Then we have general encodings for other
     207              : // characters.
     208              : //
     209              : //   __ - '_'
     210              : //   _0 - '.'
     211              : //   _1 - '/'
     212              : //   _2 - '*'
     213              : //   _3 - ','
     214              : //   _4 - '{'
     215              : //   _5 - '}'
     216              : //   _6 - '['
     217              : //   _7 - ']'
     218              : //   _8 - '('
     219              : //   _9 - ')'
     220              : //   _a - '"'
     221              : //   _b - ' '
     222              : //   _c - ';'
     223              : //
     224              : // Other non-alphanumeric ASCII characters are encoded as _xNN, where
     225              : // NN is the hex value for the character.  If an encoded name would
     226              : // otherwise start with a digit, this encoding is also used for the
     227              : // leading digit.
     228              : //
     229              : // Non-ASCII Unicode characters are encoded as _u and four hex digits
     230              : // or _U and eight digits, just as in the language only using _u and
     231              : // _U instead of \u and \U.
     232              : //
     233              : // Demangling these names is straightforward:
     234              : //  - replace _xXX with an ASCII character
     235              : //  - replace _uXXXX with a unicode character
     236              : //  - replace _UXXXXXXXX with a unicode character
     237              : //  - replace _C per the table above
     238              : // That will get you as close as possible to a readable name.
     239              : 
     240              : // Set BNAME to the name to use for an exported function, a method, or
     241              : // a function/method declaration.  GO_NAME is the name that appears in
     242              : // the Go code.  PACKAGE is the package where the function is defined,
     243              : // and is NULL for the package being compiled.  For a method, RTYPE is
     244              : // the method's receiver type; for a function, RTYPE is NULL.
     245              : 
     246              : void
     247       431353 : Gogo::function_backend_name(const std::string& go_name,
     248              :                             const Package* package, const Type* rtype,
     249              :                             Backend_name* bname)
     250              : {
     251       431353 :   if (rtype != NULL)
     252       404186 :     rtype->deref()->backend_name(this, bname);
     253       229260 :   else if (package == NULL)
     254       160884 :     bname->add(this->pkgpath());
     255              :   else
     256        68376 :     bname->add(package->pkgpath());
     257              : 
     258       431353 :   size_t pos = Gogo::special_name_pos(go_name);
     259       431353 :   if (pos == std::string::npos)
     260       375529 :     bname->add(Gogo::unpack_hidden_name(go_name));
     261              :   else
     262              :     {
     263        55824 :       if (pos > 0)
     264        55824 :         bname->add(go_name.substr(0, pos));
     265        55824 :       bname->set_suffix(go_name.substr(pos));
     266              :     }
     267       431353 : }
     268              : 
     269              : // Set BNAME to the name to use for a function descriptor.  These
     270              : // symbols are globally visible.
     271              : 
     272              : void
     273       259775 : Gogo::function_descriptor_backend_name(Named_object* no,
     274              :                                        Backend_name* bname)
     275              : {
     276       259775 :   if (no->is_function())
     277       154636 :     no->func_value()->backend_name(this, no, bname);
     278       105139 :   else if (no->is_function_declaration())
     279       105139 :     no->func_declaration_value()->backend_name(this, no, bname);
     280              :   else
     281            0 :     go_unreachable();
     282       259775 :   bname->append_suffix("..f");
     283       259775 : }
     284              : 
     285              : // Return the name to use for a generated stub method.  A stub method
     286              : // is used as the method table entry for a promoted method of an
     287              : // embedded type.  MNAME is the method name.  PACKAGE is the package
     288              : // where the type that needs this stub method is defined.  These
     289              : // functions are globally visible.
     290              : //
     291              : // This returns a name that acts like a Go identifier, as though the
     292              : // stub method were written in Go as an explicitly defined method that
     293              : // simply calls the promoted method.  The name we return here will
     294              : // eventually be passed to function_backend_name, which will return a
     295              : // name that includes the receiver type.
     296              : //
     297              : // We construct a unique method name and append "..stub".
     298              : // function_backend_name will look for the "..stub" and turn that into
     299              : // an unencoded suffix.  The rest of the name will be encoded as
     300              : // usual.
     301              : 
     302              : std::string
     303       302971 : Gogo::stub_method_name(const Package* package, const std::string& mname)
     304              : {
     305       302971 :   if (!Gogo::is_hidden_name(mname))
     306       107476 :     return mname + "..stub";
     307              : 
     308       195495 :   const std::string& ppkgpath(package == NULL
     309       195495 :                               ? this->pkgpath()
     310       180888 :                               : package->pkgpath());
     311       195495 :   std::string mpkgpath = Gogo::hidden_name_pkgpath(mname);
     312       195495 :   if (mpkgpath == ppkgpath)
     313       353150 :     return Gogo::unpack_hidden_name(mname) + "..stub";
     314              : 
     315              :   // We are creating a stub method for an unexported method of an
     316              :   // imported embedded type.  A single type can have multiple promoted
     317              :   // methods with the same unexported name, if it embeds types from
     318              :   // different packages.  We need to disambiguate the method name.
     319              :   // This produces an unambiguous name because even though MPKGPATH
     320              :   // can be anything, we know that MNAME does not contain a dot.  The
     321              :   // dot we return here, between MPKGPATH and MNAME, will wind up
     322              :   // being underscore encoded.
     323        18920 :   std::string ret(mpkgpath);
     324        18920 :   ret.push_back('.');
     325        37840 :   ret.append(Gogo::unpack_hidden_name(mname));
     326        18920 :   ret.append("..stub");
     327        18920 :   return ret;
     328       214415 : }
     329              : 
     330              : // Set BNAME to the name of the hash function for TYPE.
     331              : 
     332              : void
     333          229 : Gogo::hash_function_name(const Type* type, Backend_name* bname)
     334              : {
     335          229 :   if (type->named_type() != NULL)
     336            0 :     type->backend_name(this, bname);
     337              :   else
     338              :     {
     339          229 :       bname->add(this->pkgpath());
     340          229 :       type->backend_name(this, bname);
     341              :     }
     342          229 :   bname->set_suffix("..hash");
     343          229 : }
     344              : 
     345              : // Set BNAME to the name of the equal function for TYPE.  If NAME is
     346              : // not NULL it is the name of the type.
     347              : 
     348              : void
     349       319647 : Gogo::equal_function_name(const Type* type, const Named_type* name,
     350              :                           Backend_name* bname)
     351              : {
     352       319647 :   if (name != NULL)
     353       240019 :     name->backend_name(this, bname);
     354              :   else
     355              :     {
     356        79628 :       bname->add(this->pkgpath());
     357        79628 :       type->backend_name(this, bname);
     358              :     }
     359       319647 :   bname->set_suffix("..eq");
     360       319647 : }
     361              : 
     362              : // Set BNAME to the name to use for a global variable.  GO_NAME is the
     363              : // name that appears in the Go code.  PACKAGE is the package where the
     364              : // variable is defined, and is NULL for the package being compiled.
     365              : 
     366              : void
     367        34342 : Gogo::global_var_backend_name(const std::string& go_name,
     368              :                               const Package* package,
     369              :                               Backend_name* bname)
     370              : {
     371        34342 :   if (package == NULL)
     372        25297 :     bname->add(this->pkgpath());
     373              :   else
     374         9045 :     bname->add(package->pkgpath());
     375        34342 :   bname->add(Gogo::unpack_hidden_name(go_name));
     376        34342 : }
     377              : 
     378              : // Return an erroneous name that indicates that an error has already
     379              : // been reported.  This name will act like a Go identifier.
     380              : 
     381              : std::string
     382            2 : Gogo::erroneous_name()
     383              : {
     384            2 :   go_assert(saw_errors());
     385            2 :   static int erroneous_count;
     386            2 :   char name[50];
     387            2 :   snprintf(name, sizeof name, ".erroneous%d", erroneous_count);
     388            2 :   ++erroneous_count;
     389            2 :   return name;
     390              : }
     391              : 
     392              : // Return whether a name is an erroneous name.
     393              : 
     394              : bool
     395       349344 : Gogo::is_erroneous_name(const std::string& name)
     396              : {
     397       349344 :   return name.compare(0, 10, ".erroneous") == 0;
     398              : }
     399              : 
     400              : // Return a name for a thunk object.  This name will act like a Go
     401              : // identifier.  The name returned here will eventually be passed to
     402              : // function_backend_name, which will pull off the ..thunk as an
     403              : // unencoded suffix.
     404              : 
     405              : std::string
     406        14947 : Gogo::thunk_name()
     407              : {
     408        14947 :   static int thunk_count;
     409        14947 :   char thunk_name[50];
     410        14947 :   snprintf(thunk_name, sizeof thunk_name, "..thunk%d", thunk_count);
     411        14947 :   ++thunk_count;
     412              :   // We don't want to return a name that starts with a dot, as that
     413              :   // will confuse Gogo::is_hidden_name.  And we don't want to change
     414              :   // ..thunk, which fits our general theme and is used by code like
     415              :   // runtime.Callers.  But the prefix doesn't matter, as the actual
     416              :   // name will include the package path.
     417        14947 :   std::string ret = "go";
     418        14947 :   return ret + thunk_name;
     419        14947 : }
     420              : 
     421              : // Return whether a function is a thunk.
     422              : 
     423              : bool
     424       431150 : Gogo::is_thunk(const Named_object* no)
     425              : {
     426       431150 :   const std::string& name(no->name());
     427       431150 :   size_t i = name.rfind("..thunk");
     428       431150 :   if (i == std::string::npos)
     429              :     return false;
     430        16792 :   return Gogo::is_digits(name.substr(i + 7));
     431              : }
     432              : 
     433              : // Return the name to use for an init function.  There can be multiple
     434              : // functions named "init" so each one needs a different name.
     435              : 
     436              : std::string
     437         1884 : Gogo::init_function_name()
     438              : {
     439         1884 :   static int init_count;
     440         1884 :   char buf[30];
     441         1884 :   snprintf(buf, sizeof buf, "..init%d", init_count);
     442         1884 :   ++init_count;
     443         1884 :   return this->pkgpath() + buf;
     444              : }
     445              : 
     446              : // Return the name to use for a nested function.  This name acts like
     447              : // a Go identifier.  This name will be rewritten by
     448              : // Function::backend_name.
     449              : 
     450              : std::string
     451        25609 : Gogo::nested_function_name(Named_object* enclosing)
     452              : {
     453        25609 :   std::string prefix;
     454        25609 :   unsigned int index;
     455        25609 :   if (enclosing == NULL)
     456              :     {
     457              :       // A function literal at top level, as in
     458              :       // var f = func() {}
     459         1301 :       static unsigned int toplevel_index;
     460         1301 :       ++toplevel_index;
     461         1301 :       index = toplevel_index;
     462         1301 :       prefix = ".go";
     463              :     }
     464              :   else
     465              :     {
     466        27330 :       while (true)
     467              :         {
     468        27330 :           Named_object* parent = enclosing->func_value()->enclosing();
     469        27330 :           if (parent == NULL)
     470              :             break;
     471              :           enclosing = parent;
     472              :         }
     473        24308 :       const Typed_identifier* rcvr =
     474        24308 :         enclosing->func_value()->type()->receiver();
     475        24308 :       if (rcvr != NULL)
     476              :         {
     477         3624 :           Backend_name bname;
     478         3624 :           rcvr->type()->backend_name(this, &bname);
     479         3624 :           prefix = bname.name();
     480         3624 :           prefix.push_back('.');
     481         3624 :         }
     482        48616 :       prefix.append(Gogo::unpack_hidden_name(enclosing->name()));
     483        24308 :       index = enclosing->func_value()->next_nested_function_index();
     484              :     }
     485        25609 :   char buf[30];
     486        25609 :   snprintf(buf, sizeof buf, "..func%u", index);
     487        25609 :   return prefix + buf;
     488        25609 : }
     489              : 
     490              : // Return the name to use for a sink function, a function whose name
     491              : // is simply underscore.  We don't really need these functions but we
     492              : // do have to generate them for error checking.
     493              : 
     494              : std::string
     495          305 : Gogo::sink_function_name()
     496              : {
     497          305 :   static int sink_count;
     498          305 :   char buf[30];
     499          305 :   snprintf(buf, sizeof buf, ".sink%d", sink_count);
     500          305 :   ++sink_count;
     501          305 :   return buf;
     502              : }
     503              : 
     504              : // Return the name to use for a redefined function.  These functions
     505              : // are erroneous but we still generate them for further error
     506              : // checking.
     507              : 
     508              : std::string
     509            2 : Gogo::redefined_function_name()
     510              : {
     511            2 :   static int redefinition_count;
     512            2 :   char buf[30];
     513            2 :   snprintf(buf, sizeof buf, ".redefined%d", redefinition_count);
     514            2 :   ++redefinition_count;
     515            2 :   return buf;
     516              : }
     517              : 
     518              : // Return the name to use for a recover thunk for the function NAME.
     519              : // If the function is a method, RTYPE is the receiver type.  This is a
     520              : // name that acts like a Go identifier.
     521              : 
     522              : std::string
     523          831 : Gogo::recover_thunk_name(const std::string& name, const Type* rtype)
     524              : {
     525          831 :   std::string ret;
     526          831 :   if (rtype != NULL)
     527              :     {
     528           42 :       Backend_name bname;
     529           84 :       rtype->deref()->backend_name(this, &bname);
     530           42 :       ret = bname.name();
     531           42 :       ret.append(1, '.');
     532           42 :     }
     533          831 :   if (Gogo::special_name_pos(name) != std::string::npos)
     534          737 :     ret.append(name);
     535              :   else
     536          188 :     ret.append(Gogo::unpack_hidden_name(name));
     537          831 :   ret.append("..r");
     538          831 :   return ret;
     539              : }
     540              : 
     541              : // Return the name to use for a GC root variable.  The GC root
     542              : // variable is a composite literal that is passed to
     543              : // runtime.registerGCRoots.  There is at most one of these variables
     544              : // per compilation.
     545              : 
     546              : std::string
     547         2111 : Gogo::gc_root_name()
     548              : {
     549         2111 :   return "go..C0";
     550              : }
     551              : 
     552              : // Return the name to use for a composite literal or string
     553              : // initializer.  This is a local name never referenced outside of this
     554              : // file.
     555              : 
     556              : std::string
     557      1009222 : Gogo::initializer_name()
     558              : {
     559      1009222 :   static unsigned int counter;
     560      1009222 :   char buf[30];
     561      1009222 :   ++counter;
     562      1009222 :   snprintf(buf, sizeof buf, "go..C%u", counter);
     563      1009222 :   return buf;
     564              : }
     565              : 
     566              : // Return the assembler name of the variable used to represent the
     567              : // zero value of a map.  This is a globally visible common symbol.
     568              : 
     569              : std::string
     570            3 : Gogo::map_zero_value_name()
     571              : {
     572            3 :   return "go..zerovalue";
     573              : }
     574              : 
     575              : // Return the name to use for the import control function.  This name
     576              : // is handled specially by Function::backend_name.  It is not encoded
     577              : // further.
     578              : 
     579              : const std::string&
     580       495139 : Gogo::get_init_fn_name()
     581              : {
     582       495139 :   if (this->init_fn_name_.empty())
     583              :     {
     584         4464 :       go_assert(this->package_ != NULL);
     585         4464 :       if (this->is_main_package())
     586              :         {
     587              :           // Use a name that the runtime knows.
     588         1889 :           this->init_fn_name_ = "__go_init_main";
     589              :         }
     590              :       else
     591              :         {
     592         2575 :           std::string s = this->pkgpath_symbol();
     593         2575 :           s.append("..import");
     594         2575 :           this->init_fn_name_ = s;
     595         2575 :         }
     596              :     }
     597              : 
     598       495139 :   return this->init_fn_name_;
     599              : }
     600              : 
     601              : // Return the name for a dummy init function, which is not a real
     602              : // function but only for tracking transitive import.
     603              : 
     604              : std::string
     605         1091 : Gogo::dummy_init_fn_name()
     606              : {
     607         1091 :   return "~" + this->pkgpath_symbol();
     608              : }
     609              : 
     610              : // Return the package path symbol from an init function name, which
     611              : // can be a real init function or a dummy one.
     612              : 
     613              : std::string
     614        62428 : Gogo::pkgpath_symbol_from_init_fn_name(std::string name)
     615              : {
     616        62428 :   go_assert(!name.empty());
     617        62428 :   if (name[0] == '~')
     618        27184 :     return name.substr(1);
     619        35244 :   size_t pos = name.find("..import");
     620        35244 :   if (pos != std::string::npos)
     621        35244 :     return name.substr(0, pos);
     622            0 :   go_unreachable();
     623              : }
     624              : 
     625              : // Set BNAME to a name for a type to use in a symbol.  Return a name
     626              : // for a type to use in a symbol.  These names appear in symbol names
     627              : // in the assembler file for things like type descriptors and methods.
     628              : 
     629              : void
     630      2627554 : Type::backend_name(Gogo* gogo, Backend_name* bname) const
     631              : {
     632              :   // Special case top level named types to get nicer name encodings
     633              :   // for this common case.
     634      2627554 :   const Named_type* nt = this->unalias()->named_type();
     635      3724543 :   if (nt != NULL && !nt->is_builtin())
     636              :     {
     637      1034061 :       unsigned int index;
     638      1034061 :       if (nt->in_function(&index) == NULL)
     639              :         {
     640      1030958 :           const Named_object* no = nt->named_object();
     641      1030958 :           if (no->package() == NULL)
     642       239964 :             bname->add(gogo->pkgpath());
     643              :           else
     644       790994 :             bname->add(no->package()->pkgpath());
     645      1030958 :           bname->add(Gogo::unpack_hidden_name(no->name()));
     646      1030958 :           return;
     647              :         }
     648              :     }
     649              : 
     650      1596596 :   std::string name;
     651      1596596 :   bool is_non_identifier = false;
     652              : 
     653              :   // The do_symbol_name virtual function will set RET to the mangled
     654              :   // name before encoding.
     655      1596596 :   this->do_mangled_name(gogo, &name, &is_non_identifier);
     656              : 
     657      1596596 :   bname->add(name);
     658      1596596 :   if (is_non_identifier)
     659      1530562 :     bname->set_is_non_identifier();
     660      1596596 : }
     661              : 
     662              : // The mangled name is implemented as a method on each instance of
     663              : // Type.
     664              : 
     665              : void
     666            1 : Error_type::do_mangled_name(Gogo*, std::string* ret,
     667              :                             bool* is_non_identifier) const
     668              : {
     669            1 :   ret->append("{error}");
     670            1 :   *is_non_identifier = true;
     671            1 : }
     672              : 
     673              : void
     674         8621 : Void_type::do_mangled_name(Gogo*, std::string* ret,
     675              :                            bool* is_non_identifier) const
     676              : {
     677         8621 :   ret->append("{void}");
     678         8621 :   *is_non_identifier = true;
     679         8621 : }
     680              : 
     681              : void
     682            0 : Boolean_type::do_mangled_name(Gogo*, std::string* ret, bool*) const
     683              : {
     684            0 :   ret->append("bool");
     685            0 : }
     686              : 
     687              : void
     688            0 : Integer_type::do_mangled_name(Gogo*, std::string* ret,
     689              :                               bool* is_non_identifier) const
     690              : {
     691            0 :   char buf[100];
     692            0 :   snprintf(buf, sizeof buf, "%s%si%d",
     693            0 :            this->is_abstract_ ? "{abstract}" : "",
     694            0 :            this->is_unsigned_ ? "u" : "",
     695            0 :            this->bits_);
     696            0 :   ret->append(buf);
     697            0 :   if (this->is_abstract_)
     698            0 :     *is_non_identifier = true;
     699            0 : }
     700              : 
     701              : void
     702            0 : Float_type::do_mangled_name(Gogo*, std::string* ret,
     703              :                             bool* is_non_identifier) const
     704              : {
     705            0 :   char buf[100];
     706            0 :   snprintf(buf, sizeof buf, "%sfloat%d",
     707            0 :            this->is_abstract_ ? "{abstract}" : "",
     708            0 :            this->bits_);
     709            0 :   ret->append(buf);
     710            0 :   if (this->is_abstract_)
     711            0 :     *is_non_identifier = true;
     712            0 : }
     713              : 
     714              : void
     715            0 : Complex_type::do_mangled_name(Gogo*, std::string* ret,
     716              :                               bool* is_non_identifier) const
     717              : {
     718            0 :   char buf[100];
     719            0 :   snprintf(buf, sizeof buf, "%sc%d",
     720            0 :            this->is_abstract_ ? "{abstract}" : "",
     721            0 :            this->bits_);
     722            0 :   ret->append(buf);
     723            0 :   if (this->is_abstract_)
     724            0 :     *is_non_identifier = true;
     725            0 : }
     726              : 
     727              : void
     728            0 : String_type::do_mangled_name(Gogo*, std::string* ret, bool*) const
     729              : {
     730            0 :   ret->append("string");
     731            0 : }
     732              : 
     733              : void
     734      1123765 : Function_type::do_mangled_name(Gogo* gogo, std::string* ret,
     735              :                                bool* is_non_identifier) const
     736              : {
     737      1123765 :   ret->append("func");
     738              : 
     739      1123765 :   if (this->receiver_ != NULL)
     740              :     {
     741            0 :       ret->push_back('(');
     742            0 :       this->append_mangled_name(this->receiver_->type(), gogo, ret,
     743              :                                 is_non_identifier);
     744            0 :       ret->append(")");
     745              :     }
     746              : 
     747      1123765 :   ret->push_back('(');
     748      1123765 :   const Typed_identifier_list* params = this->parameters();
     749      1123765 :   if (params != NULL)
     750              :     {
     751       603534 :       bool first = true;
     752       603534 :       for (Typed_identifier_list::const_iterator p = params->begin();
     753      1577498 :            p != params->end();
     754       973964 :            ++p)
     755              :         {
     756       973964 :           if (first)
     757              :             first = false;
     758              :           else
     759       370562 :             ret->push_back(',');
     760       973964 :           if (this->is_varargs_ && p + 1 == params->end())
     761        68131 :             ret->append("...");
     762       973964 :           this->append_mangled_name(p->type(), gogo, ret,
     763              :                                     is_non_identifier);
     764              :         }
     765              :     }
     766      1123765 :   ret->push_back(')');
     767              : 
     768      1123765 :   ret->push_back('(');
     769      1123765 :   const Typed_identifier_list* results = this->results();
     770      1123765 :   if (results != NULL)
     771              :     {
     772       788263 :       bool first = true;
     773       788263 :       for (Typed_identifier_list::const_iterator p = results->begin();
     774      1735343 :            p != results->end();
     775       947080 :            ++p)
     776              :         {
     777       947080 :           if (first)
     778              :             first = false;
     779              :           else
     780       158817 :             ret->append(",");
     781       947080 :           this->append_mangled_name(p->type(), gogo, ret, is_non_identifier);
     782              :         }
     783              :     }
     784      1123765 :   ret->push_back(')');
     785              : 
     786      1123765 :   *is_non_identifier = true;
     787      1123765 : }
     788              : 
     789              : void
     790       812997 : Pointer_type::do_mangled_name(Gogo* gogo, std::string* ret,
     791              :                               bool* is_non_identifier) const
     792              : {
     793       812997 :   ret->push_back('*');
     794       812997 :   this->append_mangled_name(this->to_type_, gogo, ret, is_non_identifier);
     795       812997 :   *is_non_identifier = true;
     796       812997 : }
     797              : 
     798              : void
     799            0 : Nil_type::do_mangled_name(Gogo*, std::string* ret,
     800              :                           bool* is_non_identifier) const
     801              : {
     802            0 :   ret->append("{nil}");
     803            0 :   *is_non_identifier = true;
     804            0 : }
     805              : 
     806              : void
     807       629520 : Struct_type::do_mangled_name(Gogo* gogo, std::string* ret,
     808              :                              bool* is_non_identifier) const
     809              : {
     810       629520 :   ret->append("struct{");
     811              : 
     812       629520 :   if (this->is_struct_incomparable_)
     813        11355 :     ret->append("{x}");
     814              : 
     815       629520 :   const Struct_field_list* fields = this->fields_;
     816       629520 :   if (fields != NULL)
     817              :     {
     818       629520 :       bool first = true;
     819      3748607 :       for (Struct_field_list::const_iterator p = fields->begin();
     820      3748607 :            p != fields->end();
     821      3119087 :            ++p)
     822              :         {
     823      3119087 :           if (first)
     824              :             first = false;
     825              :           else
     826      2527656 :             ret->push_back(';');
     827              : 
     828      3119087 :           if (!p->is_anonymous())
     829              :             {
     830      3030294 :               Gogo::append_possibly_hidden_name(ret, p->field_name());
     831      3030294 :               ret->push_back(' ');
     832              :             }
     833              : 
     834      3119087 :           const Type* ft = p->type();
     835      3119087 :           const Named_type* nt = ft->named_type();
     836              : 
     837      3195530 :           if (p->is_anonymous() && nt != NULL && nt->is_builtin())
     838              :             {
     839              :               // For an embedded field with a builtin type, we must
     840              :               // include a package path.  Otherwise embedding builtin
     841              :               // types in different packages will produce identical
     842              :               // types, which shouldn't happen because the builtin
     843              :               // types are not exported.
     844          481 :               ret->append(gogo->pkgpath());
     845          481 :               ret->push_back('.');
     846          481 :               nt->append_symbol_type_name(gogo, true, ret, is_non_identifier);
     847              :             }
     848      3118606 :           else if (p->is_anonymous() && nt != NULL && nt->is_alias())
     849              :             {
     850              :               // For an anonymous field with an alias type, the field name
     851              :               // is the alias name.
     852           65 :               nt->append_symbol_type_name(gogo, true, ret, is_non_identifier);
     853              :             }
     854              :           else
     855      3118541 :             this->append_mangled_name(ft, gogo, ret, is_non_identifier);
     856              : 
     857      3119087 :           if (p->has_tag())
     858              :             {
     859              :               // Use curly braces around a struct tag, since they are
     860              :               // unambiguous here and struct tags rarely contain curly
     861              :               // braces.
     862        47283 :               ret->push_back('{');
     863        94566 :               ret->append(go_mangle_struct_tag(p->tag()));
     864        47283 :               ret->push_back('}');
     865              :             }
     866              :         }
     867              :     }
     868              : 
     869       629520 :   ret->push_back('}');
     870              : 
     871       629520 :   *is_non_identifier = true;
     872       629520 : }
     873              : 
     874              : void
     875      1191294 : Array_type::do_mangled_name(Gogo* gogo, std::string* ret,
     876              :                             bool* is_non_identifier) const
     877              : {
     878      1191294 :   ret->push_back('[');
     879      1191294 :   if (this->length_ != NULL)
     880              :     {
     881       274277 :       Numeric_constant nc;
     882       274277 :       if (!this->length_->numeric_constant_value(&nc))
     883              :         {
     884            0 :           go_assert(saw_errors());
     885              :           return;
     886              :         }
     887       274277 :       mpz_t val;
     888       274277 :       if (!nc.to_int(&val))
     889              :         {
     890            0 :           go_assert(saw_errors());
     891              :           return;
     892              :         }
     893       274277 :       char *s = mpz_get_str(NULL, 10, val);
     894       274277 :       ret->append(s);
     895       274277 :       free(s);
     896       274277 :       mpz_clear(val);
     897       274277 :       if (this->is_array_incomparable_)
     898        26850 :         ret->append("x");
     899       274277 :     }
     900      1191294 :   ret->push_back(']');
     901      1191294 :   this->append_mangled_name(this->element_type_, gogo, ret, is_non_identifier);
     902      1191294 :   *is_non_identifier = true;
     903              : }
     904              : 
     905              : void
     906       129930 : Map_type::do_mangled_name(Gogo* gogo, std::string* ret,
     907              :                           bool* is_non_identifier) const
     908              : {
     909       129930 :   ret->append("map[");
     910       129930 :   this->append_mangled_name(this->key_type_, gogo, ret, is_non_identifier);
     911       129930 :   ret->push_back(']');
     912       129930 :   this->append_mangled_name(this->val_type_, gogo, ret, is_non_identifier);
     913       129930 :   *is_non_identifier = true;
     914       129930 : }
     915              : 
     916              : void
     917        39634 : Channel_type::do_mangled_name(Gogo* gogo, std::string* ret,
     918              :                               bool* is_non_identifier) const
     919              : {
     920        39634 :   if (!this->may_send_)
     921         6255 :     ret->append("<-");
     922        39634 :   ret->append("chan");
     923        39634 :   if (!this->may_receive_)
     924         1289 :     ret->append("<-");
     925        39634 :   ret->push_back(' ');
     926        39634 :   this->append_mangled_name(this->element_type_, gogo, ret, is_non_identifier);
     927        39634 :   *is_non_identifier = true;
     928        39634 : }
     929              : 
     930              : void
     931       276303 : Interface_type::do_mangled_name(Gogo* gogo, std::string* ret,
     932              :                                 bool* is_non_identifier) const
     933              : {
     934       276303 :   go_assert(this->methods_are_finalized_);
     935              : 
     936       276303 :   ret->append("interface{");
     937              : 
     938       276303 :   const Typed_identifier_list* methods = this->all_methods_;
     939       276303 :   if (methods != NULL && !this->seen_)
     940              :     {
     941       140534 :       this->seen_ = true;
     942       140534 :       bool first = true;
     943       140534 :       for (Typed_identifier_list::const_iterator p = methods->begin();
     944       840773 :            p != methods->end();
     945       700239 :            ++p)
     946              :         {
     947       700239 :           if (first)
     948              :             first = false;
     949              :           else
     950       559705 :             ret->push_back(';');
     951              : 
     952       700239 :           if (!p->name().empty())
     953              :             {
     954       700239 :               Gogo::append_possibly_hidden_name(ret, p->name());
     955       700239 :               ret->push_back(' ');
     956              :             }
     957              : 
     958       700239 :           this->append_mangled_name(p->type(), gogo, ret, is_non_identifier);
     959              :         }
     960       140534 :       this->seen_ = false;
     961              :     }
     962              : 
     963       276303 :   ret->push_back('}');
     964              : 
     965       276303 :   *is_non_identifier = true;
     966       276303 : }
     967              : 
     968              : void
     969      5916197 : Named_type::do_mangled_name(Gogo* gogo, std::string* ret,
     970              :                             bool* is_non_identifier) const
     971              : {
     972      5916197 :   this->append_symbol_type_name(gogo, false, ret, is_non_identifier);
     973      5916197 : }
     974              : 
     975              : void
     976      1116203 : Forward_declaration_type::do_mangled_name(Gogo* gogo, std::string* ret,
     977              :                                           bool *is_non_identifier) const
     978              : {
     979      1116203 :   if (this->is_defined())
     980      1115833 :     this->append_mangled_name(this->real_type(), gogo, ret, is_non_identifier);
     981              :   else
     982              :     {
     983          370 :       const Named_object* no = this->named_object();
     984          370 :       if (no->package() == NULL)
     985          370 :         ret->append(gogo->pkgpath());
     986              :       else
     987            0 :         ret->append(no->package()->pkgpath());
     988          370 :       ret->push_back('.');
     989          740 :       ret->append(Gogo::unpack_hidden_name(no->name()));
     990              :     }
     991      1116203 : }
     992              : 
     993              : // Append the symbol name for a named type to RET.  For an alias we
     994              : // normally use the real name, but if USE_ALIAS is true we use the
     995              : // alias name itself.
     996              : 
     997              : void
     998      5916743 : Named_type::append_symbol_type_name(Gogo* gogo, bool use_alias,
     999              :                                     std::string* ret,
    1000              :                                     bool* is_non_identifier) const
    1001              : {
    1002      5916743 :   if (this->is_error_)
    1003       488427 :     return;
    1004      5916743 :   if (this->is_alias_ && !use_alias)
    1005              :     {
    1006       488427 :       if (this->seen_alias_)
    1007              :         return;
    1008       488427 :       this->seen_alias_ = true;
    1009       488427 :       this->append_mangled_name(this->type_, gogo, ret, is_non_identifier);
    1010       488427 :       this->seen_alias_ = false;
    1011       488427 :       return;
    1012              :     }
    1013      5428316 :   Named_object* no = this->named_object_;
    1014      5428316 :   std::string name;
    1015      5428316 :   if (this->is_builtin())
    1016      3374584 :     go_assert(this->in_function_ == NULL);
    1017              :   else
    1018              :     {
    1019      2053732 :       if (this->in_function_ != NULL)
    1020              :         {
    1021         5463 :           const Typed_identifier* rcvr =
    1022         5463 :             this->in_function_->func_value()->type()->receiver();
    1023         5463 :           if (rcvr != NULL)
    1024              :             {
    1025          603 :               Backend_name bname;
    1026         1206 :               rcvr->type()->deref()->backend_name(gogo, &bname);
    1027         1206 :               ret->append(bname.name());
    1028          603 :               if (bname.is_non_identifier())
    1029            0 :                 *is_non_identifier = true;
    1030          603 :             }
    1031         4860 :           else if (this->in_function_->package() == NULL)
    1032         4860 :             ret->append(gogo->pkgpath());
    1033              :           else
    1034            0 :             ret->append(this->in_function_->package()->pkgpath());
    1035         5463 :           ret->push_back('.');
    1036        10926 :           ret->append(Gogo::unpack_hidden_name(this->in_function_->name()));
    1037              :         }
    1038              :       else
    1039              :         {
    1040      2048269 :           if (no->package() == NULL)
    1041       379768 :             ret->append(gogo->pkgpath());
    1042              :           else
    1043      1668501 :             ret->append(no->package()->pkgpath());
    1044              :         }
    1045      2053732 :       ret->push_back('.');
    1046              :     }
    1047              : 
    1048     10856632 :   ret->append(Gogo::unpack_hidden_name(no->name()));
    1049              : 
    1050      5428316 :   if (this->in_function_ != NULL && this->in_function_index_ > 0)
    1051              :     {
    1052         1499 :       char buf[30];
    1053         1499 :       snprintf(buf, sizeof buf, ".i%u", this->in_function_index_);
    1054         1499 :       ret->append(buf);
    1055              :     }
    1056      5428316 : }
    1057              : 
    1058              : // Given a name which may or may not have been hidden, append the
    1059              : // appropriate version of the name to the result string.
    1060              : 
    1061              : void
    1062      3730533 : Gogo::append_possibly_hidden_name(std::string *result, const std::string& name)
    1063              : {
    1064      3730533 :   if (!Gogo::is_hidden_name(name))
    1065      1776759 :     *result += name;
    1066              :   else
    1067      3907548 :     *result += name.substr(1);
    1068      3730533 : }
    1069              : 
    1070              : // Set BNAME to the name for the type descriptor symbol for TYPE.
    1071              : // This can be a global, common, or local symbol, depending.  NT is
    1072              : // not NULL if it is the name to use.
    1073              : 
    1074              : void
    1075      1974724 : Gogo::type_descriptor_backend_name(const Type* type, Named_type* nt,
    1076              :                                    Backend_name* bname)
    1077              : {
    1078              :   // The type descriptor symbol for the unsafe.Pointer type is defined
    1079              :   // in libgo/runtime/go-unsafe-pointer.c, so just use a reference to
    1080              :   // that symbol for all unsafe pointer types.
    1081      1974724 :   if (type->is_unsafe_pointer_type())
    1082              :     {
    1083         5416 :       bname->set_asm_name("unsafe.Pointer..d");
    1084         5416 :       return;
    1085              :     }
    1086              : 
    1087      1969308 :   bool is_pointer = false;
    1088      1969308 :   if (nt == NULL && type->points_to() != NULL)
    1089              :     {
    1090       567064 :       nt = type->points_to()->unalias()->named_type();
    1091       567064 :       is_pointer = true;
    1092              :     }
    1093              : 
    1094      1969308 :   if (nt == NULL)
    1095              :     {
    1096              :       // Sanity check: we should never generate a type descriptor for
    1097              :       // an unnamed primitive type.  For those we should always be
    1098              :       // using a named type, like "int".
    1099      1371054 :       go_assert(!type->is_basic_type());
    1100              : 
    1101      1371054 :       type->backend_name(this, bname);
    1102      1371054 :       bname->set_prefix("type..");
    1103              :     }
    1104              :   else
    1105              :     {
    1106       598254 :       nt->backend_name(this, bname);
    1107       661244 :       bname->set_suffix(is_pointer ? "..p" : "..d");
    1108              :     }
    1109              : }
    1110              : 
    1111              : // Return the name of the type descriptor list symbol of a package.
    1112              : // This is passed directly to the backend without further encoding.
    1113              : 
    1114              : std::string
    1115        68963 : Gogo::type_descriptor_list_symbol(const std::string& pkgpath_symbol)
    1116              : {
    1117        68963 :   return pkgpath_symbol + "..types";
    1118              : }
    1119              : 
    1120              : // Return the name of the list of all type descriptor lists.  This is
    1121              : // only used in the main package.  This is passed directly to the
    1122              : // backend without further encoding.
    1123              : 
    1124              : std::string
    1125         1889 : Gogo::typelists_symbol()
    1126              : {
    1127         1889 :   return "go..typelists";
    1128              : }
    1129              : 
    1130              : // Return the assembler name for the GC symbol for a type.  This is
    1131              : // used to initialize the gcdata field of a type descriptor.  This is
    1132              : // a local name never referenced outside of this assembly file.  (Note
    1133              : // that some type descriptors will initialize the gcdata field with a
    1134              : // name generated by ptrmask_symbol_name rather than this method.)
    1135              : // This is passed directly to the backend without further encoding.
    1136              : 
    1137              : std::string
    1138          114 : Gogo::gc_symbol_name(Type* type)
    1139              : {
    1140          114 :   Backend_name bname;
    1141          114 :   this->type_descriptor_backend_name(type, type->named_type(), &bname);
    1142          114 :   bname.append_suffix("..g");
    1143          114 :   return bname.asm_name();
    1144          114 : }
    1145              : 
    1146              : // Return the assembler name for a ptrmask variable.  PTRMASK_SYM_NAME
    1147              : // is a base32 string encoding the ptrmask (as returned by
    1148              : // Ptrmask::symname in types.cc).  This name is used to intialize the
    1149              : // gcdata field of a type descriptor.  These names are globally
    1150              : // visible.  (Note that some type descriptors will initialize the
    1151              : // gcdata field with a name generated by gc_symbol_name rather than
    1152              : // this method.)  This is passed directly to the backend without
    1153              : // further encoding.
    1154              : 
    1155              : std::string
    1156       231725 : Gogo::ptrmask_symbol_name(const std::string& ptrmask_sym_name)
    1157              : {
    1158       231725 :   return "gcbits.." + ptrmask_sym_name;
    1159              : }
    1160              : 
    1161              : // Return the assembler name to use for an interface method table used
    1162              : // for the ordinary type TYPE converted to the interface type ITYPE.
    1163              : // IS_POINTER is true if this is for the method set for a pointer
    1164              : // receiver.  This is passed directly to the backend without further
    1165              : // encoding.
    1166              : 
    1167              : std::string
    1168        66004 : Gogo::interface_method_table_name(Interface_type* itype, Type* type,
    1169              :                                   bool is_pointer)
    1170              : {
    1171        66004 :   Backend_name iname;
    1172        66004 :   itype->backend_name(this, &iname);
    1173        66004 :   Backend_name tname;
    1174        66004 :   type->backend_name(this, &tname);
    1175        66004 :   return ((is_pointer ? "pimt.." : "imt..")
    1176       163191 :           + iname.asm_name()
    1177       132008 :           + ".."
    1178       132008 :           + tname.asm_name());
    1179        66004 : }
    1180              : 
    1181              : // If NAME is a special name with a ".." suffix, return the position
    1182              : // of that suffix.  This is needed because various special names use
    1183              : // "..SUFFIX", but unpack_hidden_name just looks for '.', and because
    1184              : // we don't want to encode the suffix.
    1185              : 
    1186              : size_t
    1187       597464 : Gogo::special_name_pos(const std::string& name)
    1188              : {
    1189       597464 :   size_t pos = name.rfind("..");
    1190       597464 :   if (pos == std::string::npos)
    1191              :     return pos;
    1192       110001 :   std::string suffix(name.substr(pos));
    1193       110001 :   if (suffix == "..hash"
    1194       110001 :       || suffix == "..eq"
    1195       109928 :       || suffix == "..stub"
    1196        55605 :       || suffix == "..d"
    1197        55605 :       || suffix == "..f"
    1198        55605 :       || suffix == "..r"
    1199       165512 :       || suffix == "..import")
    1200              :     return pos;
    1201        55511 :   if ((suffix.compare(2, 4, "func") == 0
    1202        27885 :        || suffix.compare(2, 4, "init") == 0)
    1203       116795 :       && Gogo::is_digits(suffix.substr(6)))
    1204              :     return pos;
    1205        22112 :   if (suffix.compare(2, 5, "thunk") == 0
    1206        38900 :       && Gogo::is_digits(suffix.substr(7)))
    1207              :     return pos;
    1208              :   return std::string::npos;
    1209       110001 : }
    1210              : 
    1211              : // Return whether the string is non-empty and contains only digits.
    1212              : 
    1213              : bool
    1214        66979 : Gogo::is_digits(const std::string& s)
    1215              : {
    1216        66979 :   if (s.empty())
    1217              :     return false;
    1218       192375 :   for (size_t i = 0; i < s.size(); ++i)
    1219       125396 :     if (s[i] < '0' || s[i] > '9')
    1220              :       return false;
    1221              :   return true;
    1222              : }
    1223              : 
    1224              : // Class Backend_name.
    1225              : 
    1226              : // Get the user visible name.
    1227              : 
    1228              : std::string
    1229      3654292 : Backend_name::name() const
    1230              : {
    1231      3654292 :   if (this->is_asm_name_)
    1232       502912 :     return this->components_[0];
    1233              : 
    1234              :   // If there is some character in the name that can't appear in an
    1235              :   // identifier, use the assembler name as the user name.  This avoids
    1236              :   // possible problems in the assembler or debugger.  The usual
    1237              :   // demangling scheme will still work.  We use a prefix of "g." to
    1238              :   // tell the debugger about this.
    1239      3151380 :   if (this->is_non_identifier_)
    1240      1703968 :     return "g." + this->asm_name();
    1241              : 
    1242      1447412 :   std::string ret;
    1243      1447412 :   if (this->prefix_ != NULL)
    1244            2 :     ret.append(this->prefix_);
    1245      4441054 :   for (int i = 0; i < this->count_; i++)
    1246              :     {
    1247      2993642 :       if (i > 0)
    1248      1546230 :         ret.push_back('.');
    1249      5987284 :       ret.append(this->components_[i]);
    1250              :     }
    1251      1447412 :   if (!this->suffix_.empty())
    1252      1132326 :     ret.append(this->suffix_);
    1253      1447412 :   return ret;
    1254      1447412 : }
    1255              : 
    1256              : // Get the assembler name.
    1257              : 
    1258              : std::string
    1259      2655787 : Backend_name::asm_name() const
    1260              : {
    1261      2655787 :   if (this->is_asm_name_)
    1262            0 :     return this->components_[0];
    1263      2655787 :   std::string ret;
    1264      2655787 :   if (this->prefix_ != NULL)
    1265      1690522 :     ret.append(this->prefix_);
    1266      6296023 :   for (int i = 0; i < this->count_; i++)
    1267              :     {
    1268      3640236 :       if (i > 0)
    1269       984449 :         ret.push_back('.');
    1270      7280472 :       ret.append(go_encode_id(this->components_[i]));
    1271              :     }
    1272      2655787 :   if (!this->suffix_.empty())
    1273       659492 :     ret.append(this->suffix_);
    1274      2655787 :   return ret;
    1275      2655787 : }
    1276              : 
    1277              : // Get the assembler name, or the empty string if it is the same as
    1278              : // the user visible name.
    1279              : 
    1280              : std::string
    1281      1120762 : Backend_name::optional_asm_name() const
    1282              : {
    1283      1120762 :   if (this->is_asm_name_)
    1284       405801 :     return "";
    1285       714961 :   if (this->is_non_identifier_)
    1286       169801 :     return this->asm_name();
    1287      1140054 :   for (int i = 0; i < this->count_; i++)
    1288       890572 :     if (go_id_needs_encoding(this->components_[i]))
    1289       295678 :       return this->asm_name();
    1290       249482 :   return "";
    1291              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.