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 #include "go-diagnostics.h"
14 #include "expressions.h"
15 #include "statements.h"
17 #include "go-linemap.h"
20 // This file handles exporting global declarations.
24 const int Export::magic_len
;
26 // Current version magic string.
27 const char Export::cur_magic
[Export::magic_len
] =
32 // Magic strings for previous versions (still supported).
33 const char Export::v1_magic
[Export::magic_len
] =
37 const char Export::v2_magic
[Export::magic_len
] =
42 const int Export::checksum_len
;
44 // Type hash table operations, treating aliases as distinct.
46 class Type_hash_alias_identical
50 operator()(const Type
* type
) const
52 return type
->hash_for_method(NULL
,
55 | Type::COMPARE_EMBEDDED_INTERFACES
56 | Type::COMPARE_ALIASES
));
60 class Type_alias_identical
64 operator()(const Type
* t1
, const Type
* t2
) const
66 return Type::are_identical(t1
, t2
,
69 | Type::COMPARE_EMBEDDED_INTERFACES
70 | Type::COMPARE_ALIASES
),
75 // Mapping from Type objects to a constant index.
76 typedef Unordered_map_hash(const Type
*, int, Type_hash_alias_identical
,
77 Type_alias_identical
) Type_refs
;
79 // Implementation object for class Export. Hidden implementation avoids
80 // having to #include types.h in export.h, or use a static map.
88 Export::Export(Stream
* stream
)
89 : stream_(stream
), type_index_(1), packages_(), impl_(new Export_impl
)
91 go_assert(Export::checksum_len
== Go_sha1_helper::checksum_len
);
101 // A traversal class to collect functions and global variables
102 // referenced by inlined functions, and also to gather up
103 // referenced types that need to be included in the exports.
105 class Collect_export_references
: public Traverse
108 Collect_export_references(Export
* exp
,
109 const std::map
<std::string
, Package
*>& packages
,
110 Unordered_set(Named_object
*)* exports
,
111 Unordered_set(const Package
*)* imports
)
112 : Traverse(traverse_expressions
114 exp_(exp
), packages_(packages
), exports_(exports
), imports_(imports
),
115 inline_fcn_worklist_(NULL
), exports_finalized_(false)
118 // Initial entry point; performs a walk to expand the exports set.
120 expand_exports(std::vector
<Named_object
*>* inlinable_functions
);
122 // Second entry point (called after the method above), to find
123 // all types referenced by exports.
125 prepare_types(const std::vector
<Named_object
*>& sorted_exports
);
127 // Third entry point (called after the method above), to find
128 // all types in expressions referenced by exports.
130 prepare_expressions(const std::vector
<Named_object
*>& sorted_exports
);
133 // Override of parent class method.
135 expression(Expression
**);
137 // Override of parent class method.
141 // Traverse the components of a function type.
143 traverse_function_type(Function_type
*);
145 // Traverse the methods of a named type, and register its package.
147 traverse_named_type(Named_type
*);
151 // Add a named object to the exports set (during expand_exports()).
152 // Returns TRUE if a new object was added to the exports set,
155 add_to_exports(Named_object
*);
159 // The list of packages known to this compilation.
160 const std::map
<std::string
, Package
*>& packages_
;
161 // The set of named objects to export.
162 Unordered_set(Named_object
*)* exports_
;
163 // Set containing all directly and indirectly imported packages.
164 Unordered_set(const Package
*)* imports_
;
165 // Functions we've already traversed and don't need to visit again.
166 Unordered_set(Named_object
*) checked_functions_
;
167 // Worklist of functions we are exporting with inline bodies that need
169 std::vector
<Named_object
*>* inline_fcn_worklist_
;
170 // Set to true if expand_exports() has been called and is complete.
171 bool exports_finalized_
;
175 Collect_export_references::expand_exports(std::vector
<Named_object
*>* fcns
)
177 this->inline_fcn_worklist_
= fcns
;
178 while (!this->inline_fcn_worklist_
->empty())
180 Named_object
* no
= this->inline_fcn_worklist_
->back();
181 this->inline_fcn_worklist_
->pop_back();
182 std::pair
<Unordered_set(Named_object
*)::iterator
, bool> ins
=
183 this->checked_functions_
.insert(no
);
186 // This traversal may add new objects to this->exports_ and new
187 // functions to this->inline_fcn_worklist_.
188 no
->func_value()->block()->traverse(this);
191 this->inline_fcn_worklist_
= NULL
;
192 this->exports_finalized_
= true;
196 Collect_export_references::add_to_exports(Named_object
* no
)
198 std::pair
<Unordered_set(Named_object
*)::iterator
, bool> ins
=
199 this->exports_
->insert(no
);
200 // If the export list has been finalized, then we should not be
201 // adding anything new to the exports set.
202 go_assert(!this->exports_finalized_
|| !ins
.second
);
207 Collect_export_references::expression(Expression
** pexpr
)
209 const Expression
* expr
= *pexpr
;
211 const Var_expression
* ve
= expr
->var_expression();
214 Named_object
* no
= ve
->named_object();
215 if (no
->is_variable() && no
->var_value()->is_global())
217 const Package
* var_package
= no
->package();
218 if (var_package
!= NULL
)
219 this->imports_
->insert(var_package
);
221 this->add_to_exports(no
);
222 no
->var_value()->set_is_referenced_by_inline();
224 return TRAVERSE_CONTINUE
;
227 const Func_expression
* fe
= expr
->func_expression();
230 Named_object
* no
= fe
->named_object();
232 const Package
* func_package
= fe
->named_object()->package();
233 if (func_package
!= NULL
)
234 this->imports_
->insert(func_package
);
236 if (no
->is_function_declaration()
237 && no
->func_declaration_value()->type()->is_builtin())
238 return TRAVERSE_CONTINUE
;
240 if (this->inline_fcn_worklist_
!= NULL
)
242 bool added
= this->add_to_exports(no
);
244 if (no
->is_function())
245 no
->func_value()->set_is_referenced_by_inline();
247 // If 'added' is false then this object was already in
248 // exports_, in which case it was already added to
249 // check_inline_refs_ the first time we added it to exports_, so
250 // we don't need to add it again.
253 && no
->func_value()->export_for_inlining())
254 this->inline_fcn_worklist_
->push_back(no
);
257 return TRAVERSE_CONTINUE
;
260 const Named_object
* nco
= expr
->named_constant();
263 const Named_constant
*nc
= nco
->const_value();
264 Type::traverse(nc
->type(), this);
265 return TRAVERSE_CONTINUE
;
268 const Call_expression
* call
= expr
->call_expression();
271 const Builtin_call_expression
* bce
= call
->builtin_call_expression();
273 && (bce
->code() == Builtin_call_expression::BUILTIN_ADD
274 || bce
->code() == Builtin_call_expression::BUILTIN_SLICE
))
276 // This is a reference to unsafe.Add or unsafe.Slice. Make
277 // sure we list the "unsafe" package in the imports and give
278 // it a package index.
279 const std::map
<std::string
, Package
*>::const_iterator p
=
280 this->packages_
.find("unsafe");
281 go_assert(p
!= this->packages_
.end());
282 this->imports_
->insert(p
->second
);
286 return TRAVERSE_CONTINUE
;
289 // Collect up the set of types mentioned in expressions of things we're exporting,
290 // and collect all the packages encountered during type traversal, to make sure
291 // we can declare things referered to indirectly (for example, in the body of an
292 // exported inline function from another package).
295 Collect_export_references::prepare_expressions(const std::vector
<Named_object
*>& sorted_exports
)
297 for (std::vector
<Named_object
*>::const_iterator p
= sorted_exports
.begin();
298 p
!= sorted_exports
.end();
301 Named_object
* no
= *p
;
302 if (no
->classification() == Named_object::NAMED_OBJECT_CONST
)
304 Expression
* e
= no
->const_value()->expr();
306 Expression::traverse(&e
, this);
311 // Collect up the set of types mentioned in things we're exporting, and collect
312 // all the packages encountered during type traversal, to make sure we can
313 // declare things referered to indirectly (for example, in the body of an
314 // exported inline function from another package).
317 Collect_export_references::prepare_types(const std::vector
<Named_object
*>& sorted_exports
)
319 // Iterate through the exported objects and traverse any types encountered.
320 for (std::vector
<Named_object
*>::const_iterator p
= sorted_exports
.begin();
321 p
!= sorted_exports
.end();
324 Named_object
* no
= *p
;
325 switch (no
->classification())
327 case Named_object::NAMED_OBJECT_CONST
:
329 Type
* t
= no
->const_value()->type();
330 if (t
!= NULL
&& !t
->is_abstract())
331 Type::traverse(t
, this);
335 case Named_object::NAMED_OBJECT_TYPE
:
336 Type::traverse(no
->type_value()->real_type(), this);
337 this->traverse_named_type(no
->type_value());
340 case Named_object::NAMED_OBJECT_VAR
:
341 Type::traverse(no
->var_value()->type(), this);
344 case Named_object::NAMED_OBJECT_FUNC
:
346 Function
* fn
= no
->func_value();
347 this->traverse_function_type(fn
->type());
348 if (fn
->export_for_inlining())
349 fn
->block()->traverse(this);
353 case Named_object::NAMED_OBJECT_FUNC_DECLARATION
:
354 this->traverse_function_type(no
->func_declaration_value()->type());
358 // We shouldn't see anything else. If we do we'll give an
359 // error later when we try to actually export it.
365 // Record referenced type, record package imports, and make sure we traverse
366 // methods of named types.
369 Collect_export_references::type(Type
* type
)
371 // Skip forwarders; don't try to give them a type index.
372 if (type
->forward_declaration_type() != NULL
)
373 return TRAVERSE_CONTINUE
;
375 // Skip the void type, which we'll see when exporting
376 // unsafe.Pointer. The void type is not itself exported, because
377 // Pointer_type::do_export checks for it.
378 if (type
->is_void_type())
379 return TRAVERSE_SKIP_COMPONENTS
;
381 // Skip the nil type, turns up in function bodies.
382 if (type
->is_nil_type())
383 return TRAVERSE_SKIP_COMPONENTS
;
385 // Skip abstract types. We should never see these in real code,
386 // only in things like const declarations.
387 if (type
->is_abstract())
388 return TRAVERSE_SKIP_COMPONENTS
;
390 if (!this->exp_
->record_type(type
))
392 // We've already seen this type.
393 return TRAVERSE_SKIP_COMPONENTS
;
396 // At this stage of compilation traversing interface types traverses
397 // the final list of methods, but we export the locally defined
398 // methods. If there is an embedded interface type we need to make
399 // sure to export that. Check classification, rather than calling
400 // the interface_type method, because we want to handle named types
402 if (type
->classification() == Type::TYPE_INTERFACE
)
404 Interface_type
* it
= type
->interface_type();
405 const Typed_identifier_list
* methods
= it
->local_methods();
408 for (Typed_identifier_list::const_iterator p
= methods
->begin();
412 if (p
->name().empty())
413 Type::traverse(p
->type(), this);
415 this->traverse_function_type(p
->type()->function_type());
418 return TRAVERSE_SKIP_COMPONENTS
;
421 Named_type
* nt
= type
->named_type();
423 this->traverse_named_type(nt
);
425 return TRAVERSE_CONTINUE
;
429 Collect_export_references::traverse_named_type(Named_type
* nt
)
431 const Package
* package
= nt
->named_object()->package();
433 this->imports_
->insert(package
);
435 // We have to traverse the methods of named types, because we are
436 // going to export them. This is not done by ordinary type
438 const Bindings
* methods
= nt
->local_methods();
441 for (Bindings::const_definitions_iterator pm
=
442 methods
->begin_definitions();
443 pm
!= methods
->end_definitions();
446 Function
* fn
= (*pm
)->func_value();
447 this->traverse_function_type(fn
->type());
448 if (fn
->export_for_inlining())
449 fn
->block()->traverse(this);
452 for (Bindings::const_declarations_iterator pm
=
453 methods
->begin_declarations();
454 pm
!= methods
->end_declarations();
457 Named_object
* mno
= pm
->second
;
458 if (mno
->is_function_declaration())
459 this->traverse_function_type(mno
->func_declaration_value()->type());
464 // Traverse the types in a function type. We don't need the function
465 // type itself, just the receiver, parameter, and result types.
468 Collect_export_references::traverse_function_type(Function_type
* type
)
470 go_assert(type
!= NULL
);
471 if (this->remember_type(type
))
473 const Typed_identifier
* receiver
= type
->receiver();
474 if (receiver
!= NULL
)
475 Type::traverse(receiver
->type(), this);
476 const Typed_identifier_list
* parameters
= type
->parameters();
477 if (parameters
!= NULL
)
478 parameters
->traverse(this);
479 const Typed_identifier_list
* results
= type
->results();
481 results
->traverse(this);
484 // Return true if we should export NO.
487 should_export(Named_object
* no
)
489 // We only export objects which are locally defined.
490 if (no
->package() != NULL
)
493 // We don't export packages.
494 if (no
->is_package())
497 // We don't export hidden names.
498 if (Gogo::is_hidden_name(no
->name()))
501 // We don't export various special functions.
502 if (Gogo::special_name_pos(no
->name()) != std::string::npos
)
505 // Methods are exported with the type, not here.
506 if (no
->is_function()
507 && no
->func_value()->type()->is_method())
509 if (no
->is_function_declaration()
510 && no
->func_declaration_value()->type()->is_method())
513 // Don't export dummy global variables created for initializers when
515 if (no
->is_variable() && no
->name()[0] == '_' && no
->name()[1] == '.')
521 // Compare Typed_identifier_list's.
524 compare_til(const Typed_identifier_list
*, const Typed_identifier_list
*);
526 // A functor to sort Named_object pointers by name.
531 operator()(const Named_object
* n1
, const Named_object
* n2
) const
536 if (n1
->package() != n2
->package())
538 if (n1
->package() == NULL
)
540 if (n2
->package() == NULL
)
543 // Make sure we don't see the same pkgpath twice.
544 const std::string
& p1(n1
->package()->pkgpath());
545 const std::string
& p2(n2
->package()->pkgpath());
551 if (n1
->name() != n2
->name())
552 return n1
->name() < n2
->name();
554 // We shouldn't see the same name twice, but it can happen for
555 // nested type names.
557 go_assert(n1
->is_type() && n2
->is_type());
560 const Named_object
* g1
= n1
->type_value()->in_function(&ind1
);
562 const Named_object
* g2
= n2
->type_value()->in_function(&ind2
);
566 go_assert(g2
!= NULL
);
573 go_assert(ind1
!= ind2
);
576 else if ((g1
->package() != g2
->package()) || (g1
->name() != g2
->name()))
577 return Sort_bindings()(g1
, g2
);
580 // This case can happen if g1 or g2 is a method.
581 if (g1
!= NULL
&& g1
->func_value()->is_method())
583 const Typed_identifier
* r
= g1
->func_value()->type()->receiver();
584 g1
= r
->type()->named_type()->named_object();
586 if (g2
!= NULL
&& g2
->func_value()->is_method())
588 const Typed_identifier
* r
= g2
->func_value()->type()->receiver();
589 g2
= r
->type()->named_type()->named_object();
591 return Sort_bindings()(g1
, g2
);
596 // A functor to sort types for export.
601 operator()(const Type
* t1
, const Type
* t2
) const
603 t1
= t1
->forwarded();
604 t2
= t2
->forwarded();
606 const Named_type
* nt1
= t1
->named_type();
607 const Named_type
* nt2
= t2
->named_type();
613 return sb(nt1
->named_object(), nt2
->named_object());
618 else if (nt2
!= NULL
)
620 if (t1
->classification() != t2
->classification())
621 return t1
->classification() < t2
->classification();
622 Gogo
* gogo
= go_get_gogo();
624 gogo
->type_descriptor_backend_name(t1
, NULL
, &b1
);
626 gogo
->type_descriptor_backend_name(t2
, NULL
, &b2
);
628 std::string n1
= b1
.name();
629 std::string n2
= b2
.name();
633 // We should never see equal types here. If we do, we may not
634 // generate an identical output file for identical input. But the
635 // backend names can be equal because we want to treat aliases
636 // differently while type_descriptor_backend_name does not. In
637 // that case we need to traverse the type elements.
639 // t1 == t2 in case std::sort compares elements to themselves.
644 Type_alias_identical identical
;
645 go_assert(!identical(t1
, t2
));
647 switch (t1
->classification())
649 case Type::TYPE_ERROR
:
652 case Type::TYPE_VOID
:
653 case Type::TYPE_BOOLEAN
:
654 case Type::TYPE_INTEGER
:
655 case Type::TYPE_FLOAT
:
656 case Type::TYPE_COMPLEX
:
657 case Type::TYPE_STRING
:
658 case Type::TYPE_SINK
:
660 case Type::TYPE_CALL_MULTIPLE_RESULT
:
661 case Type::TYPE_NAMED
:
662 case Type::TYPE_FORWARD
:
666 case Type::TYPE_FUNCTION
:
668 const Function_type
* ft1
= t1
->function_type();
669 const Function_type
* ft2
= t2
->function_type();
670 const Typed_identifier
* r1
= ft1
->receiver();
671 const Typed_identifier
* r2
= ft2
->receiver();
673 go_assert(r2
== NULL
);
676 go_assert(r2
!= NULL
);
677 const Type
* rt1
= r1
->type()->forwarded();
678 const Type
* rt2
= r2
->type()->forwarded();
679 if (!identical(rt1
, rt2
))
680 return sort(rt1
, rt2
);
683 const Typed_identifier_list
* p1
= ft1
->parameters();
684 const Typed_identifier_list
* p2
= ft2
->parameters();
685 if (p1
== NULL
|| p1
->empty())
686 go_assert(p2
== NULL
|| p2
->empty());
689 go_assert(p2
!= NULL
&& !p2
->empty());
690 int i
= compare_til(p1
, p2
);
699 if (p1
== NULL
|| p1
->empty())
700 go_assert(p2
== NULL
|| p2
->empty());
703 go_assert(p2
!= NULL
&& !p2
->empty());
704 int i
= compare_til(p1
, p2
);
714 case Type::TYPE_POINTER
:
716 const Type
* p1
= t1
->points_to()->forwarded();
717 const Type
* p2
= t2
->points_to()->forwarded();
718 go_assert(!identical(p1
, p2
));
722 case Type::TYPE_STRUCT
:
724 const Struct_type
* s1
= t1
->struct_type();
725 const Struct_type
* s2
= t2
->struct_type();
726 const Struct_field_list
* f1
= s1
->fields();
727 const Struct_field_list
* f2
= s2
->fields();
728 go_assert(f1
!= NULL
&& f2
!= NULL
);
729 Struct_field_list::const_iterator p1
= f1
->begin();
730 Struct_field_list::const_iterator p2
= f2
->begin();
731 for (; p2
!= f2
->end(); ++p1
, ++p2
)
733 go_assert(p1
!= f1
->end());
734 go_assert(p1
->field_name() == p2
->field_name());
735 go_assert(p1
->is_anonymous() == p2
->is_anonymous());
736 const Type
* ft1
= p1
->type()->forwarded();
737 const Type
* ft2
= p2
->type()->forwarded();
738 if (!identical(ft1
, ft2
))
739 return sort(ft1
, ft2
);
741 go_assert(p1
== f1
->end());
745 case Type::TYPE_ARRAY
:
747 const Type
* e1
= t1
->array_type()->element_type()->forwarded();
748 const Type
* e2
= t2
->array_type()->element_type()->forwarded();
749 go_assert(!identical(e1
, e2
));
755 const Map_type
* m1
= t1
->map_type();
756 const Map_type
* m2
= t2
->map_type();
757 const Type
* k1
= m1
->key_type()->forwarded();
758 const Type
* k2
= m2
->key_type()->forwarded();
759 if (!identical(k1
, k2
))
761 const Type
* v1
= m1
->val_type()->forwarded();
762 const Type
* v2
= m2
->val_type()->forwarded();
763 go_assert(!identical(v1
, v2
));
767 case Type::TYPE_CHANNEL
:
769 const Type
* e1
= t1
->channel_type()->element_type()->forwarded();
770 const Type
* e2
= t2
->channel_type()->element_type()->forwarded();
771 go_assert(!identical(e1
, e2
));
775 case Type::TYPE_INTERFACE
:
777 const Interface_type
* it1
= t1
->interface_type();
778 const Interface_type
* it2
= t2
->interface_type();
779 const Typed_identifier_list
* m1
= it1
->local_methods();
780 const Typed_identifier_list
* m2
= it2
->local_methods();
782 // We know the full method lists are the same, because the
783 // mangled type names were the same, but here we are looking
784 // at the local method lists, which include embedded
785 // interfaces, and we can have an embedded empty interface.
786 if (m1
== NULL
|| m1
->empty())
788 go_assert(m2
!= NULL
&& !m2
->empty());
791 else if (m2
== NULL
|| m2
->empty())
793 go_assert(m1
!= NULL
&& !m1
->empty());
797 int i
= compare_til(m1
, m2
);
809 // Compare Typed_identifier_list's with Sort_types, returning -1, 0, +1.
813 const Typed_identifier_list
* til1
,
814 const Typed_identifier_list
* til2
)
816 Type_alias_identical identical
;
818 Typed_identifier_list::const_iterator p1
= til1
->begin();
819 Typed_identifier_list::const_iterator p2
= til2
->begin();
820 for (; p2
!= til2
->end(); ++p1
, ++p2
)
822 if (p1
== til1
->end())
824 const Type
* t1
= p1
->type()->forwarded();
825 const Type
* t2
= p2
->type()->forwarded();
826 if (!identical(t1
, t2
))
834 if (p1
!= til1
->end())
839 // Export those identifiers marked for exporting.
842 Export::export_globals(const std::string
& package_name
,
843 const std::string
& prefix
,
844 const std::string
& pkgpath
,
845 const std::map
<std::string
, Package
*>& packages
,
846 const std::map
<std::string
, Package
*>& imports
,
847 const std::string
& import_init_fn
,
848 const Import_init_set
& imported_init_fns
,
849 const Bindings
* bindings
,
850 Unordered_set(Named_object
*)* functions_marked_inline
)
852 // If there have been any errors so far, don't try to export
853 // anything. That way the export code doesn't have to worry about
854 // mismatched types or other confusions.
858 // EXPORTS is the set of objects to export. CHECK_INLINE_REFS is a
859 // list of exported function with inline bodies that need to be
860 // checked for references to other objects. Every function on
861 // CHECK_INLINE_REFS is also on EXPORTS.
862 Unordered_set(Named_object
*) exports
;
863 std::vector
<Named_object
*> check_inline_refs
;
864 check_inline_refs
.reserve(functions_marked_inline
->size());
866 // Add all functions/methods from the "marked inlined" set to the
867 // CHECK_INLINE_REFS worklist.
868 for (Unordered_set(Named_object
*)::const_iterator p
= functions_marked_inline
->begin();
869 p
!= functions_marked_inline
->end();
871 check_inline_refs
.push_back(*p
);
873 for (Bindings::const_definitions_iterator p
= bindings
->begin_definitions();
874 p
!= bindings
->end_definitions();
877 if (should_export(*p
))
881 for (Bindings::const_declarations_iterator p
=
882 bindings
->begin_declarations();
883 p
!= bindings
->end_declarations();
886 // We export a function declaration as it may be implemented in
887 // supporting C code. We do not export type declarations.
888 if (p
->second
->is_function_declaration()
889 && should_export(p
->second
))
890 exports
.insert(p
->second
);
893 // Track all imported packages mentioned in export data.
894 Unordered_set(const Package
*) all_imports
;
896 Collect_export_references
collect(this, packages
, &exports
, &all_imports
);
898 // Walk the set of inlinable routine bodies collected above. This
899 // can potentially expand the exports set.
900 collect
.expand_exports(&check_inline_refs
);
902 // Export the symbols in sorted order. That will reduce cases where
903 // irrelevant changes to the source code affect the exported
905 std::vector
<Named_object
*> sorted_exports
;
906 sorted_exports
.reserve(exports
.size());
908 for (Unordered_set(Named_object
*)::const_iterator p
= exports
.begin();
912 sorted_exports
.push_back(*p
);
914 const Package
* pkg
= (*p
)->package();
916 all_imports
.insert(pkg
);
919 std::sort(sorted_exports
.begin(), sorted_exports
.end(), Sort_bindings());
921 // Collect up the set of types mentioned in things we're exporting,
922 // and any packages that may be referred to indirectly.
923 collect
.prepare_types(sorted_exports
);
924 collect
.prepare_expressions(sorted_exports
);
926 // Assign indexes to all exported types and types referenced by
927 // things we're exporting. Return value is index of first non-exported
929 int unexported_type_index
= this->assign_type_indices(sorted_exports
);
931 // Although the export data is readable, at least this version is,
932 // it is conceptually a binary format. Start with a four byte
934 this->write_bytes(Export::cur_magic
, Export::magic_len
);
937 this->write_c_string("package ");
938 this->write_string(package_name
);
939 this->write_c_string("\n");
941 // The prefix or package path, used for all global symbols.
944 go_assert(!pkgpath
.empty());
945 this->write_c_string("pkgpath ");
946 this->write_string(pkgpath
);
950 this->write_c_string("prefix ");
951 this->write_string(prefix
);
953 this->write_c_string("\n");
955 this->write_packages(packages
);
957 this->write_imports(imports
, all_imports
);
959 this->write_imported_init_fns(package_name
, import_init_fn
,
962 // FIXME: It might be clever to add something about the processor
963 // and ABI being used, although ideally any problems in that area
964 // would be caught by the linker.
966 // Write out all the types, both exported and not.
967 this->write_types(unexported_type_index
);
969 // Write out the non-type export data.
970 for (std::vector
<Named_object
*>::const_iterator p
= sorted_exports
.begin();
971 p
!= sorted_exports
.end();
974 if (!(*p
)->is_type())
975 (*p
)->export_named_object(this);
978 std::string checksum
= this->stream_
->checksum();
979 std::string s
= "checksum ";
980 for (std::string::const_iterator p
= checksum
.begin();
984 unsigned char c
= *p
;
985 unsigned int dig
= c
>> 4;
986 s
+= dig
< 10 ? '0' + dig
: 'A' + dig
- 10;
988 s
+= dig
< 10 ? '0' + dig
: 'A' + dig
- 10;
991 this->stream_
->write_checksum(s
);
994 // Record a type in the "to be indexed" set. Return true if the type
995 // was not already in the set, false otherwise.
998 Export::record_type(Type
* type
)
1000 type
= type
->forwarded();
1001 std::pair
<Type_refs::iterator
, bool> ins
=
1002 this->impl_
->type_refs
.insert(std::make_pair(type
, 0));
1006 // Assign the specified type an index.
1009 Export::set_type_index(const Type
* type
)
1011 type
= type
->forwarded();
1012 Type_refs::iterator p
= this->impl_
->type_refs
.find(type
);
1013 go_assert(p
!= this->impl_
->type_refs
.end());
1014 int index
= this->type_index_
;
1015 ++this->type_index_
;
1016 go_assert(p
->second
== 0);
1020 // This helper assigns type indices to all types mentioned directly or
1021 // indirectly in the things we're exporting. Actual exported types are given
1022 // indices according to where the appear on the sorted exports list; all other
1023 // types appear afterwards. Return value is the total number of exported types
1024 // plus 1, e.g. the index of the 1st non-exported type.
1027 Export::assign_type_indices(const std::vector
<Named_object
*>& sorted_exports
)
1029 // Assign indexes to all the exported types.
1030 for (std::vector
<Named_object
*>::const_iterator p
= sorted_exports
.begin();
1031 p
!= sorted_exports
.end();
1034 if (!(*p
)->is_type())
1036 this->record_type((*p
)->type_value());
1037 this->set_type_index((*p
)->type_value());
1039 int ret
= this->type_index_
;
1041 // Collect export-referenced, non-builtin types.
1042 std::vector
<const Type
*> types
;
1043 types
.reserve(this->impl_
->type_refs
.size());
1044 for (Type_refs::const_iterator p
= this->impl_
->type_refs
.begin();
1045 p
!= this->impl_
->type_refs
.end();
1048 const Type
* t
= p
->first
;
1055 std::sort(types
.begin(), types
.end(), Sort_types());
1057 // Assign numbers to the sorted list.
1058 for (std::vector
<const Type
*>::const_iterator p
= types
.begin();
1061 this->set_type_index((*p
));
1069 packages_compare(const Package
* a
, const Package
* b
)
1071 if (a
->package_name() < b
->package_name())
1073 else if (a
->package_name() > b
->package_name())
1076 if (a
->pkgpath() < b
->pkgpath())
1078 else if (a
->pkgpath() > b
->pkgpath())
1081 // In principle if we get here then a == b. Try to do something sensible
1082 // even if the import information is inconsistent.
1083 if (a
->pkgpath_symbol() < b
->pkgpath_symbol())
1085 else if (a
->pkgpath_symbol() > b
->pkgpath_symbol())
1091 // Write out all the known packages whose pkgpath symbol is not a
1092 // simple transformation of the pkgpath, so that the importing code
1093 // can reliably know it.
1096 Export::write_packages(const std::map
<std::string
, Package
*>& packages
)
1098 // Sort for consistent output.
1099 std::vector
<Package
*> out
;
1100 for (std::map
<std::string
, Package
*>::const_iterator p
= packages
.begin();
1101 p
!= packages
.end();
1104 if (p
->second
->pkgpath_symbol()
1105 != Gogo::pkgpath_for_symbol(p
->second
->pkgpath()))
1106 out
.push_back(p
->second
);
1109 std::sort(out
.begin(), out
.end(), packages_compare
);
1111 for (std::vector
<Package
*>::const_iterator p
= out
.begin();
1115 this->write_c_string("package ");
1116 this->write_string((*p
)->package_name());
1117 this->write_c_string(" ");
1118 this->write_string((*p
)->pkgpath());
1119 this->write_c_string(" ");
1120 this->write_string((*p
)->pkgpath_symbol());
1121 this->write_c_string("\n");
1125 // Sort imported packages.
1128 import_compare(const std::pair
<std::string
, Package
*>& a
,
1129 const std::pair
<std::string
, Package
*>& b
)
1131 return a
.first
< b
.first
;
1134 // Write out the imported packages.
1137 Export::write_imports(const std::map
<std::string
, Package
*>& imports
,
1138 const Unordered_set(const Package
*)& all_imports
)
1140 // Sort the imports for more consistent output.
1141 Unordered_set(const Package
*) seen
;
1142 std::vector
<std::pair
<std::string
, Package
*> > sorted_imports
;
1143 for (std::map
<std::string
, Package
*>::const_iterator p
= imports
.begin();
1147 sorted_imports
.push_back(std::make_pair(p
->first
, p
->second
));
1148 seen
.insert(p
->second
);
1151 std::sort(sorted_imports
.begin(), sorted_imports
.end(), import_compare
);
1153 int package_index
= 1;
1154 for (std::vector
<std::pair
<std::string
, Package
*> >::const_iterator p
=
1155 sorted_imports
.begin();
1156 p
!= sorted_imports
.end();
1159 this->write_c_string("import ");
1160 this->write_string(p
->second
->package_name());
1161 this->write_c_string(" ");
1162 this->write_string(p
->second
->pkgpath());
1163 this->write_c_string(" \"");
1164 this->write_string(p
->first
);
1165 this->write_c_string("\"\n");
1167 this->packages_
[p
->second
] = package_index
;
1171 // Write out a separate list of indirectly imported packages.
1172 std::vector
<const Package
*> indirect_imports
;
1173 for (Unordered_set(const Package
*)::const_iterator p
=
1174 all_imports
.begin();
1175 p
!= all_imports
.end();
1178 if (seen
.find(*p
) == seen
.end())
1179 indirect_imports
.push_back(*p
);
1182 std::sort(indirect_imports
.begin(), indirect_imports
.end(),
1185 for (std::vector
<const Package
*>::const_iterator p
=
1186 indirect_imports
.begin();
1187 p
!= indirect_imports
.end();
1190 this->write_c_string("indirectimport ");
1191 this->write_string((*p
)->package_name());
1192 this->write_c_string(" ");
1193 this->write_string((*p
)->pkgpath());
1194 this->write_c_string("\n");
1196 this->packages_
[*p
] = package_index
;
1202 Export::add_init_graph_edge(Init_graph
* init_graph
, unsigned src
, unsigned sink
)
1204 Init_graph::iterator it
= init_graph
->find(src
);
1205 if (it
!= init_graph
->end())
1206 it
->second
.insert(sink
);
1209 std::set
<unsigned> succs
;
1211 (*init_graph
)[src
] = succs
;
1215 // Constructs the imported portion of the init graph, e.g. those
1216 // edges that we read from imported packages.
1219 Export::populate_init_graph(Init_graph
* init_graph
,
1220 const Import_init_set
& imported_init_fns
,
1221 const std::map
<std::string
, unsigned>& init_idx
)
1223 for (Import_init_set::const_iterator p
= imported_init_fns
.begin();
1224 p
!= imported_init_fns
.end();
1227 const Import_init
* ii
= *p
;
1230 std::map
<std::string
, unsigned>::const_iterator srcit
=
1231 init_idx
.find(ii
->init_name());
1232 go_assert(srcit
!= init_idx
.end());
1233 unsigned src
= srcit
->second
;
1234 for (std::set
<std::string
>::const_iterator pci
= ii
->precursors().begin();
1235 pci
!= ii
->precursors().end();
1238 std::map
<std::string
, unsigned>::const_iterator it
=
1239 init_idx
.find(*pci
);
1240 go_assert(it
!= init_idx
.end());
1241 unsigned sink
= it
->second
;
1242 add_init_graph_edge(init_graph
, src
, sink
);
1247 // Write out the initialization functions which need to run for this
1251 Export::write_imported_init_fns(const std::string
& package_name
,
1252 const std::string
& import_init_fn
,
1253 const Import_init_set
& imported_init_fns
)
1255 if (import_init_fn
.empty() && imported_init_fns
.empty()) return;
1257 // Maps a given init function to the its index in the exported "init" clause.
1258 std::map
<std::string
, unsigned> init_idx
;
1260 this->write_c_string("init");
1262 if (!import_init_fn
.empty())
1264 this->write_c_string(" ");
1265 this->write_string(package_name
);
1266 this->write_c_string(" ");
1267 this->write_string(import_init_fn
);
1268 init_idx
[import_init_fn
] = 0;
1271 if (imported_init_fns
.empty())
1273 this->write_c_string("\n");
1277 typedef std::map
<int, std::vector
<std::string
> > level_map
;
1278 Init_graph init_graph
;
1279 level_map inits_at_level
;
1281 // Walk through the set of import inits (already sorted by
1282 // init fcn name) and write them out to the exports.
1283 for (Import_init_set::const_iterator p
= imported_init_fns
.begin();
1284 p
!= imported_init_fns
.end();
1287 const Import_init
* ii
= *p
;
1289 if (ii
->init_name() == import_init_fn
)
1292 this->write_c_string(" ");
1293 this->write_string(ii
->package_name());
1294 this->write_c_string(" ");
1295 this->write_string(ii
->init_name());
1297 // Populate init_idx.
1298 go_assert(init_idx
.find(ii
->init_name()) == init_idx
.end());
1299 unsigned idx
= init_idx
.size();
1300 init_idx
[ii
->init_name()] = idx
;
1302 // If the init function has a non-negative priority value, this
1303 // is an indication that it was referred to in an older version
1304 // export data section (e.g. we read a legacy object
1305 // file). Record such init fcns so that we can fix up the graph
1306 // for them (handled later in this function).
1307 if (ii
->priority() > 0)
1309 level_map::iterator it
= inits_at_level
.find(ii
->priority());
1310 if (it
== inits_at_level
.end())
1312 std::vector
<std::string
> l
;
1313 l
.push_back(ii
->init_name());
1314 inits_at_level
[ii
->priority()] = l
;
1317 it
->second
.push_back(ii
->init_name());
1320 this->write_c_string("\n");
1322 // Create the init graph. Start by populating the graph with
1323 // all the edges we inherited from imported packages.
1324 populate_init_graph(&init_graph
, imported_init_fns
, init_idx
);
1326 // Now add edges from the local init function to each of the
1328 if (!import_init_fn
.empty() && import_init_fn
[0] != '~')
1331 go_assert(init_idx
[import_init_fn
] == 0);
1332 for (Import_init_set::const_iterator p
= imported_init_fns
.begin();
1333 p
!= imported_init_fns
.end();
1336 const Import_init
* ii
= *p
;
1339 unsigned sink
= init_idx
[ii
->init_name()];
1340 add_init_graph_edge(&init_graph
, src
, sink
);
1344 // In the scenario where one or more of the packages we imported
1345 // was written with the legacy export data format, add dummy edges
1346 // to capture the priority relationships. Here is a package import
1347 // graph as an example:
1360 // Let's suppose that the object for package "C" is from an old
1361 // gccgo, e.g. it has the old export data format. All other
1362 // packages are compiled with the new compiler and have the new
1363 // format. Packages with *'s have init functions. The scenario is
1364 // that we're compiling a package "A"; during this process we'll
1365 // read the export data for "C". It should look something like
1367 // init F F..import 1 G G..import 1 D D..import 2 E E..import 2;
1369 // To capture this information and convey it to the consumers of
1370 // "A", the code below adds edges to the graph from each priority K
1371 // function to every priority K-1 function for appropriate values
1372 // of K. This will potentially add more edges than we need (for
1373 // example, an edge from D to G), but given that we don't expect
1374 // to see large numbers of old objects, this will hopefully be OK.
1376 if (inits_at_level
.size() > 0)
1378 for (level_map::reverse_iterator it
= inits_at_level
.rbegin();
1379 it
!= inits_at_level
.rend(); ++it
)
1381 int level
= it
->first
;
1382 if (level
< 2) break;
1383 const std::vector
<std::string
>& fcns_at_level
= it
->second
;
1384 for (std::vector
<std::string
>::const_iterator sit
=
1385 fcns_at_level
.begin();
1386 sit
!= fcns_at_level
.end(); ++sit
)
1388 unsigned src
= init_idx
[*sit
];
1389 level_map::iterator it2
= inits_at_level
.find(level
- 1);
1390 if (it2
!= inits_at_level
.end())
1392 const std::vector
<std::string
> fcns_at_lm1
= it2
->second
;
1393 for (std::vector
<std::string
>::const_iterator mit
=
1394 fcns_at_lm1
.begin();
1395 mit
!= fcns_at_lm1
.end(); ++mit
)
1397 unsigned sink
= init_idx
[*mit
];
1398 add_init_graph_edge(&init_graph
, src
, sink
);
1405 // Write out the resulting graph.
1406 this->write_c_string("init_graph");
1407 for (Init_graph::const_iterator ki
= init_graph
.begin();
1408 ki
!= init_graph
.end(); ++ki
)
1410 unsigned src
= ki
->first
;
1411 const std::set
<unsigned>& successors
= ki
->second
;
1412 for (std::set
<unsigned>::const_iterator vi
= successors
.begin();
1413 vi
!= successors
.end(); ++vi
)
1415 this->write_c_string(" ");
1416 this->write_unsigned(src
);
1417 unsigned sink
= (*vi
);
1418 this->write_c_string(" ");
1419 this->write_unsigned(sink
);
1422 this->write_c_string("\n");
1425 // Write the types to the export stream.
1428 Export::write_types(int unexported_type_index
)
1430 // Map from type index to type.
1431 std::vector
<const Type
*> types(static_cast<size_t>(this->type_index_
));
1432 for (Type_refs::const_iterator p
= this->impl_
->type_refs
.begin();
1433 p
!= this->impl_
->type_refs
.end();
1437 types
.at(p
->second
) = p
->first
;
1440 // Write the type information to a buffer.
1441 Stream_to_string type_data
;
1442 Export::Stream
* orig_stream
= this->stream_
;
1443 this->stream_
= &type_data
;
1445 std::vector
<size_t> type_sizes(static_cast<size_t>(this->type_index_
));
1448 // Start at 1 because type index 0 is not used.
1449 size_t start_size
= 0;
1450 for (int i
= 1; i
< this->type_index_
; ++i
)
1452 this->write_type_definition(types
[i
], i
);
1454 size_t cur_size
= type_data
.string().size();
1455 type_sizes
[i
] = cur_size
- start_size
;
1456 start_size
= cur_size
;
1459 // Back to original stream.
1460 this->stream_
= orig_stream
;
1462 // The line "types MAXP1 EXPORTEDP1 SIZES..." appears before the
1463 // types. MAXP1 is one more than the maximum type index used; that
1464 // is, it is the size of the array we need to allocate to hold all
1465 // the values. Indexes 1 up to but not including EXPORTEDP1 are the
1466 // exported types. The other types are not exported. SIZES... is a
1467 // list of MAXP1-1 entries listing the size of the type definition
1468 // for each type, starting at index 1.
1470 snprintf(buf
, sizeof buf
, "types %d %d", this->type_index_
,
1471 unexported_type_index
);
1472 this->write_c_string(buf
);
1474 // Start at 1 because type index 0 is not used.
1475 for (int i
= 1; i
< this->type_index_
; ++i
)
1477 snprintf(buf
, sizeof buf
, " %lu",
1478 static_cast<unsigned long>(type_sizes
[i
]));
1479 this->write_c_string(buf
);
1481 this->write_c_string("\n");
1482 this->write_string(type_data
.string());
1485 // Write a single type to the export stream.
1488 Export::write_type_definition(const Type
* type
, int index
)
1490 this->write_c_string("type ");
1493 snprintf(buf
, sizeof buf
, "%d ", index
);
1494 this->write_c_string(buf
);
1496 const Named_type
* nt
= type
->named_type();
1499 const Named_object
* no
= nt
->named_object();
1500 const Package
* package
= no
->package();
1502 this->write_c_string("\"");
1503 if (package
!= NULL
&& !Gogo::is_hidden_name(no
->name()))
1505 this->write_string(package
->pkgpath());
1506 this->write_c_string(".");
1508 this->write_string(nt
->named_object()->name());
1509 this->write_c_string("\" ");
1512 this->write_c_string("notinheap ");
1515 this->write_c_string("= ");
1518 type
->export_type(this);
1520 // Type::export_type will print a newline for a named type, but not
1523 this->write_c_string("\n");
1526 // Write a name to the export stream.
1529 Export::write_name(const std::string
& name
)
1532 this->write_c_string("?");
1534 this->write_string(Gogo::unpack_hidden_name(name
));
1537 // Write an integer value to the export stream.
1540 Export::write_int(int value
)
1543 snprintf(buf
, sizeof buf
, "%d", value
);
1544 this->write_c_string(buf
);
1547 // Write an integer value to the export stream.
1550 Export::write_unsigned(unsigned value
)
1553 snprintf(buf
, sizeof buf
, "%u", value
);
1554 this->write_c_string(buf
);
1557 // Return the index of a package.
1560 Export::package_index(const Package
* pkg
) const
1562 Unordered_map(const Package
*, int)::const_iterator p
=
1563 this->packages_
.find(pkg
);
1564 go_assert(p
!= this->packages_
.end());
1565 int index
= p
->second
;
1566 go_assert(index
!= 0);
1570 // Return the index of the "unsafe" package.
1573 Export::unsafe_package_index() const
1575 for (Unordered_map(const Package
*, int)::const_iterator p
=
1576 this->packages_
.begin();
1577 p
!= this->packages_
.end();
1580 if (p
->first
->pkgpath() == "unsafe")
1582 go_assert(p
->second
!= 0);
1589 // Return the index of a type.
1592 Export::type_index(const Type
* type
)
1594 type
= type
->forwarded();
1595 Type_refs::const_iterator p
= this->impl_
->type_refs
.find(type
);
1596 go_assert(p
!= this->impl_
->type_refs
.end());
1597 int index
= p
->second
;
1598 go_assert(index
!= 0);
1605 Export::write_type(const Type
* type
)
1607 int index
= this->type_index(type
);
1609 snprintf(buf
, sizeof buf
, "<type %d>", index
);
1610 this->write_c_string(buf
);
1613 // Export a type to a function body.
1616 Export::write_type_to(const Type
* type
, Export_function_body
* efb
)
1618 int index
= this->type_index(type
);
1620 snprintf(buf
, sizeof buf
, "<type %d>", index
);
1621 efb
->write_c_string(buf
);
1624 // Export escape note.
1627 Export::write_escape(std::string
* note
)
1629 if (note
!= NULL
&& *note
!= "esc:0x0")
1631 this->write_c_string(" ");
1633 go_assert(note
->find("esc:") != std::string::npos
);
1634 snprintf(buf
, sizeof buf
, "<%s>", note
->c_str());
1635 this->write_c_string(buf
);
1639 // Add the builtin types to the export table.
1642 Export::register_builtin_types(Gogo
* gogo
)
1644 this->register_builtin_type(gogo
, "int8", BUILTIN_INT8
);
1645 this->register_builtin_type(gogo
, "int16", BUILTIN_INT16
);
1646 this->register_builtin_type(gogo
, "int32", BUILTIN_INT32
);
1647 this->register_builtin_type(gogo
, "int64", BUILTIN_INT64
);
1648 this->register_builtin_type(gogo
, "uint8", BUILTIN_UINT8
);
1649 this->register_builtin_type(gogo
, "uint16", BUILTIN_UINT16
);
1650 this->register_builtin_type(gogo
, "uint32", BUILTIN_UINT32
);
1651 this->register_builtin_type(gogo
, "uint64", BUILTIN_UINT64
);
1652 this->register_builtin_type(gogo
, "float32", BUILTIN_FLOAT32
);
1653 this->register_builtin_type(gogo
, "float64", BUILTIN_FLOAT64
);
1654 this->register_builtin_type(gogo
, "complex64", BUILTIN_COMPLEX64
);
1655 this->register_builtin_type(gogo
, "complex128", BUILTIN_COMPLEX128
);
1656 this->register_builtin_type(gogo
, "int", BUILTIN_INT
);
1657 this->register_builtin_type(gogo
, "uint", BUILTIN_UINT
);
1658 this->register_builtin_type(gogo
, "uintptr", BUILTIN_UINTPTR
);
1659 this->register_builtin_type(gogo
, "bool", BUILTIN_BOOL
);
1660 this->register_builtin_type(gogo
, "string", BUILTIN_STRING
);
1661 this->register_builtin_type(gogo
, "error", BUILTIN_ERROR
);
1662 this->register_builtin_type(gogo
, "byte", BUILTIN_BYTE
);
1663 this->register_builtin_type(gogo
, "rune", BUILTIN_RUNE
);
1664 this->register_builtin_type(gogo
, "any", BUILTIN_ANY
);
1667 // Register one builtin type in the export table.
1670 Export::register_builtin_type(Gogo
* gogo
, const char* name
, Builtin_code code
)
1672 Named_object
* named_object
= gogo
->lookup_global(name
);
1673 go_assert(named_object
!= NULL
&& named_object
->is_type());
1674 std::pair
<Type_refs::iterator
, bool> ins
=
1675 this->impl_
->type_refs
.insert(std::make_pair(named_object
->type_value(), code
));
1676 go_assert(ins
.second
);
1678 // We also insert the underlying type. We can see the underlying
1679 // type at least for string and bool. It's OK if this insert
1680 // fails--we expect duplications here, and it doesn't matter when
1682 Type
* real_type
= named_object
->type_value()->real_type();
1683 this->impl_
->type_refs
.insert(std::make_pair(real_type
, code
));
1686 // Class Export::Stream.
1688 Export::Stream::Stream()
1690 this->sha1_helper_
= go_create_sha1_helper();
1691 go_assert(this->sha1_helper_
!= NULL
);
1694 Export::Stream::~Stream()
1698 // Write bytes to the stream. This keeps a checksum of bytes as they
1702 Export::Stream::write_and_sum_bytes(const char* bytes
, size_t length
)
1704 this->sha1_helper_
->process_bytes(bytes
, length
);
1705 this->do_write(bytes
, length
);
1708 // Get the checksum.
1711 Export::Stream::checksum()
1713 std::string rval
= this->sha1_helper_
->finish();
1714 delete this->sha1_helper_
;
1718 // Write the checksum string to the export data.
1721 Export::Stream::write_checksum(const std::string
& s
)
1723 this->do_write(s
.data(), s
.length());
1726 // Class Stream_to_section.
1728 Stream_to_section::Stream_to_section(Backend
* backend
)
1733 // Write data to a section.
1736 Stream_to_section::do_write(const char* bytes
, size_t length
)
1738 this->backend_
->write_export_data (bytes
, length
);
1741 // Class Export_function_body.
1743 // Record a temporary statement.
1746 Export_function_body::record_temporary(const Temporary_statement
* temp
)
1748 unsigned int ret
= this->next_temporary_index_
;
1749 if (ret
> 0x7fffffff)
1750 go_error_at(temp
->location(),
1751 "too many temporary statements in export data");
1752 ++this->next_temporary_index_
;
1753 std::pair
<const Temporary_statement
*, unsigned int> val(temp
, ret
);
1754 std::pair
<Unordered_map(const Temporary_statement
*, unsigned int)::iterator
,
1755 bool> ins
= this->temporary_indexes_
.insert(val
);
1756 go_assert(ins
.second
);
1760 // Return the index of a temporary statement.
1763 Export_function_body::temporary_index(const Temporary_statement
* temp
)
1765 Unordered_map(const Temporary_statement
*, unsigned int)::const_iterator p
=
1766 this->temporary_indexes_
.find(temp
);
1767 go_assert(p
!= this->temporary_indexes_
.end());
1771 // Return the index of an unnamed label. If it doesn't already have
1772 // an index, give it one.
1775 Export_function_body::unnamed_label_index(const Unnamed_label
* label
)
1777 unsigned int next
= this->next_label_index_
;
1778 std::pair
<const Unnamed_label
*, unsigned int> val(label
, next
);
1779 std::pair
<Unordered_map(const Unnamed_label
*, unsigned int)::iterator
,
1781 this->label_indexes_
.insert(val
);
1783 return ins
.first
->second
;
1786 if (next
> 0x7fffffff)
1787 go_error_at(label
->location(),
1788 "too many unnamed labels in export data");
1789 ++this->next_label_index_
;