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.
14 #include "statements.h"
17 // This file handles exporting global declarations.
21 const int Export::magic_len
;
23 // Current version magic string.
24 const char Export::cur_magic
[Export::magic_len
] =
29 // Magic string for previous version (still supported)
30 const char Export::v1_magic
[Export::magic_len
] =
35 const int Export::checksum_len
;
39 Export::Export(Stream
* stream
)
40 : stream_(stream
), type_refs_(), type_index_(1), packages_()
42 go_assert(Export::checksum_len
== Go_sha1_helper::checksum_len
);
45 // A functor to sort Named_object pointers by name.
50 operator()(const Named_object
* n1
, const Named_object
* n2
) const
51 { return n1
->name() < n2
->name(); }
54 // Return true if we should export NO.
57 should_export(Named_object
* no
)
59 // We only export objects which are locally defined.
60 if (no
->package() != NULL
)
63 // We don't export packages.
67 // We don't export hidden names.
68 if (Gogo::is_hidden_name(no
->name()))
71 // We don't export nested functions.
72 if (no
->is_function() && no
->func_value()->enclosing() != NULL
)
75 // We don't export thunks.
76 if (no
->is_function() && Gogo::is_thunk(no
))
79 // Methods are exported with the type, not here.
81 && no
->func_value()->type()->is_method())
83 if (no
->is_function_declaration()
84 && no
->func_declaration_value()->type()->is_method())
87 // Don't export dummy global variables created for initializers when
89 if (no
->is_variable() && no
->name()[0] == '_' && no
->name()[1] == '.')
95 // Export those identifiers marked for exporting.
98 Export::export_globals(const std::string
& package_name
,
99 const std::string
& prefix
,
100 const std::string
& pkgpath
,
101 const std::map
<std::string
, Package
*>& packages
,
102 const std::map
<std::string
, Package
*>& imports
,
103 const std::string
& import_init_fn
,
104 const Import_init_set
& imported_init_fns
,
105 const Bindings
* bindings
)
107 // If there have been any errors so far, don't try to export
108 // anything. That way the export code doesn't have to worry about
109 // mismatched types or other confusions.
113 // Export the symbols in sorted order. That will reduce cases where
114 // irrelevant changes to the source code affect the exported
116 std::vector
<Named_object
*> exports
;
117 exports
.reserve(bindings
->size_definitions());
119 for (Bindings::const_definitions_iterator p
= bindings
->begin_definitions();
120 p
!= bindings
->end_definitions();
122 if (should_export(*p
))
123 exports
.push_back(*p
);
125 for (Bindings::const_declarations_iterator p
=
126 bindings
->begin_declarations();
127 p
!= bindings
->end_declarations();
130 // We export a function declaration as it may be implemented in
131 // supporting C code. We do not export type declarations.
132 if (p
->second
->is_function_declaration()
133 && should_export(p
->second
))
134 exports
.push_back(p
->second
);
137 std::sort(exports
.begin(), exports
.end(), Sort_bindings());
139 // Although the export data is readable, at least this version is,
140 // it is conceptually a binary format. Start with a four byte
142 this->write_bytes(Export::cur_magic
, Export::magic_len
);
145 this->write_c_string("package ");
146 this->write_string(package_name
);
147 this->write_c_string(";\n");
149 // The prefix or package path, used for all global symbols.
152 go_assert(!pkgpath
.empty());
153 this->write_c_string("pkgpath ");
154 this->write_string(pkgpath
);
158 this->write_c_string("prefix ");
159 this->write_string(prefix
);
161 this->write_c_string(";\n");
163 this->write_packages(packages
);
165 this->write_imports(imports
);
167 this->write_imported_init_fns(package_name
, import_init_fn
,
170 // FIXME: It might be clever to add something about the processor
171 // and ABI being used, although ideally any problems in that area
172 // would be caught by the linker.
174 for (std::vector
<Named_object
*>::const_iterator p
= exports
.begin();
177 (*p
)->export_named_object(this);
179 std::string checksum
= this->stream_
->checksum();
180 std::string s
= "checksum ";
181 for (std::string::const_iterator p
= checksum
.begin();
185 unsigned char c
= *p
;
186 unsigned int dig
= c
>> 4;
187 s
+= dig
< 10 ? '0' + dig
: 'A' + dig
- 10;
189 s
+= dig
< 10 ? '0' + dig
: 'A' + dig
- 10;
192 this->stream_
->write_checksum(s
);
198 packages_compare(const Package
* a
, const Package
* b
)
200 return a
->package_name() < b
->package_name();
203 // Write out all the known packages whose pkgpath symbol is not a
204 // simple transformation of the pkgpath, so that the importing code
205 // can reliably know it.
208 Export::write_packages(const std::map
<std::string
, Package
*>& packages
)
210 // Sort for consistent output.
211 std::vector
<Package
*> out
;
212 for (std::map
<std::string
, Package
*>::const_iterator p
= packages
.begin();
216 if (p
->second
->pkgpath_symbol()
217 != Gogo::pkgpath_for_symbol(p
->second
->pkgpath()))
218 out
.push_back(p
->second
);
221 std::sort(out
.begin(), out
.end(), packages_compare
);
223 for (std::vector
<Package
*>::const_iterator p
= out
.begin();
227 this->write_c_string("package ");
228 this->write_string((*p
)->package_name());
229 this->write_c_string(" ");
230 this->write_string((*p
)->pkgpath());
231 this->write_c_string(" ");
232 this->write_string((*p
)->pkgpath_symbol());
233 this->write_c_string(";\n");
237 // Sort imported packages.
240 import_compare(const std::pair
<std::string
, Package
*>& a
,
241 const std::pair
<std::string
, Package
*>& b
)
243 return a
.first
< b
.first
;
246 // Write out the imported packages.
249 Export::write_imports(const std::map
<std::string
, Package
*>& imports
)
251 // Sort the imports for more consistent output.
252 std::vector
<std::pair
<std::string
, Package
*> > sorted_imports
;
253 for (std::map
<std::string
, Package
*>::const_iterator p
= imports
.begin();
256 sorted_imports
.push_back(std::make_pair(p
->first
, p
->second
));
258 std::sort(sorted_imports
.begin(), sorted_imports
.end(), import_compare
);
260 for (std::vector
<std::pair
<std::string
, Package
*> >::const_iterator p
=
261 sorted_imports
.begin();
262 p
!= sorted_imports
.end();
265 this->write_c_string("import ");
266 this->write_string(p
->second
->package_name());
267 this->write_c_string(" ");
268 this->write_string(p
->second
->pkgpath());
269 this->write_c_string(" \"");
270 this->write_string(p
->first
);
271 this->write_c_string("\";\n");
273 this->packages_
.insert(p
->second
);
278 Export::add_init_graph_edge(Init_graph
* init_graph
, unsigned src
, unsigned sink
)
280 Init_graph::iterator it
= init_graph
->find(src
);
281 if (it
!= init_graph
->end())
282 it
->second
.insert(sink
);
285 std::set
<unsigned> succs
;
287 (*init_graph
)[src
] = succs
;
291 // Constructs the imported portion of the init graph, e.g. those
292 // edges that we read from imported packages.
295 Export::populate_init_graph(Init_graph
* init_graph
,
296 const Import_init_set
& imported_init_fns
,
297 const std::map
<std::string
, unsigned>& init_idx
)
299 for (Import_init_set::const_iterator p
= imported_init_fns
.begin();
300 p
!= imported_init_fns
.end();
303 const Import_init
* ii
= *p
;
304 std::map
<std::string
, unsigned>::const_iterator srcit
=
305 init_idx
.find(ii
->init_name());
306 go_assert(srcit
!= init_idx
.end());
307 unsigned src
= srcit
->second
;
308 for (std::set
<std::string
>::const_iterator pci
= ii
->precursors().begin();
309 pci
!= ii
->precursors().end();
312 std::map
<std::string
, unsigned>::const_iterator it
=
314 go_assert(it
!= init_idx
.end());
315 unsigned sink
= it
->second
;
316 add_init_graph_edge(init_graph
, src
, sink
);
321 // Write out the initialization functions which need to run for this
325 Export::write_imported_init_fns(const std::string
& package_name
,
326 const std::string
& import_init_fn
,
327 const Import_init_set
& imported_init_fns
)
329 if (import_init_fn
.empty() && imported_init_fns
.empty()) return;
331 // Maps a given init function to the its index in the exported "init" clause.
332 std::map
<std::string
, unsigned> init_idx
;
334 this->write_c_string("init");
336 if (!import_init_fn
.empty())
338 this->write_c_string(" ");
339 this->write_string(package_name
);
340 this->write_c_string(" ");
341 this->write_string(import_init_fn
);
342 init_idx
[import_init_fn
] = 0;
345 if (imported_init_fns
.empty())
347 this->write_c_string(";\n");
351 typedef std::map
<int, std::vector
<std::string
> > level_map
;
352 Init_graph init_graph
;
353 level_map inits_at_level
;
355 // Walk through the set of import inits (already sorted by
356 // init fcn name) and write them out to the exports.
357 for (Import_init_set::const_iterator p
= imported_init_fns
.begin();
358 p
!= imported_init_fns
.end();
361 const Import_init
* ii
= *p
;
362 this->write_c_string(" ");
363 this->write_string(ii
->package_name());
364 this->write_c_string(" ");
365 this->write_string(ii
->init_name());
367 // Populate init_idx.
368 go_assert(init_idx
.find(ii
->init_name()) == init_idx
.end());
369 unsigned idx
= init_idx
.size();
370 init_idx
[ii
->init_name()] = idx
;
372 // If the init function has a non-negative priority value, this
373 // is an indication that it was referred to in an older version
374 // export data section (e.g. we read a legacy object
375 // file). Record such init fcns so that we can fix up the graph
376 // for them (handled later in this function).
377 if (ii
->priority() > 0)
379 level_map::iterator it
= inits_at_level
.find(ii
->priority());
380 if (it
== inits_at_level
.end())
382 std::vector
<std::string
> l
;
383 l
.push_back(ii
->init_name());
384 inits_at_level
[ii
->priority()] = l
;
387 it
->second
.push_back(ii
->init_name());
390 this->write_c_string(";\n");
392 // Create the init graph. Start by populating the graph with
393 // all the edges we inherited from imported packages.
394 populate_init_graph(&init_graph
, imported_init_fns
, init_idx
);
396 // Now add edges from the local init function to each of the
398 if (!import_init_fn
.empty())
401 go_assert(init_idx
[import_init_fn
] == 0);
402 for (Import_init_set::const_iterator p
= imported_init_fns
.begin();
403 p
!= imported_init_fns
.end();
406 const Import_init
* ii
= *p
;
407 unsigned sink
= init_idx
[ii
->init_name()];
408 add_init_graph_edge(&init_graph
, src
, sink
);
412 // In the scenario where one or more of the packages we imported
413 // was written with the legacy export data format, add dummy edges
414 // to capture the priority relationships. Here is a package import
415 // graph as an example:
428 // Let's suppose that the object for package "C" is from an old
429 // gccgo, e.g. it has the old export data format. All other
430 // packages are compiled with the new compiler and have the new
431 // format. Packages with *'s have init functions. The scenario is
432 // that we're compiling a package "A"; during this process we'll
433 // read the export data for "C". It should look something like
435 // init F F..import 1 G G..import 1 D D..import 2 E E..import 2;
437 // To capture this information and convey it to the consumers of
438 // "A", the code below adds edges to the graph from each priority K
439 // function to every priority K-1 function for appropriate values
440 // of K. This will potentially add more edges than we need (for
441 // example, an edge from D to G), but given that we don't expect
442 // to see large numbers of old objects, this will hopefully be OK.
444 if (inits_at_level
.size() > 0)
446 for (level_map::reverse_iterator it
= inits_at_level
.rbegin();
447 it
!= inits_at_level
.rend(); ++it
)
449 int level
= it
->first
;
450 if (level
< 2) break;
451 const std::vector
<std::string
>& fcns_at_level
= it
->second
;
452 for (std::vector
<std::string
>::const_iterator sit
=
453 fcns_at_level
.begin();
454 sit
!= fcns_at_level
.end(); ++sit
)
456 unsigned src
= init_idx
[*sit
];
457 level_map::iterator it2
= inits_at_level
.find(level
- 1);
458 if (it2
!= inits_at_level
.end())
460 const std::vector
<std::string
> fcns_at_lm1
= it2
->second
;
461 for (std::vector
<std::string
>::const_iterator mit
=
463 mit
!= fcns_at_lm1
.end(); ++mit
)
465 unsigned sink
= init_idx
[*mit
];
466 add_init_graph_edge(&init_graph
, src
, sink
);
473 // Write out the resulting graph.
474 this->write_c_string("init_graph");
475 for (Init_graph::const_iterator ki
= init_graph
.begin();
476 ki
!= init_graph
.end(); ++ki
)
478 unsigned src
= ki
->first
;
479 const std::set
<unsigned>& successors
= ki
->second
;
480 for (std::set
<unsigned>::const_iterator vi
= successors
.begin();
481 vi
!= successors
.end(); ++vi
)
483 this->write_c_string(" ");
484 this->write_unsigned(src
);
485 unsigned sink
= (*vi
);
486 this->write_c_string(" ");
487 this->write_unsigned(sink
);
490 this->write_c_string(";\n");
493 // Write a name to the export stream.
496 Export::write_name(const std::string
& name
)
499 this->write_c_string("?");
501 this->write_string(Gogo::message_name(name
));
504 // Write an integer value to the export stream.
507 Export::write_int(int value
)
510 snprintf(buf
, sizeof buf
, "%d", value
);
511 this->write_c_string(buf
);
514 // Write an integer value to the export stream.
517 Export::write_unsigned(unsigned value
)
520 snprintf(buf
, sizeof buf
, "%u", value
);
521 this->write_c_string(buf
);
524 // Export a type. We have to ensure that on import we create a single
525 // Named_type node for each named type. We do this by keeping a hash
526 // table mapping named types to reference numbers. The first time we
527 // see a named type we assign it a reference number by making an entry
528 // in the hash table. If we see it again, we just refer to the
531 // Named types are, of course, associated with packages. Note that we
532 // may see a named type when importing one package, and then later see
533 // the same named type when importing a different package. The home
534 // package may or may not be imported during this compilation. The
535 // reference number scheme has to get this all right. Basic approach
536 // taken from "On the Linearization of Graphs and Writing Symbol
537 // Files" by Robert Griesemer.
540 Export::write_type(const Type
* type
)
542 // We don't want to assign a reference number to a forward
543 // declaration to a type which was defined later.
544 type
= type
->forwarded();
546 Type_refs::const_iterator p
= this->type_refs_
.find(type
);
547 if (p
!= this->type_refs_
.end())
549 // This type was already in the table.
550 int index
= p
->second
;
551 go_assert(index
!= 0);
553 snprintf(buf
, sizeof buf
, "<type %d>", index
);
554 this->write_c_string(buf
);
558 const Named_type
* named_type
= type
->named_type();
559 const Forward_declaration_type
* forward
= type
->forward_declaration_type();
561 int index
= this->type_index_
;
565 snprintf(buf
, sizeof buf
, "<type %d ", index
);
566 this->write_c_string(buf
);
568 if (named_type
!= NULL
|| forward
!= NULL
)
570 const Named_object
* named_object
;
571 if (named_type
!= NULL
)
573 // The builtin types should have been predefined.
574 go_assert(!Linemap::is_predeclared_location(named_type
->location())
575 || (named_type
->named_object()->package()->package_name()
577 named_object
= named_type
->named_object();
580 named_object
= forward
->named_object();
582 const Package
* package
= named_object
->package();
584 std::string s
= "\"";
585 if (package
!= NULL
&& !Gogo::is_hidden_name(named_object
->name()))
587 s
+= package
->pkgpath();
590 s
+= named_object
->name();
592 this->write_string(s
);
594 // It is possible that this type was imported indirectly, and is
595 // not in a package in the import list. If we have not
596 // mentioned this package before, write out the package name
597 // here so that any package importing this one will know it.
599 && this->packages_
.find(package
) == this->packages_
.end())
601 this->write_c_string("\"");
602 this->write_string(package
->package_name());
603 this->packages_
.insert(package
);
604 this->write_c_string("\" ");
607 // We must add a named type to the table now, since the
608 // definition of the type may refer to the named type via a
610 this->type_refs_
[type
] = index
;
612 if (named_type
!= NULL
&& named_type
->is_alias())
613 this->write_c_string("= ");
616 type
->export_type(this);
618 this->write_c_string(">");
620 if (named_type
== NULL
)
621 this->type_refs_
[type
] = index
;
624 // Export escape note.
627 Export::write_escape(std::string
* note
)
629 if (note
!= NULL
&& *note
!= "esc:0x0")
631 this->write_c_string(" ");
633 go_assert(note
->find("esc:") != std::string::npos
);
634 snprintf(buf
, sizeof buf
, "<%s>", note
->c_str());
635 this->write_c_string(buf
);
639 // Add the builtin types to the export table.
642 Export::register_builtin_types(Gogo
* gogo
)
644 this->register_builtin_type(gogo
, "int8", BUILTIN_INT8
);
645 this->register_builtin_type(gogo
, "int16", BUILTIN_INT16
);
646 this->register_builtin_type(gogo
, "int32", BUILTIN_INT32
);
647 this->register_builtin_type(gogo
, "int64", BUILTIN_INT64
);
648 this->register_builtin_type(gogo
, "uint8", BUILTIN_UINT8
);
649 this->register_builtin_type(gogo
, "uint16", BUILTIN_UINT16
);
650 this->register_builtin_type(gogo
, "uint32", BUILTIN_UINT32
);
651 this->register_builtin_type(gogo
, "uint64", BUILTIN_UINT64
);
652 this->register_builtin_type(gogo
, "float32", BUILTIN_FLOAT32
);
653 this->register_builtin_type(gogo
, "float64", BUILTIN_FLOAT64
);
654 this->register_builtin_type(gogo
, "complex64", BUILTIN_COMPLEX64
);
655 this->register_builtin_type(gogo
, "complex128", BUILTIN_COMPLEX128
);
656 this->register_builtin_type(gogo
, "int", BUILTIN_INT
);
657 this->register_builtin_type(gogo
, "uint", BUILTIN_UINT
);
658 this->register_builtin_type(gogo
, "uintptr", BUILTIN_UINTPTR
);
659 this->register_builtin_type(gogo
, "bool", BUILTIN_BOOL
);
660 this->register_builtin_type(gogo
, "string", BUILTIN_STRING
);
661 this->register_builtin_type(gogo
, "error", BUILTIN_ERROR
);
662 this->register_builtin_type(gogo
, "byte", BUILTIN_BYTE
);
663 this->register_builtin_type(gogo
, "rune", BUILTIN_RUNE
);
666 // Register one builtin type in the export table.
669 Export::register_builtin_type(Gogo
* gogo
, const char* name
, Builtin_code code
)
671 Named_object
* named_object
= gogo
->lookup_global(name
);
672 go_assert(named_object
!= NULL
&& named_object
->is_type());
673 std::pair
<Type_refs::iterator
, bool> ins
=
674 this->type_refs_
.insert(std::make_pair(named_object
->type_value(), code
));
675 go_assert(ins
.second
);
677 // We also insert the underlying type. We can see the underlying
678 // type at least for string and bool. We skip the type aliases byte
680 if (code
!= BUILTIN_BYTE
&& code
!= BUILTIN_RUNE
)
682 Type
* real_type
= named_object
->type_value()->real_type();
683 ins
= this->type_refs_
.insert(std::make_pair(real_type
, code
));
684 go_assert(ins
.second
);
688 // Class Export::Stream.
690 Export::Stream::Stream()
692 this->sha1_helper_
= go_create_sha1_helper();
693 go_assert(this->sha1_helper_
!= NULL
);
696 Export::Stream::~Stream()
700 // Write bytes to the stream. This keeps a checksum of bytes as they
704 Export::Stream::write_and_sum_bytes(const char* bytes
, size_t length
)
706 this->sha1_helper_
->process_bytes(bytes
, length
);
707 this->do_write(bytes
, length
);
713 Export::Stream::checksum()
715 std::string rval
= this->sha1_helper_
->finish();
716 delete this->sha1_helper_
;
720 // Write the checksum string to the export data.
723 Export::Stream::write_checksum(const std::string
& s
)
725 this->do_write(s
.data(), s
.length());
728 // Class Stream_to_section.
730 Stream_to_section::Stream_to_section()
734 // Write data to a section.
737 Stream_to_section::do_write(const char* bytes
, size_t length
)
739 go_write_export_data (bytes
, length
);