LCOV - code coverage report
Current view: top level - gcc/go/gofrontend - names.cc (source / functions) Hit Total Coverage
Test: gcc.info Lines: 389 427 91.1 %
Date: 2020-07-04 13:15:35 Functions: 42 47 89.4 %
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 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 names can not contain dot, so we rely
      22                 :            : // on using dot to encode Unicode characters, and to separate Go
      23                 :            : // symbols by package, and so forth.  We assume that none of the
      24                 :            : // non-Go symbols in the final link will contain a dot, so we don't
      25                 :            : // worry about conflicts.
      26                 :            : //
      27                 :            : // We first describe the basic symbol names, used to represent Go
      28                 :            : // functions and variables.  These never start with a dot, never end
      29                 :            : // with a dot, never contain two consecutive dots, and never contain a
      30                 :            : // dot followed by a digit.
      31                 :            : //
      32                 :            : // The external name for a normal Go symbol NAME, a function or
      33                 :            : // variable, is simply "PKGPATH.NAME".  Note that NAME is not the
      34                 :            : // packed form used for the "hidden" name internally in the compiler;
      35                 :            : // it is the name that appears in the source code.  PKGPATH is the
      36                 :            : // -fgo-pkgpath option as adjusted by Gogo::pkgpath_for_symbol. Note
      37                 :            : // that PKGPATH can not contain a dot and neither can NAME.  Also,
      38                 :            : // NAME may not begin with a digit.  NAME may require further encoding
      39                 :            : // for non-ASCII characters as described below, but until that
      40                 :            : // encoding these symbols contain exactly one dot, and they do not
      41                 :            : // start with a dot.
      42                 :            : //
      43                 :            : // The external name for a method NAME for a named type TYPE is
      44                 :            : // "PKGPATH.TYPE.NAME".  Unlike the gc compiler, the external name
      45                 :            : // does not indicate whether this is a pointer method or a value
      46                 :            : // method; a named type can not have both a pointer and value method
      47                 :            : // with the same name, so there is no ambiguity.  PKGPATH is the
      48                 :            : // package path of the package in which TYPE is defined.  Here none of
      49                 :            : // PKGPATH, TYPE, or NAME can be empty or contain a dot, and neither
      50                 :            : // TYPE nor NAME may begin with a digit.  Before encoding these names
      51                 :            : // contain exactly two dots, not consecutive, and they do not start
      52                 :            : // with a dot.
      53                 :            : //
      54                 :            : // It's uncommon, but the use of type literals with embedded fields
      55                 :            : // can cause us to have methods on unnamed types.  The external names
      56                 :            : // for these are also PKGPATH.TYPE.NAME, where TYPE is an
      57                 :            : // approximately readable version of the type literal, described
      58                 :            : // below.  As the type literal encoding always contains multiple dots,
      59                 :            : // these names always contain more than two dots.  Although the type
      60                 :            : // literal encoding contains dots, neither PKGPATH nor NAME can
      61                 :            : // contain a dot, and neither TYPE nor NAME can begin with a digit.
      62                 :            : // The effect is that PKGPATH is always the portion of the name before
      63                 :            : // the first dot and NAME is always the portion after the last dot.
      64                 :            : // There is no ambiguity as long as encoded type literals are
      65                 :            : // unambiguous.
      66                 :            : //
      67                 :            : // Also uncommon is an external name that must refer to a named type
      68                 :            : // defined within a function.  While such a type can not have methods
      69                 :            : // itself, it can pick up embedded methods, and those methods need
      70                 :            : // names.  These are treated as a kind of type literal written as,
      71                 :            : // before type literal encoding, FNNAME.TYPENAME(INDEX) or, for a
      72                 :            : // method, TYPE.MNAME.TYPENAME(INDEX).  INDEX is the index of that
      73                 :            : // named type within the function, as a single function can have
      74                 :            : // multiple types with the same name.  This is unambiguous as
      75                 :            : // parentheses can not appear in a type literal in this form (they can
      76                 :            : // only appear in interface method declarations).
      77                 :            : //
      78                 :            : // That is the end of the list of basic names.  The remaining names
      79                 :            : // exist for special purposes, and are differentiated from the basic
      80                 :            : // names by containing two consecutive dots.
      81                 :            : //
      82                 :            : // The hash function for a type is treated as a method whose name is
      83                 :            : // ".hash".  That is, the method name begins with a dot.  The effect
      84                 :            : // is that there will be two consecutive dots in the name; the name
      85                 :            : // will always end with "..hash".
      86                 :            : //
      87                 :            : // Similarly the equality function for a type is treated as a method
      88                 :            : // whose name is ".eq".
      89                 :            : //
      90                 :            : // The function descriptor for a function is the same as the name of
      91                 :            : // the function with an added suffix "..f".
      92                 :            : //
      93                 :            : // A thunk for a go or defer statement is treated as a function whose
      94                 :            : // name is ".thunkNN" where NN is a sequence of digits (these
      95                 :            : // functions are never globally visible).  Thus the final name of a
      96                 :            : // thunk will be PKGPATH..thunkNN.
      97                 :            : //
      98                 :            : // An init function is treated as a function whose name is ".initNN"
      99                 :            : // where NN is a sequence of digits (these functions are never
     100                 :            : // globally visible).  Thus the final name of an init function will be
     101                 :            : // PKGPATH..initNN.
     102                 :            : //
     103                 :            : // A nested function is given the name of outermost enclosing function
     104                 :            : // or method with an added suffix "..funcNN" where NN is a sequence of
     105                 :            : // digits.  Note that the function descriptor of a nested function, if
     106                 :            : // needed, will end with "..funcNN..f".
     107                 :            : //
     108                 :            : // A recover thunk is the same as the name of the function with an
     109                 :            : // added suffix "..r".
     110                 :            : //
     111                 :            : // The name of a type descriptor for a named type is PKGPATH.TYPE..d.
     112                 :            : //
     113                 :            : // The name of a type descriptor for an unnamed type is type..TYPE.
     114                 :            : // That is, the string "type.." followed by the type literal encoding.
     115                 :            : // These names are common symbols, in the linker's sense of the word
     116                 :            : // common: in the final executable there is only one instance of the
     117                 :            : // type descriptor for a given unnamed type.  The type literal
     118                 :            : // encoding can never start with a digit or with 'u' or 'U'.
     119                 :            : //
     120                 :            : // The name of the GC symbol for a named type is PKGPATH.TYPE..g.
     121                 :            : //
     122                 :            : // The name of the GC symbol for an unnamed type is typeg..TYPE.
     123                 :            : // These are common symbols.
     124                 :            : //
     125                 :            : // The name of a ptrmask symbol is gcbits..B32 where B32 is an
     126                 :            : // encoding of the ptrmask bits using only ASCII letters without 'u'
     127                 :            : // or 'U'.  These are common symbols.
     128                 :            : //
     129                 :            : // An interface method table for assigning the non-interface type TYPE
     130                 :            : // to the interface type ITYPE is named imt..ITYPE..TYPE.  If ITYPE or
     131                 :            : // TYPE is a named type, they are written as PKGPATH.TYPE.  Otherwise
     132                 :            : // they are written as a type literal.  An interface method table for
     133                 :            : // a pointer method set uses pimt instead of imt.
     134                 :            : //
     135                 :            : // The names of composite literal initializers, including the GC root
     136                 :            : // variable, are not referenced.  They must not conflict with any C
     137                 :            : // language names, but the names are otherwise unimportant.  They are
     138                 :            : // named "go..CNN" where NN is a sequence of digits.  The names do not
     139                 :            : // include the PKGPATH.
     140                 :            : //
     141                 :            : // The map zero value, a common symbol that represents the zero value
     142                 :            : // of a map, is named simply "go..zerovalue".  The name does not
     143                 :            : // include the PKGPATH.
     144                 :            : //
     145                 :            : // The import function for the main package is referenced by C code,
     146                 :            : // and is named __go_init_main.  For other packages it is
     147                 :            : // PKGPATH..import.  If a package doesn't need an init function, it
     148                 :            : // will have a dummy one, named ~PKGPATH.
     149                 :            : //
     150                 :            : // In each pacakge there is a list of all the type descriptors defined
     151                 :            : // in this package.  The name of the list is PKGPATH..types.
     152                 :            : //
     153                 :            : // In the main package it gathers all the type descriptor lists in a
     154                 :            : // single list, named go..typelists.
     155                 :            : //
     156                 :            : // The type literal encoding is essentially a single line version of
     157                 :            : // the type literal, such as "struct { pkgpath.i int; J int }".  In
     158                 :            : // this representation unexported names use their pkgpath, exported
     159                 :            : // names omit it.
     160                 :            : //
     161                 :            : // The type literal encoding is not quite valid Go, as some aspects of
     162                 :            : // compiler generated types can not be represented.  For example,
     163                 :            : // incomparable struct types have an extra field "{x}".  Struct tags
     164                 :            : // are quoted inside curly braces, rather than introduce an encoding
     165                 :            : // for quotes.  Struct tags can contain any character, so any single
     166                 :            : // byte Unicode character that is not alphanumeric or underscore is
     167                 :            : // replaced with .xNN where NN is the hex encoding.
     168                 :            : //
     169                 :            : // There is a simple encoding for glue characters in type literals:
     170                 :            : //   .0 - ' '
     171                 :            : //   .1 - '*'
     172                 :            : //   .2 - ';'
     173                 :            : //   .3 - ','
     174                 :            : //   .4 - '{'
     175                 :            : //   .5 - '}'
     176                 :            : //   .6 - '['
     177                 :            : //   .7 - ']'
     178                 :            : //   .8 - '('
     179                 :            : //   .9 - ')'
     180                 :            : // This is unambiguous as, although the type literal can contain a dot
     181                 :            : // as shown above, those dots are always followed by a name and names
     182                 :            : // can not begin with a digit.  A dot is always followed by a name or
     183                 :            : // a digit, and a type literal can neither start nor end with a dot,
     184                 :            : // so this never introduces consecutive dots.
     185                 :            : //
     186                 :            : // Struct tags can contain any character, so they need special
     187                 :            : // treatment.  Alphanumerics, underscores, and Unicode characters that
     188                 :            : // require more than a single byte are left alone (Unicode characters
     189                 :            : // will be encoded later, as described below).  Other single bytes
     190                 :            : // characters are replace with .xNN where NN is the hex encoding.
     191                 :            : //
     192                 :            : // Since Go identifiers can contain Unicode characters, we must encode
     193                 :            : // them into ASCII.  We do this last, after the name is generated as
     194                 :            : // described above and after type literals are encoded.  To make the
     195                 :            : // encoding unambiguous, we introduce it with two consecutive dots.
     196                 :            : // This is followed by the letter u and four hex digits or the letter
     197                 :            : // U and eight digits, just as in the language only using ..u and ..U
     198                 :            : // instead of \u and \U.  The compiler also produces identifiers that
     199                 :            : // are qualified by package path, which means that there may also be ASCII
     200                 :            : // characters that are not assembler-friendly (ex: '=', '/'). The encoding
     201                 :            : // scheme translates such characters into the "..zNN" where NN is the
     202                 :            : // hex value for the character. Since before this encoding names can never
     203                 :            : // contain consecutive dots followed by 'z', 'u' or 'U', and after this
     204                 :            : // encoding "..z", "..u" and "..U" are followed by a known number of
     205                 :            : // characters, this is unambiguous.
     206                 :            : //
     207                 :            : // Demangling these names is straightforward:
     208                 :            : //  - replace ..zXX with an ASCII character
     209                 :            : //  - replace ..uXXXX with a unicode character
     210                 :            : //  - replace ..UXXXXXXXX with a unicode character
     211                 :            : //  - replace .D, where D is a digit, with the character from the above
     212                 :            : // That will get you as close as possible to a readable name.
     213                 :            : 
     214                 :            : // Return the assembler name to use for an exported function, a
     215                 :            : // method, or a function/method declaration.  This is not called if
     216                 :            : // the function has been given an explicit name via a magic //extern
     217                 :            : // or //go:linkname comment.  GO_NAME is the name that appears in the
     218                 :            : // Go code.  PACKAGE is the package where the function is defined, and
     219                 :            : // is NULL for the package being compiled.  For a method, RTYPE is
     220                 :            : // the method's receiver type; for a function, RTYPE is NULL.
     221                 :            : 
     222                 :            : std::string
     223                 :     496286 : Gogo::function_asm_name(const std::string& go_name, const Package* package,
     224                 :            :                         const Type* rtype)
     225                 :            : {
     226                 :     496286 :   std::string ret;
     227                 :     496286 :   if (rtype != NULL)
     228                 :     286104 :     ret = rtype->deref()->mangled_name(this);
     229                 :     353234 :   else if (package == NULL)
     230                 :     293678 :     ret = this->pkgpath();
     231                 :            :   else
     232                 :      59556 :     ret = package->pkgpath();
     233                 :     496286 :   ret.push_back('.');
     234                 :            :   // Check for special names that will break if we use
     235                 :            :   // Gogo::unpack_hidden_name.
     236                 :     496286 :   if (Gogo::is_special_name(go_name))
     237                 :     225484 :     ret.append(go_name);
     238                 :            :   else
     239                 :     270802 :     ret.append(Gogo::unpack_hidden_name(go_name));
     240                 :     496286 :   return go_encode_id(ret);
     241                 :            : }
     242                 :            : 
     243                 :            : // Return the name to use for a function descriptor.  These symbols
     244                 :            : // are globally visible.
     245                 :            : 
     246                 :            : std::string
     247                 :     220593 : Gogo::function_descriptor_name(Named_object* no)
     248                 :            : {
     249                 :     220593 :   if (no->is_function() && !no->func_value()->asm_name().empty())
     250                 :         49 :     return no->func_value()->asm_name() + "..f";
     251                 :     220544 :   else if (no->is_function_declaration()
     252                 :     220544 :            && !no->func_declaration_value()->asm_name().empty())
     253                 :      76941 :     return no->func_declaration_value()->asm_name() + "..f";
     254                 :     143603 :   std::string ret = this->function_asm_name(no->name(), no->package(), NULL);
     255                 :     143603 :   ret.append("..f");
     256                 :     287206 :   return ret;
     257                 :            : }
     258                 :            : 
     259                 :            : // Return the name to use for a generated stub method.  MNAME is the
     260                 :            : // method name.  PACKAGE is the package where the type that needs this
     261                 :            : // stub method is defined.  These functions are globally visible.
     262                 :            : // Note that this is the function name that corresponds to the name
     263                 :            : // used for the method in Go source code, if this stub method were
     264                 :            : // written in Go.  The assembler name will be generated by
     265                 :            : // Gogo::function_asm_name, and because this is a method that name
     266                 :            : // will include the receiver type.
     267                 :            : 
     268                 :            : std::string
     269                 :     153700 : Gogo::stub_method_name(const Package* package, const std::string& mname)
     270                 :            : {
     271                 :     153700 :   if (!Gogo::is_hidden_name(mname))
     272                 :      77146 :     return mname + "..stub";
     273                 :            : 
     274                 :      76554 :   const std::string& ppkgpath(package == NULL
     275                 :      76554 :                               ? this->pkgpath()
     276                 :      65304 :                               : package->pkgpath());
     277                 :      76554 :   std::string mpkgpath = Gogo::hidden_name_pkgpath(mname);
     278                 :      76554 :   if (mpkgpath == ppkgpath)
     279                 :      60539 :     return Gogo::unpack_hidden_name(mname) + "..stub";
     280                 :            : 
     281                 :            :   // We are creating a stub method for an unexported method of an
     282                 :            :   // imported embedded type.  We need to disambiguate the method name.
     283                 :      92569 :   std::string ret = mpkgpath;
     284                 :      16015 :   ret.push_back('.');
     285                 :      16015 :   ret.append(Gogo::unpack_hidden_name(mname));
     286                 :      16015 :   ret.append("..stub");
     287                 :      32030 :   return ret;
     288                 :            : }
     289                 :            : 
     290                 :            : // Return the name of the hash function for TYPE.
     291                 :            : 
     292                 :            : std::string
     293                 :        189 : Gogo::hash_function_name(const Type* type)
     294                 :            : {
     295                 :        189 :   std::string tname = type->mangled_name(this);
     296                 :        378 :   return tname + "..hash";
     297                 :            : }
     298                 :            : 
     299                 :            : // Return the name of the equal function for TYPE.  If NAME is not
     300                 :            : // NULL it is the name of the type.
     301                 :            : 
     302                 :            : std::string
     303                 :     241260 : Gogo::equal_function_name(const Type* type, const Named_type* name)
     304                 :            : {
     305                 :     241260 :   const Type* rtype = type;
     306                 :     241260 :   if (name != NULL)
     307                 :     178053 :     rtype = name;
     308                 :     241260 :   std::string tname = rtype->mangled_name(this);
     309                 :     482520 :   return tname + "..eq";
     310                 :            : }
     311                 :            : 
     312                 :            : // Return the assembler name to use for a global variable.  GO_NAME is
     313                 :            : // the name that appears in the Go code.  PACKAGE is the package where
     314                 :            : // the variable is defined, and is NULL for the package being
     315                 :            : // compiled.
     316                 :            : 
     317                 :            : std::string
     318                 :      30158 : Gogo::global_var_asm_name(const std::string& go_name, const Package* package)
     319                 :            : {
     320                 :      30158 :   std::string ret;
     321                 :      30158 :   if (package == NULL)
     322                 :      22428 :     ret = this->pkgpath();
     323                 :            :   else
     324                 :       7730 :     ret = package->pkgpath();
     325                 :      30158 :   ret.append(1, '.');
     326                 :      30158 :   ret.append(Gogo::unpack_hidden_name(go_name));
     327                 :      30158 :   return go_encode_id(ret);
     328                 :            : }
     329                 :            : 
     330                 :            : // Return an erroneous name that indicates that an error has already
     331                 :            : // been reported.
     332                 :            : 
     333                 :            : std::string
     334                 :          2 : Gogo::erroneous_name()
     335                 :            : {
     336                 :          2 :   go_assert(saw_errors());
     337                 :          2 :   static int erroneous_count;
     338                 :          2 :   char name[50];
     339                 :          2 :   snprintf(name, sizeof name, ".erroneous%d", erroneous_count);
     340                 :          2 :   ++erroneous_count;
     341                 :          2 :   return name;
     342                 :            : }
     343                 :            : 
     344                 :            : // Return whether a name is an erroneous name.
     345                 :            : 
     346                 :            : bool
     347                 :     295869 : Gogo::is_erroneous_name(const std::string& name)
     348                 :            : {
     349                 :     295869 :   return name.compare(0, 10, ".erroneous") == 0;
     350                 :            : }
     351                 :            : 
     352                 :            : // Return a name for a thunk object.
     353                 :            : 
     354                 :            : std::string
     355                 :      13154 : Gogo::thunk_name()
     356                 :            : {
     357                 :      13154 :   static int thunk_count;
     358                 :      13154 :   char thunk_name[50];
     359                 :      13154 :   snprintf(thunk_name, sizeof thunk_name, "..thunk%d", thunk_count);
     360                 :      13154 :   ++thunk_count;
     361                 :      13154 :   std::string ret = this->pkgpath();
     362                 :      26308 :   return ret + thunk_name;
     363                 :            : }
     364                 :            : 
     365                 :            : // Return whether a function is a thunk.
     366                 :            : 
     367                 :            : bool
     368                 :     303502 : Gogo::is_thunk(const Named_object* no)
     369                 :            : {
     370                 :     303502 :   const std::string& name(no->name());
     371                 :     303502 :   size_t i = name.find("..thunk");
     372                 :     303502 :   if (i == std::string::npos)
     373                 :            :     return false;
     374                 :      43500 :   for (i += 7; i < name.size(); ++i)
     375                 :      28754 :     if (name[i] < '0' || name[i] > '9')
     376                 :            :       return false;
     377                 :            :   return true;
     378                 :            : }
     379                 :            : 
     380                 :            : // Return the name to use for an init function.  There can be multiple
     381                 :            : // functions named "init" so each one needs a different name.
     382                 :            : 
     383                 :            : std::string
     384                 :        625 : Gogo::init_function_name()
     385                 :            : {
     386                 :        625 :   static int init_count;
     387                 :        625 :   char buf[30];
     388                 :        625 :   snprintf(buf, sizeof buf, "..init%d", init_count);
     389                 :        625 :   ++init_count;
     390                 :        625 :   std::string ret = this->pkgpath();
     391                 :       1250 :   return ret + buf;
     392                 :            : }
     393                 :            : 
     394                 :            : // Return the name to use for a nested function.
     395                 :            : 
     396                 :            : std::string
     397                 :      21461 : Gogo::nested_function_name(Named_object* enclosing)
     398                 :            : {
     399                 :      21461 :   std::string prefix;
     400                 :      21461 :   unsigned int index;
     401                 :      21461 :   if (enclosing == NULL)
     402                 :            :     {
     403                 :            :       // A function literal at top level, as in
     404                 :            :       // var f = func() {}
     405                 :       1208 :       static unsigned int toplevel_index;
     406                 :       1208 :       ++toplevel_index;
     407                 :       1208 :       index = toplevel_index;
     408                 :       1208 :       prefix = ".go";
     409                 :            :     }
     410                 :            :   else
     411                 :            :     {
     412                 :      22808 :       while (true)
     413                 :            :         {
     414                 :      22808 :           Named_object* parent = enclosing->func_value()->enclosing();
     415                 :      22808 :           if (parent == NULL)
     416                 :            :             break;
     417                 :            :           enclosing = parent;
     418                 :            :         }
     419                 :      20253 :       const Typed_identifier* rcvr =
     420                 :      20253 :         enclosing->func_value()->type()->receiver();
     421                 :      20253 :       if (rcvr != NULL)
     422                 :            :         {
     423                 :       2589 :           prefix = rcvr->type()->mangled_name(this);
     424                 :       2589 :           prefix.push_back('.');
     425                 :            :         }
     426                 :      20253 :       prefix.append(Gogo::unpack_hidden_name(enclosing->name()));
     427                 :      20253 :       index = enclosing->func_value()->next_nested_function_index();
     428                 :            :     }
     429                 :      21461 :   char buf[30];
     430                 :      21461 :   snprintf(buf, sizeof buf, "..func%u", index);
     431                 :      42922 :   return prefix + buf;
     432                 :            : }
     433                 :            : 
     434                 :            : // Return the name to use for a sink function, a function whose name
     435                 :            : // is simply underscore.  We don't really need these functions but we
     436                 :            : // do have to generate them for error checking.
     437                 :            : 
     438                 :            : std::string
     439                 :        241 : Gogo::sink_function_name()
     440                 :            : {
     441                 :        241 :   static int sink_count;
     442                 :        241 :   char buf[30];
     443                 :        241 :   snprintf(buf, sizeof buf, ".sink%d", sink_count);
     444                 :        241 :   ++sink_count;
     445                 :        241 :   return buf;
     446                 :            : }
     447                 :            : 
     448                 :            : // Return the name to use for a redefined function.  These functions
     449                 :            : // are erroneous but we still generate them for further error
     450                 :            : // checking.
     451                 :            : 
     452                 :            : std::string
     453                 :          1 : Gogo::redefined_function_name()
     454                 :            : {
     455                 :          1 :   static int redefinition_count;
     456                 :          1 :   char buf[30];
     457                 :          1 :   snprintf(buf, sizeof buf, ".redefined%d", redefinition_count);
     458                 :          1 :   ++redefinition_count;
     459                 :          1 :   return buf;
     460                 :            : }
     461                 :            : 
     462                 :            : // Return the name to use for a recover thunk for the function NAME.
     463                 :            : // If the function is a method, RTYPE is the receiver type.
     464                 :            : 
     465                 :            : std::string
     466                 :        666 : Gogo::recover_thunk_name(const std::string& name, const Type* rtype)
     467                 :            : {
     468                 :        666 :   std::string ret;
     469                 :        666 :   if (rtype != NULL)
     470                 :            :     {
     471                 :         36 :       ret = rtype->mangled_name(this);
     472                 :         36 :       ret.append(1, '.');
     473                 :            :     }
     474                 :        666 :   if (Gogo::is_special_name(name))
     475                 :        583 :     ret.append(name);
     476                 :            :   else
     477                 :         83 :     ret.append(Gogo::unpack_hidden_name(name));
     478                 :        666 :   ret.append("..r");
     479                 :        666 :   return ret;
     480                 :            : }
     481                 :            : 
     482                 :            : // Return the name to use for a GC root variable.  The GC root
     483                 :            : // variable is a composite literal that is passed to
     484                 :            : // runtime.registerGCRoots.  There is at most one of these variables
     485                 :            : // per compilation.
     486                 :            : 
     487                 :            : std::string
     488                 :       1764 : Gogo::gc_root_name()
     489                 :            : {
     490                 :       1764 :   return "go..C0";
     491                 :            : }
     492                 :            : 
     493                 :            : // Return the name to use for a composite literal or string
     494                 :            : // initializer.  This is a local name never referenced outside of this
     495                 :            : // file.
     496                 :            : 
     497                 :            : std::string
     498                 :     866875 : Gogo::initializer_name()
     499                 :            : {
     500                 :     866875 :   static unsigned int counter;
     501                 :     866875 :   char buf[30];
     502                 :     866875 :   ++counter;
     503                 :     866875 :   snprintf(buf, sizeof buf, "go..C%u", counter);
     504                 :     866875 :   return buf;
     505                 :            : }
     506                 :            : 
     507                 :            : // Return the name of the variable used to represent the zero value of
     508                 :            : // a map.  This is a globally visible common symbol.
     509                 :            : 
     510                 :            : std::string
     511                 :          3 : Gogo::map_zero_value_name()
     512                 :            : {
     513                 :          3 :   return "go..zerovalue";
     514                 :            : }
     515                 :            : 
     516                 :            : // Return the name to use for the import control function.
     517                 :            : 
     518                 :            : const std::string&
     519                 :     210533 : Gogo::get_init_fn_name()
     520                 :            : {
     521                 :     210533 :   if (this->init_fn_name_.empty())
     522                 :            :     {
     523                 :       3248 :       go_assert(this->package_ != NULL);
     524                 :       3248 :       if (this->is_main_package())
     525                 :            :         {
     526                 :            :           // Use a name that the runtime knows.
     527                 :       1414 :           this->init_fn_name_ = "__go_init_main";
     528                 :            :         }
     529                 :            :       else
     530                 :            :         {
     531                 :       3668 :           std::string s = this->pkgpath_symbol();
     532                 :       1834 :           s.append("..import");
     533                 :       1834 :           this->init_fn_name_ = s;
     534                 :            :         }
     535                 :            :     }
     536                 :            : 
     537                 :     210533 :   return this->init_fn_name_;
     538                 :            : }
     539                 :            : 
     540                 :            : // Return the name for a dummy init function, which is not a real
     541                 :            : // function but only for tracking transitive import.
     542                 :            : 
     543                 :            : std::string
     544                 :        645 : Gogo::dummy_init_fn_name()
     545                 :            : {
     546                 :        645 :   return "~" + this->pkgpath_symbol();
     547                 :            : }
     548                 :            : 
     549                 :            : // Return the package path symbol from an init function name, which
     550                 :            : // can be a real init function or a dummy one.
     551                 :            : 
     552                 :            : std::string
     553                 :      35225 : Gogo::pkgpath_from_init_fn_name(std::string name)
     554                 :            : {
     555                 :      35225 :   go_assert(!name.empty());
     556                 :      35225 :   if (name[0] == '~')
     557                 :      11591 :     return name.substr(1);
     558                 :      23634 :   size_t pos = name.find("..import");
     559                 :      23634 :   if (pos != std::string::npos)
     560                 :      23634 :     return name.substr(0, pos);
     561                 :          0 :   go_unreachable();
     562                 :            : }
     563                 :            : 
     564                 :            : // Return a mangled name for a type.  These names appear in symbol
     565                 :            : // names in the assembler file for things like type descriptors and
     566                 :            : // methods.
     567                 :            : 
     568                 :            : std::string
     569                 :    2075182 : Type::mangled_name(Gogo* gogo) const
     570                 :            : {
     571                 :    2075182 :   std::string ret;
     572                 :            : 
     573                 :            :   // The do_mangled_name virtual function will set RET to the mangled
     574                 :            :   // name before glue character mapping.
     575                 :    2075182 :   this->do_mangled_name(gogo, &ret);
     576                 :            : 
     577                 :            :   // Type descriptor names and interface method table names use a ".."
     578                 :            :   // before the mangled name of a type, so to avoid ambiguity the
     579                 :            :   // mangled name must not start with 'u' or 'U' or a digit.
     580                 :    2075182 :   go_assert((ret[0] < '0' || ret[0] > '9') && ret[0] != ' ');
     581                 :    2075182 :   if (ret[0] == 'u' || ret[0] == 'U')
     582                 :       4341 :     ret = " " + ret;
     583                 :            : 
     584                 :            :   // Map glue characters as described above.
     585                 :            : 
     586                 :            :   // The mapping is only unambiguous if there is no .DIGIT in the
     587                 :            :   // string, so check that.
     588                 :    2075182 :   for (size_t i = ret.find('.');
     589                 :    7287959 :        i != std::string::npos;
     590                 :    5212777 :        i = ret.find('.', i + 1))
     591                 :            :     {
     592                 :    5212777 :       if (i + 1 < ret.size())
     593                 :            :         {
     594                 :    5212777 :           char c = ret[i + 1];
     595                 :    5212777 :           go_assert(c < '0' || c > '9');
     596                 :            :         }
     597                 :            :     }
     598                 :            : 
     599                 :            :   // The order of these characters is the replacement code.
     600                 :    2075182 :   const char * const replace = " *;,{}[]()";
     601                 :            : 
     602                 :    2075182 :   const size_t rlen = strlen(replace);
     603                 :    2075182 :   char buf[2];
     604                 :    2075182 :   buf[0] = '.';
     605                 :   22827002 :   for (size_t ri = 0; ri < rlen; ++ri)
     606                 :            :     {
     607                 :   20751820 :       buf[1] = '0' + ri;
     608                 :   47206502 :       while (true)
     609                 :            :         {
     610                 :   33979161 :           size_t i = ret.find(replace[ri]);
     611                 :   33979161 :           if (i == std::string::npos)
     612                 :            :             break;
     613                 :   13227341 :           ret.replace(i, 1, buf, 2);
     614                 :   13227341 :         }
     615                 :            :     }
     616                 :            : 
     617                 :    2075182 :   return ret;
     618                 :            : }
     619                 :            : 
     620                 :            : // The mangled name is implemented as a method on each instance of
     621                 :            : // Type.
     622                 :            : 
     623                 :            : void
     624                 :          1 : Error_type::do_mangled_name(Gogo*, std::string* ret) const
     625                 :            : {
     626                 :          1 :   ret->append("{error}");
     627                 :          1 : }
     628                 :            : 
     629                 :            : void
     630                 :       7118 : Void_type::do_mangled_name(Gogo*, std::string* ret) const
     631                 :            : {
     632                 :       7118 :   ret->append("{void}");
     633                 :       7118 : }
     634                 :            : 
     635                 :            : void
     636                 :          1 : Boolean_type::do_mangled_name(Gogo*, std::string* ret) const
     637                 :            : {
     638                 :          1 :   ret->append("bool");
     639                 :          1 : }
     640                 :            : 
     641                 :            : void
     642                 :          0 : Integer_type::do_mangled_name(Gogo*, std::string* ret) const
     643                 :            : {
     644                 :          0 :   char buf[100];
     645                 :          0 :   snprintf(buf, sizeof buf, "%s%si%d",
     646                 :          0 :            this->is_abstract_ ? "{abstract}" : "",
     647                 :          0 :            this->is_unsigned_ ? "u" : "",
     648                 :          0 :            this->bits_);
     649                 :          0 :   ret->append(buf);
     650                 :          0 : }
     651                 :            : 
     652                 :            : void
     653                 :          0 : Float_type::do_mangled_name(Gogo*, std::string* ret) const
     654                 :            : {
     655                 :          0 :   char buf[100];
     656                 :          0 :   snprintf(buf, sizeof buf, "%sfloat%d",
     657                 :          0 :            this->is_abstract_ ? "{abstract}" : "",
     658                 :          0 :            this->bits_);
     659                 :          0 :   ret->append(buf);
     660                 :          0 : }
     661                 :            : 
     662                 :            : void
     663                 :          0 : Complex_type::do_mangled_name(Gogo*, std::string* ret) const
     664                 :            : {
     665                 :          0 :   char buf[100];
     666                 :          0 :   snprintf(buf, sizeof buf, "%sc%d",
     667                 :          0 :            this->is_abstract_ ? "{abstract}" : "",
     668                 :          0 :            this->bits_);
     669                 :          0 :   ret->append(buf);
     670                 :          0 : }
     671                 :            : 
     672                 :            : void
     673                 :          0 : String_type::do_mangled_name(Gogo*, std::string* ret) const
     674                 :            : {
     675                 :          0 :   ret->append("string");
     676                 :          0 : }
     677                 :            : 
     678                 :            : void
     679                 :     859067 : Function_type::do_mangled_name(Gogo* gogo, std::string* ret) const
     680                 :            : {
     681                 :     859067 :   ret->append("func");
     682                 :            : 
     683                 :     859067 :   if (this->receiver_ != NULL)
     684                 :            :     {
     685                 :          0 :       ret->push_back('(');
     686                 :          0 :       this->append_mangled_name(this->receiver_->type(), gogo, ret);
     687                 :          0 :       ret->append(")");
     688                 :            :     }
     689                 :            : 
     690                 :     859067 :   ret->push_back('(');
     691                 :     859067 :   const Typed_identifier_list* params = this->parameters();
     692                 :     859067 :   if (params != NULL)
     693                 :            :     {
     694                 :     479448 :       bool first = true;
     695                 :     479448 :       for (Typed_identifier_list::const_iterator p = params->begin();
     696                 :    1254582 :            p != params->end();
     697                 :    1254582 :            ++p)
     698                 :            :         {
     699                 :     775134 :           if (first)
     700                 :            :             first = false;
     701                 :            :           else
     702                 :     295787 :             ret->push_back(',');
     703                 :     775134 :           if (this->is_varargs_ && p + 1 == params->end())
     704                 :            :             {
     705                 :            :               // We can't use "..." here because the mangled name
     706                 :            :               // might start with 'u' or 'U', which would be ambiguous
     707                 :            :               // with the encoding of Unicode characters.
     708                 :      42647 :               ret->append(",,,");
     709                 :            :             }
     710                 :     775134 :           this->append_mangled_name(p->type(), gogo, ret);
     711                 :            :         }
     712                 :            :     }
     713                 :     859067 :   ret->push_back(')');
     714                 :            : 
     715                 :     859067 :   ret->push_back('(');
     716                 :     859067 :   const Typed_identifier_list* results = this->results();
     717                 :     859067 :   if (results != NULL)
     718                 :            :     {
     719                 :     608517 :       bool first = true;
     720                 :     608517 :       for (Typed_identifier_list::const_iterator p = results->begin();
     721                 :    1335430 :            p != results->end();
     722                 :    1335430 :            ++p)
     723                 :            :         {
     724                 :     726913 :           if (first)
     725                 :            :             first = false;
     726                 :            :           else
     727                 :     118396 :             ret->append(",");
     728                 :     726913 :           this->append_mangled_name(p->type(), gogo, ret);
     729                 :            :         }
     730                 :            :     }
     731                 :     859067 :   ret->push_back(')');
     732                 :     859067 : }
     733                 :            : 
     734                 :            : void
     735                 :    1101246 : Pointer_type::do_mangled_name(Gogo* gogo, std::string* ret) const
     736                 :            : {
     737                 :    1101246 :   ret->push_back('*');
     738                 :    1101246 :   this->append_mangled_name(this->to_type_, gogo, ret);
     739                 :    1101246 : }
     740                 :            : 
     741                 :            : void
     742                 :          0 : Nil_type::do_mangled_name(Gogo*, std::string* ret) const
     743                 :            : {
     744                 :          0 :   ret->append("{nil}");
     745                 :          0 : }
     746                 :            : 
     747                 :            : void
     748                 :     448985 : Struct_type::do_mangled_name(Gogo* gogo, std::string* ret) const
     749                 :            : {
     750                 :     448985 :   ret->append("struct{");
     751                 :            : 
     752                 :     448985 :   if (this->is_struct_incomparable_)
     753                 :       9218 :     ret->append("{x}");
     754                 :            : 
     755                 :     448985 :   const Struct_field_list* fields = this->fields_;
     756                 :     448985 :   if (fields != NULL)
     757                 :            :     {
     758                 :     448985 :       bool first = true;
     759                 :    2659013 :       for (Struct_field_list::const_iterator p = fields->begin();
     760                 :    2659013 :            p != fields->end();
     761                 :    2659013 :            ++p)
     762                 :            :         {
     763                 :    2210028 :           if (first)
     764                 :            :             first = false;
     765                 :            :           else
     766                 :    1780286 :             ret->push_back(';');
     767                 :            : 
     768                 :    2210028 :           if (!p->is_anonymous())
     769                 :            :             {
     770                 :    2141549 :               Gogo::append_possibly_hidden_name(ret, p->field_name());
     771                 :    2141549 :               ret->push_back(' ');
     772                 :            :             }
     773                 :            : 
     774                 :            :           // For an anonymous field with an alias type, the field name
     775                 :            :           // is the alias name.
     776                 :    2210028 :           if (p->is_anonymous()
     777                 :      68479 :               && p->type()->named_type() != NULL
     778                 :    2270637 :               && p->type()->named_type()->is_alias())
     779                 :        108 :             p->type()->named_type()->append_mangled_type_name(gogo, true, ret);
     780                 :            :           else
     781                 :    2209920 :             this->append_mangled_name(p->type(), gogo, ret);
     782                 :            : 
     783                 :    2210028 :           if (p->has_tag())
     784                 :            :             {
     785                 :            :               // Use curly braces around a struct tag, since they are
     786                 :            :               // unambiguous here and we have no encoding for
     787                 :            :               // quotation marks.
     788                 :      41624 :               ret->push_back('{');
     789                 :      41624 :               ret->append(go_mangle_struct_tag(p->tag()));
     790                 :      41624 :               ret->push_back('}');
     791                 :            :             }
     792                 :            :         }
     793                 :            :     }
     794                 :            : 
     795                 :     448985 :   ret->push_back('}');
     796                 :     448985 : }
     797                 :            : 
     798                 :            : void
     799                 :     852557 : Array_type::do_mangled_name(Gogo* gogo, std::string* ret) const
     800                 :            : {
     801                 :     852557 :   ret->push_back('[');
     802                 :     852557 :   if (this->length_ != NULL)
     803                 :            :     {
     804                 :     477112 :       Numeric_constant nc;
     805                 :     238556 :       if (!this->length_->numeric_constant_value(&nc))
     806                 :            :         {
     807                 :          0 :           go_assert(saw_errors());
     808                 :          0 :           return;
     809                 :            :         }
     810                 :     238556 :       mpz_t val;
     811                 :     238556 :       if (!nc.to_int(&val))
     812                 :            :         {
     813                 :          0 :           go_assert(saw_errors());
     814                 :            :           return;
     815                 :            :         }
     816                 :     238556 :       char *s = mpz_get_str(NULL, 10, val);
     817                 :     238556 :       ret->append(s);
     818                 :     238556 :       free(s);
     819                 :     238556 :       mpz_clear(val);
     820                 :     238556 :       if (this->is_array_incomparable_)
     821                 :      23122 :         ret->append("x");
     822                 :            :     }
     823                 :     852557 :   ret->push_back(']');
     824                 :     852557 :   this->append_mangled_name(this->element_type_, gogo, ret);
     825                 :            : }
     826                 :            : 
     827                 :            : void
     828                 :      79435 : Map_type::do_mangled_name(Gogo* gogo, std::string* ret) const
     829                 :            : {
     830                 :      79435 :   ret->append("map[");
     831                 :      79435 :   this->append_mangled_name(this->key_type_, gogo, ret);
     832                 :      79435 :   ret->push_back(']');
     833                 :      79435 :   this->append_mangled_name(this->val_type_, gogo, ret);
     834                 :      79435 : }
     835                 :            : 
     836                 :            : void
     837                 :      30947 : Channel_type::do_mangled_name(Gogo* gogo, std::string* ret) const
     838                 :            : {
     839                 :      30947 :   if (!this->may_send_)
     840                 :       4897 :     ret->append("{}");
     841                 :      30947 :   ret->append("chan");
     842                 :      30947 :   if (!this->may_receive_)
     843                 :       1171 :     ret->append("{}");
     844                 :      30947 :   ret->push_back(' ');
     845                 :      30947 :   this->append_mangled_name(this->element_type_, gogo, ret);
     846                 :      30947 : }
     847                 :            : 
     848                 :            : void
     849                 :     200487 : Interface_type::do_mangled_name(Gogo* gogo, std::string* ret) const
     850                 :            : {
     851                 :     200487 :   go_assert(this->methods_are_finalized_);
     852                 :            : 
     853                 :     200487 :   ret->append("interface{");
     854                 :            : 
     855                 :     200487 :   const Typed_identifier_list* methods = this->all_methods_;
     856                 :     200487 :   if (methods != NULL && !this->seen_)
     857                 :            :     {
     858                 :     106262 :       this->seen_ = true;
     859                 :     106262 :       bool first = true;
     860                 :     106262 :       for (Typed_identifier_list::const_iterator p = methods->begin();
     861                 :     609190 :            p != methods->end();
     862                 :     609190 :            ++p)
     863                 :            :         {
     864                 :     502928 :           if (first)
     865                 :            :             first = false;
     866                 :            :           else
     867                 :     396666 :             ret->push_back(';');
     868                 :            : 
     869                 :     502928 :           if (!p->name().empty())
     870                 :            :             {
     871                 :     502928 :               Gogo::append_possibly_hidden_name(ret, p->name());
     872                 :     502928 :               ret->push_back(' ');
     873                 :            :             }
     874                 :            : 
     875                 :     502928 :           this->append_mangled_name(p->type(), gogo, ret);
     876                 :            :         }
     877                 :     106262 :       this->seen_ = false;
     878                 :            :     }
     879                 :            : 
     880                 :     200487 :   ret->push_back('}');
     881                 :     200487 : }
     882                 :            : 
     883                 :            : void
     884                 :    5142061 : Named_type::do_mangled_name(Gogo* gogo, std::string* ret) const
     885                 :            : {
     886                 :    5142061 :   this->append_mangled_type_name(gogo, false, ret);
     887                 :    5142061 : }
     888                 :            : 
     889                 :            : void
     890                 :    1033155 : Forward_declaration_type::do_mangled_name(Gogo* gogo, std::string* ret) const
     891                 :            : {
     892                 :    1033155 :   if (this->is_defined())
     893                 :    1032861 :     this->append_mangled_name(this->real_type(), gogo, ret);
     894                 :            :   else
     895                 :            :     {
     896                 :        294 :       const Named_object* no = this->named_object();
     897                 :        294 :       if (no->package() == NULL)
     898                 :        294 :         ret->append(gogo->pkgpath());
     899                 :            :       else
     900                 :          0 :         ret->append(no->package()->pkgpath());
     901                 :        294 :       ret->push_back('.');
     902                 :        294 :       ret->append(Gogo::unpack_hidden_name(no->name()));
     903                 :            :     }
     904                 :    1033155 : }
     905                 :            : 
     906                 :            : // Append the mangled name for a named type to RET.  For an alias we
     907                 :            : // normally use the real name, but if USE_ALIAS is true we use the
     908                 :            : // alias name itself.
     909                 :            : 
     910                 :            : void
     911                 :    5142169 : Named_type::append_mangled_type_name(Gogo* gogo, bool use_alias,
     912                 :            :                                      std::string* ret) const
     913                 :            : {
     914                 :    5142169 :   if (this->is_error_)
     915                 :     288504 :     return;
     916                 :    5142167 :   if (this->is_alias_ && !use_alias)
     917                 :            :     {
     918                 :     288502 :       if (this->seen_alias_)
     919                 :            :         return;
     920                 :     288502 :       this->seen_alias_ = true;
     921                 :     288502 :       this->append_mangled_name(this->type_, gogo, ret);
     922                 :     288502 :       this->seen_alias_ = false;
     923                 :     288502 :       return;
     924                 :            :     }
     925                 :    4853665 :   Named_object* no = this->named_object_;
     926                 :    9707330 :   std::string name;
     927                 :    4853665 :   if (this->is_builtin())
     928                 :    2572401 :     go_assert(this->in_function_ == NULL);
     929                 :            :   else
     930                 :            :     {
     931                 :    2281264 :       if (this->in_function_ != NULL)
     932                 :            :         {
     933                 :       4190 :           const Typed_identifier* rcvr =
     934                 :       4190 :             this->in_function_->func_value()->type()->receiver();
     935                 :       4190 :           if (rcvr != NULL)
     936                 :        752 :             ret->append(rcvr->type()->deref()->mangled_name(gogo));
     937                 :       3814 :           else if (this->in_function_->package() == NULL)
     938                 :       3814 :             ret->append(gogo->pkgpath());
     939                 :            :           else
     940                 :          0 :             ret->append(this->in_function_->package()->pkgpath());
     941                 :       4190 :           ret->push_back('.');
     942                 :       4190 :           ret->append(Gogo::unpack_hidden_name(this->in_function_->name()));
     943                 :            :         }
     944                 :            :       else
     945                 :            :         {
     946                 :    2277074 :           if (no->package() == NULL)
     947                 :     551434 :             ret->append(gogo->pkgpath());
     948                 :            :           else
     949                 :    1725640 :             ret->append(no->package()->pkgpath());
     950                 :            :         }
     951                 :    2281264 :       ret->push_back('.');
     952                 :            :     }
     953                 :            : 
     954                 :    4853665 :   ret->append(Gogo::unpack_hidden_name(no->name()));
     955                 :            : 
     956                 :    4853665 :   if (this->in_function_ != NULL && this->in_function_index_ > 0)
     957                 :            :     {
     958                 :       1097 :       char buf[30];
     959                 :       1097 :       snprintf(buf, sizeof buf, "..i%u", this->in_function_index_);
     960                 :       1097 :       ret->append(buf);
     961                 :            :     }
     962                 :            : }
     963                 :            : 
     964                 :            : // Return the name for the type descriptor symbol for TYPE.  This can
     965                 :            : // be a global, common, or local symbol, depending.  NT is not NULL if
     966                 :            : // it is the name to use.
     967                 :            : 
     968                 :            : std::string
     969                 :    1504438 : Gogo::type_descriptor_name(const Type* type, Named_type* nt)
     970                 :            : {
     971                 :            :   // The type descriptor symbol for the unsafe.Pointer type is defined
     972                 :            :   // in libgo/runtime/go-unsafe-pointer.c, so just use a reference to
     973                 :            :   // that symbol for all unsafe pointer types.
     974                 :    1504438 :   if (type->is_unsafe_pointer_type())
     975                 :       4159 :     return "unsafe.Pointer..d";
     976                 :            : 
     977                 :    1500279 :   if (nt == NULL)
     978                 :    1448841 :     return "type.." + type->mangled_name(this);
     979                 :            : 
     980                 :      51438 :   std::string ret;
     981                 :      51438 :   Named_object* no = nt->named_object();
     982                 :      51438 :   unsigned int index;
     983                 :      51438 :   const Named_object* in_function = nt->in_function(&index);
     984                 :      51438 :   if (nt->is_builtin())
     985                 :      10118 :     go_assert(in_function == NULL);
     986                 :            :   else
     987                 :            :     {
     988                 :      41320 :       if (in_function != NULL)
     989                 :            :         {
     990                 :        991 :           const Typed_identifier* rcvr =
     991                 :        991 :             in_function->func_value()->type()->receiver();
     992                 :        991 :           if (rcvr != NULL)
     993                 :        166 :             ret.append(rcvr->type()->deref()->mangled_name(this));
     994                 :        908 :           else if (in_function->package() == NULL)
     995                 :        908 :             ret.append(this->pkgpath());
     996                 :            :           else
     997                 :          0 :             ret.append(in_function->package()->pkgpath());
     998                 :        991 :           ret.push_back('.');
     999                 :        991 :           ret.append(Gogo::unpack_hidden_name(in_function->name()));
    1000                 :        991 :           ret.push_back('.');
    1001                 :            :         }
    1002                 :            : 
    1003                 :      41320 :       if (no->package() == NULL)
    1004                 :      27119 :         ret.append(this->pkgpath());
    1005                 :            :       else
    1006                 :      14201 :         ret.append(no->package()->pkgpath());
    1007                 :      41320 :       ret.push_back('.');
    1008                 :            :     }
    1009                 :            : 
    1010                 :      51438 :   Gogo::append_possibly_hidden_name(&ret, no->name());
    1011                 :            : 
    1012                 :      51438 :   if (in_function != NULL && index > 0)
    1013                 :            :     {
    1014                 :        323 :       char buf[30];
    1015                 :        323 :       snprintf(buf, sizeof buf, "..i%u", index);
    1016                 :        323 :       ret.append(buf);
    1017                 :            :     }
    1018                 :            : 
    1019                 :      51438 :   ret.append("..d");
    1020                 :            : 
    1021                 :     102876 :   return ret;
    1022                 :            : }
    1023                 :            : 
    1024                 :            : // Return the name of the type descriptor list symbol of a package.
    1025                 :            : 
    1026                 :            : std::string
    1027                 :      40017 : Gogo::type_descriptor_list_symbol(const std::string& pkgpath)
    1028                 :            : {
    1029                 :      40017 :   return pkgpath + "..types";
    1030                 :            : }
    1031                 :            : 
    1032                 :            : // Return the name of the list of all type descriptor lists.  This is
    1033                 :            : // only used in the main package.
    1034                 :            : 
    1035                 :            : std::string
    1036                 :       1414 : Gogo::typelists_symbol()
    1037                 :            : {
    1038                 :       1414 :   return "go..typelists";
    1039                 :            : }
    1040                 :            : 
    1041                 :            : // Return the name for the GC symbol for a type.  This is used to
    1042                 :            : // initialize the gcdata field of a type descriptor.  This is a local
    1043                 :            : // name never referenced outside of this assembly file.  (Note that
    1044                 :            : // some type descriptors will initialize the gcdata field with a name
    1045                 :            : // generated by ptrmask_symbol_name rather than this method.)
    1046                 :            : 
    1047                 :            : std::string
    1048                 :        193 : Gogo::gc_symbol_name(Type* type)
    1049                 :            : {
    1050                 :        193 :   return this->type_descriptor_name(type, type->named_type()) + "..g";
    1051                 :            : }
    1052                 :            : 
    1053                 :            : // Return the name for a ptrmask variable.  PTRMASK_SYM_NAME is a
    1054                 :            : // base32 string encoding the ptrmask (as returned by Ptrmask::symname
    1055                 :            : // in types.cc).  This name is used to intialize the gcdata field of a
    1056                 :            : // type descriptor.  These names are globally visible.  (Note that
    1057                 :            : // some type descriptors will initialize the gcdata field with a name
    1058                 :            : // generated by gc_symbol_name rather than this method.)
    1059                 :            : 
    1060                 :            : std::string
    1061                 :     198572 : Gogo::ptrmask_symbol_name(const std::string& ptrmask_sym_name)
    1062                 :            : {
    1063                 :     198572 :   return "gcbits.." + ptrmask_sym_name;
    1064                 :            : }
    1065                 :            : 
    1066                 :            : // Return the name to use for an interface method table used for the
    1067                 :            : // ordinary type TYPE converted to the interface type ITYPE.
    1068                 :            : // IS_POINTER is true if this is for the method set for a pointer
    1069                 :            : // receiver.
    1070                 :            : 
    1071                 :            : std::string
    1072                 :      47852 : Gogo::interface_method_table_name(Interface_type* itype, Type* type,
    1073                 :            :                                   bool is_pointer)
    1074                 :            : {
    1075                 :      47852 :   return ((is_pointer ? "pimt.." : "imt..")
    1076                 :     118075 :           + itype->mangled_name(this)
    1077                 :      95704 :           + ".."
    1078                 :      95704 :           + type->mangled_name(this));
    1079                 :            : }
    1080                 :            : 
    1081                 :            : // Return whether NAME is a special name that can not be passed to
    1082                 :            : // unpack_hidden_name.  This is needed because various special names
    1083                 :            : // use "..SUFFIX", but unpack_hidden_name just looks for '.'.
    1084                 :            : 
    1085                 :            : bool
    1086                 :     637668 : Gogo::is_special_name(const std::string& name)
    1087                 :            : {
    1088                 :     637668 :   return (name.find("..hash") != std::string::npos
    1089                 :     637290 :           || name.find("..eq") != std::string::npos
    1090                 :     487436 :           || name.find("..stub") != std::string::npos
    1091                 :     440974 :           || name.find("..func") != std::string::npos
    1092                 :     389807 :           || name.find("..r") != std::string::npos
    1093                 :     389724 :           || name.find("..init") != std::string::npos
    1094                 :     387851 :           || name.find("..thunk") != std::string::npos
    1095                 :    1010774 :           || name.find("..import") != std::string::npos);
    1096                 :            : }

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.