1 // export.cc -- Export declarations in Go frontend.
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.
15 #include "statements.h"
18 // This file handles exporting global declarations.
22 // Version 1 magic number.
24 const int Export::v1_magic_len;
26 const char Export::v1_magic[Export::v1_magic_len] =
31 const int Export::v1_checksum_len;
35 Export::Export(Stream* stream)
36 : stream_(stream), type_refs_(), type_index_(1)
40 // A functor to sort Named_object pointers by name.
45 operator()(const Named_object* n1, const Named_object* n2) const
46 { return n1->name() < n2->name(); }
49 // Return true if we should export NO.
52 should_export(Named_object* no)
54 // We only export objects which are locally defined.
55 if (no->package() != NULL)
58 // We don't export packages.
62 // We don't export hidden names.
63 if (Gogo::is_hidden_name(no->name()))
66 // We don't export nested functions.
67 if (no->is_function() && no->func_value()->enclosing() != NULL)
70 // We don't export thunks.
71 if (no->is_function() && Gogo::is_thunk(no))
74 // Methods are exported with the type, not here.
76 && no->func_value()->type()->is_method())
78 if (no->is_function_declaration()
79 && no->func_declaration_value()->type()->is_method())
82 // Don't export dummy global variables created for initializers when
84 if (no->is_variable() && no->name()[0] == '_' && no->name()[1] == '.')
90 // Export those identifiers marked for exporting.
93 Export::export_globals(const std::string& package_name,
94 const std::string& unique_prefix,
96 const std::map<std::string, Package*>& imports,
97 const std::string& import_init_fn,
98 const std::set<Import_init>& imported_init_fns,
99 const Bindings* bindings)
101 // If there have been any errors so far, don't try to export
102 // anything. That way the export code doesn't have to worry about
103 // mismatched types or other confusions.
107 // Export the symbols in sorted order. That will reduce cases where
108 // irrelevant changes to the source code affect the exported
110 std::vector<Named_object*> exports;
111 exports.reserve(bindings->size_definitions());
113 for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
114 p != bindings->end_definitions();
116 if (should_export(*p))
117 exports.push_back(*p);
119 for (Bindings::const_declarations_iterator p =
120 bindings->begin_declarations();
121 p != bindings->end_declarations();
124 // We export a function declaration as it may be implemented in
125 // supporting C code. We do not export type declarations.
126 if (p->second->is_function_declaration()
127 && should_export(p->second))
128 exports.push_back(p->second);
131 std::sort(exports.begin(), exports.end(), Sort_bindings());
133 // Although the export data is readable, at least this version is,
134 // it is conceptually a binary format. Start with a four byte
136 this->write_bytes(Export::v1_magic, Export::v1_magic_len);
139 this->write_c_string("package ");
140 this->write_string(package_name);
141 this->write_c_string(";\n");
143 // The unique prefix. This prefix is used for all global symbols.
144 this->write_c_string("prefix ");
145 this->write_string(unique_prefix);
146 this->write_c_string(";\n");
148 // The package priority.
150 snprintf(buf, sizeof buf, "priority %d;\n", package_priority);
151 this->write_c_string(buf);
153 this->write_imports(imports);
155 this->write_imported_init_fns(package_name, package_priority, import_init_fn,
158 // FIXME: It might be clever to add something about the processor
159 // and ABI being used, although ideally any problems in that area
160 // would be caught by the linker.
162 for (std::vector<Named_object*>::const_iterator p = exports.begin();
165 (*p)->export_named_object(this);
167 std::string checksum = this->stream_->checksum();
168 std::string s = "checksum ";
169 for (std::string::const_iterator p = checksum.begin();
173 unsigned char c = *p;
174 unsigned int dig = c >> 4;
175 s += dig < 10 ? '0' + dig : 'A' + dig - 10;
177 s += dig < 10 ? '0' + dig : 'A' + dig - 10;
180 this->stream_->write_checksum(s);
183 // Sort imported packages.
186 import_compare(const std::pair<std::string, Package*>& a,
187 const std::pair<std::string, Package*>& b)
189 return a.first < b.first;
192 // Write out the imported packages.
195 Export::write_imports(const std::map<std::string, Package*>& imports)
197 // Sort the imports for more consistent output.
198 std::vector<std::pair<std::string, Package*> > imp;
199 for (std::map<std::string, Package*>::const_iterator p = imports.begin();
202 imp.push_back(std::make_pair(p->first, p->second));
204 std::sort(imp.begin(), imp.end(), import_compare);
206 for (std::vector<std::pair<std::string, Package*> >::const_iterator p =
211 this->write_c_string("import ");
212 this->write_string(p->second->name());
213 this->write_c_string(" ");
214 this->write_string(p->second->unique_prefix());
215 this->write_c_string(" \"");
216 this->write_string(p->first);
217 this->write_c_string("\";\n");
221 // Write out the initialization functions which need to run for this
225 Export::write_imported_init_fns(
226 const std::string& package_name,
228 const std::string& import_init_fn,
229 const std::set<Import_init>& imported_init_fns)
231 if (import_init_fn.empty() && imported_init_fns.empty())
234 this->write_c_string("init");
236 if (!import_init_fn.empty())
238 this->write_c_string(" ");
239 this->write_string(package_name);
240 this->write_c_string(" ");
241 this->write_string(import_init_fn);
243 snprintf(buf, sizeof buf, " %d", priority);
244 this->write_c_string(buf);
247 if (!imported_init_fns.empty())
249 // Sort the list of functions for more consistent output.
250 std::vector<Import_init> v;
251 for (std::set<Import_init>::const_iterator p = imported_init_fns.begin();
252 p != imported_init_fns.end();
255 std::sort(v.begin(), v.end());
257 for (std::vector<Import_init>::const_iterator p = v.begin();
261 this->write_c_string(" ");
262 this->write_string(p->package_name());
263 this->write_c_string(" ");
264 this->write_string(p->init_name());
266 snprintf(buf, sizeof buf, " %d", p->priority());
267 this->write_c_string(buf);
271 this->write_c_string(";\n");
274 // Write a name to the export stream.
277 Export::write_name(const std::string& name)
280 this->write_c_string("?");
282 this->write_string(Gogo::message_name(name));
285 // Export a type. We have to ensure that on import we create a single
286 // Named_type node for each named type. We do this by keeping a hash
287 // table mapping named types to reference numbers. The first time we
288 // see a named type we assign it a reference number by making an entry
289 // in the hash table. If we see it again, we just refer to the
292 // Named types are, of course, associated with packages. Note that we
293 // may see a named type when importing one package, and then later see
294 // the same named type when importing a different package. The home
295 // package may or may not be imported during this compilation. The
296 // reference number scheme has to get this all right. Basic approach
297 // taken from "On the Linearization of Graphs and Writing Symbol
298 // Files" by Robert Griesemer.
301 Export::write_type(const Type* type)
303 // We don't want to assign a reference number to a forward
304 // declaration to a type which was defined later.
305 type = type->forwarded();
307 Type_refs::const_iterator p = this->type_refs_.find(type);
308 if (p != this->type_refs_.end())
310 // This type was already in the table.
311 int index = p->second;
312 go_assert(index != 0);
314 snprintf(buf, sizeof buf, "<type %d>", index);
315 this->write_c_string(buf);
319 const Named_type* named_type = type->named_type();
320 const Forward_declaration_type* forward = type->forward_declaration_type();
322 int index = this->type_index_;
326 snprintf(buf, sizeof buf, "<type %d ", index);
327 this->write_c_string(buf);
329 if (named_type != NULL || forward != NULL)
331 const Named_object* named_object;
332 if (named_type != NULL)
334 // The builtin types should have been predefined.
335 go_assert(!Linemap::is_predeclared_location(named_type->location())
336 || (named_type->named_object()->package()->name()
338 named_object = named_type->named_object();
341 named_object = forward->named_object();
343 const Package* package = named_object->package();
345 std::string s = "\"";
346 if (package != NULL && !Gogo::is_hidden_name(named_object->name()))
348 s += package->unique_prefix();
350 s += package->name();
353 s += named_object->name();
355 this->write_string(s);
357 // We must add a named type to the table now, since the
358 // definition of the type may refer to the named type via a
360 this->type_refs_[type] = index;
363 type->export_type(this);
365 this->write_c_string(">");
367 if (named_type == NULL)
368 this->type_refs_[type] = index;
371 // Add the builtin types to the export table.
374 Export::register_builtin_types(Gogo* gogo)
376 this->register_builtin_type(gogo, "int8", BUILTIN_INT8);
377 this->register_builtin_type(gogo, "int16", BUILTIN_INT16);
378 this->register_builtin_type(gogo, "int32", BUILTIN_INT32);
379 this->register_builtin_type(gogo, "int64", BUILTIN_INT64);
380 this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8);
381 this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16);
382 this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32);
383 this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64);
384 this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32);
385 this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64);
386 this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64);
387 this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128);
388 this->register_builtin_type(gogo, "int", BUILTIN_INT);
389 this->register_builtin_type(gogo, "uint", BUILTIN_UINT);
390 this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR);
391 this->register_builtin_type(gogo, "bool", BUILTIN_BOOL);
392 this->register_builtin_type(gogo, "string", BUILTIN_STRING);
393 this->register_builtin_type(gogo, "error", BUILTIN_ERROR);
394 this->register_builtin_type(gogo, "byte", BUILTIN_BYTE);
395 this->register_builtin_type(gogo, "rune", BUILTIN_RUNE);
398 // Register one builtin type in the export table.
401 Export::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
403 Named_object* named_object = gogo->lookup_global(name);
404 go_assert(named_object != NULL && named_object->is_type());
405 std::pair<Type_refs::iterator, bool> ins =
406 this->type_refs_.insert(std::make_pair(named_object->type_value(), code));
407 go_assert(ins.second);
409 // We also insert the underlying type. We can see the underlying
410 // type at least for string and bool. We skip the type aliases byte
412 if (code != BUILTIN_BYTE && code != BUILTIN_RUNE)
414 Type* real_type = named_object->type_value()->real_type();
415 ins = this->type_refs_.insert(std::make_pair(real_type, code));
416 go_assert(ins.second);
420 // Class Export::Stream.
422 Export::Stream::Stream()
424 this->checksum_ = new sha1_ctx;
425 memset(this->checksum_, 0, sizeof(sha1_ctx));
426 sha1_init_ctx(this->checksum_);
429 Export::Stream::~Stream()
433 // Write bytes to the stream. This keeps a checksum of bytes as they
437 Export::Stream::write_and_sum_bytes(const char* bytes, size_t length)
439 sha1_process_bytes(bytes, length, this->checksum_);
440 this->do_write(bytes, length);
446 Export::Stream::checksum()
448 // Use a union to provide the required alignment.
451 char checksum[Export::v1_checksum_len];
454 sha1_finish_ctx(this->checksum_, u.checksum);
455 return std::string(u.checksum, Export::v1_checksum_len);
458 // Write the checksum string to the export data.
461 Export::Stream::write_checksum(const std::string& s)
463 this->do_write(s.data(), s.length());
466 // Class Stream_to_section.
468 Stream_to_section::Stream_to_section()
472 // Write data to a section.
475 Stream_to_section::do_write(const char* bytes, size_t length)
477 go_write_export_data (bytes, length);