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.
10 #ifndef ENABLE_BUILD_WITH_CXX
19 #ifndef ENABLE_BUILD_WITH_CXX
25 #include "statements.h"
28 // This file handles exporting global declarations.
32 // Version 1 magic number.
34 const int Export::v1_magic_len;
36 const char Export::v1_magic[Export::v1_magic_len] =
41 const int Export::v1_checksum_len;
45 Export::Export(Stream* stream)
46 : stream_(stream), type_refs_(), type_index_(1)
50 // A functor to sort Named_object pointers by name.
55 operator()(const Named_object* n1, const Named_object* n2) const
56 { return n1->name() < n2->name(); }
59 // Return true if we should export NO.
62 should_export(Named_object* no)
64 // We only export objects which are locally defined.
65 if (no->package() != NULL)
68 // We don't export packages.
72 // We don't export hidden names.
73 if (Gogo::is_hidden_name(no->name()))
76 // We don't export nested functions.
77 if (no->is_function() && no->func_value()->enclosing() != NULL)
80 // We don't export thunks.
81 if (no->is_function() && Gogo::is_thunk(no))
84 // Methods are exported with the type, not here.
86 && no->func_value()->type()->is_method())
88 if (no->is_function_declaration()
89 && no->func_declaration_value()->type()->is_method())
92 // Don't export dummy global variables created for initializers when
94 if (no->is_variable() && no->name()[0] == '_' && no->name()[1] == '.')
100 // Export those identifiers marked for exporting.
103 Export::export_globals(const std::string& package_name,
104 const std::string& unique_prefix,
105 int package_priority,
106 const std::string& import_init_fn,
107 const std::set<Import_init>& imported_init_fns,
108 const Bindings* bindings)
110 // If there have been any errors so far, don't try to export
111 // anything. That way the export code doesn't have to worry about
112 // mismatched types or other confusions.
116 // Export the symbols in sorted order. That will reduce cases where
117 // irrelevant changes to the source code affect the exported
119 std::vector<Named_object*> exports;
120 exports.reserve(bindings->size_definitions());
122 for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
123 p != bindings->end_definitions();
125 if (should_export(*p))
126 exports.push_back(*p);
128 for (Bindings::const_declarations_iterator p =
129 bindings->begin_declarations();
130 p != bindings->end_declarations();
133 // We export a function declaration as it may be implemented in
134 // supporting C code. We do not export type declarations.
135 if (p->second->is_function_declaration()
136 && should_export(p->second))
137 exports.push_back(p->second);
140 std::sort(exports.begin(), exports.end(), Sort_bindings());
142 // Although the export data is readable, at least this version is,
143 // it is conceptually a binary format. Start with a four byte
145 this->write_bytes(Export::v1_magic, Export::v1_magic_len);
148 this->write_c_string("package ");
149 this->write_string(package_name);
150 this->write_c_string(";\n");
152 // The unique prefix. This prefix is used for all global symbols.
153 this->write_c_string("prefix ");
154 this->write_string(unique_prefix);
155 this->write_c_string(";\n");
157 // The package priority.
159 snprintf(buf, sizeof buf, "priority %d;\n", package_priority);
160 this->write_c_string(buf);
162 this->write_imported_init_fns(package_name, package_priority, import_init_fn,
165 // FIXME: It might be clever to add something about the processor
166 // and ABI being used, although ideally any problems in that area
167 // would be caught by the linker.
169 for (std::vector<Named_object*>::const_iterator p = exports.begin();
172 (*p)->export_named_object(this);
174 std::string checksum = this->stream_->checksum();
175 std::string s = "checksum ";
176 for (std::string::const_iterator p = checksum.begin();
180 unsigned char c = *p;
181 unsigned int dig = c >> 4;
182 s += dig < 10 ? '0' + dig : 'A' + dig - 10;
184 s += dig < 10 ? '0' + dig : 'A' + dig - 10;
187 this->stream_->write_checksum(s);
190 // Write out the import control variables for this package.
193 Export::write_imported_init_fns(
194 const std::string& package_name,
196 const std::string& import_init_fn,
197 const std::set<Import_init>& imported_init_fns)
199 if (import_init_fn.empty() && imported_init_fns.empty())
202 this->write_c_string("import");
204 if (!import_init_fn.empty())
206 this->write_c_string(" ");
207 this->write_string(package_name);
208 this->write_c_string(" ");
209 this->write_string(import_init_fn);
211 snprintf(buf, sizeof buf, " %d", priority);
212 this->write_c_string(buf);
215 if (!imported_init_fns.empty())
217 // Sort the list of functions for more consistent output.
218 std::vector<Import_init> v;
219 for (std::set<Import_init>::const_iterator p = imported_init_fns.begin();
220 p != imported_init_fns.end();
223 std::sort(v.begin(), v.end());
225 for (std::vector<Import_init>::const_iterator p = v.begin();
229 this->write_c_string(" ");
230 this->write_string(p->package_name());
231 this->write_c_string(" ");
232 this->write_string(p->init_name());
234 snprintf(buf, sizeof buf, " %d", p->priority());
235 this->write_c_string(buf);
239 this->write_c_string(";\n");
242 // Export a type. We have to ensure that on import we create a single
243 // Named_type node for each named type. We do this by keeping a hash
244 // table mapping named types to reference numbers. The first time we
245 // see a named type we assign it a reference number by making an entry
246 // in the hash table. If we see it again, we just refer to the
249 // Named types are, of course, associated with packages. Note that we
250 // may see a named type when importing one package, and then later see
251 // the same named type when importing a different package. The home
252 // package may or may not be imported during this compilation. The
253 // reference number scheme has to get this all right. Basic approach
254 // taken from "On the Linearization of Graphs and Writing Symbol
255 // Files" by Robert Griesemer.
258 Export::write_type(const Type* type)
260 // We don't want to assign a reference number to a forward
261 // declaration to a type which was defined later.
262 type = type->forwarded();
264 Type_refs::const_iterator p = this->type_refs_.find(type);
265 if (p != this->type_refs_.end())
267 // This type was already in the table.
268 int index = p->second;
269 gcc_assert(index != 0);
271 snprintf(buf, sizeof buf, "<type %d>", index);
272 this->write_c_string(buf);
276 const Named_type* named_type = type->named_type();
277 const Forward_declaration_type* forward = type->forward_declaration_type();
279 int index = this->type_index_;
283 snprintf(buf, sizeof buf, "<type %d ", index);
284 this->write_c_string(buf);
286 if (named_type != NULL || forward != NULL)
288 const Named_object* named_object;
289 if (named_type != NULL)
291 // The builtin types should have been predefined.
292 gcc_assert(named_type->location() != BUILTINS_LOCATION
293 || (named_type->named_object()->package()->name()
295 named_object = named_type->named_object();
298 named_object = forward->named_object();
300 const Package* package = named_object->package();
302 std::string s = "\"";
303 if (package != NULL && !Gogo::is_hidden_name(named_object->name()))
305 s += package->unique_prefix();
307 s += package->name();
310 s += named_object->name();
312 this->write_string(s);
314 // We must add a named type to the table now, since the
315 // definition of the type may refer to the named type via a
317 this->type_refs_[type] = index;
320 type->export_type(this);
322 this->write_c_string(">");
324 if (named_type == NULL)
325 this->type_refs_[type] = index;
328 // Add the builtin types to the export table.
331 Export::register_builtin_types(Gogo* gogo)
333 this->register_builtin_type(gogo, "int8", BUILTIN_INT8);
334 this->register_builtin_type(gogo, "int16", BUILTIN_INT16);
335 this->register_builtin_type(gogo, "int32", BUILTIN_INT32);
336 this->register_builtin_type(gogo, "int64", BUILTIN_INT64);
337 this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8);
338 this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16);
339 this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32);
340 this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64);
341 this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32);
342 this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64);
343 this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64);
344 this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128);
345 this->register_builtin_type(gogo, "int", BUILTIN_INT);
346 this->register_builtin_type(gogo, "uint", BUILTIN_UINT);
347 this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR);
348 this->register_builtin_type(gogo, "float", BUILTIN_FLOAT);
349 this->register_builtin_type(gogo, "complex", BUILTIN_COMPLEX);
350 this->register_builtin_type(gogo, "bool", BUILTIN_BOOL);
351 this->register_builtin_type(gogo, "string", BUILTIN_STRING);
354 // Register one builtin type in the export table.
357 Export::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
359 Named_object* named_object = gogo->lookup_global(name);
360 gcc_assert(named_object != NULL && named_object->is_type());
361 std::pair<Type_refs::iterator, bool> ins =
362 this->type_refs_.insert(std::make_pair(named_object->type_value(), code));
363 gcc_assert(ins.second);
365 // We also insert the underlying type. We can see the underlying
366 // type at least for string and bool.
367 Type* real_type = named_object->type_value()->real_type();
368 ins = this->type_refs_.insert(std::make_pair(real_type, code));
369 gcc_assert(ins.second);
372 // Class Export::Stream.
374 Export::Stream::Stream()
376 this->checksum_ = new sha1_ctx;
377 memset(this->checksum_, 0, sizeof(sha1_ctx));
378 sha1_init_ctx(this->checksum_);
381 Export::Stream::~Stream()
385 // Write bytes to the stream. This keeps a checksum of bytes as they
389 Export::Stream::write_and_sum_bytes(const char* bytes, size_t length)
391 sha1_process_bytes(bytes, length, this->checksum_);
392 this->do_write(bytes, length);
398 Export::Stream::checksum()
400 // Use a union to provide the required alignment.
403 char checksum[Export::v1_checksum_len];
406 sha1_finish_ctx(this->checksum_, u.checksum);
407 return std::string(u.checksum, Export::v1_checksum_len);
410 // Write the checksum string to the export data.
413 Export::Stream::write_checksum(const std::string& s)
415 this->do_write(s.data(), s.length());
418 // Class Stream_to_section.
420 Stream_to_section::Stream_to_section()
425 // Write data to a section.
428 Stream_to_section::do_write(const char* bytes, size_t length)
430 section* sec = (section*) this->section_;
433 gcc_assert(targetm.have_named_sections);
435 sec = get_section(".go_export", SECTION_DEBUG, NULL);
436 this->section_ = (void*) sec;
439 switch_to_section(sec);
440 assemble_string(bytes, length);