LCOV - code coverage report
Current view: top level - gcc/rust/metadata - rust-export-metadata.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 48.9 % 131 64
Test Date: 2026-08-22 16:33:35 Functions: 76.9 % 13 10
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 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-export-metadata.h"
      20              : #include "rust-hir-visitor.h"
      21              : #include "rust-hir-full.h"
      22              : #include "rust-hir-map.h"
      23              : #include "rust-ast-dump.h"
      24              : #include "rust-abi.h"
      25              : #include "rust-item.h"
      26              : #include "rust-macro.h"
      27              : #include "rust-object-export.h"
      28              : 
      29              : #include "md5.h"
      30              : #include "rust-system.h"
      31              : 
      32              : namespace Rust {
      33              : namespace Metadata {
      34              : 
      35              : static const std::string extension_path = ".rox";
      36              : 
      37         4305 : ExportContext::ExportContext () : mappings (Analysis::Mappings::get ()) {}
      38              : 
      39         4305 : ExportContext::~ExportContext () {}
      40              : 
      41              : void
      42         4305 : ExportContext::emit_crate (AST::Crate &c)
      43              : {
      44         4305 :   std::stringstream oss;
      45         4305 :   using AST::Dump;
      46         4305 :   AST::Dump dumper (
      47              :     oss,
      48              :     Dump::Configuration{Dump::Configuration::InternalComment::Hide,
      49              :                         Dump::Configuration::NodeDescription::Hide,
      50              :                         Dump::Configuration::Comment::Hide,
      51              :                         Dump::Configuration::Newline::Hide,
      52              :                         Dump::Configuration::Indentation::None},
      53         4305 :     {});
      54         4305 :   dumper.process (c);
      55              : 
      56         8610 :   public_interface_buffer += oss.str ();
      57         4305 : }
      58              : void
      59            3 : ExportContext::emit_macro (AST::MacroRulesDefinition &macro)
      60              : {
      61            3 :   std::stringstream oss;
      62            3 :   AST::Dump dumper (oss);
      63              : 
      64            3 :   dumper.go (macro);
      65              : 
      66            6 :   public_interface_buffer += oss.str ();
      67            3 : }
      68              : 
      69              : const std::string &
      70         4305 : ExportContext::get_interface_buffer () const
      71              : {
      72         4305 :   return public_interface_buffer;
      73              : }
      74              : 
      75         4305 : PublicInterface::PublicInterface (HIR::Crate &crate)
      76         4305 :   : crate (crate), mappings (Analysis::Mappings::get ()), context ()
      77         4305 : {}
      78              : 
      79              : void
      80            0 : PublicInterface::Export (HIR::Crate &crate)
      81              : {
      82            0 :   PublicInterface interface (crate);
      83            0 :   interface.gather_export_data ();
      84            0 :   interface.write_to_object_file ();
      85            0 : }
      86              : 
      87              : void
      88         4305 : PublicInterface::ExportTo (HIR::Crate &crate, const std::string &output_path)
      89              : {
      90         4305 :   PublicInterface interface (crate);
      91         4305 :   interface.gather_export_data ();
      92         4305 :   interface.write_to_path (output_path);
      93         4305 : }
      94              : 
      95              : void
      96         4305 : PublicInterface::gather_export_data ()
      97              : {
      98         4305 :   auto crate_num
      99         4305 :     = mappings.lookup_crate_num (crate.get_mappings ().get_nodeid ());
     100         4305 :   auto &ast_crate = mappings.get_ast_crate (crate_num.value ());
     101         4305 :   context.emit_crate (ast_crate);
     102              : 
     103         4308 :   for (auto &macro : mappings.get_exported_macros ())
     104         4308 :     context.emit_macro (macro);
     105         4305 : }
     106              : 
     107              : void
     108            0 : PublicInterface::write_to_object_file () const
     109              : {
     110              :   // done
     111            0 :   const auto &buf = context.get_interface_buffer ();
     112            0 :   std::string size_buffer = std::to_string (buf.size ());
     113              : 
     114              :   // md5 this
     115            0 :   struct md5_ctx chksm;
     116            0 :   unsigned char checksum[16];
     117              : 
     118            0 :   md5_init_ctx (&chksm);
     119            0 :   md5_process_bytes (buf.c_str (), buf.size (), &chksm);
     120            0 :   md5_finish_ctx (&chksm, checksum);
     121              : 
     122              :   // MAGIC MD5 DLIM  DLIM buffer-size DELIM contents
     123            0 :   const std::string current_crate_name = mappings.get_current_crate_name ();
     124              : 
     125              :   // extern void
     126            0 :   rust_write_export_data (kMagicHeader, sizeof (kMagicHeader));
     127            0 :   rust_write_export_data ((const char *) checksum, sizeof (checksum));
     128            0 :   rust_write_export_data (kSzDelim, sizeof (kSzDelim));
     129            0 :   rust_write_export_data (current_crate_name.c_str (),
     130            0 :                           current_crate_name.size ());
     131            0 :   rust_write_export_data (kSzDelim, sizeof (kSzDelim));
     132            0 :   rust_write_export_data (size_buffer.c_str (), size_buffer.size ());
     133            0 :   rust_write_export_data (kSzDelim, sizeof (kSzDelim));
     134            0 :   rust_write_export_data (buf.c_str (), buf.size ());
     135            0 : }
     136              : 
     137              : void
     138         4305 : PublicInterface::write_to_path (const std::string &path) const
     139              : {
     140              :   // validate path contains correct extension
     141         4305 :   const std::string expected_file_name = expected_metadata_filename ();
     142         4305 :   const char *path_base_name = lbasename (path.c_str ());
     143         4305 :   if (strcmp (path_base_name, expected_file_name.c_str ()) != 0)
     144              :     {
     145            0 :       rust_error_at (UNDEF_LOCATION,
     146              :                      "expected metadata-output path to have base file name of: "
     147              :                      "%qs got %qs",
     148              :                      expected_file_name.c_str (), path_base_name);
     149            0 :       return;
     150              :     }
     151              : 
     152              :   // done
     153         4305 :   const auto &buf = context.get_interface_buffer ();
     154         4305 :   std::string size_buffer = std::to_string (buf.size ());
     155              : 
     156              :   // md5 this
     157         4305 :   struct md5_ctx chksm;
     158         4305 :   unsigned char checksum[16];
     159              : 
     160         4305 :   md5_init_ctx (&chksm);
     161         4305 :   md5_process_bytes (buf.c_str (), buf.size (), &chksm);
     162         4305 :   md5_finish_ctx (&chksm, checksum);
     163              : 
     164              :   // MAGIC MD5 DLIM  DLIM buffer-size DELIM contents
     165         4305 :   const std::string current_crate_name = mappings.get_current_crate_name ();
     166              : 
     167              :   // write to path
     168         4305 :   FILE *nfd = fopen (path.c_str (), "wb");
     169         4305 :   if (nfd == NULL)
     170              :     {
     171            0 :       rust_error_at (UNDEF_LOCATION, "failed to open file %qs for writing: %s",
     172            0 :                      path.c_str (), xstrerror (errno));
     173            0 :       return;
     174              :     }
     175              : 
     176              :   // write data
     177         4305 :   if (fwrite (kMagicHeader, sizeof (kMagicHeader), 1, nfd) < 1)
     178              :     {
     179            0 :       rust_error_at (UNDEF_LOCATION, "failed to write to file %qs: %s",
     180            0 :                      path.c_str (), xstrerror (errno));
     181            0 :       fclose (nfd);
     182            0 :       return;
     183              :     }
     184              : 
     185         4305 :   if (fwrite (checksum, sizeof (checksum), 1, nfd) < 1)
     186              :     {
     187            0 :       rust_error_at (UNDEF_LOCATION, "failed to write to file %qs: %s",
     188            0 :                      path.c_str (), xstrerror (errno));
     189            0 :       fclose (nfd);
     190            0 :       return;
     191              :     }
     192              : 
     193         4305 :   if (fwrite (kSzDelim, sizeof (kSzDelim), 1, nfd) < 1)
     194              :     {
     195            0 :       rust_error_at (UNDEF_LOCATION, "failed to write to file %qs: %s",
     196            0 :                      path.c_str (), xstrerror (errno));
     197            0 :       fclose (nfd);
     198            0 :       return;
     199              :     }
     200              : 
     201         4305 :   if (fwrite (current_crate_name.c_str (), current_crate_name.size (), 1, nfd)
     202              :       < 1)
     203              :     {
     204            0 :       rust_error_at (UNDEF_LOCATION, "failed to write to file %qs: %s",
     205            0 :                      path.c_str (), xstrerror (errno));
     206            0 :       fclose (nfd);
     207            0 :       return;
     208              :     }
     209              : 
     210         4305 :   if (fwrite (kSzDelim, sizeof (kSzDelim), 1, nfd) < 1)
     211              :     {
     212            0 :       rust_error_at (UNDEF_LOCATION, "failed to write to file %qs: %s",
     213            0 :                      path.c_str (), xstrerror (errno));
     214            0 :       fclose (nfd);
     215            0 :       return;
     216              :     }
     217              : 
     218         4305 :   if (fwrite (size_buffer.c_str (), size_buffer.size (), 1, nfd) < 1)
     219              :     {
     220            0 :       rust_error_at (UNDEF_LOCATION, "failed to write to file %qs: %s",
     221            0 :                      path.c_str (), xstrerror (errno));
     222            0 :       fclose (nfd);
     223            0 :       return;
     224              :     }
     225              : 
     226         4305 :   if (fwrite (kSzDelim, sizeof (kSzDelim), 1, nfd) < 1)
     227              :     {
     228            0 :       rust_error_at (UNDEF_LOCATION, "failed to write to file %qs: %s",
     229            0 :                      path.c_str (), xstrerror (errno));
     230            0 :       fclose (nfd);
     231            0 :       return;
     232              :     }
     233              : 
     234         4305 :   if (!buf.empty ())
     235         4305 :     if (fwrite (buf.c_str (), buf.size (), 1, nfd) < 1)
     236              :       {
     237            0 :         rust_error_at (UNDEF_LOCATION, "failed to write to file %qs: %s",
     238            0 :                        path.c_str (), xstrerror (errno));
     239            0 :         fclose (nfd);
     240            0 :         return;
     241              :       }
     242              : 
     243              :   // done
     244         4305 :   fclose (nfd);
     245         4305 : }
     246              : 
     247              : bool
     248            0 : PublicInterface::is_crate_public (const HIR::VisItem &item)
     249              : {
     250            0 :   const HIR::Visibility &visibility = item.get_visibility ();
     251              : 
     252            0 :   bool is_public
     253            0 :     = visibility.get_vis_type () == HIR::Visibility::VisType::Public;
     254            0 :   bool has_path = !visibility.get_path ().is_error ();
     255              : 
     256              :   // FIXME this might be pub(crate)
     257              :   // Arthur magic required here
     258              : 
     259            0 :   return is_public && !has_path;
     260              : }
     261              : 
     262              : std::string
     263         8610 : PublicInterface::expected_metadata_filename ()
     264              : {
     265         8610 :   auto &mappings = Analysis::Mappings::get ();
     266              : 
     267         8610 :   const std::string current_crate_name = mappings.get_current_crate_name ();
     268         8610 :   return current_crate_name + extension_path;
     269         8610 : }
     270              : 
     271              : } // namespace Metadata
     272              : } // namespace Rust
        

Generated by: LCOV version 2.4-beta

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