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), packages_()
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
& prefix
,
95 const std::string
& pkgpath
,
97 const std::map
<std::string
, Package
*>& packages
,
98 const std::map
<std::string
, Package
*>& imports
,
99 const std::string
& import_init_fn
,
100 const std::set
<Import_init
>& imported_init_fns
,
101 const Bindings
* bindings
)
103 // If there have been any errors so far, don't try to export
104 // anything. That way the export code doesn't have to worry about
105 // mismatched types or other confusions.
109 // Export the symbols in sorted order. That will reduce cases where
110 // irrelevant changes to the source code affect the exported
112 std::vector
<Named_object
*> exports
;
113 exports
.reserve(bindings
->size_definitions());
115 for (Bindings::const_definitions_iterator p
= bindings
->begin_definitions();
116 p
!= bindings
->end_definitions();
118 if (should_export(*p
))
119 exports
.push_back(*p
);
121 for (Bindings::const_declarations_iterator p
=
122 bindings
->begin_declarations();
123 p
!= bindings
->end_declarations();
126 // We export a function declaration as it may be implemented in
127 // supporting C code. We do not export type declarations.
128 if (p
->second
->is_function_declaration()
129 && should_export(p
->second
))
130 exports
.push_back(p
->second
);
133 std::sort(exports
.begin(), exports
.end(), Sort_bindings());
135 // Although the export data is readable, at least this version is,
136 // it is conceptually a binary format. Start with a four byte
138 this->write_bytes(Export::v1_magic
, Export::v1_magic_len
);
141 this->write_c_string("package ");
142 this->write_string(package_name
);
143 this->write_c_string(";\n");
145 // The prefix or package path, used for all global symbols.
148 go_assert(!pkgpath
.empty());
149 this->write_c_string("pkgpath ");
150 this->write_string(pkgpath
);
154 this->write_c_string("prefix ");
155 this->write_string(prefix
);
157 this->write_c_string(";\n");
159 // The package priority.
161 snprintf(buf
, sizeof buf
, "priority %d;\n", package_priority
);
162 this->write_c_string(buf
);
164 this->write_packages(packages
);
166 this->write_imports(imports
);
168 this->write_imported_init_fns(package_name
, package_priority
, import_init_fn
,
171 // FIXME: It might be clever to add something about the processor
172 // and ABI being used, although ideally any problems in that area
173 // would be caught by the linker.
175 for (std::vector
<Named_object
*>::const_iterator p
= exports
.begin();
178 (*p
)->export_named_object(this);
180 std::string checksum
= this->stream_
->checksum();
181 std::string s
= "checksum ";
182 for (std::string::const_iterator p
= checksum
.begin();
186 unsigned char c
= *p
;
187 unsigned int dig
= c
>> 4;
188 s
+= dig
< 10 ? '0' + dig
: 'A' + dig
- 10;
190 s
+= dig
< 10 ? '0' + dig
: 'A' + dig
- 10;
193 this->stream_
->write_checksum(s
);
199 packages_compare(const Package
* a
, const Package
* b
)
201 return a
->package_name() < b
->package_name();
204 // Write out all the known packages whose pkgpath symbol is not a
205 // simple transformation of the pkgpath, so that the importing code
206 // can reliably know it.
209 Export::write_packages(const std::map
<std::string
, Package
*>& packages
)
211 // Sort for consistent output.
212 std::vector
<Package
*> out
;
213 for (std::map
<std::string
, Package
*>::const_iterator p
= packages
.begin();
217 if (p
->second
->pkgpath_symbol()
218 != Gogo::pkgpath_for_symbol(p
->second
->pkgpath()))
219 out
.push_back(p
->second
);
222 std::sort(out
.begin(), out
.end(), packages_compare
);
224 for (std::vector
<Package
*>::const_iterator p
= out
.begin();
228 this->write_c_string("package ");
229 this->write_string((*p
)->package_name());
230 this->write_c_string(" ");
231 this->write_string((*p
)->pkgpath());
232 this->write_c_string(" ");
233 this->write_string((*p
)->pkgpath_symbol());
234 this->write_c_string(";\n");
238 // Sort imported packages.
241 import_compare(const std::pair
<std::string
, Package
*>& a
,
242 const std::pair
<std::string
, Package
*>& b
)
244 return a
.first
< b
.first
;
247 // Write out the imported packages.
250 Export::write_imports(const std::map
<std::string
, Package
*>& imports
)
252 // Sort the imports for more consistent output.
253 std::vector
<std::pair
<std::string
, Package
*> > imp
;
254 for (std::map
<std::string
, Package
*>::const_iterator p
= imports
.begin();
257 imp
.push_back(std::make_pair(p
->first
, p
->second
));
259 std::sort(imp
.begin(), imp
.end(), import_compare
);
261 for (std::vector
<std::pair
<std::string
, Package
*> >::const_iterator p
=
266 this->write_c_string("import ");
267 this->write_string(p
->second
->package_name());
268 this->write_c_string(" ");
269 this->write_string(p
->second
->pkgpath());
270 this->write_c_string(" \"");
271 this->write_string(p
->first
);
272 this->write_c_string("\";\n");
274 this->packages_
.insert(p
->second
);
278 // Write out the initialization functions which need to run for this
282 Export::write_imported_init_fns(
283 const std::string
& package_name
,
285 const std::string
& import_init_fn
,
286 const std::set
<Import_init
>& imported_init_fns
)
288 if (import_init_fn
.empty() && imported_init_fns
.empty())
291 this->write_c_string("init");
293 if (!import_init_fn
.empty())
295 this->write_c_string(" ");
296 this->write_string(package_name
);
297 this->write_c_string(" ");
298 this->write_string(import_init_fn
);
300 snprintf(buf
, sizeof buf
, " %d", priority
);
301 this->write_c_string(buf
);
304 if (!imported_init_fns
.empty())
306 // Sort the list of functions for more consistent output.
307 std::vector
<Import_init
> v
;
308 for (std::set
<Import_init
>::const_iterator p
= imported_init_fns
.begin();
309 p
!= imported_init_fns
.end();
312 std::sort(v
.begin(), v
.end());
314 for (std::vector
<Import_init
>::const_iterator p
= v
.begin();
318 this->write_c_string(" ");
319 this->write_string(p
->package_name());
320 this->write_c_string(" ");
321 this->write_string(p
->init_name());
323 snprintf(buf
, sizeof buf
, " %d", p
->priority());
324 this->write_c_string(buf
);
328 this->write_c_string(";\n");
331 // Write a name to the export stream.
334 Export::write_name(const std::string
& name
)
337 this->write_c_string("?");
339 this->write_string(Gogo::message_name(name
));
342 // Export a type. We have to ensure that on import we create a single
343 // Named_type node for each named type. We do this by keeping a hash
344 // table mapping named types to reference numbers. The first time we
345 // see a named type we assign it a reference number by making an entry
346 // in the hash table. If we see it again, we just refer to the
349 // Named types are, of course, associated with packages. Note that we
350 // may see a named type when importing one package, and then later see
351 // the same named type when importing a different package. The home
352 // package may or may not be imported during this compilation. The
353 // reference number scheme has to get this all right. Basic approach
354 // taken from "On the Linearization of Graphs and Writing Symbol
355 // Files" by Robert Griesemer.
358 Export::write_type(const Type
* type
)
360 // We don't want to assign a reference number to a forward
361 // declaration to a type which was defined later.
362 type
= type
->forwarded();
364 Type_refs::const_iterator p
= this->type_refs_
.find(type
);
365 if (p
!= this->type_refs_
.end())
367 // This type was already in the table.
368 int index
= p
->second
;
369 go_assert(index
!= 0);
371 snprintf(buf
, sizeof buf
, "<type %d>", index
);
372 this->write_c_string(buf
);
376 const Named_type
* named_type
= type
->named_type();
377 const Forward_declaration_type
* forward
= type
->forward_declaration_type();
379 int index
= this->type_index_
;
383 snprintf(buf
, sizeof buf
, "<type %d ", index
);
384 this->write_c_string(buf
);
386 if (named_type
!= NULL
|| forward
!= NULL
)
388 const Named_object
* named_object
;
389 if (named_type
!= NULL
)
391 // The builtin types should have been predefined.
392 go_assert(!Linemap::is_predeclared_location(named_type
->location())
393 || (named_type
->named_object()->package()->package_name()
395 named_object
= named_type
->named_object();
398 named_object
= forward
->named_object();
400 const Package
* package
= named_object
->package();
402 std::string s
= "\"";
403 if (package
!= NULL
&& !Gogo::is_hidden_name(named_object
->name()))
405 s
+= package
->pkgpath();
408 s
+= named_object
->name();
410 this->write_string(s
);
412 // It is possible that this type was imported indirectly, and is
413 // not in a package in the import list. If we have not
414 // mentioned this package before, write out the package name
415 // here so that any package importing this one will know it.
417 && this->packages_
.find(package
) == this->packages_
.end())
419 this->write_c_string("\"");
420 this->write_string(package
->package_name());
421 this->packages_
.insert(package
);
422 this->write_c_string("\" ");
425 // We must add a named type to the table now, since the
426 // definition of the type may refer to the named type via a
428 this->type_refs_
[type
] = index
;
431 type
->export_type(this);
433 this->write_c_string(">");
435 if (named_type
== NULL
)
436 this->type_refs_
[type
] = index
;
439 // Export escape information.
442 Export::write_escape(const Node::Escapement_lattice
& e
)
445 snprintf(buf
, sizeof buf
, "<escape %d>", e
);
446 this->write_c_string(buf
);
450 // Add the builtin types to the export table.
453 Export::register_builtin_types(Gogo
* gogo
)
455 this->register_builtin_type(gogo
, "int8", BUILTIN_INT8
);
456 this->register_builtin_type(gogo
, "int16", BUILTIN_INT16
);
457 this->register_builtin_type(gogo
, "int32", BUILTIN_INT32
);
458 this->register_builtin_type(gogo
, "int64", BUILTIN_INT64
);
459 this->register_builtin_type(gogo
, "uint8", BUILTIN_UINT8
);
460 this->register_builtin_type(gogo
, "uint16", BUILTIN_UINT16
);
461 this->register_builtin_type(gogo
, "uint32", BUILTIN_UINT32
);
462 this->register_builtin_type(gogo
, "uint64", BUILTIN_UINT64
);
463 this->register_builtin_type(gogo
, "float32", BUILTIN_FLOAT32
);
464 this->register_builtin_type(gogo
, "float64", BUILTIN_FLOAT64
);
465 this->register_builtin_type(gogo
, "complex64", BUILTIN_COMPLEX64
);
466 this->register_builtin_type(gogo
, "complex128", BUILTIN_COMPLEX128
);
467 this->register_builtin_type(gogo
, "int", BUILTIN_INT
);
468 this->register_builtin_type(gogo
, "uint", BUILTIN_UINT
);
469 this->register_builtin_type(gogo
, "uintptr", BUILTIN_UINTPTR
);
470 this->register_builtin_type(gogo
, "bool", BUILTIN_BOOL
);
471 this->register_builtin_type(gogo
, "string", BUILTIN_STRING
);
472 this->register_builtin_type(gogo
, "error", BUILTIN_ERROR
);
473 this->register_builtin_type(gogo
, "byte", BUILTIN_BYTE
);
474 this->register_builtin_type(gogo
, "rune", BUILTIN_RUNE
);
477 // Register one builtin type in the export table.
480 Export::register_builtin_type(Gogo
* gogo
, const char* name
, Builtin_code code
)
482 Named_object
* named_object
= gogo
->lookup_global(name
);
483 go_assert(named_object
!= NULL
&& named_object
->is_type());
484 std::pair
<Type_refs::iterator
, bool> ins
=
485 this->type_refs_
.insert(std::make_pair(named_object
->type_value(), code
));
486 go_assert(ins
.second
);
488 // We also insert the underlying type. We can see the underlying
489 // type at least for string and bool. We skip the type aliases byte
491 if (code
!= BUILTIN_BYTE
&& code
!= BUILTIN_RUNE
)
493 Type
* real_type
= named_object
->type_value()->real_type();
494 ins
= this->type_refs_
.insert(std::make_pair(real_type
, code
));
495 go_assert(ins
.second
);
499 // Class Export::Stream.
501 Export::Stream::Stream()
503 this->checksum_
= new sha1_ctx
;
504 memset(this->checksum_
, 0, sizeof(sha1_ctx
));
505 sha1_init_ctx(this->checksum_
);
508 Export::Stream::~Stream()
512 // Write bytes to the stream. This keeps a checksum of bytes as they
516 Export::Stream::write_and_sum_bytes(const char* bytes
, size_t length
)
518 sha1_process_bytes(bytes
, length
, this->checksum_
);
519 this->do_write(bytes
, length
);
525 Export::Stream::checksum()
527 // Use a union to provide the required alignment.
530 char checksum
[Export::v1_checksum_len
];
533 sha1_finish_ctx(this->checksum_
, u
.checksum
);
534 return std::string(u
.checksum
, Export::v1_checksum_len
);
537 // Write the checksum string to the export data.
540 Export::Stream::write_checksum(const std::string
& s
)
542 this->do_write(s
.data(), s
.length());
545 // Class Stream_to_section.
547 Stream_to_section::Stream_to_section()
551 // Write data to a section.
554 Stream_to_section::do_write(const char* bytes
, size_t length
)
556 go_write_export_data (bytes
, length
);