LCOV - code coverage report
Current view: top level - gcc/go/gofrontend - export.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.0 % 50 48
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 8 8
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // export.h -- Export declarations in Go frontend.     -*- C++ -*-
       2              : 
       3              : // Copyright 2009 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              : #ifndef GO_EXPORT_H
       8              : #define GO_EXPORT_H
       9              : 
      10              : #include "string-dump.h"
      11              : 
      12              : class Go_sha1_helper;
      13              : class Gogo;
      14              : class Named_object;
      15              : class Export_function_body;
      16              : class Import_init;
      17              : class Named_object;
      18              : class Bindings;
      19              : class Type;
      20              : class Package;
      21              : class Import_init_set;
      22              : class Backend;
      23              : class Temporary_statement;
      24              : class Unnamed_label;
      25              : struct Export_impl;
      26              : 
      27              : // Codes used for the builtin types.  These are all negative to make
      28              : // them easily distinct from the codes assigned by Export::write_type.
      29              : // Note that these codes may not be changed!  Changing them would
      30              : // break existing export data.
      31              : 
      32              : enum Builtin_code
      33              : {
      34              :   BUILTIN_INT8 = -1,
      35              :   BUILTIN_INT16 = -2,
      36              :   BUILTIN_INT32 = -3,
      37              :   BUILTIN_INT64 = -4,
      38              :   BUILTIN_UINT8 = -5,
      39              :   BUILTIN_UINT16 = -6,
      40              :   BUILTIN_UINT32 = -7,
      41              :   BUILTIN_UINT64 = -8,
      42              :   BUILTIN_FLOAT32 = -9,
      43              :   BUILTIN_FLOAT64 = -10,
      44              :   BUILTIN_INT = -11,
      45              :   BUILTIN_UINT = -12,
      46              :   BUILTIN_UINTPTR = -13,
      47              :   BUILTIN_BOOL = -15,
      48              :   BUILTIN_STRING = -16,
      49              :   BUILTIN_COMPLEX64 = -17,
      50              :   BUILTIN_COMPLEX128 = -18,
      51              :   BUILTIN_ERROR = -19,
      52              :   BUILTIN_BYTE = -20,
      53              :   BUILTIN_RUNE = -21,
      54              :   BUILTIN_ANY = -22,
      55              : 
      56              :   SMALLEST_BUILTIN_CODE = -22
      57              : };
      58              : 
      59              : // Export data version number. New export data is written with the
      60              : // "current" version, but there is support for reading files with
      61              : // older version export data (at least for now).
      62              : 
      63              : enum Export_data_version {
      64              :   EXPORT_FORMAT_UNKNOWN = 0,
      65              :   EXPORT_FORMAT_V1 = 1,
      66              :   EXPORT_FORMAT_V2 = 2,
      67              :   EXPORT_FORMAT_V3 = 3,
      68              :   EXPORT_FORMAT_CURRENT = EXPORT_FORMAT_V3
      69              : };
      70              : 
      71              : // This class manages exporting Go declarations.  It handles the main
      72              : // loop of exporting.  A pointer to this class is also passed to the
      73              : // various specific export implementations.
      74              : 
      75              : class Export : public String_dump
      76              : {
      77              :  public:
      78              :   // The Stream class is an interface used to output the exported
      79              :   // information.  The caller should instantiate a child of this
      80              :   // class.
      81              :   class Stream
      82              :   {
      83              :    public:
      84              :     Stream();
      85              :     virtual ~Stream();
      86              : 
      87              :     // Write a string. Implements the String_dump interface.
      88              :     void
      89      2066887 :     write_string(const std::string& s)
      90      2066887 :     { this->write_and_sum_bytes(s.data(), s.length()); }
      91              : 
      92              :     // Write a nul terminated string. Implements the String_dump interface.
      93              :     void
      94     14169003 :     write_c_string(const char* s)
      95     14169003 :     { this->write_and_sum_bytes(s, strlen(s)); }
      96              : 
      97              :     // Write some bytes.
      98              :     void
      99         4252 :     write_bytes(const char* bytes, size_t length)
     100         4252 :     { this->write_and_sum_bytes(bytes, length); }
     101              : 
     102              :     // Return the raw bytes of the checksum data.
     103              :     std::string
     104              :     checksum();
     105              : 
     106              :     // Write a checksum string to the stream.  This will be called at
     107              :     // the end of the other output.
     108              :     void
     109              :     write_checksum(const std::string&);
     110              : 
     111              :    protected:
     112              :     // This function is called with data to export.  This data must be
     113              :     // made available as a contiguous stream for the importer.
     114              :     virtual void
     115              :     do_write(const char* bytes, size_t length) = 0;
     116              : 
     117              :   private:
     118              :     void
     119              :     write_and_sum_bytes(const char*, size_t);
     120              : 
     121              :     // The checksum helper.
     122              :     Go_sha1_helper* sha1_helper_;
     123              :   };
     124              : 
     125              :   Export(Stream*);
     126              :   ~Export();
     127              : 
     128              :   // Size of export data magic string (which includes version number).
     129              :   static const int magic_len = 4;
     130              : 
     131              :   // Magic strings (current version and older versions).
     132              :   static const char cur_magic[magic_len];
     133              :   static const char v1_magic[magic_len];
     134              :   static const char v2_magic[magic_len];
     135              : 
     136              :   // The length of the checksum string.
     137              :   static const int checksum_len = 20;
     138              : 
     139              :   // Register the builtin types.
     140              :   void
     141              :   register_builtin_types(Gogo*);
     142              : 
     143              :   // Export the identifiers in BINDINGS which are marked for export.
     144              :   // The exporting is done via a series of calls to THIS->STREAM_.  If
     145              :   // is nothing to export, this->stream_->write will not be called.
     146              :   // PREFIX is the package prefix.  PKGPATH is the package path.
     147              :   // Only one of PREFIX and PKGPATH will be non-empty.
     148              :   // PACKAGES is all the packages we have seen.
     149              :   // IMPORTS is the explicitly imported packages.
     150              :   // IMPORT_INIT_FN is the name of the import initialization function
     151              :   // for this package; it will be empty if none is needed.
     152              :   // IMPORTED_INIT_FNS is the list of initialization functions for
     153              :   // imported packages.
     154              :   void
     155              :   export_globals(const std::string& package_name,
     156              :                  const std::string& prefix,
     157              :                  const std::string& pkgpath,
     158              :                  const std::map<std::string, Package*>& packages,
     159              :                  const std::map<std::string, Package*>& imports,
     160              :                  const std::string& import_init_fn,
     161              :                  const Import_init_set& imported_init_fns,
     162              :                  const Bindings* bindings,
     163              :                  Unordered_set(Named_object*)* marked_inline_functions);
     164              : 
     165              :   // Record a type that is mentioned in export data. Return value is
     166              :   // TRUE for newly visited types, FALSE for types that have been seen
     167              :   // previously.
     168              :   bool
     169              :   record_type(Type*);
     170              : 
     171              :   // Assign type indices to types mentioned in export data.
     172              :   int
     173              :   assign_type_indices(const std::vector<Named_object*>& sorted_exports);
     174              : 
     175              :   // Write a string to the export stream.
     176              :   void
     177      2066887 :   write_string(const std::string& s)
     178      2066887 :   { this->stream_->write_string(s); }
     179              : 
     180              :   // Write a nul terminated string to the export stream.
     181              :   void
     182     14169003 :   write_c_string(const char* s)
     183     14169003 :   { this->stream_->write_c_string(s); }
     184              : 
     185              :   // Write some bytes to the export stream.
     186              :   void
     187         4252 :   write_bytes(const char* bytes, size_t length)
     188         4252 :   { this->stream_->write_bytes(bytes, length); }
     189              : 
     190              :   // Write a name to the export stream.  If NAME is empty, write "?".
     191              :   void
     192              :   write_name(const std::string& name);
     193              : 
     194              :   // Write out a type.  This handles references back to previous
     195              :   // definitions.
     196              :   void
     197              :   write_type(const Type*);
     198              : 
     199              :   // Write a type to an exported function body.
     200              :   void
     201              :   write_type_to(const Type*, Export_function_body*);
     202              : 
     203              :   // Write the escape note to the export stream.  If NOTE is NULL, write
     204              :   // nothing.
     205              :   void
     206              :   write_escape(std::string* note);
     207              : 
     208              :   // Write an integer value.
     209              :   void
     210              :   write_int(int);
     211              : 
     212              :   // Write an unsigned value.
     213              :   void
     214              :   write_unsigned(unsigned);
     215              : 
     216              :   // Return the index of a package.
     217              :   int
     218              :   package_index(const Package* p) const;
     219              : 
     220              :   // Return the index of the "unsafe" package, which must be one of
     221              :   // the exported packages.
     222              :   int
     223              :   unsafe_package_index() const;
     224              : 
     225              :  private:
     226              :   Export(const Export&);
     227              :   Export& operator=(const Export&);
     228              : 
     229              :   // Write out all known packages.
     230              :   void
     231              :   write_packages(const std::map<std::string, Package*>& packages);
     232              : 
     233              :   typedef std::map<unsigned, std::set<unsigned> > Init_graph;
     234              : 
     235              :   static void
     236              :   add_init_graph_edge(Init_graph* init_graph, unsigned src, unsigned sink);
     237              : 
     238              :   static void
     239              :   populate_init_graph(Init_graph* init_graph,
     240              :                       const Import_init_set& imported_init_fns,
     241              :                       const std::map<std::string, unsigned>& init_idx);
     242              : 
     243              :   // Write out the imported packages.
     244              :   void
     245              :   write_imports(const std::map<std::string, Package*>& imports,
     246              :                 const Unordered_set(const Package*)& type_imports);
     247              : 
     248              :   // Write out the imported initialization functions and init graph.
     249              :   void
     250              :   write_imported_init_fns(const std::string& package_name,
     251              :                           const std::string&, const Import_init_set&);
     252              : 
     253              :   // Write out all types.
     254              :   void
     255              :   write_types(int unexported_type_index);
     256              : 
     257              :   // Write out one type definition.
     258              :   void
     259              :   write_type_definition(const Type* type, int index);
     260              : 
     261              :   // Register one builtin type.
     262              :   void
     263              :   register_builtin_type(Gogo*, const char* name, Builtin_code);
     264              : 
     265              :   // Return the index of a type in the export data.
     266              :   int
     267              :   type_index(const Type*);
     268              : 
     269              :   // Set the index of a type.
     270              :   void
     271              :   set_type_index(const Type*);
     272              : 
     273              :   // The stream to which we are writing data.
     274              :   Stream* stream_;
     275              :   // Index number of next type.
     276              :   int type_index_;
     277              :   // Packages we have written out.
     278              :   Unordered_map(const Package*, int) packages_;
     279              :   // Hidden implementation-specific state.
     280              :   Export_impl* impl_;
     281              : };
     282              : 
     283              : // An export streamer that puts the export stream in a named section.
     284              : 
     285         4252 : class Stream_to_section : public Export::Stream
     286              : {
     287              :  public:
     288              :   Stream_to_section(Backend*);
     289              : 
     290              :  protected:
     291              :   void
     292              :   do_write(const char*, size_t);
     293              : 
     294              :  private:
     295              :   Backend* backend_;
     296              : };
     297              : 
     298              : // An export streamer that puts the export stream in a string.
     299              : 
     300              : class Stream_to_string : public Export::Stream
     301              : {
     302              :  public:
     303         4252 :   Stream_to_string()
     304         4252 :     : string_()
     305              :   {}
     306              : 
     307              :   const std::string&
     308         4252 :   string() const
     309         4252 :   { return this->string_; }
     310              : 
     311              :  protected:
     312              :   void
     313      9084894 :   do_write(const char* s, size_t len)
     314      9084894 :   { this->string_.append(s, len); }
     315              : 
     316              :  private:
     317              :   std::string string_;
     318              : };
     319              : 
     320              : // Class to manage exporting a function body.  This is passed around
     321              : // to Statements and Expressions.  It builds up the export data for
     322              : // the function.
     323              : 
     324              : class Export_function_body : public String_dump
     325              : {
     326              :  public:
     327        60098 :   Export_function_body(Export* exp, int indent)
     328        60098 :     : exp_(exp), body_(), type_context_(NULL), next_temporary_index_(0),
     329        60098 :       temporary_indexes_(), next_label_index_(0), label_indexes_(),
     330        60098 :       indent_(indent)
     331        60098 :   { }
     332              : 
     333              :   // Write a character to the body.
     334              :   void
     335       322738 :   write_char(char c)
     336        93704 :   { this->body_.append(1, c); }
     337              : 
     338              :   // Write a NUL terminated string to the body.
     339              :   void
     340       616867 :   write_c_string(const char* str)
     341       616867 :   { this->body_.append(str); }
     342              : 
     343              :   // Write a string to the body.
     344              :   void
     345        92898 :   write_string(const std::string& str)
     346       109605 :   { this->body_.append(str); }
     347              : 
     348              :   // Write a type reference to the body.
     349              :   void
     350        31465 :   write_type(const Type* type)
     351        31465 :   { this->exp_->write_type_to(type, this); }
     352              : 
     353              :   // Return the current type context.
     354              :   Type*
     355        51980 :   type_context() const
     356        51980 :   { return this->type_context_; }
     357              : 
     358              :   // Set the current type context.
     359              :   void
     360        58888 :   set_type_context(Type* type)
     361        41729 :   { this->type_context_ = type; }
     362              : 
     363              :   // Append as many spaces as the current indentation level.
     364              :   void
     365       122751 :   indent()
     366              :   {
     367       412075 :     for (int i = this->indent_; i > 0; i--)
     368       289324 :       this->write_char(' ');
     369       122751 :   }
     370              : 
     371              :   // Increment the indentation level.
     372              :   void
     373       106044 :   increment_indent()
     374       106044 :   { ++this->indent_; }
     375              : 
     376              :   // Decrement the indentation level.
     377              :   void
     378       106044 :   decrement_indent()
     379       106044 :   { --this->indent_; }
     380              : 
     381              :   // Return the index of a package.
     382              :   int
     383         4700 :   package_index(const Package* p) const
     384         4700 :   { return this->exp_->package_index(p); }
     385              : 
     386              :   // Return the index of the "unsafe" package.
     387              :   int
     388            0 :   unsafe_package_index() const
     389            0 :   { return this->exp_->unsafe_package_index(); }
     390              : 
     391              :   // Record a temporary statement and return its index.
     392              :   unsigned int
     393              :   record_temporary(const Temporary_statement*);
     394              : 
     395              :   // Return the index of a temporary statement.
     396              :   unsigned int
     397              :   temporary_index(const Temporary_statement*);
     398              : 
     399              :   // Return the index of an unnamed label.  If it doesn't already have
     400              :   // an index, give it one.
     401              :   unsigned int
     402              :   unnamed_label_index(const Unnamed_label*);
     403              : 
     404              :   // Return a reference to the completed body.
     405              :   const std::string&
     406        60098 :   body() const
     407        60098 :   { return this->body_; }
     408              : 
     409              :  private:
     410              :   // The overall export data.
     411              :   Export* exp_;
     412              :   // The body we are building.
     413              :   std::string body_;
     414              :   // Current type context.  Used to avoid duplicate type conversions.
     415              :   Type* type_context_;
     416              :   // Index to give to next temporary statement.
     417              :   unsigned int next_temporary_index_;
     418              :   // Map temporary statements to indexes.
     419              :   Unordered_map(const Temporary_statement*, unsigned int) temporary_indexes_;
     420              :   // Index to give to the next unnamed label.
     421              :   unsigned int next_label_index_;
     422              :   // Map unnamed labels to indexes.
     423              :   Unordered_map(const Unnamed_label*, unsigned int) label_indexes_;
     424              :   // Current indentation level: the number of spaces before each statement.
     425              :   int indent_;
     426              : };
     427              : 
     428              : #endif // !defined(GO_EXPORT_H)
        

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.