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: 2024-03-23 14:05:01 Functions: 88.5 % 52 46
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     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                 :      431361 : Gogo::function_backend_name(const std::string& go_name,
     248                 :             :                             const Package* package, const Type* rtype,
     249                 :             :                             Backend_name* bname)
     250                 :             : {
     251                 :      431361 :   if (rtype != NULL)
     252                 :      404186 :     rtype->deref()->backend_name(this, bname);
     253                 :      229268 :   else if (package == NULL)
     254                 :      160892 :     bname->add(this->pkgpath());
     255                 :             :   else
     256                 :       68376 :     bname->add(package->pkgpath());
     257                 :             : 
     258                 :      431361 :   size_t pos = Gogo::special_name_pos(go_name);
     259                 :      431361 :   if (pos == std::string::npos)
     260                 :      375541 :     bname->add(Gogo::unpack_hidden_name(go_name));
     261                 :             :   else
     262                 :             :     {
     263                 :       55820 :       if (pos > 0)
     264                 :       55820 :         bname->add(go_name.substr(0, pos));
     265                 :       55820 :       bname->set_suffix(go_name.substr(pos));
     266                 :             :     }
     267                 :      431361 : }
     268                 :             : 
     269                 :             : // Set BNAME to the name to use for a function descriptor.  These
     270                 :             : // symbols are globally visible.
     271                 :             : 
     272                 :             : void
     273                 :      259405 : Gogo::function_descriptor_backend_name(Named_object* no,
     274                 :             :                                        Backend_name* bname)
     275                 :             : {
     276                 :      259405 :   if (no->is_function())
     277                 :      154421 :     no->func_value()->backend_name(this, no, bname);
     278                 :      104984 :   else if (no->is_function_declaration())
     279                 :      104984 :     no->func_declaration_value()->backend_name(this, no, bname);
     280                 :             :   else
     281                 :           0 :     go_unreachable();
     282                 :      259405 :   bname->append_suffix("..f");
     283                 :      259405 : }
     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                 :       18920 :   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                 :      319428 : Gogo::equal_function_name(const Type* type, const Named_type* name,
     350                 :             :                           Backend_name* bname)
     351                 :             : {
     352                 :      319428 :   if (name != NULL)
     353                 :      239980 :     name->backend_name(this, bname);
     354                 :             :   else
     355                 :             :     {
     356                 :       79448 :       bname->add(this->pkgpath());
     357                 :       79448 :       type->backend_name(this, bname);
     358                 :             :     }
     359                 :      319428 :   bname->set_suffix("..eq");
     360                 :      319428 : }
     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                 :       34340 : Gogo::global_var_backend_name(const std::string& go_name,
     368                 :             :                               const Package* package,
     369                 :             :                               Backend_name* bname)
     370                 :             : {
     371                 :       34340 :   if (package == NULL)
     372                 :       25295 :     bname->add(this->pkgpath());
     373                 :             :   else
     374                 :        9045 :     bname->add(package->pkgpath());
     375                 :       34340 :   bname->add(Gogo::unpack_hidden_name(go_name));
     376                 :       34340 : }
     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                 :      349038 : Gogo::is_erroneous_name(const std::string& name)
     396                 :             : {
     397                 :      349038 :   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                 :      430710 : Gogo::is_thunk(const Named_object* no)
     425                 :             : {
     426                 :      430710 :   const std::string& name(no->name());
     427                 :      430710 :   size_t i = name.rfind("..thunk");
     428                 :      430710 :   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                 :       25613 : Gogo::nested_function_name(Named_object* enclosing)
     452                 :             : {
     453                 :       25613 :   std::string prefix;
     454                 :       25613 :   unsigned int index;
     455                 :       25613 :   if (enclosing == NULL)
     456                 :             :     {
     457                 :             :       // A function literal at top level, as in
     458                 :             :       // var f = func() {}
     459                 :        1299 :       static unsigned int toplevel_index;
     460                 :        1299 :       ++toplevel_index;
     461                 :        1299 :       index = toplevel_index;
     462                 :        1299 :       prefix = ".go";
     463                 :             :     }
     464                 :             :   else
     465                 :             :     {
     466                 :       27336 :       while (true)
     467                 :             :         {
     468                 :       27336 :           Named_object* parent = enclosing->func_value()->enclosing();
     469                 :       27336 :           if (parent == NULL)
     470                 :             :             break;
     471                 :             :           enclosing = parent;
     472                 :             :         }
     473                 :       24314 :       const Typed_identifier* rcvr =
     474                 :       24314 :         enclosing->func_value()->type()->receiver();
     475                 :       24314 :       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                 :       24314 :       prefix.append(Gogo::unpack_hidden_name(enclosing->name()));
     483                 :       24314 :       index = enclosing->func_value()->next_nested_function_index();
     484                 :             :     }
     485                 :       25613 :   char buf[30];
     486                 :       25613 :   snprintf(buf, sizeof buf, "..func%u", index);
     487                 :       25613 :   return prefix + buf;
     488                 :       25613 : }
     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                 :          94 :     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                 :     1007030 : Gogo::initializer_name()
     558                 :             : {
     559                 :     1007030 :   static unsigned int counter;
     560                 :     1007030 :   char buf[30];
     561                 :     1007030 :   ++counter;
     562                 :     1007030 :   snprintf(buf, sizeof buf, "go..C%u", counter);
     563                 :     1007030 :   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                 :      494926 : Gogo::get_init_fn_name()
     581                 :             : {
     582                 :      494926 :   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                 :      494926 :   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                 :     2624626 : 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                 :     2624626 :   const Named_type* nt = this->unalias()->named_type();
     635                 :     3720897 :   if (nt != NULL && !nt->is_builtin())
     636                 :             :     {
     637                 :     1031859 :       unsigned int index;
     638                 :     1031859 :       if (nt->in_function(&index) == NULL)
     639                 :             :         {
     640                 :     1028723 :           const Named_object* no = nt->named_object();
     641                 :     1028723 :           if (no->package() == NULL)
     642                 :      239138 :             bname->add(gogo->pkgpath());
     643                 :             :           else
     644                 :      789585 :             bname->add(no->package()->pkgpath());
     645                 :     1028723 :           bname->add(Gogo::unpack_hidden_name(no->name()));
     646                 :     1028723 :           return;
     647                 :             :         }
     648                 :             :     }
     649                 :             : 
     650                 :     1595903 :   std::string name;
     651                 :     1595903 :   bool is_non_identifier = false;
     652                 :             : 
     653                 :             :   // The do_symbol_name virtual function will set RET to the mangled
     654                 :             :   // name before encoding.
     655                 :     1595903 :   this->do_mangled_name(gogo, &name, &is_non_identifier);
     656                 :             : 
     657                 :     1595903 :   bname->add(name);
     658                 :     1595903 :   if (is_non_identifier)
     659                 :     1528352 :     bname->set_is_non_identifier();
     660                 :     1595903 : }
     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                 :        8682 : Void_type::do_mangled_name(Gogo*, std::string* ret,
     675                 :             :                            bool* is_non_identifier) const
     676                 :             : {
     677                 :        8682 :   ret->append("{void}");
     678                 :        8682 :   *is_non_identifier = true;
     679                 :        8682 : }
     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                 :     1124194 : Function_type::do_mangled_name(Gogo* gogo, std::string* ret,
     735                 :             :                                bool* is_non_identifier) const
     736                 :             : {
     737                 :     1124194 :   ret->append("func");
     738                 :             : 
     739                 :     1124194 :   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                 :     1124194 :   ret->push_back('(');
     748                 :     1124194 :   const Typed_identifier_list* params = this->parameters();
     749                 :     1124194 :   if (params != NULL)
     750                 :             :     {
     751                 :      602968 :       bool first = true;
     752                 :      602968 :       for (Typed_identifier_list::const_iterator p = params->begin();
     753                 :     1573483 :            p != params->end();
     754                 :      970515 :            ++p)
     755                 :             :         {
     756                 :      970515 :           if (first)
     757                 :             :             first = false;
     758                 :             :           else
     759                 :      367679 :             ret->push_back(',');
     760                 :      970515 :           if (this->is_varargs_ && p + 1 == params->end())
     761                 :       67684 :             ret->append("...");
     762                 :      970515 :           this->append_mangled_name(p->type(), gogo, ret,
     763                 :             :                                     is_non_identifier);
     764                 :             :         }
     765                 :             :     }
     766                 :     1124194 :   ret->push_back(')');
     767                 :             : 
     768                 :     1124194 :   ret->push_back('(');
     769                 :     1124194 :   const Typed_identifier_list* results = this->results();
     770                 :     1124194 :   if (results != NULL)
     771                 :             :     {
     772                 :      789219 :       bool first = true;
     773                 :      789219 :       for (Typed_identifier_list::const_iterator p = results->begin();
     774                 :     1738044 :            p != results->end();
     775                 :      948825 :            ++p)
     776                 :             :         {
     777                 :      948825 :           if (first)
     778                 :             :             first = false;
     779                 :             :           else
     780                 :      159606 :             ret->append(",");
     781                 :      948825 :           this->append_mangled_name(p->type(), gogo, ret, is_non_identifier);
     782                 :             :         }
     783                 :             :     }
     784                 :     1124194 :   ret->push_back(')');
     785                 :             : 
     786                 :     1124194 :   *is_non_identifier = true;
     787                 :     1124194 : }
     788                 :             : 
     789                 :             : void
     790                 :      810855 : Pointer_type::do_mangled_name(Gogo* gogo, std::string* ret,
     791                 :             :                               bool* is_non_identifier) const
     792                 :             : {
     793                 :      810855 :   ret->push_back('*');
     794                 :      810855 :   this->append_mangled_name(this->to_type_, gogo, ret, is_non_identifier);
     795                 :      810855 :   *is_non_identifier = true;
     796                 :      810855 : }
     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                 :      624458 : Struct_type::do_mangled_name(Gogo* gogo, std::string* ret,
     808                 :             :                              bool* is_non_identifier) const
     809                 :             : {
     810                 :      624458 :   ret->append("struct{");
     811                 :             : 
     812                 :      624458 :   if (this->is_struct_incomparable_)
     813                 :       11335 :     ret->append("{x}");
     814                 :             : 
     815                 :      624458 :   const Struct_field_list* fields = this->fields_;
     816                 :      624458 :   if (fields != NULL)
     817                 :             :     {
     818                 :      624458 :       bool first = true;
     819                 :     3726587 :       for (Struct_field_list::const_iterator p = fields->begin();
     820                 :     3726587 :            p != fields->end();
     821                 :     3102129 :            ++p)
     822                 :             :         {
     823                 :     3102129 :           if (first)
     824                 :             :             first = false;
     825                 :             :           else
     826                 :     2514240 :             ret->push_back(';');
     827                 :             : 
     828                 :     3102129 :           if (!p->is_anonymous())
     829                 :             :             {
     830                 :     3014516 :               Gogo::append_possibly_hidden_name(ret, p->field_name());
     831                 :     3014516 :               ret->push_back(' ');
     832                 :             :             }
     833                 :             : 
     834                 :     3102129 :           const Type* ft = p->type();
     835                 :     3102129 :           const Named_type* nt = ft->named_type();
     836                 :             : 
     837                 :     3177856 :           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                 :         509 :               ret->append(gogo->pkgpath());
     845                 :         509 :               ret->push_back('.');
     846                 :         509 :               nt->append_symbol_type_name(gogo, true, ret, is_non_identifier);
     847                 :             :             }
     848                 :     3101620 :           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                 :          61 :               nt->append_symbol_type_name(gogo, true, ret, is_non_identifier);
     853                 :             :             }
     854                 :             :           else
     855                 :     3101559 :             this->append_mangled_name(ft, gogo, ret, is_non_identifier);
     856                 :             : 
     857                 :     3102129 :           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                 :       54047 :               ret->push_back('{');
     863                 :       54047 :               ret->append(go_mangle_struct_tag(p->tag()));
     864                 :       54047 :               ret->push_back('}');
     865                 :             :             }
     866                 :             :         }
     867                 :             :     }
     868                 :             : 
     869                 :      624458 :   ret->push_back('}');
     870                 :             : 
     871                 :      624458 :   *is_non_identifier = true;
     872                 :      624458 : }
     873                 :             : 
     874                 :             : void
     875                 :     1191734 : Array_type::do_mangled_name(Gogo* gogo, std::string* ret,
     876                 :             :                             bool* is_non_identifier) const
     877                 :             : {
     878                 :     1191734 :   ret->push_back('[');
     879                 :     1191734 :   if (this->length_ != NULL)
     880                 :             :     {
     881                 :      269942 :       Numeric_constant nc;
     882                 :      269942 :       if (!this->length_->numeric_constant_value(&nc))
     883                 :             :         {
     884                 :           0 :           go_assert(saw_errors());
     885                 :             :           return;
     886                 :             :         }
     887                 :      269942 :       mpz_t val;
     888                 :      269942 :       if (!nc.to_int(&val))
     889                 :             :         {
     890                 :           0 :           go_assert(saw_errors());
     891                 :             :           return;
     892                 :             :         }
     893                 :      269942 :       char *s = mpz_get_str(NULL, 10, val);
     894                 :      269942 :       ret->append(s);
     895                 :      269942 :       free(s);
     896                 :      269942 :       mpz_clear(val);
     897                 :      269942 :       if (this->is_array_incomparable_)
     898                 :       26850 :         ret->append("x");
     899                 :      269942 :     }
     900                 :     1191734 :   ret->push_back(']');
     901                 :     1191734 :   this->append_mangled_name(this->element_type_, gogo, ret, is_non_identifier);
     902                 :     1191734 :   *is_non_identifier = true;
     903                 :             : }
     904                 :             : 
     905                 :             : void
     906                 :      130285 : Map_type::do_mangled_name(Gogo* gogo, std::string* ret,
     907                 :             :                           bool* is_non_identifier) const
     908                 :             : {
     909                 :      130285 :   ret->append("map[");
     910                 :      130285 :   this->append_mangled_name(this->key_type_, gogo, ret, is_non_identifier);
     911                 :      130285 :   ret->push_back(']');
     912                 :      130285 :   this->append_mangled_name(this->val_type_, gogo, ret, is_non_identifier);
     913                 :      130285 :   *is_non_identifier = true;
     914                 :      130285 : }
     915                 :             : 
     916                 :             : void
     917                 :       39093 : Channel_type::do_mangled_name(Gogo* gogo, std::string* ret,
     918                 :             :                               bool* is_non_identifier) const
     919                 :             : {
     920                 :       39093 :   if (!this->may_send_)
     921                 :        6067 :     ret->append("<-");
     922                 :       39093 :   ret->append("chan");
     923                 :       39093 :   if (!this->may_receive_)
     924                 :        1135 :     ret->append("<-");
     925                 :       39093 :   ret->push_back(' ');
     926                 :       39093 :   this->append_mangled_name(this->element_type_, gogo, ret, is_non_identifier);
     927                 :       39093 :   *is_non_identifier = true;
     928                 :       39093 : }
     929                 :             : 
     930                 :             : void
     931                 :      277225 : Interface_type::do_mangled_name(Gogo* gogo, std::string* ret,
     932                 :             :                                 bool* is_non_identifier) const
     933                 :             : {
     934                 :      277225 :   go_assert(this->methods_are_finalized_);
     935                 :             : 
     936                 :      277225 :   ret->append("interface{");
     937                 :             : 
     938                 :      277225 :   const Typed_identifier_list* methods = this->all_methods_;
     939                 :      277225 :   if (methods != NULL && !this->seen_)
     940                 :             :     {
     941                 :      141458 :       this->seen_ = true;
     942                 :      141458 :       bool first = true;
     943                 :      141458 :       for (Typed_identifier_list::const_iterator p = methods->begin();
     944                 :      843883 :            p != methods->end();
     945                 :      702425 :            ++p)
     946                 :             :         {
     947                 :      702425 :           if (first)
     948                 :             :             first = false;
     949                 :             :           else
     950                 :      560967 :             ret->push_back(';');
     951                 :             : 
     952                 :      702425 :           if (!p->name().empty())
     953                 :             :             {
     954                 :      702425 :               Gogo::append_possibly_hidden_name(ret, p->name());
     955                 :      702425 :               ret->push_back(' ');
     956                 :             :             }
     957                 :             : 
     958                 :      702425 :           this->append_mangled_name(p->type(), gogo, ret, is_non_identifier);
     959                 :             :         }
     960                 :      141458 :       this->seen_ = false;
     961                 :             :     }
     962                 :             : 
     963                 :      277225 :   ret->push_back('}');
     964                 :             : 
     965                 :      277225 :   *is_non_identifier = true;
     966                 :      277225 : }
     967                 :             : 
     968                 :             : void
     969                 :     5899946 : Named_type::do_mangled_name(Gogo* gogo, std::string* ret,
     970                 :             :                             bool* is_non_identifier) const
     971                 :             : {
     972                 :     5899946 :   this->append_symbol_type_name(gogo, false, ret, is_non_identifier);
     973                 :     5899946 : }
     974                 :             : 
     975                 :             : void
     976                 :     1106818 : Forward_declaration_type::do_mangled_name(Gogo* gogo, std::string* ret,
     977                 :             :                                           bool *is_non_identifier) const
     978                 :             : {
     979                 :     1106818 :   if (this->is_defined())
     980                 :     1106448 :     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                 :         370 :       ret->append(Gogo::unpack_hidden_name(no->name()));
     990                 :             :     }
     991                 :     1106818 : }
     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                 :     5900516 : Named_type::append_symbol_type_name(Gogo* gogo, bool use_alias,
     999                 :             :                                     std::string* ret,
    1000                 :             :                                     bool* is_non_identifier) const
    1001                 :             : {
    1002                 :     5900516 :   if (this->is_error_)
    1003                 :      485364 :     return;
    1004                 :     5900516 :   if (this->is_alias_ && !use_alias)
    1005                 :             :     {
    1006                 :      485364 :       if (this->seen_alias_)
    1007                 :             :         return;
    1008                 :      485364 :       this->seen_alias_ = true;
    1009                 :      485364 :       this->append_mangled_name(this->type_, gogo, ret, is_non_identifier);
    1010                 :      485364 :       this->seen_alias_ = false;
    1011                 :      485364 :       return;
    1012                 :             :     }
    1013                 :     5415152 :   Named_object* no = this->named_object_;
    1014                 :     5415152 :   std::string name;
    1015                 :     5415152 :   if (this->is_builtin())
    1016                 :     3368992 :     go_assert(this->in_function_ == NULL);
    1017                 :             :   else
    1018                 :             :     {
    1019                 :     2046160 :       if (this->in_function_ != NULL)
    1020                 :             :         {
    1021                 :        5704 :           const Typed_identifier* rcvr =
    1022                 :        5704 :             this->in_function_->func_value()->type()->receiver();
    1023                 :        5704 :           if (rcvr != NULL)
    1024                 :             :             {
    1025                 :         603 :               Backend_name bname;
    1026                 :        1206 :               rcvr->type()->deref()->backend_name(gogo, &bname);
    1027                 :         603 :               ret->append(bname.name());
    1028                 :         603 :               if (bname.is_non_identifier())
    1029                 :           0 :                 *is_non_identifier = true;
    1030                 :         603 :             }
    1031                 :        5101 :           else if (this->in_function_->package() == NULL)
    1032                 :        5101 :             ret->append(gogo->pkgpath());
    1033                 :             :           else
    1034                 :           0 :             ret->append(this->in_function_->package()->pkgpath());
    1035                 :        5704 :           ret->push_back('.');
    1036                 :        5704 :           ret->append(Gogo::unpack_hidden_name(this->in_function_->name()));
    1037                 :             :         }
    1038                 :             :       else
    1039                 :             :         {
    1040                 :     2040456 :           if (no->package() == NULL)
    1041                 :      380550 :             ret->append(gogo->pkgpath());
    1042                 :             :           else
    1043                 :     1659906 :             ret->append(no->package()->pkgpath());
    1044                 :             :         }
    1045                 :     2046160 :       ret->push_back('.');
    1046                 :             :     }
    1047                 :             : 
    1048                 :     5415152 :   ret->append(Gogo::unpack_hidden_name(no->name()));
    1049                 :             : 
    1050                 :     5415152 :   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                 :     5415152 : }
    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                 :     3716941 : Gogo::append_possibly_hidden_name(std::string *result, const std::string& name)
    1063                 :             : {
    1064                 :     3716941 :   if (!Gogo::is_hidden_name(name))
    1065                 :     1778157 :     *result += name;
    1066                 :             :   else
    1067                 :     1938784 :     *result += name.substr(1);
    1068                 :     3716941 : }
    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                 :     1971922 : 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                 :     1971922 :   if (type->is_unsafe_pointer_type())
    1082                 :             :     {
    1083                 :        5323 :       bname->set_asm_name("unsafe.Pointer..d");
    1084                 :        5323 :       return;
    1085                 :             :     }
    1086                 :             : 
    1087                 :     1966599 :   bool is_pointer = false;
    1088                 :     1966599 :   if (nt == NULL && type->points_to() != NULL)
    1089                 :             :     {
    1090                 :      565980 :       nt = type->points_to()->unalias()->named_type();
    1091                 :      565980 :       is_pointer = true;
    1092                 :             :     }
    1093                 :             : 
    1094                 :     1966599 :   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                 :     1369024 :       go_assert(!type->is_basic_type());
    1100                 :             : 
    1101                 :     1369024 :       type->backend_name(this, bname);
    1102                 :     1369024 :       bname->set_prefix("type..");
    1103                 :             :     }
    1104                 :             :   else
    1105                 :             :     {
    1106                 :      597575 :       nt->backend_name(this, bname);
    1107                 :      660474 :       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                 :      231622 : Gogo::ptrmask_symbol_name(const std::string& ptrmask_sym_name)
    1157                 :             : {
    1158                 :      231622 :   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                 :      596641 : Gogo::special_name_pos(const std::string& name)
    1188                 :             : {
    1189                 :      596641 :   size_t pos = name.rfind("..");
    1190                 :      596641 :   if (pos == std::string::npos)
    1191                 :             :     return pos;
    1192                 :      110003 :   std::string suffix(name.substr(pos));
    1193                 :      110003 :   if (suffix == "..hash"
    1194                 :      110003 :       || suffix == "..eq"
    1195                 :      109930 :       || suffix == "..stub"
    1196                 :       55607 :       || suffix == "..d"
    1197                 :       55607 :       || suffix == "..f"
    1198                 :       55607 :       || suffix == "..r"
    1199                 :      165516 :       || suffix == "..import")
    1200                 :             :     return pos;
    1201                 :       55513 :   if ((suffix.compare(2, 4, "func") == 0
    1202                 :       27885 :        || suffix.compare(2, 4, "init") == 0)
    1203                 :      116799 :       && 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                 :      110003 : }
    1210                 :             : 
    1211                 :             : // Return whether the string is non-empty and contains only digits.
    1212                 :             : 
    1213                 :             : bool
    1214                 :       66981 : Gogo::is_digits(const std::string& s)
    1215                 :             : {
    1216                 :       66981 :   if (s.empty())
    1217                 :             :     return false;
    1218                 :      192377 :   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                 :     3649825 : Backend_name::name() const
    1230                 :             : {
    1231                 :     3649825 :   if (this->is_asm_name_)
    1232                 :      501782 :     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                 :     3148043 :   if (this->is_non_identifier_)
    1240                 :     1701560 :     return "g." + this->asm_name();
    1241                 :             : 
    1242                 :     1446483 :   std::string ret;
    1243                 :     1446483 :   if (this->prefix_ != NULL)
    1244                 :           2 :     ret.append(this->prefix_);
    1245                 :     4436750 :   for (int i = 0; i < this->count_; i++)
    1246                 :             :     {
    1247                 :     2990267 :       if (i > 0)
    1248                 :     1543784 :         ret.push_back('.');
    1249                 :     2990267 :       ret.append(this->components_[i]);
    1250                 :             :     }
    1251                 :     1446483 :   if (!this->suffix_.empty())
    1252                 :     1131399 :     ret.append(this->suffix_);
    1253                 :     1446483 :   return ret;
    1254                 :     1446483 : }
    1255                 :             : 
    1256                 :             : // Get the assembler name.
    1257                 :             : 
    1258                 :             : std::string
    1259                 :     2652966 : Backend_name::asm_name() const
    1260                 :             : {
    1261                 :     2652966 :   if (this->is_asm_name_)
    1262                 :           0 :     return this->components_[0];
    1263                 :     2652966 :   std::string ret;
    1264                 :     2652966 :   if (this->prefix_ != NULL)
    1265                 :     1688456 :     ret.append(this->prefix_);
    1266                 :     6289626 :   for (int i = 0; i < this->count_; i++)
    1267                 :             :     {
    1268                 :     3636660 :       if (i > 0)
    1269                 :      983694 :         ret.push_back('.');
    1270                 :     3636660 :       ret.append(go_encode_id(this->components_[i]));
    1271                 :             :     }
    1272                 :     2652966 :   if (!this->suffix_.empty())
    1273                 :      658739 :     ret.append(this->suffix_);
    1274                 :     2652966 :   return ret;
    1275                 :     2652966 : }
    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                 :     1119752 : Backend_name::optional_asm_name() const
    1282                 :             : {
    1283                 :     1119752 :   if (this->is_asm_name_)
    1284                 :      404983 :     return "";
    1285                 :      714769 :   if (this->is_non_identifier_)
    1286                 :      169783 :     return this->asm_name();
    1287                 :     1139698 :   for (int i = 0; i < this->count_; i++)
    1288                 :      890216 :     if (go_id_needs_encoding(this->components_[i]))
    1289                 :      295504 :       return this->asm_name();
    1290                 :      249482 :   return "";
    1291                 :             : }
        

Generated by: LCOV version 2.0-1

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.