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