Branch data 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 : 2065946 : write_string(const std::string& s)
90 : 2065946 : { this->write_and_sum_bytes(s.data(), s.length()); }
91 : :
92 : : // Write a nul terminated string. Implements the String_dump interface.
93 : : void
94 : 14167097 : write_c_string(const char* s)
95 : 14167097 : { this->write_and_sum_bytes(s, strlen(s)); }
96 : :
97 : : // Write some bytes.
98 : : void
99 : 4251 : write_bytes(const char* bytes, size_t length)
100 : 4251 : { 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 : 2065946 : write_string(const std::string& s)
178 : 2065946 : { this->stream_->write_string(s); }
179 : :
180 : : // Write a nul terminated string to the export stream.
181 : : void
182 : 14167097 : write_c_string(const char* s)
183 : 14167097 : { this->stream_->write_c_string(s); }
184 : :
185 : : // Write some bytes to the export stream.
186 : : void
187 : 4251 : write_bytes(const char* bytes, size_t length)
188 : 4251 : { 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 : 4251 : 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 : 4251 : Stream_to_string()
304 : 4251 : : string_()
305 : : {}
306 : :
307 : : const std::string&
308 : 4251 : string() const
309 : 4251 : { return this->string_; }
310 : :
311 : : protected:
312 : : void
313 : 9084822 : do_write(const char* s, size_t len)
314 : 9084822 : { 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 : 59639 : Export_function_body(Export* exp, int indent)
328 : 59639 : : exp_(exp), body_(), type_context_(NULL), next_temporary_index_(0),
329 : 59639 : temporary_indexes_(), next_label_index_(0), label_indexes_(),
330 : 59639 : indent_(indent)
331 : 59639 : { }
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 : 615949 : write_c_string(const char* str)
341 : 615949 : { this->body_.append(str); }
342 : :
343 : : // Write a string to the body.
344 : : void
345 : 92898 : write_string(const std::string& str)
346 : 92898 : { 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 : 59639 : body() const
407 : 59639 : { 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)
|