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 Import_init;
15 class Bindings;
16 class Type;
17 class Package;
18 class Import_init_set;
19 class Backend;
20 
21 // Codes used for the builtin types.  These are all negative to make
22 // them easily distinct from the codes assigned by Export::write_type.
23 // Note that these codes may not be changed!  Changing them would
24 // break existing export data.
25 
26 enum Builtin_code
27 {
28   BUILTIN_INT8 = -1,
29   BUILTIN_INT16 = -2,
30   BUILTIN_INT32 = -3,
31   BUILTIN_INT64 = -4,
32   BUILTIN_UINT8 = -5,
33   BUILTIN_UINT16 = -6,
34   BUILTIN_UINT32 = -7,
35   BUILTIN_UINT64 = -8,
36   BUILTIN_FLOAT32 = -9,
37   BUILTIN_FLOAT64 = -10,
38   BUILTIN_INT = -11,
39   BUILTIN_UINT = -12,
40   BUILTIN_UINTPTR = -13,
41   BUILTIN_BOOL = -15,
42   BUILTIN_STRING = -16,
43   BUILTIN_COMPLEX64 = -17,
44   BUILTIN_COMPLEX128 = -18,
45   BUILTIN_ERROR = -19,
46   BUILTIN_BYTE = -20,
47   BUILTIN_RUNE = -21,
48 
49   SMALLEST_BUILTIN_CODE = -21
50 };
51 
52 // Export data version number. New export data is written with the
53 // "current" version, but there is support for reading files with
54 // older version export data (at least for now).
55 
56 enum Export_data_version {
57   EXPORT_FORMAT_UNKNOWN = 0,
58   EXPORT_FORMAT_V1 = 1,
59   EXPORT_FORMAT_V2 = 2,
60   EXPORT_FORMAT_CURRENT = EXPORT_FORMAT_V2
61 };
62 
63 // This class manages exporting Go declarations.  It handles the main
64 // loop of exporting.  A pointer to this class is also passed to the
65 // various specific export implementations.
66 
67 class Export : public String_dump
68 {
69  public:
70   // The Stream class is an interface used to output the exported
71   // information.  The caller should instantiate a child of this
72   // class.
73   class Stream
74   {
75    public:
76     Stream();
77     virtual ~Stream();
78 
79     // Write a string. Implements the String_dump interface.
80     void
write_string(const std::string & s)81     write_string(const std::string& s)
82     { this->write_and_sum_bytes(s.data(), s.length()); }
83 
84     // Write a nul terminated string. Implements the String_dump interface.
85     void
write_c_string(const char * s)86     write_c_string(const char* s)
87     { this->write_and_sum_bytes(s, strlen(s)); }
88 
89     // Write some bytes.
90     void
write_bytes(const char * bytes,size_t length)91     write_bytes(const char* bytes, size_t length)
92     { this->write_and_sum_bytes(bytes, length); }
93 
94     // Return the raw bytes of the checksum data.
95     std::string
96     checksum();
97 
98     // Write a checksum string to the stream.  This will be called at
99     // the end of the other output.
100     void
101     write_checksum(const std::string&);
102 
103    protected:
104     // This function is called with data to export.  This data must be
105     // made available as a contiguous stream for the importer.
106     virtual void
107     do_write(const char* bytes, size_t length) = 0;
108 
109   private:
110     void
111     write_and_sum_bytes(const char*, size_t);
112 
113     // The checksum helper.
114     Go_sha1_helper* sha1_helper_;
115   };
116 
117   Export(Stream*);
118 
119   // Size of export data magic string (which includes version number).
120   static const int magic_len = 4;
121 
122   // Magic strings (current version and older v1 version).
123   static const char cur_magic[magic_len];
124   static const char v1_magic[magic_len];
125 
126   // The length of the checksum string.
127   static const int checksum_len = 20;
128 
129   // Register the builtin types.
130   void
131   register_builtin_types(Gogo*);
132 
133   // Export the identifiers in BINDINGS which are marked for export.
134   // The exporting is done via a series of calls to THIS->STREAM_.  If
135   // is nothing to export, this->stream_->write will not be called.
136   // PREFIX is the package prefix.  PKGPATH is the package path.
137   // Only one of PREFIX and PKGPATH will be non-empty.
138   // PACKAGES is all the packages we have seen.
139   // IMPORTS is the explicitly imported packages.
140   // IMPORT_INIT_FN is the name of the import initialization function
141   // for this package; it will be empty if none is needed.
142   // IMPORTED_INIT_FNS is the list of initialization functions for
143   // imported packages.
144   void
145   export_globals(const std::string& package_name,
146 		 const std::string& prefix,
147 		 const std::string& pkgpath,
148 		 const std::map<std::string, Package*>& packages,
149 		 const std::map<std::string, Package*>& imports,
150 		 const std::string& import_init_fn,
151 		 const Import_init_set& imported_init_fns,
152 		 const Bindings* bindings);
153 
154   // Write a string to the export stream.
155   void
write_string(const std::string & s)156   write_string(const std::string& s)
157   { this->stream_->write_string(s); }
158 
159   // Write a nul terminated string to the export stream.
160   void
write_c_string(const char * s)161   write_c_string(const char* s)
162   { this->stream_->write_c_string(s); }
163 
164   // Write some bytes to the export stream.
165   void
write_bytes(const char * bytes,size_t length)166   write_bytes(const char* bytes, size_t length)
167   { this->stream_->write_bytes(bytes, length); }
168 
169   // Write a name to the export stream.  If NAME is empty, write "?".
170   void
171   write_name(const std::string& name);
172 
173   // Write out a type.  This handles references back to previous
174   // definitions.
175   void
176   write_type(const Type*);
177 
178   // Write the escape note to the export stream.  If NOTE is NULL, write
179   // nothing.
180   void
181   write_escape(std::string* note);
182 
183   // Write an integer value.
184   void
185   write_int(int);
186 
187   // Write an unsigned value.
188   void
189   write_unsigned(unsigned);
190 
191  private:
192   Export(const Export&);
193   Export& operator=(const Export&);
194 
195   // Write out all known packages.
196   void
197   write_packages(const std::map<std::string, Package*>& packages);
198 
199   typedef std::map<unsigned, std::set<unsigned> > Init_graph;
200 
201   static void
202   add_init_graph_edge(Init_graph* init_graph, unsigned src, unsigned sink);
203 
204   static void
205   populate_init_graph(Init_graph* init_graph,
206                       const Import_init_set& imported_init_fns,
207                       const std::map<std::string, unsigned>& init_idx);
208 
209   // Write out the imported packages.
210   void
211   write_imports(const std::map<std::string, Package*>& imports);
212 
213   // Write out the imported initialization functions and init graph.
214   void
215   write_imported_init_fns(const std::string& package_name,
216 			  const std::string&, const Import_init_set&);
217 
218   // Register one builtin type.
219   void
220   register_builtin_type(Gogo*, const char* name, Builtin_code);
221 
222   // Mapping from Type objects to a constant index.
223   typedef Unordered_map(const Type*, int) Type_refs;
224 
225   // The stream to which we are writing data.
226   Stream* stream_;
227   // Type mappings.
228   Type_refs type_refs_;
229   // Index number of next type.
230   int type_index_;
231   // Packages we have written out.
232   Unordered_set(const Package*) packages_;
233 };
234 
235 // An export streamer which puts the export stream in a named section.
236 
237 class Stream_to_section : public Export::Stream
238 {
239  public:
240   Stream_to_section(Backend*);
241 
242  protected:
243   void
244   do_write(const char*, size_t);
245 
246  private:
247   Backend* backend_;
248 };
249 
250 #endif // !defined(GO_EXPORT_H)
251