111
|
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;
|
131
|
14 class Named_object;
|
145
|
15 class Export_function_body;
|
111
|
16 class Import_init;
|
131
|
17 class Named_object;
|
111
|
18 class Bindings;
|
|
19 class Type;
|
|
20 class Package;
|
|
21 class Import_init_set;
|
|
22 class Backend;
|
145
|
23 class Temporary_statement;
|
|
24 class Unnamed_label;
|
|
25 struct Export_impl;
|
111
|
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,
|
131
|
66 EXPORT_FORMAT_V3 = 3,
|
|
67 EXPORT_FORMAT_CURRENT = EXPORT_FORMAT_V3
|
111
|
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*);
|
145
|
125 ~Export();
|
111
|
126
|
|
127 // Size of export data magic string (which includes version number).
|
|
128 static const int magic_len = 4;
|
|
129
|
131
|
130 // Magic strings (current version and older versions).
|
111
|
131 static const char cur_magic[magic_len];
|
|
132 static const char v1_magic[magic_len];
|
131
|
133 static const char v2_magic[magic_len];
|
111
|
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,
|
145
|
161 const Bindings* bindings,
|
|
162 Unordered_set(Named_object*)* marked_inline_functions);
|
111
|
163
|
145
|
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.
|
131
|
167 bool
|
145
|
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);
|
131
|
173
|
111
|
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
|
145
|
198 // Write a type to an exported function body.
|
|
199 void
|
|
200 write_type_to(const Type*, Export_function_body*);
|
|
201
|
111
|
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
|
145
|
215 // Return the index of a package.
|
|
216 int
|
|
217 package_index(const Package* p) const;
|
|
218
|
111
|
219 private:
|
|
220 Export(const Export&);
|
|
221 Export& operator=(const Export&);
|
|
222
|
|
223 // Write out all known packages.
|
|
224 void
|
|
225 write_packages(const std::map<std::string, Package*>& packages);
|
|
226
|
|
227 typedef std::map<unsigned, std::set<unsigned> > Init_graph;
|
|
228
|
|
229 static void
|
|
230 add_init_graph_edge(Init_graph* init_graph, unsigned src, unsigned sink);
|
|
231
|
|
232 static void
|
|
233 populate_init_graph(Init_graph* init_graph,
|
|
234 const Import_init_set& imported_init_fns,
|
|
235 const std::map<std::string, unsigned>& init_idx);
|
|
236
|
|
237 // Write out the imported packages.
|
|
238 void
|
131
|
239 write_imports(const std::map<std::string, Package*>& imports,
|
|
240 const Unordered_set(const Package*)& type_imports);
|
111
|
241
|
|
242 // Write out the imported initialization functions and init graph.
|
|
243 void
|
|
244 write_imported_init_fns(const std::string& package_name,
|
|
245 const std::string&, const Import_init_set&);
|
|
246
|
131
|
247 // Write out all types.
|
|
248 void
|
|
249 write_types(int unexported_type_index);
|
|
250
|
|
251 // Write out one type definition.
|
|
252 void
|
|
253 write_type_definition(const Type* type, int index);
|
|
254
|
111
|
255 // Register one builtin type.
|
|
256 void
|
|
257 register_builtin_type(Gogo*, const char* name, Builtin_code);
|
|
258
|
145
|
259 // Return the index of a type in the export data.
|
|
260 int
|
|
261 type_index(const Type*);
|
|
262
|
|
263 // Set the index of a type.
|
|
264 void
|
|
265 set_type_index(const Type*);
|
|
266
|
111
|
267 // The stream to which we are writing data.
|
|
268 Stream* stream_;
|
|
269 // Index number of next type.
|
|
270 int type_index_;
|
|
271 // Packages we have written out.
|
145
|
272 Unordered_map(const Package*, int) packages_;
|
|
273 // Hidden implementation-specific state.
|
|
274 Export_impl* impl_;
|
111
|
275 };
|
|
276
|
131
|
277 // An export streamer that puts the export stream in a named section.
|
111
|
278
|
|
279 class Stream_to_section : public Export::Stream
|
|
280 {
|
|
281 public:
|
|
282 Stream_to_section(Backend*);
|
|
283
|
|
284 protected:
|
|
285 void
|
|
286 do_write(const char*, size_t);
|
|
287
|
|
288 private:
|
|
289 Backend* backend_;
|
|
290 };
|
|
291
|
131
|
292 // An export streamer that puts the export stream in a string.
|
|
293
|
|
294 class Stream_to_string : public Export::Stream
|
|
295 {
|
|
296 public:
|
|
297 Stream_to_string()
|
|
298 : string_()
|
|
299 {}
|
|
300
|
|
301 const std::string&
|
|
302 string() const
|
|
303 { return this->string_; }
|
|
304
|
|
305 protected:
|
|
306 void
|
|
307 do_write(const char* s, size_t len)
|
|
308 { this->string_.append(s, len); }
|
|
309
|
|
310 private:
|
|
311 std::string string_;
|
|
312 };
|
|
313
|
145
|
314 // Class to manage exporting a function body. This is passed around
|
|
315 // to Statements and Expressions. It builds up the export data for
|
|
316 // the function.
|
|
317
|
|
318 class Export_function_body : public String_dump
|
|
319 {
|
|
320 public:
|
|
321 Export_function_body(Export* exp, int indent)
|
|
322 : exp_(exp), body_(), type_context_(NULL), next_temporary_index_(0),
|
|
323 temporary_indexes_(), next_label_index_(0), label_indexes_(),
|
|
324 indent_(indent)
|
|
325 { }
|
|
326
|
|
327 // Write a character to the body.
|
|
328 void
|
|
329 write_char(char c)
|
|
330 { this->body_.append(1, c); }
|
|
331
|
|
332 // Write a NUL terminated string to the body.
|
|
333 void
|
|
334 write_c_string(const char* str)
|
|
335 { this->body_.append(str); }
|
|
336
|
|
337 // Write a string to the body.
|
|
338 void
|
|
339 write_string(const std::string& str)
|
|
340 { this->body_.append(str); }
|
|
341
|
|
342 // Write a type reference to the body.
|
|
343 void
|
|
344 write_type(const Type* type)
|
|
345 { this->exp_->write_type_to(type, this); }
|
|
346
|
|
347 // Return the current type context.
|
|
348 Type*
|
|
349 type_context() const
|
|
350 { return this->type_context_; }
|
|
351
|
|
352 // Set the current type context.
|
|
353 void
|
|
354 set_type_context(Type* type)
|
|
355 { this->type_context_ = type; }
|
|
356
|
|
357 // Append as many spaces as the current indentation level.
|
|
358 void
|
|
359 indent()
|
|
360 {
|
|
361 for (int i = this->indent_; i > 0; i--)
|
|
362 this->write_char(' ');
|
|
363 }
|
|
364
|
|
365 // Increment the indentation level.
|
|
366 void
|
|
367 increment_indent()
|
|
368 { ++this->indent_; }
|
|
369
|
|
370 // Decrement the indentation level.
|
|
371 void
|
|
372 decrement_indent()
|
|
373 { --this->indent_; }
|
|
374
|
|
375 // Return the index of a package.
|
|
376 int
|
|
377 package_index(const Package* p) const
|
|
378 { return this->exp_->package_index(p); }
|
|
379
|
|
380 // Record a temporary statement and return its index.
|
|
381 unsigned int
|
|
382 record_temporary(const Temporary_statement*);
|
|
383
|
|
384 // Return the index of a temporary statement.
|
|
385 unsigned int
|
|
386 temporary_index(const Temporary_statement*);
|
|
387
|
|
388 // Return the index of an unnamed label. If it doesn't already have
|
|
389 // an index, give it one.
|
|
390 unsigned int
|
|
391 unnamed_label_index(const Unnamed_label*);
|
|
392
|
|
393 // Return a reference to the completed body.
|
|
394 const std::string&
|
|
395 body() const
|
|
396 { return this->body_; }
|
|
397
|
|
398 private:
|
|
399 // The overall export data.
|
|
400 Export* exp_;
|
|
401 // The body we are building.
|
|
402 std::string body_;
|
|
403 // Current type context. Used to avoid duplicate type conversions.
|
|
404 Type* type_context_;
|
|
405 // Index to give to next temporary statement.
|
|
406 unsigned int next_temporary_index_;
|
|
407 // Map temporary statements to indexes.
|
|
408 Unordered_map(const Temporary_statement*, unsigned int) temporary_indexes_;
|
|
409 // Index to give to the next unnamed label.
|
|
410 unsigned int next_label_index_;
|
|
411 // Map unnamed labels to indexes.
|
|
412 Unordered_map(const Unnamed_label*, unsigned int) label_indexes_;
|
|
413 // Current indentation level: the number of spaces before each statement.
|
|
414 int indent_;
|
|
415 };
|
|
416
|
111
|
417 #endif // !defined(GO_EXPORT_H)
|