LCOV - code coverage report
Current view: top level - gcc/rust/backend - rust-mangle-legacy.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.9 % 66 62
Test Date: 2025-06-21 16:26:05 Functions: 100.0 % 4 4
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
       2                 :             : 
       3                 :             : // This file is part of GCC.
       4                 :             : 
       5                 :             : // GCC is free software; you can redistribute it and/or modify it under
       6                 :             : // the terms of the GNU General Public License as published by the Free
       7                 :             : // Software Foundation; either version 3, or (at your option) any later
       8                 :             : // version.
       9                 :             : 
      10                 :             : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11                 :             : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12                 :             : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13                 :             : // for more details.
      14                 :             : 
      15                 :             : // You should have received a copy of the GNU General Public License
      16                 :             : // along with GCC; see the file COPYING3.  If not see
      17                 :             : // <http://www.gnu.org/licenses/>.
      18                 :             : 
      19                 :             : #include "rust-mangle.h"
      20                 :             : #include "fnv-hash.h"
      21                 :             : #include "rust-unicode.h"
      22                 :             : #include "rust-diagnostics.h"
      23                 :             : #include "rust-system.h"
      24                 :             : 
      25                 :             : namespace Rust {
      26                 :             : namespace Compile {
      27                 :             : 
      28                 :             : const std::string kLegacySymbolPrefix = "_ZN";
      29                 :             : static const std::string kLegacySymbolDelim = "E";
      30                 :             : static const std::string kLegacyGenericDelim = "$C$";
      31                 :             : static const std::string kLegacySubstBegin = "$LT$";
      32                 :             : static const std::string kLegacySubstEnd = "$GT$";
      33                 :             : static const std::string kLegacySpace = "$u20$";
      34                 :             : static const std::string kLegacyRef = "$RF$";
      35                 :             : static const std::string kLegacyPtr = "$BP$";
      36                 :             : static const std::string kLegacyLeftSqParen = "$u5b$";        // [
      37                 :             : static const std::string kLegacyRightSqParen = "$u5d$"; // ]
      38                 :             : static const std::string kLegacyLeftBrace = "$u7b$";  // {
      39                 :             : static const std::string kLegacyRightBrace = "$u7d$"; // }
      40                 :             : static const std::string kQualPathBegin = "_" + kLegacySubstBegin;
      41                 :             : static const std::string kLegacyComma = "$C$";
      42                 :             : 
      43                 :             : static std::string
      44                 :       83733 : legacy_mangle_name (const std::string &name)
      45                 :             : {
      46                 :             :   // example
      47                 :             :   //  <&T as core::fmt::Debug>::fmt:
      48                 :             :   //  _ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h6dac924c0051eef7E
      49                 :             :   // replace all white space with $ and & with RF
      50                 :             :   //
      51                 :             :   // <example::Bar as example::A>::fooA:
      52                 :             :   // _ZN43_$LT$example..Bar$u20$as$u20$example..A$GT$4fooA17hfc615fa76c7db7a0E:
      53                 :             :   //
      54                 :             :   // core::ptr::const_ptr::<impl *const T>::cast:
      55                 :             :   // _ZN4core3ptr9const_ptr33_$LT$impl$u20$$BP$const$u20$T$GT$4cast17hb79f4617226f1d55E:
      56                 :             :   //
      57                 :             :   // core::ptr::const_ptr::<impl *const [T]>::as_ptr:
      58                 :             :   // _ZN4core3ptr9const_ptr43_$LT$impl$u20$$BP$const$u20$$u5b$T$u5d$$GT$6as_ptr17he16e0dcd9473b04fE:
      59                 :             :   //
      60                 :             :   // example::Foo<T>::new:
      61                 :             :   // _ZN7example12Foo$LT$T$GT$3new17h9a2aacb7fd783515E:
      62                 :             :   //
      63                 :             :   // <example::Identity as example::FnLike<&T,&T>>::call
      64                 :             :   // _ZN74_$LT$example..Identity$u20$as$u20$example..FnLike$LT$$RF$T$C$$RF$T$GT$$GT$4call17ha9ee58935895acb3E
      65                 :             : 
      66                 :       83733 :   tl::optional<Utf8String> utf8_name = Utf8String::make_utf8_string (name);
      67                 :       83733 :   rust_assert (utf8_name.has_value ());
      68                 :       83733 :   std::vector<Codepoint> chars = utf8_name.value ().get_chars ();
      69                 :       83733 :   std::string buffer;
      70                 :     1146621 :   for (size_t i = 0; i < chars.size (); i++)
      71                 :             :     {
      72                 :     1062888 :       std::string m;
      73                 :     1062888 :       Codepoint c = chars.at (i);
      74                 :             : 
      75                 :     1062888 :       if (c == ' ')
      76                 :       13880 :         m = kLegacySpace;
      77                 :     1049008 :       else if (c == '&')
      78                 :         300 :         m = kLegacyRef;
      79                 :     1048708 :       else if (i == 0 && c == '<')
      80                 :       10796 :         m = kQualPathBegin;
      81                 :     1037912 :       else if (c == '<')
      82                 :        1654 :         m = kLegacySubstBegin;
      83                 :     1036258 :       else if (c == '>')
      84                 :       12450 :         m = kLegacySubstEnd;
      85                 :     1023808 :       else if (c == '*')
      86                 :         378 :         m = kLegacyPtr;
      87                 :     1023430 :       else if (c == '[')
      88                 :         394 :         m = kLegacyLeftSqParen;
      89                 :     1023036 :       else if (c == ']')
      90                 :         394 :         m = kLegacyRightSqParen;
      91                 :     1022642 :       else if (c == '{')
      92                 :         106 :         m = kLegacyLeftBrace;
      93                 :     1022536 :       else if (c == '}')
      94                 :         106 :         m = kLegacyRightBrace;
      95                 :     1022430 :       else if (c == ',')
      96                 :         198 :         m = kLegacyComma;
      97                 :     1022232 :       else if (c == ':')
      98                 :             :         {
      99                 :       10693 :           rust_assert (i + 1 < chars.size ());
     100                 :       10693 :           rust_assert (chars.at (i + 1) == ':');
     101                 :       10693 :           i++;
     102                 :       10693 :           m = "..";
     103                 :             :         }
     104                 :     1011539 :       else if (c.is_ascii ())
     105                 :             :         // ASCII
     106                 :     1011539 :         m.push_back (c.value);
     107                 :             :       else
     108                 :             :         {
     109                 :             :           // Non-ASCII
     110                 :           0 :           std::stringstream escaped;
     111                 :           0 :           escaped << std::hex << "$u" << c.value << "$";
     112                 :           0 :           m += escaped.str ();
     113                 :           0 :         }
     114                 :     2125776 :       buffer += m;
     115                 :     1062888 :     }
     116                 :             : 
     117                 :       83733 :   return std::to_string (buffer.size ()) + buffer;
     118                 :       83733 : }
     119                 :             : 
     120                 :             : static std::string
     121                 :       28488 : legacy_mangle_canonical_path (const Resolver::CanonicalPath &path)
     122                 :             : {
     123                 :       28488 :   std::string buffer;
     124                 :       83733 :   for (size_t i = 0; i < path.size (); i++)
     125                 :             :     {
     126                 :       55245 :       auto &seg = path.get_seg_at (i);
     127                 :      110490 :       buffer += legacy_mangle_name (seg.second);
     128                 :             :     }
     129                 :       28488 :   return buffer;
     130                 :             : }
     131                 :             : 
     132                 :             : // rustc uses a sip128 hash for legacy mangling, but an fnv 128 was quicker to
     133                 :             : // implement for now
     134                 :             : static std::string
     135                 :       28488 : legacy_hash (const std::string &fingerprint)
     136                 :             : {
     137                 :       28488 :   Hash::FNV128 hasher;
     138                 :       28488 :   hasher.write ((const unsigned char *) fingerprint.c_str (),
     139                 :             :                 fingerprint.size ());
     140                 :             : 
     141                 :       28488 :   uint64_t hi, lo;
     142                 :       28488 :   hasher.sum (&hi, &lo);
     143                 :             : 
     144                 :       28488 :   char hex[16 + 1];
     145                 :       28488 :   memset (hex, 0, sizeof hex);
     146                 :       28488 :   snprintf (hex, sizeof hex, "%08" PRIx64 "%08" PRIx64, lo, hi);
     147                 :             : 
     148                 :       28488 :   return "h" + std::string (hex, sizeof (hex) - 1);
     149                 :             : }
     150                 :             : 
     151                 :             : std::string
     152                 :       28488 : legacy_mangle_item (const TyTy::BaseType *ty,
     153                 :             :                     const Resolver::CanonicalPath &path)
     154                 :             : {
     155                 :       28488 :   const std::string hash = legacy_hash (ty->mangle_string ());
     156                 :       28488 :   const std::string hash_sig = legacy_mangle_name (hash);
     157                 :             : 
     158                 :       56976 :   return kLegacySymbolPrefix + legacy_mangle_canonical_path (path) + hash_sig
     159                 :       28488 :          + kLegacySymbolDelim;
     160                 :       28488 : }
     161                 :             : 
     162                 :             : } // namespace Compile
     163                 :             : } // namespace Rust
        

Generated by: LCOV version 2.1-beta

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