1 // export.cc -- Export declarations in Go frontend.
2 
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.
6 
7 #include "go-system.h"
8 
9 #include "go-c.h"
10 #include "go-diagnostics.h"
11 #include "go-sha1.h"
12 #include "gogo.h"
13 #include "types.h"
14 #include "expressions.h"
15 #include "statements.h"
16 #include "export.h"
17 #include "go-linemap.h"
18 #include "backend.h"
19 
20 // This file handles exporting global declarations.
21 
22 // Class Export.
23 
24 const int Export::magic_len;
25 
26 // Current version magic string.
27 const char Export::cur_magic[Export::magic_len] =
28   {
29     'v', '3', ';', '\n'
30   };
31 
32 // Magic strings for previous versions (still supported).
33 const char Export::v1_magic[Export::magic_len] =
34   {
35     'v', '1', ';', '\n'
36   };
37 const char Export::v2_magic[Export::magic_len] =
38   {
39     'v', '2', ';', '\n'
40   };
41 
42 const int Export::checksum_len;
43 
44 // Type hash table operations, treating aliases as distinct.
45 
46 class Type_hash_alias_identical
47 {
48  public:
49   unsigned int
operator ()(const Type * type) const50   operator()(const Type* type) const
51   {
52     return type->hash_for_method(NULL,
53 				 (Type::COMPARE_ERRORS
54 				  | Type::COMPARE_TAGS
55 				  | Type::COMPARE_EMBEDDED_INTERFACES
56 				  | Type::COMPARE_ALIASES));
57   }
58 };
59 
60 class Type_alias_identical
61 {
62  public:
63   bool
operator ()(const Type * t1,const Type * t2) const64   operator()(const Type* t1, const Type* t2) const
65   {
66     return Type::are_identical(t1, t2,
67 			       (Type::COMPARE_ERRORS
68 				| Type::COMPARE_TAGS
69                                 | Type::COMPARE_EMBEDDED_INTERFACES
70 				| Type::COMPARE_ALIASES),
71 			       NULL);
72   }
73 };
74 
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;
78 
79 // Implementation object for class Export.  Hidden implementation avoids
80 // having to #include types.h in export.h, or use a static map.
81 
82 struct Export_impl {
83   Type_refs type_refs;
84 };
85 
86 // Constructor.
87 
Export(Stream * stream)88 Export::Export(Stream* stream)
89     : stream_(stream), type_index_(1), packages_(), impl_(new Export_impl)
90 {
91   go_assert(Export::checksum_len == Go_sha1_helper::checksum_len);
92 }
93 
94 // Destructor.
95 
~Export()96 Export::~Export()
97 {
98   delete this->impl_;
99 }
100 
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.
104 
105 class Collect_export_references : public Traverse
106 {
107  public:
Collect_export_references(Export * exp,Unordered_set (Named_object *)* exports,Unordered_set (const Package *)* imports)108   Collect_export_references(Export* exp,
109                             Unordered_set(Named_object*)* exports,
110                             Unordered_set(const Package*)* imports)
111     : Traverse(traverse_expressions
112                | traverse_types),
113       exp_(exp), exports_(exports), imports_(imports),
114       inline_fcn_worklist_(NULL), exports_finalized_(false)
115   { }
116 
117   // Initial entry point; performs a walk to expand the exports set.
118   void
119   expand_exports(std::vector<Named_object*>* inlinable_functions);
120 
121   // Second entry point (called after the method above), to find
122   // all types referenced by exports.
123   void
124   prepare_types(const std::vector<Named_object*>& sorted_exports);
125 
126  protected:
127   // Override of parent class method.
128   int
129   expression(Expression**);
130 
131   // Override of parent class method.
132   int
133   type(Type* type);
134 
135   // Traverse the components of a function type.
136   void
137   traverse_function_type(Function_type*);
138 
139   // Traverse the methods of a named type, and register its package.
140   void
141   traverse_named_type(Named_type*);
142 
143  private:
144 
145   // Add a named object to the exports set (during expand_exports()).
146   // Returns TRUE if a new object was added to the exports set,
147   // FALSE otherwise.
148   bool
149   add_to_exports(Named_object*);
150 
151   // The exporter.
152   Export* exp_;
153   // The set of named objects to export.
154   Unordered_set(Named_object*)* exports_;
155   // Set containing all directly and indirectly imported packages.
156   Unordered_set(const Package*)* imports_;
157   // Functions we've already traversed and don't need to visit again.
158   Unordered_set(Named_object*) checked_functions_;
159   // Worklist of functions we are exporting with inline bodies that need
160   // to be checked.
161   std::vector<Named_object*>* inline_fcn_worklist_;
162   // Set to true if expand_exports() has been called and is complete.
163   bool exports_finalized_;
164 };
165 
166 void
expand_exports(std::vector<Named_object * > * fcns)167 Collect_export_references::expand_exports(std::vector<Named_object*>* fcns)
168 {
169   this->inline_fcn_worklist_ = fcns;
170   while (!this->inline_fcn_worklist_->empty())
171     {
172       Named_object* no = this->inline_fcn_worklist_->back();
173       this->inline_fcn_worklist_->pop_back();
174       std::pair<Unordered_set(Named_object*)::iterator, bool> ins =
175 	this->checked_functions_.insert(no);
176       if (ins.second)
177 	{
178 	  // This traversal may add new objects to this->exports_ and new
179 	  // functions to this->inline_fcn_worklist_.
180 	  no->func_value()->block()->traverse(this);
181 	}
182     }
183   this->inline_fcn_worklist_ = NULL;
184   this->exports_finalized_ = true;
185 }
186 
187 bool
add_to_exports(Named_object * no)188 Collect_export_references::add_to_exports(Named_object* no)
189 {
190   std::pair<Unordered_set(Named_object*)::iterator, bool> ins =
191       this->exports_->insert(no);
192   // If the export list has been finalized, then we should not be
193   // adding anything new to the exports set.
194   go_assert(!this->exports_finalized_ || !ins.second);
195   return ins.second;
196 }
197 
198 int
expression(Expression ** pexpr)199 Collect_export_references::expression(Expression** pexpr)
200 {
201   const Expression* expr = *pexpr;
202 
203   const Var_expression* ve = expr->var_expression();
204   if (ve != NULL)
205     {
206       Named_object* no = ve->named_object();
207       if (no->is_variable() && no->var_value()->is_global())
208 	{
209           const Package* var_package = no->package();
210           if (var_package != NULL)
211             this->imports_->insert(var_package);
212 
213 	  this->add_to_exports(no);
214 	  no->var_value()->set_is_referenced_by_inline();
215 	}
216       return TRAVERSE_CONTINUE;
217     }
218 
219   const Func_expression* fe = expr->func_expression();
220   if (fe != NULL)
221     {
222       Named_object* no = fe->named_object();
223 
224       const Package* func_package = fe->named_object()->package();
225       if (func_package != NULL)
226         this->imports_->insert(func_package);
227 
228       if (no->is_function_declaration()
229 	  && no->func_declaration_value()->type()->is_builtin())
230 	return TRAVERSE_CONTINUE;
231 
232       if (this->inline_fcn_worklist_ != NULL)
233         {
234           bool added = this->add_to_exports(no);
235 
236           if (no->is_function())
237             no->func_value()->set_is_referenced_by_inline();
238 
239           // If 'added' is false then this object was already in
240           // exports_, in which case it was already added to
241           // check_inline_refs_ the first time we added it to exports_, so
242           // we don't need to add it again.
243           if (added
244               && no->is_function()
245               && no->func_value()->export_for_inlining())
246             this->inline_fcn_worklist_->push_back(no);
247         }
248 
249       return TRAVERSE_CONTINUE;
250     }
251 
252   const Named_object* nco = expr->named_constant();
253   if (nco != 0)
254     {
255       const Named_constant *nc = nco->const_value();
256       Type::traverse(nc->type(), this);
257       return TRAVERSE_CONTINUE;
258     }
259 
260   return TRAVERSE_CONTINUE;
261 }
262 
263 // Collect up the set of types mentioned in things we're exporting, and collect
264 // all the packages encountered during type traversal, to make sure we can
265 // declare things referered to indirectly (for example, in the body of an
266 // exported inline function from another package).
267 
268 void
prepare_types(const std::vector<Named_object * > & sorted_exports)269 Collect_export_references::prepare_types(const std::vector<Named_object*>& sorted_exports)
270 {
271   // Iterate through the exported objects and traverse any types encountered.
272   for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin();
273        p != sorted_exports.end();
274        ++p)
275     {
276       Named_object* no = *p;
277       switch (no->classification())
278 	{
279 	case Named_object::NAMED_OBJECT_CONST:
280 	  {
281 	    Type* t = no->const_value()->type();
282 	    if (t != NULL && !t->is_abstract())
283 	      Type::traverse(t, this);
284 	  }
285 	  break;
286 
287 	case Named_object::NAMED_OBJECT_TYPE:
288 	  Type::traverse(no->type_value()->real_type(), this);
289 	  this->traverse_named_type(no->type_value());
290 	  break;
291 
292 	case Named_object::NAMED_OBJECT_VAR:
293 	  Type::traverse(no->var_value()->type(), this);
294 	  break;
295 
296 	case Named_object::NAMED_OBJECT_FUNC:
297 	  {
298 	    Function* fn = no->func_value();
299 	    this->traverse_function_type(fn->type());
300 	    if (fn->export_for_inlining())
301 	      fn->block()->traverse(this);
302 	  }
303 	  break;
304 
305 	case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
306 	  this->traverse_function_type(no->func_declaration_value()->type());
307 	  break;
308 
309 	default:
310 	  // We shouldn't see anything else.  If we do we'll give an
311 	  // error later when we try to actually export it.
312 	  break;
313 	}
314     }
315 }
316 
317 // Record referenced type, record package imports, and make sure we traverse
318 // methods of named types.
319 
320 int
type(Type * type)321 Collect_export_references::type(Type* type)
322 {
323   // Skip forwarders; don't try to give them a type index.
324   if (type->forward_declaration_type() != NULL)
325     return TRAVERSE_CONTINUE;
326 
327   // Skip the void type, which we'll see when exporting
328   // unsafe.Pointer.  The void type is not itself exported, because
329   // Pointer_type::do_export checks for it.
330   if (type->is_void_type())
331     return TRAVERSE_SKIP_COMPONENTS;
332 
333   // Skip the nil type, turns up in function bodies.
334   if (type->is_nil_type())
335     return TRAVERSE_SKIP_COMPONENTS;
336 
337   // Skip abstract types.  We should never see these in real code,
338   // only in things like const declarations.
339   if (type->is_abstract())
340     return TRAVERSE_SKIP_COMPONENTS;
341 
342   // For interfaces make sure that embedded methods are sorted, since the
343   // comparison function we use for indexing types relies on it (this call has
344   // to happen before the record_type call below).
345   if (type->classification() == Type::TYPE_INTERFACE)
346     {
347       Interface_type* it = type->interface_type();
348       if (it != NULL)
349         it->sort_embedded();
350     }
351 
352   if (!this->exp_->record_type(type))
353     {
354       // We've already seen this type.
355       return TRAVERSE_SKIP_COMPONENTS;
356     }
357 
358   // At this stage of compilation traversing interface types traverses
359   // the final list of methods, but we export the locally defined
360   // methods.  If there is an embedded interface type we need to make
361   // sure to export that.  Check classification, rather than calling
362   // the interface_type method, because we want to handle named types
363   // below.
364   if (type->classification() == Type::TYPE_INTERFACE)
365     {
366       Interface_type* it = type->interface_type();
367       const Typed_identifier_list* methods = it->local_methods();
368       if (methods != NULL)
369 	{
370 	  for (Typed_identifier_list::const_iterator p = methods->begin();
371 	       p != methods->end();
372 	       ++p)
373 	    {
374 	      if (p->name().empty())
375 		Type::traverse(p->type(), this);
376 	      else
377 		this->traverse_function_type(p->type()->function_type());
378 	    }
379 	}
380       return TRAVERSE_SKIP_COMPONENTS;
381     }
382 
383   Named_type* nt = type->named_type();
384   if (nt != NULL)
385     this->traverse_named_type(nt);
386 
387   return TRAVERSE_CONTINUE;
388 }
389 
390 void
traverse_named_type(Named_type * nt)391 Collect_export_references::traverse_named_type(Named_type* nt)
392 {
393   const Package* package = nt->named_object()->package();
394   if (package != NULL)
395     this->imports_->insert(package);
396 
397   // We have to traverse the methods of named types, because we are
398   // going to export them.  This is not done by ordinary type
399   // traversal.
400   const Bindings* methods = nt->local_methods();
401   if (methods != NULL)
402     {
403       for (Bindings::const_definitions_iterator pm =
404 	     methods->begin_definitions();
405 	   pm != methods->end_definitions();
406 	   ++pm)
407 	{
408 	  Function* fn = (*pm)->func_value();
409 	  this->traverse_function_type(fn->type());
410 	  if (fn->export_for_inlining())
411 	    fn->block()->traverse(this);
412 	}
413 
414       for (Bindings::const_declarations_iterator pm =
415 	     methods->begin_declarations();
416 	   pm != methods->end_declarations();
417 	   ++pm)
418 	{
419 	  Named_object* mno = pm->second;
420 	  if (mno->is_function_declaration())
421 	    this->traverse_function_type(mno->func_declaration_value()->type());
422 	}
423     }
424 }
425 
426 // Traverse the types in a function type.  We don't need the function
427 // type itself, just the receiver, parameter, and result types.
428 
429 void
traverse_function_type(Function_type * type)430 Collect_export_references::traverse_function_type(Function_type* type)
431 {
432   go_assert(type != NULL);
433   if (this->remember_type(type))
434     return;
435   const Typed_identifier* receiver = type->receiver();
436   if (receiver != NULL)
437     Type::traverse(receiver->type(), this);
438   const Typed_identifier_list* parameters = type->parameters();
439   if (parameters != NULL)
440     parameters->traverse(this);
441   const Typed_identifier_list* results = type->results();
442   if (results != NULL)
443     results->traverse(this);
444 }
445 
446 // Return true if we should export NO.
447 
448 static bool
should_export(Named_object * no)449 should_export(Named_object* no)
450 {
451   // We only export objects which are locally defined.
452   if (no->package() != NULL)
453     return false;
454 
455   // We don't export packages.
456   if (no->is_package())
457     return false;
458 
459   // We don't export hidden names.
460   if (Gogo::is_hidden_name(no->name()))
461     return false;
462 
463   // We don't export various special functions.
464   if (Gogo::special_name_pos(no->name()) != std::string::npos)
465     return false;
466 
467   // Methods are exported with the type, not here.
468   if (no->is_function()
469       && no->func_value()->type()->is_method())
470     return false;
471   if (no->is_function_declaration()
472       && no->func_declaration_value()->type()->is_method())
473     return false;
474 
475   // Don't export dummy global variables created for initializers when
476   // used with sinks.
477   if (no->is_variable() && no->name()[0] == '_' && no->name()[1] == '.')
478     return false;
479 
480   return true;
481 }
482 
483 // A functor to sort Named_object pointers by name.
484 
485 struct Sort_bindings
486 {
487   bool
operator ()Sort_bindings488   operator()(const Named_object* n1, const Named_object* n2) const
489   {
490     if (n1->package() != n2->package())
491       {
492 	if (n1->package() == NULL)
493 	  return true;
494 	if (n2->package() == NULL)
495 	  return false;
496 	return n1->package()->pkgpath() < n2->package()->pkgpath();
497       }
498 
499     return n1->name() < n2->name();
500   }
501 };
502 
503 // A functor to sort types for export.
504 
505 struct Sort_types
506 {
507   bool
operator ()Sort_types508   operator()(const Type* t1, const Type* t2) const
509   {
510     const Named_type* nt1 = t1->named_type();
511     const Named_type* nt2 = t2->named_type();
512     if (nt1 != NULL)
513       {
514         if (nt2 != NULL)
515           {
516             Sort_bindings sb;
517             return sb(nt1->named_object(), nt2->named_object());
518           }
519         else
520           return true;
521       }
522     else if (nt2 != NULL)
523       return false;
524     if (t1->classification() != t2->classification())
525       return t1->classification() < t2->classification();
526     Gogo* gogo = go_get_gogo();
527     Backend_name b1;
528     gogo->type_descriptor_backend_name(t1, NULL, &b1);
529     Backend_name b2;
530     gogo->type_descriptor_backend_name(t2, NULL, &b2);
531     return b1.name() < b2.name();
532   }
533 };
534 
535 // Export those identifiers marked for exporting.
536 
537 void
export_globals(const std::string & package_name,const std::string & prefix,const std::string & pkgpath,const std::map<std::string,Package * > & packages,const std::map<std::string,Package * > & imports,const std::string & import_init_fn,const Import_init_set & imported_init_fns,const Bindings * bindings,Unordered_set (Named_object *)* functions_marked_inline)538 Export::export_globals(const std::string& package_name,
539 		       const std::string& prefix,
540 		       const std::string& pkgpath,
541 		       const std::map<std::string, Package*>& packages,
542 		       const std::map<std::string, Package*>& imports,
543 		       const std::string& import_init_fn,
544                        const Import_init_set& imported_init_fns,
545 		       const Bindings* bindings,
546                        Unordered_set(Named_object*)* functions_marked_inline)
547 {
548   // If there have been any errors so far, don't try to export
549   // anything.  That way the export code doesn't have to worry about
550   // mismatched types or other confusions.
551   if (saw_errors())
552     return;
553 
554   // EXPORTS is the set of objects to export.  CHECK_INLINE_REFS is a
555   // list of exported function with inline bodies that need to be
556   // checked for references to other objects.  Every function on
557   // CHECK_INLINE_REFS is also on EXPORTS.
558   Unordered_set(Named_object*) exports;
559   std::vector<Named_object*> check_inline_refs;
560   check_inline_refs.reserve(functions_marked_inline->size());
561 
562   // Add all functions/methods from the "marked inlined" set to the
563   // CHECK_INLINE_REFS worklist.
564   for (Unordered_set(Named_object*)::const_iterator p = functions_marked_inline->begin();
565        p != functions_marked_inline->end();
566        ++p)
567       check_inline_refs.push_back(*p);
568 
569   for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
570        p != bindings->end_definitions();
571        ++p)
572     {
573       if (should_export(*p))
574         exports.insert(*p);
575     }
576 
577   for (Bindings::const_declarations_iterator p =
578 	 bindings->begin_declarations();
579        p != bindings->end_declarations();
580        ++p)
581     {
582       // We export a function declaration as it may be implemented in
583       // supporting C code.  We do not export type declarations.
584       if (p->second->is_function_declaration()
585 	  && should_export(p->second))
586 	exports.insert(p->second);
587     }
588 
589   // Track all imported packages mentioned in export data.
590   Unordered_set(const Package*) all_imports;
591 
592   Collect_export_references collect(this, &exports, &all_imports);
593 
594   // Walk the set of inlinable routine bodies collected above. This
595   // can potentially expand the exports set.
596   collect.expand_exports(&check_inline_refs);
597 
598   // Export the symbols in sorted order.  That will reduce cases where
599   // irrelevant changes to the source code affect the exported
600   // interface.
601   std::vector<Named_object*> sorted_exports;
602   sorted_exports.reserve(exports.size());
603 
604   for (Unordered_set(Named_object*)::const_iterator p = exports.begin();
605        p != exports.end();
606        ++p)
607     {
608       sorted_exports.push_back(*p);
609 
610       const Package* pkg = (*p)->package();
611       if (pkg != NULL)
612 	all_imports.insert(pkg);
613     }
614 
615   std::sort(sorted_exports.begin(), sorted_exports.end(), Sort_bindings());
616 
617   // Collect up the set of types mentioned in things we're exporting,
618   // and any packages that may be referred to indirectly.
619   collect.prepare_types(sorted_exports);
620 
621   // Assign indexes to all exported types and types referenced by
622   // things we're exporting.  Return value is index of first non-exported
623   // type.
624   int unexported_type_index = this->assign_type_indices(sorted_exports);
625 
626   // Although the export data is readable, at least this version is,
627   // it is conceptually a binary format.  Start with a four byte
628   // version number.
629   this->write_bytes(Export::cur_magic, Export::magic_len);
630 
631   // The package name.
632   this->write_c_string("package ");
633   this->write_string(package_name);
634   this->write_c_string("\n");
635 
636   // The prefix or package path, used for all global symbols.
637   if (prefix.empty())
638     {
639       go_assert(!pkgpath.empty());
640       this->write_c_string("pkgpath ");
641       this->write_string(pkgpath);
642     }
643   else
644     {
645       this->write_c_string("prefix ");
646       this->write_string(prefix);
647     }
648   this->write_c_string("\n");
649 
650   this->write_packages(packages);
651 
652   this->write_imports(imports, all_imports);
653 
654   this->write_imported_init_fns(package_name, import_init_fn,
655 				imported_init_fns);
656 
657   // FIXME: It might be clever to add something about the processor
658   // and ABI being used, although ideally any problems in that area
659   // would be caught by the linker.
660 
661   // Write out all the types, both exported and not.
662   this->write_types(unexported_type_index);
663 
664   // Write out the non-type export data.
665   for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin();
666        p != sorted_exports.end();
667        ++p)
668     {
669       if (!(*p)->is_type())
670 	(*p)->export_named_object(this);
671     }
672 
673   std::string checksum = this->stream_->checksum();
674   std::string s = "checksum ";
675   for (std::string::const_iterator p = checksum.begin();
676        p != checksum.end();
677        ++p)
678     {
679       unsigned char c = *p;
680       unsigned int dig = c >> 4;
681       s += dig < 10 ? '0' + dig : 'A' + dig - 10;
682       dig = c & 0xf;
683       s += dig < 10 ? '0' + dig : 'A' + dig - 10;
684     }
685   s += "\n";
686   this->stream_->write_checksum(s);
687 }
688 
689 // Record a type in the "to be indexed" set. Return true if the type
690 // was not already in the set, false otherwise.
691 
692 bool
record_type(Type * type)693 Export::record_type(Type* type)
694 {
695   type = type->forwarded();
696 
697   std::pair<Type_refs::iterator, bool> ins =
698     this->impl_->type_refs.insert(std::make_pair(type, 0));
699   if (!ins.second)
700     {
701       // We've already seen this type.
702       return false;
703     }
704   ins.first->second = 0;
705 
706   return true;
707 }
708 
709 // Assign the specified type an index.
710 
711 void
set_type_index(const Type * type)712 Export::set_type_index(const Type* type)
713 {
714   type = type->forwarded();
715   std::pair<Type_refs::iterator, bool> ins =
716     this->impl_->type_refs.insert(std::make_pair(type, 0));
717   go_assert(!ins.second);
718   int index = this->type_index_;
719   ++this->type_index_;
720   go_assert(ins.first->second == 0);
721   ins.first->second = index;
722 }
723 
724 // This helper assigns type indices to all types mentioned directly or
725 // indirectly in the things we're exporting. Actual exported types are given
726 // indices according to where the appear on the sorted exports list; all other
727 // types appear afterwards. Return value is the total number of exported types
728 // plus 1, e.g. the index of the 1st non-exported type.
729 
730 int
assign_type_indices(const std::vector<Named_object * > & sorted_exports)731 Export::assign_type_indices(const std::vector<Named_object*>& sorted_exports)
732 {
733   // Assign indexes to all the exported types.
734   for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin();
735        p != sorted_exports.end();
736        ++p)
737     {
738       if (!(*p)->is_type())
739 	continue;
740       Interface_type* it = (*p)->type_value()->interface_type();
741       if (it != NULL)
742         it->sort_embedded();
743       this->record_type((*p)->type_value());
744       this->set_type_index((*p)->type_value());
745     }
746   int ret = this->type_index_;
747 
748   // Collect export-referenced, non-builtin types.
749   std::vector<const Type*> types;
750   types.reserve(this->impl_->type_refs.size());
751   for (Type_refs::const_iterator p = this->impl_->type_refs.begin();
752        p != this->impl_->type_refs.end();
753        ++p)
754     {
755       const Type* t = p->first;
756       if (p->second != 0)
757         continue;
758       types.push_back(t);
759     }
760 
761   // Sort the types.
762   std::sort(types.begin(), types.end(), Sort_types());
763 
764   // Assign numbers to the sorted list.
765   for (std::vector<const Type *>::const_iterator p = types.begin();
766        p != types.end();
767        ++p)
768     this->set_type_index((*p));
769 
770   return ret;
771 }
772 
773 // Sort packages.
774 
775 static bool
packages_compare(const Package * a,const Package * b)776 packages_compare(const Package* a, const Package* b)
777 {
778   if (a->package_name() < b->package_name())
779     return true;
780   else if (a->package_name() > b->package_name())
781     return false;
782 
783   if (a->pkgpath() < b->pkgpath())
784     return true;
785   else if (a->pkgpath() > b->pkgpath())
786     return false;
787 
788   // In principle if we get here then a == b.  Try to do something sensible
789   // even if the import information is inconsistent.
790   if (a->pkgpath_symbol() < b->pkgpath_symbol())
791     return true;
792   else if (a->pkgpath_symbol() > b->pkgpath_symbol())
793     return false;
794 
795   return a < b;
796 }
797 
798 // Write out all the known packages whose pkgpath symbol is not a
799 // simple transformation of the pkgpath, so that the importing code
800 // can reliably know it.
801 
802 void
write_packages(const std::map<std::string,Package * > & packages)803 Export::write_packages(const std::map<std::string, Package*>& packages)
804 {
805   // Sort for consistent output.
806   std::vector<Package*> out;
807   for (std::map<std::string, Package*>::const_iterator p = packages.begin();
808        p != packages.end();
809        ++p)
810     {
811       if (p->second->pkgpath_symbol()
812 	  != Gogo::pkgpath_for_symbol(p->second->pkgpath()))
813 	out.push_back(p->second);
814     }
815 
816   std::sort(out.begin(), out.end(), packages_compare);
817 
818   for (std::vector<Package*>::const_iterator p = out.begin();
819        p != out.end();
820        ++p)
821     {
822       this->write_c_string("package ");
823       this->write_string((*p)->package_name());
824       this->write_c_string(" ");
825       this->write_string((*p)->pkgpath());
826       this->write_c_string(" ");
827       this->write_string((*p)->pkgpath_symbol());
828       this->write_c_string("\n");
829     }
830 }
831 
832 // Sort imported packages.
833 
834 static bool
import_compare(const std::pair<std::string,Package * > & a,const std::pair<std::string,Package * > & b)835 import_compare(const std::pair<std::string, Package*>& a,
836 	       const std::pair<std::string, Package*>& b)
837 {
838   return a.first < b.first;
839 }
840 
841 // Write out the imported packages.
842 
843 void
write_imports(const std::map<std::string,Package * > & imports,const Unordered_set (const Package *)& all_imports)844 Export::write_imports(const std::map<std::string, Package*>& imports,
845 		      const Unordered_set(const Package*)& all_imports)
846 {
847   // Sort the imports for more consistent output.
848   Unordered_set(const Package*) seen;
849   std::vector<std::pair<std::string, Package*> > sorted_imports;
850   for (std::map<std::string, Package*>::const_iterator p = imports.begin();
851        p != imports.end();
852        ++p)
853     {
854       sorted_imports.push_back(std::make_pair(p->first, p->second));
855       seen.insert(p->second);
856     }
857 
858   std::sort(sorted_imports.begin(), sorted_imports.end(), import_compare);
859 
860   int package_index = 1;
861   for (std::vector<std::pair<std::string, Package*> >::const_iterator p =
862 	 sorted_imports.begin();
863        p != sorted_imports.end();
864        ++p)
865     {
866       this->write_c_string("import ");
867       this->write_string(p->second->package_name());
868       this->write_c_string(" ");
869       this->write_string(p->second->pkgpath());
870       this->write_c_string(" \"");
871       this->write_string(p->first);
872       this->write_c_string("\"\n");
873 
874       this->packages_[p->second] = package_index;
875       package_index++;
876     }
877 
878   // Write out a separate list of indirectly imported packages.
879   std::vector<const Package*> indirect_imports;
880   for (Unordered_set(const Package*)::const_iterator p =
881 	 all_imports.begin();
882        p != all_imports.end();
883        ++p)
884     {
885       if (seen.find(*p) == seen.end())
886 	indirect_imports.push_back(*p);
887     }
888 
889   std::sort(indirect_imports.begin(), indirect_imports.end(),
890 	    packages_compare);
891 
892   for (std::vector<const Package*>::const_iterator p =
893 	 indirect_imports.begin();
894        p != indirect_imports.end();
895        ++p)
896     {
897       this->write_c_string("indirectimport ");
898       this->write_string((*p)->package_name());
899       this->write_c_string(" ");
900       this->write_string((*p)->pkgpath());
901       this->write_c_string("\n");
902 
903       this->packages_[*p] = package_index;
904       package_index++;
905     }
906 }
907 
908 void
add_init_graph_edge(Init_graph * init_graph,unsigned src,unsigned sink)909 Export::add_init_graph_edge(Init_graph* init_graph, unsigned src, unsigned sink)
910 {
911   Init_graph::iterator it = init_graph->find(src);
912   if (it != init_graph->end())
913     it->second.insert(sink);
914   else
915     {
916       std::set<unsigned> succs;
917       succs.insert(sink);
918       (*init_graph)[src] = succs;
919     }
920 }
921 
922 // Constructs the imported portion of the init graph, e.g. those
923 // edges that we read from imported packages.
924 
925 void
populate_init_graph(Init_graph * init_graph,const Import_init_set & imported_init_fns,const std::map<std::string,unsigned> & init_idx)926 Export::populate_init_graph(Init_graph* init_graph,
927                             const Import_init_set& imported_init_fns,
928                             const std::map<std::string, unsigned>& init_idx)
929 {
930   for (Import_init_set::const_iterator p = imported_init_fns.begin();
931        p != imported_init_fns.end();
932        ++p)
933     {
934       const Import_init* ii = *p;
935       if (ii->is_dummy())
936         continue;
937       std::map<std::string, unsigned>::const_iterator srcit =
938           init_idx.find(ii->init_name());
939       go_assert(srcit != init_idx.end());
940       unsigned src = srcit->second;
941       for (std::set<std::string>::const_iterator pci = ii->precursors().begin();
942            pci != ii->precursors().end();
943            ++pci)
944 	{
945 	  std::map<std::string, unsigned>::const_iterator it =
946 	      init_idx.find(*pci);
947 	  go_assert(it != init_idx.end());
948 	  unsigned sink = it->second;
949 	  add_init_graph_edge(init_graph, src, sink);
950 	}
951     }
952 }
953 
954 // Write out the initialization functions which need to run for this
955 // package.
956 
957 void
write_imported_init_fns(const std::string & package_name,const std::string & import_init_fn,const Import_init_set & imported_init_fns)958 Export::write_imported_init_fns(const std::string& package_name,
959                                 const std::string& import_init_fn,
960                                 const Import_init_set& imported_init_fns)
961 {
962   if (import_init_fn.empty() && imported_init_fns.empty()) return;
963 
964   // Maps a given init function to the its index in the exported "init" clause.
965   std::map<std::string, unsigned> init_idx;
966 
967   this->write_c_string("init");
968 
969   if (!import_init_fn.empty())
970     {
971       this->write_c_string(" ");
972       this->write_string(package_name);
973       this->write_c_string(" ");
974       this->write_string(import_init_fn);
975       init_idx[import_init_fn] = 0;
976     }
977 
978   if (imported_init_fns.empty())
979     {
980       this->write_c_string("\n");
981       return;
982     }
983 
984   typedef std::map<int, std::vector<std::string> > level_map;
985   Init_graph init_graph;
986   level_map inits_at_level;
987 
988   // Walk through the set of import inits (already sorted by
989   // init fcn name) and write them out to the exports.
990   for (Import_init_set::const_iterator p = imported_init_fns.begin();
991        p != imported_init_fns.end();
992        ++p)
993     {
994       const Import_init* ii = *p;
995 
996       if (ii->init_name() == import_init_fn)
997 	continue;
998 
999       this->write_c_string(" ");
1000       this->write_string(ii->package_name());
1001       this->write_c_string(" ");
1002       this->write_string(ii->init_name());
1003 
1004       // Populate init_idx.
1005       go_assert(init_idx.find(ii->init_name()) == init_idx.end());
1006       unsigned idx = init_idx.size();
1007       init_idx[ii->init_name()] = idx;
1008 
1009       // If the init function has a non-negative priority value, this
1010       // is an indication that it was referred to in an older version
1011       // export data section (e.g. we read a legacy object
1012       // file). Record such init fcns so that we can fix up the graph
1013       // for them (handled later in this function).
1014       if (ii->priority() > 0)
1015 	{
1016 	  level_map::iterator it = inits_at_level.find(ii->priority());
1017 	  if (it == inits_at_level.end())
1018 	    {
1019 	      std::vector<std::string> l;
1020 	      l.push_back(ii->init_name());
1021 	      inits_at_level[ii->priority()] = l;
1022 	    }
1023 	  else
1024 	    it->second.push_back(ii->init_name());
1025 	}
1026     }
1027   this->write_c_string("\n");
1028 
1029   // Create the init graph. Start by populating the graph with
1030   // all the edges we inherited from imported packages.
1031   populate_init_graph(&init_graph, imported_init_fns, init_idx);
1032 
1033   // Now add edges from the local init function to each of the
1034   // imported fcns.
1035   if (!import_init_fn.empty() && import_init_fn[0] != '~')
1036     {
1037       unsigned src = 0;
1038       go_assert(init_idx[import_init_fn] == 0);
1039       for (Import_init_set::const_iterator p = imported_init_fns.begin();
1040            p != imported_init_fns.end();
1041            ++p)
1042 	{
1043           const Import_init* ii = *p;
1044           if (ii->is_dummy())
1045             continue;
1046 	  unsigned sink = init_idx[ii->init_name()];
1047 	  add_init_graph_edge(&init_graph, src, sink);
1048 	}
1049     }
1050 
1051   // In the scenario where one or more of the packages we imported
1052   // was written with the legacy export data format, add dummy edges
1053   // to capture the priority relationships. Here is a package import
1054   // graph as an example:
1055   //
1056   //       *A
1057   //       /|
1058   //      / |
1059   //     B  *C
1060   //       /|
1061   //      / |
1062   //    *D *E
1063   //     | /|
1064   //     |/ |
1065   //    *F  *G
1066   //
1067   // Let's suppose that the object for package "C" is from an old
1068   // gccgo, e.g. it has the old export data format. All other
1069   // packages are compiled with the new compiler and have the new
1070   // format. Packages with *'s have init functions. The scenario is
1071   // that we're compiling a package "A"; during this process we'll
1072   // read the export data for "C". It should look something like
1073   //
1074   //   init F F..import 1 G G..import 1 D D..import 2 E E..import 2;
1075   //
1076   // To capture this information and convey it to the consumers of
1077   // "A", the code below adds edges to the graph from each priority K
1078   // function to every priority K-1 function for appropriate values
1079   // of K. This will potentially add more edges than we need (for
1080   // example, an edge from D to G), but given that we don't expect
1081   // to see large numbers of old objects, this will hopefully be OK.
1082 
1083   if (inits_at_level.size() > 0)
1084     {
1085       for (level_map::reverse_iterator it = inits_at_level.rbegin();
1086            it != inits_at_level.rend(); ++it)
1087 	{
1088 	  int level = it->first;
1089 	  if (level < 2) break;
1090 	  const std::vector<std::string>& fcns_at_level = it->second;
1091 	  for (std::vector<std::string>::const_iterator sit =
1092 	           fcns_at_level.begin();
1093 	       sit != fcns_at_level.end(); ++sit)
1094 	    {
1095 	      unsigned src = init_idx[*sit];
1096 	      level_map::iterator it2 = inits_at_level.find(level - 1);
1097 	      if (it2 != inits_at_level.end())
1098 		{
1099 		  const std::vector<std::string> fcns_at_lm1 = it2->second;
1100 		  for (std::vector<std::string>::const_iterator mit =
1101 		           fcns_at_lm1.begin();
1102 		       mit != fcns_at_lm1.end(); ++mit)
1103 		    {
1104 		      unsigned sink = init_idx[*mit];
1105 		      add_init_graph_edge(&init_graph, src, sink);
1106 		    }
1107 		}
1108 	    }
1109 	}
1110     }
1111 
1112   // Write out the resulting graph.
1113   this->write_c_string("init_graph");
1114   for (Init_graph::const_iterator ki = init_graph.begin();
1115        ki != init_graph.end(); ++ki)
1116     {
1117       unsigned src = ki->first;
1118       const std::set<unsigned>& successors = ki->second;
1119       for (std::set<unsigned>::const_iterator vi = successors.begin();
1120            vi != successors.end(); ++vi)
1121 	{
1122 	  this->write_c_string(" ");
1123 	  this->write_unsigned(src);
1124 	  unsigned sink = (*vi);
1125 	  this->write_c_string(" ");
1126 	  this->write_unsigned(sink);
1127 	}
1128     }
1129   this->write_c_string("\n");
1130 }
1131 
1132 // Write the types to the export stream.
1133 
1134 void
write_types(int unexported_type_index)1135 Export::write_types(int unexported_type_index)
1136 {
1137   // Map from type index to type.
1138   std::vector<const Type*> types(static_cast<size_t>(this->type_index_));
1139   for (Type_refs::const_iterator p = this->impl_->type_refs.begin();
1140        p != this->impl_->type_refs.end();
1141        ++p)
1142     {
1143       if (p->second >= 0)
1144 	types.at(p->second) = p->first;
1145     }
1146 
1147   // Write the type information to a buffer.
1148   Stream_to_string type_data;
1149   Export::Stream* orig_stream = this->stream_;
1150   this->stream_ = &type_data;
1151 
1152   std::vector<size_t> type_sizes(static_cast<size_t>(this->type_index_));
1153   type_sizes[0] = 0;
1154 
1155   // Start at 1 because type index 0 is not used.
1156   size_t start_size = 0;
1157   for (int i = 1; i < this->type_index_; ++i)
1158     {
1159       this->write_type_definition(types[i], i);
1160 
1161       size_t cur_size = type_data.string().size();
1162       type_sizes[i] = cur_size - start_size;
1163       start_size = cur_size;
1164     }
1165 
1166   // Back to original stream.
1167   this->stream_ = orig_stream;
1168 
1169   // The line "types MAXP1 EXPORTEDP1 SIZES..." appears before the
1170   // types.  MAXP1 is one more than the maximum type index used; that
1171   // is, it is the size of the array we need to allocate to hold all
1172   // the values.  Indexes 1 up to but not including EXPORTEDP1 are the
1173   // exported types.  The other types are not exported.  SIZES... is a
1174   // list of MAXP1-1 entries listing the size of the type definition
1175   // for each type, starting at index 1.
1176   char buf[100];
1177   snprintf(buf, sizeof buf, "types %d %d", this->type_index_,
1178 	   unexported_type_index);
1179   this->write_c_string(buf);
1180 
1181   // Start at 1 because type index 0 is not used.
1182   for (int i = 1; i < this->type_index_; ++i)
1183     {
1184       snprintf(buf, sizeof buf, " %lu",
1185 	       static_cast<unsigned long>(type_sizes[i]));
1186       this->write_c_string(buf);
1187     }
1188   this->write_c_string("\n");
1189   this->write_string(type_data.string());
1190 }
1191 
1192 // Write a single type to the export stream.
1193 
1194 void
write_type_definition(const Type * type,int index)1195 Export::write_type_definition(const Type* type, int index)
1196 {
1197   this->write_c_string("type ");
1198 
1199   char buf[30];
1200   snprintf(buf, sizeof buf, "%d ", index);
1201   this->write_c_string(buf);
1202 
1203   const Named_type* nt = type->named_type();
1204   if (nt != NULL)
1205     {
1206       const Named_object* no = nt->named_object();
1207       const Package* package = no->package();
1208 
1209       this->write_c_string("\"");
1210       if (package != NULL && !Gogo::is_hidden_name(no->name()))
1211 	{
1212 	  this->write_string(package->pkgpath());
1213 	  this->write_c_string(".");
1214 	}
1215       this->write_string(nt->named_object()->name());
1216       this->write_c_string("\" ");
1217 
1218       if (!nt->in_heap())
1219 	this->write_c_string("notinheap ");
1220 
1221       if (nt->is_alias())
1222 	this->write_c_string("= ");
1223     }
1224 
1225   type->export_type(this);
1226 
1227   // Type::export_type will print a newline for a named type, but not
1228   // otherwise.
1229   if (nt == NULL)
1230     this->write_c_string("\n");
1231 }
1232 
1233 // Write a name to the export stream.
1234 
1235 void
write_name(const std::string & name)1236 Export::write_name(const std::string& name)
1237 {
1238   if (name.empty())
1239     this->write_c_string("?");
1240   else
1241     this->write_string(Gogo::unpack_hidden_name(name));
1242 }
1243 
1244 // Write an integer value to the export stream.
1245 
1246 void
write_int(int value)1247 Export::write_int(int value)
1248 {
1249   char buf[100];
1250   snprintf(buf, sizeof buf, "%d", value);
1251   this->write_c_string(buf);
1252 }
1253 
1254 // Write an integer value to the export stream.
1255 
1256 void
write_unsigned(unsigned value)1257 Export::write_unsigned(unsigned value)
1258 {
1259   char buf[100];
1260   snprintf(buf, sizeof buf, "%u", value);
1261   this->write_c_string(buf);
1262 }
1263 
1264 // Return the index of a package.
1265 
1266 int
package_index(const Package * pkg) const1267 Export::package_index(const Package* pkg) const
1268 {
1269   Unordered_map(const Package *, int)::const_iterator p =
1270     this->packages_.find(pkg);
1271   go_assert(p != this->packages_.end());
1272   int index = p->second;
1273   go_assert(index != 0);
1274   return index;
1275 }
1276 
1277 // Return the index of a type.
1278 
1279 int
type_index(const Type * type)1280 Export::type_index(const Type* type)
1281 {
1282   type = type->forwarded();
1283   Type_refs::const_iterator p = this->impl_->type_refs.find(type);
1284   go_assert(p != this->impl_->type_refs.end());
1285   int index = p->second;
1286   go_assert(index != 0);
1287   return index;
1288 }
1289 
1290 // Export a type.
1291 
1292 void
write_type(const Type * type)1293 Export::write_type(const Type* type)
1294 {
1295   int index = this->type_index(type);
1296   char buf[30];
1297   snprintf(buf, sizeof buf, "<type %d>", index);
1298   this->write_c_string(buf);
1299 }
1300 
1301 // Export a type to a function body.
1302 
1303 void
write_type_to(const Type * type,Export_function_body * efb)1304 Export::write_type_to(const Type* type, Export_function_body* efb)
1305 {
1306   int index = this->type_index(type);
1307   char buf[30];
1308   snprintf(buf, sizeof buf, "<type %d>", index);
1309   efb->write_c_string(buf);
1310 }
1311 
1312 // Export escape note.
1313 
1314 void
write_escape(std::string * note)1315 Export::write_escape(std::string* note)
1316 {
1317   if (note != NULL && *note != "esc:0x0")
1318     {
1319       this->write_c_string(" ");
1320       char buf[50];
1321       go_assert(note->find("esc:") != std::string::npos);
1322       snprintf(buf, sizeof buf, "<%s>", note->c_str());
1323       this->write_c_string(buf);
1324     }
1325 }
1326 
1327 // Add the builtin types to the export table.
1328 
1329 void
register_builtin_types(Gogo * gogo)1330 Export::register_builtin_types(Gogo* gogo)
1331 {
1332   this->register_builtin_type(gogo, "int8", BUILTIN_INT8);
1333   this->register_builtin_type(gogo, "int16", BUILTIN_INT16);
1334   this->register_builtin_type(gogo, "int32", BUILTIN_INT32);
1335   this->register_builtin_type(gogo, "int64", BUILTIN_INT64);
1336   this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8);
1337   this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16);
1338   this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32);
1339   this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64);
1340   this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32);
1341   this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64);
1342   this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64);
1343   this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128);
1344   this->register_builtin_type(gogo, "int", BUILTIN_INT);
1345   this->register_builtin_type(gogo, "uint", BUILTIN_UINT);
1346   this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR);
1347   this->register_builtin_type(gogo, "bool", BUILTIN_BOOL);
1348   this->register_builtin_type(gogo, "string", BUILTIN_STRING);
1349   this->register_builtin_type(gogo, "error", BUILTIN_ERROR);
1350   this->register_builtin_type(gogo, "byte", BUILTIN_BYTE);
1351   this->register_builtin_type(gogo, "rune", BUILTIN_RUNE);
1352 }
1353 
1354 // Register one builtin type in the export table.
1355 
1356 void
register_builtin_type(Gogo * gogo,const char * name,Builtin_code code)1357 Export::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
1358 {
1359   Named_object* named_object = gogo->lookup_global(name);
1360   go_assert(named_object != NULL && named_object->is_type());
1361   std::pair<Type_refs::iterator, bool> ins =
1362     this->impl_->type_refs.insert(std::make_pair(named_object->type_value(), code));
1363   go_assert(ins.second);
1364 
1365   // We also insert the underlying type.  We can see the underlying
1366   // type at least for string and bool.  It's OK if this insert
1367   // fails--we expect duplications here, and it doesn't matter when
1368   // they occur.
1369   Type* real_type = named_object->type_value()->real_type();
1370   this->impl_->type_refs.insert(std::make_pair(real_type, code));
1371 }
1372 
1373 // Class Export::Stream.
1374 
Stream()1375 Export::Stream::Stream()
1376 {
1377   this->sha1_helper_ = go_create_sha1_helper();
1378   go_assert(this->sha1_helper_ != NULL);
1379 }
1380 
~Stream()1381 Export::Stream::~Stream()
1382 {
1383 }
1384 
1385 // Write bytes to the stream.  This keeps a checksum of bytes as they
1386 // go by.
1387 
1388 void
write_and_sum_bytes(const char * bytes,size_t length)1389 Export::Stream::write_and_sum_bytes(const char* bytes, size_t length)
1390 {
1391   this->sha1_helper_->process_bytes(bytes, length);
1392   this->do_write(bytes, length);
1393 }
1394 
1395 // Get the checksum.
1396 
1397 std::string
checksum()1398 Export::Stream::checksum()
1399 {
1400   std::string rval = this->sha1_helper_->finish();
1401   delete this->sha1_helper_;
1402   return rval;
1403 }
1404 
1405 // Write the checksum string to the export data.
1406 
1407 void
write_checksum(const std::string & s)1408 Export::Stream::write_checksum(const std::string& s)
1409 {
1410   this->do_write(s.data(), s.length());
1411 }
1412 
1413 // Class Stream_to_section.
1414 
Stream_to_section(Backend * backend)1415 Stream_to_section::Stream_to_section(Backend* backend)
1416     : backend_(backend)
1417 {
1418 }
1419 
1420 // Write data to a section.
1421 
1422 void
do_write(const char * bytes,size_t length)1423 Stream_to_section::do_write(const char* bytes, size_t length)
1424 {
1425   this->backend_->write_export_data (bytes, length);
1426 }
1427 
1428 // Class Export_function_body.
1429 
1430 // Record a temporary statement.
1431 
1432 unsigned int
record_temporary(const Temporary_statement * temp)1433 Export_function_body::record_temporary(const Temporary_statement* temp)
1434 {
1435   unsigned int ret = this->next_temporary_index_;
1436   if (ret > 0x7fffffff)
1437     go_error_at(temp->location(),
1438 		"too many temporary statements in export data");
1439   ++this->next_temporary_index_;
1440   std::pair<const Temporary_statement*, unsigned int> val(temp, ret);
1441   std::pair<Unordered_map(const Temporary_statement*, unsigned int)::iterator,
1442 	    bool> ins = this->temporary_indexes_.insert(val);
1443   go_assert(ins.second);
1444   return ret;
1445 }
1446 
1447 // Return the index of a temporary statement.
1448 
1449 unsigned int
temporary_index(const Temporary_statement * temp)1450 Export_function_body::temporary_index(const Temporary_statement* temp)
1451 {
1452   Unordered_map(const Temporary_statement*, unsigned int)::const_iterator p =
1453     this->temporary_indexes_.find(temp);
1454   go_assert(p != this->temporary_indexes_.end());
1455   return p->second;
1456 }
1457 
1458 // Return the index of an unnamed label.  If it doesn't already have
1459 // an index, give it one.
1460 
1461 unsigned int
unnamed_label_index(const Unnamed_label * label)1462 Export_function_body::unnamed_label_index(const Unnamed_label* label)
1463 {
1464   unsigned int next = this->next_label_index_;
1465   std::pair<const Unnamed_label*, unsigned int> val(label, next);
1466   std::pair<Unordered_map(const Unnamed_label*, unsigned int)::iterator,
1467 	    bool> ins =
1468     this->label_indexes_.insert(val);
1469   if (!ins.second)
1470     return ins.first->second;
1471   else
1472     {
1473       if (next > 0x7fffffff)
1474 	go_error_at(label->location(),
1475 		    "too many unnamed labels in export data");
1476       ++this->next_label_index_;
1477       return next;
1478     }
1479 }
1480