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)
|