github.com/ronhuafeng/gofrontend@v0.0.0-20220715151246-ff23266b8bc5/go/export.cc (about)

     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
    50    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
    64    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  
    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  
    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:
   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
   113                 | traverse_types),
   114        exp_(exp), packages_(packages), exports_(exports), imports_(imports),
   115        inline_fcn_worklist_(NULL), exports_finalized_(false)
   116    { }
   117  
   118    // Initial entry point; performs a walk to expand the exports set.
   119    void
   120    expand_exports(std::vector<Named_object*>* inlinable_functions);
   121  
   122    // Second entry point (called after the method above), to find
   123    // all types referenced by exports.
   124    void
   125    prepare_types(const std::vector<Named_object*>& sorted_exports);
   126  
   127    // Third entry point (called after the method above), to find
   128    // all types in expressions referenced by exports.
   129    void
   130    prepare_expressions(const std::vector<Named_object*>& sorted_exports);
   131  
   132   protected:
   133    // Override of parent class method.
   134    int
   135    expression(Expression**);
   136  
   137    // Override of parent class method.
   138    int
   139    type(Type* type);
   140  
   141    // Traverse the components of a function type.
   142    void
   143    traverse_function_type(Function_type*);
   144  
   145    // Traverse the methods of a named type, and register its package.
   146    void
   147    traverse_named_type(Named_type*);
   148  
   149   private:
   150  
   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,
   153    // FALSE otherwise.
   154    bool
   155    add_to_exports(Named_object*);
   156  
   157    // The exporter.
   158    Export* exp_;
   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
   168    // to be checked.
   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_;
   172  };
   173  
   174  void
   175  Collect_export_references::expand_exports(std::vector<Named_object*>* fcns)
   176  {
   177    this->inline_fcn_worklist_ = fcns;
   178    while (!this->inline_fcn_worklist_->empty())
   179      {
   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);
   184        if (ins.second)
   185  	{
   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);
   189  	}
   190      }
   191    this->inline_fcn_worklist_ = NULL;
   192    this->exports_finalized_ = true;
   193  }
   194  
   195  bool
   196  Collect_export_references::add_to_exports(Named_object* no)
   197  {
   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);
   203    return ins.second;
   204  }
   205  
   206  int
   207  Collect_export_references::expression(Expression** pexpr)
   208  {
   209    const Expression* expr = *pexpr;
   210  
   211    const Var_expression* ve = expr->var_expression();
   212    if (ve != NULL)
   213      {
   214        Named_object* no = ve->named_object();
   215        if (no->is_variable() && no->var_value()->is_global())
   216  	{
   217            const Package* var_package = no->package();
   218            if (var_package != NULL)
   219              this->imports_->insert(var_package);
   220  
   221  	  this->add_to_exports(no);
   222  	  no->var_value()->set_is_referenced_by_inline();
   223  	}
   224        return TRAVERSE_CONTINUE;
   225      }
   226  
   227    const Func_expression* fe = expr->func_expression();
   228    if (fe != NULL)
   229      {
   230        Named_object* no = fe->named_object();
   231  
   232        const Package* func_package = fe->named_object()->package();
   233        if (func_package != NULL)
   234          this->imports_->insert(func_package);
   235  
   236        if (no->is_function_declaration()
   237  	  && no->func_declaration_value()->type()->is_builtin())
   238  	return TRAVERSE_CONTINUE;
   239  
   240        if (this->inline_fcn_worklist_ != NULL)
   241          {
   242            bool added = this->add_to_exports(no);
   243  
   244            if (no->is_function())
   245              no->func_value()->set_is_referenced_by_inline();
   246  
   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.
   251            if (added
   252                && no->is_function()
   253                && no->func_value()->export_for_inlining())
   254              this->inline_fcn_worklist_->push_back(no);
   255          }
   256  
   257        return TRAVERSE_CONTINUE;
   258      }
   259  
   260    const Named_object* nco = expr->named_constant();
   261    if (nco != 0)
   262      {
   263        const Named_constant *nc = nco->const_value();
   264        Type::traverse(nc->type(), this);
   265        return TRAVERSE_CONTINUE;
   266      }
   267  
   268    const Call_expression* call = expr->call_expression();
   269    if (call != NULL)
   270      {
   271        const Builtin_call_expression* bce = call->builtin_call_expression();
   272        if (bce != NULL
   273  	  && (bce->code() == Builtin_call_expression::BUILTIN_ADD
   274  	      || bce->code() == Builtin_call_expression::BUILTIN_SLICE))
   275  	{
   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);
   283  	}
   284      }
   285  
   286    return TRAVERSE_CONTINUE;
   287  }
   288  
   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).
   293  
   294  void
   295  Collect_export_references::prepare_expressions(const std::vector<Named_object*>& sorted_exports)
   296  {
   297    for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin();
   298         p != sorted_exports.end();
   299         ++p)
   300      {
   301        Named_object* no = *p;
   302        if (no->classification() == Named_object::NAMED_OBJECT_CONST)
   303          {
   304            Expression* e = no->const_value()->expr();
   305            if (e != NULL)
   306              Expression::traverse(&e, this);
   307          }
   308      }
   309  }
   310  
   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).
   315  
   316  void
   317  Collect_export_references::prepare_types(const std::vector<Named_object*>& sorted_exports)
   318  {
   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();
   322         ++p)
   323      {
   324        Named_object* no = *p;
   325        switch (no->classification())
   326  	{
   327  	case Named_object::NAMED_OBJECT_CONST:
   328  	  {
   329  	    Type* t = no->const_value()->type();
   330  	    if (t != NULL && !t->is_abstract())
   331  	      Type::traverse(t, this);
   332  	  }
   333  	  break;
   334  
   335  	case Named_object::NAMED_OBJECT_TYPE:
   336  	  Type::traverse(no->type_value()->real_type(), this);
   337  	  this->traverse_named_type(no->type_value());
   338  	  break;
   339  
   340  	case Named_object::NAMED_OBJECT_VAR:
   341  	  Type::traverse(no->var_value()->type(), this);
   342  	  break;
   343  
   344  	case Named_object::NAMED_OBJECT_FUNC:
   345  	  {
   346  	    Function* fn = no->func_value();
   347  	    this->traverse_function_type(fn->type());
   348  	    if (fn->export_for_inlining())
   349  	      fn->block()->traverse(this);
   350  	  }
   351  	  break;
   352  
   353  	case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
   354  	  this->traverse_function_type(no->func_declaration_value()->type());
   355  	  break;
   356  
   357  	default:
   358  	  // We shouldn't see anything else.  If we do we'll give an
   359  	  // error later when we try to actually export it.
   360  	  break;
   361  	}
   362      }
   363  }
   364  
   365  // Record referenced type, record package imports, and make sure we traverse
   366  // methods of named types.
   367  
   368  int
   369  Collect_export_references::type(Type* type)
   370  {
   371    // Skip forwarders; don't try to give them a type index.
   372    if (type->forward_declaration_type() != NULL)
   373      return TRAVERSE_CONTINUE;
   374  
   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;
   380  
   381    // Skip the nil type, turns up in function bodies.
   382    if (type->is_nil_type())
   383      return TRAVERSE_SKIP_COMPONENTS;
   384  
   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;
   389  
   390    if (!this->exp_->record_type(type))
   391      {
   392        // We've already seen this type.
   393        return TRAVERSE_SKIP_COMPONENTS;
   394      }
   395  
   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
   401    // below.
   402    if (type->classification() == Type::TYPE_INTERFACE)
   403      {
   404        Interface_type* it = type->interface_type();
   405        const Typed_identifier_list* methods = it->local_methods();
   406        if (methods != NULL)
   407  	{
   408  	  for (Typed_identifier_list::const_iterator p = methods->begin();
   409  	       p != methods->end();
   410  	       ++p)
   411  	    {
   412  	      if (p->name().empty())
   413  		Type::traverse(p->type(), this);
   414  	      else
   415  		this->traverse_function_type(p->type()->function_type());
   416  	    }
   417  	}
   418        return TRAVERSE_SKIP_COMPONENTS;
   419      }
   420  
   421    Named_type* nt = type->named_type();
   422    if (nt != NULL)
   423      this->traverse_named_type(nt);
   424  
   425    return TRAVERSE_CONTINUE;
   426  }
   427  
   428  void
   429  Collect_export_references::traverse_named_type(Named_type* nt)
   430  {
   431    const Package* package = nt->named_object()->package();
   432    if (package != NULL)
   433      this->imports_->insert(package);
   434  
   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
   437    // traversal.
   438    const Bindings* methods = nt->local_methods();
   439    if (methods != NULL)
   440      {
   441        for (Bindings::const_definitions_iterator pm =
   442  	     methods->begin_definitions();
   443  	   pm != methods->end_definitions();
   444  	   ++pm)
   445  	{
   446  	  Function* fn = (*pm)->func_value();
   447  	  this->traverse_function_type(fn->type());
   448  	  if (fn->export_for_inlining())
   449  	    fn->block()->traverse(this);
   450  	}
   451  
   452        for (Bindings::const_declarations_iterator pm =
   453  	     methods->begin_declarations();
   454  	   pm != methods->end_declarations();
   455  	   ++pm)
   456  	{
   457  	  Named_object* mno = pm->second;
   458  	  if (mno->is_function_declaration())
   459  	    this->traverse_function_type(mno->func_declaration_value()->type());
   460  	}
   461      }
   462  }
   463  
   464  // Traverse the types in a function type.  We don't need the function
   465  // type itself, just the receiver, parameter, and result types.
   466  
   467  void
   468  Collect_export_references::traverse_function_type(Function_type* type)
   469  {
   470    go_assert(type != NULL);
   471    if (this->remember_type(type))
   472      return;
   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();
   480    if (results != NULL)
   481      results->traverse(this);
   482  }
   483  
   484  // Return true if we should export NO.
   485  
   486  static bool
   487  should_export(Named_object* no)
   488  {
   489    // We only export objects which are locally defined.
   490    if (no->package() != NULL)
   491      return false;
   492  
   493    // We don't export packages.
   494    if (no->is_package())
   495      return false;
   496  
   497    // We don't export hidden names.
   498    if (Gogo::is_hidden_name(no->name()))
   499      return false;
   500  
   501    // We don't export various special functions.
   502    if (Gogo::special_name_pos(no->name()) != std::string::npos)
   503      return false;
   504  
   505    // Methods are exported with the type, not here.
   506    if (no->is_function()
   507        && no->func_value()->type()->is_method())
   508      return false;
   509    if (no->is_function_declaration()
   510        && no->func_declaration_value()->type()->is_method())
   511      return false;
   512  
   513    // Don't export dummy global variables created for initializers when
   514    // used with sinks.
   515    if (no->is_variable() && no->name()[0] == '_' && no->name()[1] == '.')
   516      return false;
   517  
   518    return true;
   519  }
   520  
   521  // Compare Typed_identifier_list's.
   522  
   523  static int
   524  compare_til(const Typed_identifier_list*, const Typed_identifier_list*);
   525  
   526  // A functor to sort Named_object pointers by name.
   527  
   528  struct Sort_bindings
   529  {
   530    bool
   531    operator()(const Named_object* n1, const Named_object* n2) const
   532    {
   533      if (n1 == n2)
   534        return false;
   535  
   536      if (n1->package() != n2->package())
   537        {
   538  	if (n1->package() == NULL)
   539  	  return true;
   540  	if (n2->package() == NULL)
   541  	  return false;
   542  
   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());
   546  	go_assert(p1 != p2);
   547  
   548  	return p1 < p2;
   549        }
   550  
   551      if (n1->name() != n2->name())
   552        return n1->name() < n2->name();
   553  
   554      // We shouldn't see the same name twice, but it can happen for
   555      // nested type names.
   556  
   557      go_assert(n1->is_type() && n2->is_type());
   558  
   559      unsigned int ind1;
   560      const Named_object* g1 = n1->type_value()->in_function(&ind1);
   561      unsigned int ind2;
   562      const Named_object* g2 = n2->type_value()->in_function(&ind2);
   563  
   564      if (g1 == NULL)
   565        {
   566  	go_assert(g2 != NULL);
   567  	return true;
   568        }
   569      else if (g2 == NULL)
   570        return false;
   571      else if (g1 == g2)
   572        {
   573  	go_assert(ind1 != ind2);
   574  	return ind1 < ind2;
   575        }
   576      else if ((g1->package() != g2->package()) || (g1->name() != g2->name()))
   577        return Sort_bindings()(g1, g2);
   578      else
   579        {
   580  	// This case can happen if g1 or g2 is a method.
   581  	if (g1 != NULL && g1->func_value()->is_method())
   582  	  {
   583  	    const Typed_identifier* r = g1->func_value()->type()->receiver();
   584  	    g1 = r->type()->named_type()->named_object();
   585  	  }
   586  	if (g2 != NULL && g2->func_value()->is_method())
   587  	  {
   588  	    const Typed_identifier* r = g2->func_value()->type()->receiver();
   589  	    g2 = r->type()->named_type()->named_object();
   590  	  }
   591  	return Sort_bindings()(g1, g2);
   592        }
   593    }
   594  };
   595  
   596  // A functor to sort types for export.
   597  
   598  struct Sort_types
   599  {
   600    bool
   601    operator()(const Type* t1, const Type* t2) const
   602    {
   603      t1 = t1->forwarded();
   604      t2 = t2->forwarded();
   605  
   606      const Named_type* nt1 = t1->named_type();
   607      const Named_type* nt2 = t2->named_type();
   608      if (nt1 != NULL)
   609        {
   610  	if (nt2 != NULL)
   611  	  {
   612  	    Sort_bindings sb;
   613  	    return sb(nt1->named_object(), nt2->named_object());
   614  	  }
   615  	else
   616  	  return true;
   617        }
   618      else if (nt2 != NULL)
   619        return false;
   620      if (t1->classification() != t2->classification())
   621        return t1->classification() < t2->classification();
   622      Gogo* gogo = go_get_gogo();
   623      Backend_name b1;
   624      gogo->type_descriptor_backend_name(t1, NULL, &b1);
   625      Backend_name b2;
   626      gogo->type_descriptor_backend_name(t2, NULL, &b2);
   627  
   628      std::string n1 = b1.name();
   629      std::string n2 = b2.name();
   630      if (n1 != n2)
   631        return n1 < n2;
   632  
   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.
   638  
   639      // t1 == t2 in case std::sort compares elements to themselves.
   640      if (t1 == t2)
   641        return false;
   642  
   643      Sort_types sort;
   644      Type_alias_identical identical;
   645      go_assert(!identical(t1, t2));
   646  
   647      switch (t1->classification())
   648        {
   649        case Type::TYPE_ERROR:
   650  	return false;
   651  
   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:
   659        case Type::TYPE_NIL:
   660        case Type::TYPE_CALL_MULTIPLE_RESULT:
   661        case Type::TYPE_NAMED:
   662        case Type::TYPE_FORWARD:
   663        default:
   664  	go_unreachable();
   665  
   666        case Type::TYPE_FUNCTION:
   667  	{
   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();
   672  	  if (r1 == NULL)
   673  	    go_assert(r2 == NULL);
   674  	  else
   675  	    {
   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);
   681  	    }
   682  
   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());
   687  	  else
   688  	    {
   689  	      go_assert(p2 != NULL && !p2->empty());
   690  	      int i = compare_til(p1, p2);
   691  	      if (i < 0)
   692  		return false;
   693  	      else if (i > 0)
   694  		return true;
   695  	    }
   696  
   697  	  p1 = ft1->results();
   698  	  p2 = ft2->results();
   699  	  if (p1 == NULL || p1->empty())
   700  	    go_assert(p2 == NULL || p2->empty());
   701  	  else
   702  	    {
   703  	      go_assert(p2 != NULL && !p2->empty());
   704  	      int i = compare_til(p1, p2);
   705  	      if (i < 0)
   706  		return false;
   707  	      else if (i > 0)
   708  		return true;
   709  	    }
   710  
   711  	  go_unreachable();
   712  	}
   713  
   714        case Type::TYPE_POINTER:
   715  	{
   716  	  const Type* p1 = t1->points_to()->forwarded();
   717  	  const Type* p2 = t2->points_to()->forwarded();
   718  	  go_assert(!identical(p1, p2));
   719  	  return sort(p1, p2);
   720  	}
   721  
   722        case Type::TYPE_STRUCT:
   723  	{
   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)
   732  	    {
   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);
   740  	    }
   741  	  go_assert(p1 == f1->end());
   742  	  go_unreachable();
   743  	}
   744  
   745        case Type::TYPE_ARRAY:
   746  	{
   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));
   750  	  return sort(e1, e2);
   751  	}
   752  
   753        case Type::TYPE_MAP:
   754  	{
   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))
   760  	    return sort(k1, k2);
   761  	  const Type* v1 = m1->val_type()->forwarded();
   762  	  const Type* v2 = m2->val_type()->forwarded();
   763  	  go_assert(!identical(v1, v2));
   764  	  return sort(v1, v2);
   765  	}
   766  
   767        case Type::TYPE_CHANNEL:
   768  	{
   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));
   772  	  return sort(e1, e2);
   773  	}
   774  
   775        case Type::TYPE_INTERFACE:
   776  	{
   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();
   781  
   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())
   787  	    {
   788  	      go_assert(m2 != NULL && !m2->empty());
   789  	      return true;
   790  	    }
   791  	  else if (m2 == NULL || m2->empty())
   792  	    {
   793  	      go_assert(m1 != NULL && !m1->empty());
   794  	      return false;
   795  	    }
   796  
   797  	  int i = compare_til(m1, m2);
   798  	  if (i < 0)
   799  	    return false;
   800  	  else if (i > 0)
   801  	    return true;
   802  	  else
   803  	    go_unreachable();
   804  	}
   805        }
   806    }
   807  };
   808  
   809  // Compare Typed_identifier_list's with Sort_types, returning -1, 0, +1.
   810  
   811  static int
   812  compare_til(
   813      const Typed_identifier_list* til1,
   814      const Typed_identifier_list* til2)
   815  {
   816    Type_alias_identical identical;
   817    Sort_types sort;
   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)
   821      {
   822        if (p1 == til1->end())
   823  	return -1;
   824        const Type* t1 = p1->type()->forwarded();
   825        const Type* t2 = p2->type()->forwarded();
   826        if (!identical(t1, t2))
   827  	{
   828  	  if (sort(t1, t2))
   829  	    return -1;
   830  	  else
   831  	    return +1;
   832  	}
   833      }
   834    if (p1 != til1->end())
   835      return +1;
   836    return 0;
   837  }
   838  
   839  // Export those identifiers marked for exporting.
   840  
   841  void
   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)
   851  {
   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.
   855    if (saw_errors())
   856      return;
   857  
   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());
   865  
   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();
   870         ++p)
   871        check_inline_refs.push_back(*p);
   872  
   873    for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
   874         p != bindings->end_definitions();
   875         ++p)
   876      {
   877        if (should_export(*p))
   878          exports.insert(*p);
   879      }
   880  
   881    for (Bindings::const_declarations_iterator p =
   882  	 bindings->begin_declarations();
   883         p != bindings->end_declarations();
   884         ++p)
   885      {
   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);
   891      }
   892  
   893    // Track all imported packages mentioned in export data.
   894    Unordered_set(const Package*) all_imports;
   895  
   896    Collect_export_references collect(this, packages, &exports, &all_imports);
   897  
   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);
   901  
   902    // Export the symbols in sorted order.  That will reduce cases where
   903    // irrelevant changes to the source code affect the exported
   904    // interface.
   905    std::vector<Named_object*> sorted_exports;
   906    sorted_exports.reserve(exports.size());
   907  
   908    for (Unordered_set(Named_object*)::const_iterator p = exports.begin();
   909         p != exports.end();
   910         ++p)
   911      {
   912        sorted_exports.push_back(*p);
   913  
   914        const Package* pkg = (*p)->package();
   915        if (pkg != NULL)
   916  	all_imports.insert(pkg);
   917      }
   918  
   919    std::sort(sorted_exports.begin(), sorted_exports.end(), Sort_bindings());
   920  
   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);
   925  
   926    // Assign indexes to all exported types and types referenced by
   927    // things we're exporting.  Return value is index of first non-exported
   928    // type.
   929    int unexported_type_index = this->assign_type_indices(sorted_exports);
   930  
   931    // Although the export data is readable, at least this version is,
   932    // it is conceptually a binary format.  Start with a four byte
   933    // version number.
   934    this->write_bytes(Export::cur_magic, Export::magic_len);
   935  
   936    // The package name.
   937    this->write_c_string("package ");
   938    this->write_string(package_name);
   939    this->write_c_string("\n");
   940  
   941    // The prefix or package path, used for all global symbols.
   942    if (prefix.empty())
   943      {
   944        go_assert(!pkgpath.empty());
   945        this->write_c_string("pkgpath ");
   946        this->write_string(pkgpath);
   947      }
   948    else
   949      {
   950        this->write_c_string("prefix ");
   951        this->write_string(prefix);
   952      }
   953    this->write_c_string("\n");
   954  
   955    this->write_packages(packages);
   956  
   957    this->write_imports(imports, all_imports);
   958  
   959    this->write_imported_init_fns(package_name, import_init_fn,
   960  				imported_init_fns);
   961  
   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.
   965  
   966    // Write out all the types, both exported and not.
   967    this->write_types(unexported_type_index);
   968  
   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();
   972         ++p)
   973      {
   974        if (!(*p)->is_type())
   975  	(*p)->export_named_object(this);
   976      }
   977  
   978    std::string checksum = this->stream_->checksum();
   979    std::string s = "checksum ";
   980    for (std::string::const_iterator p = checksum.begin();
   981         p != checksum.end();
   982         ++p)
   983      {
   984        unsigned char c = *p;
   985        unsigned int dig = c >> 4;
   986        s += dig < 10 ? '0' + dig : 'A' + dig - 10;
   987        dig = c & 0xf;
   988        s += dig < 10 ? '0' + dig : 'A' + dig - 10;
   989      }
   990    s += "\n";
   991    this->stream_->write_checksum(s);
   992  }
   993  
   994  // Record a type in the "to be indexed" set. Return true if the type
   995  // was not already in the set, false otherwise.
   996  
   997  bool
   998  Export::record_type(Type* type)
   999  {
  1000    type = type->forwarded();
  1001    std::pair<Type_refs::iterator, bool> ins =
  1002      this->impl_->type_refs.insert(std::make_pair(type, 0));
  1003    return ins.second;
  1004  }
  1005  
  1006  // Assign the specified type an index.
  1007  
  1008  void
  1009  Export::set_type_index(const Type* type)
  1010  {
  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);
  1017    p->second = index;
  1018  }
  1019  
  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.
  1025  
  1026  int
  1027  Export::assign_type_indices(const std::vector<Named_object*>& sorted_exports)
  1028  {
  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();
  1032         ++p)
  1033      {
  1034        if (!(*p)->is_type())
  1035  	continue;
  1036        this->record_type((*p)->type_value());
  1037        this->set_type_index((*p)->type_value());
  1038      }
  1039    int ret = this->type_index_;
  1040  
  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();
  1046         ++p)
  1047      {
  1048        const Type* t = p->first;
  1049        if (p->second != 0)
  1050          continue;
  1051        types.push_back(t);
  1052      }
  1053  
  1054    // Sort the types.
  1055    std::sort(types.begin(), types.end(), Sort_types());
  1056  
  1057    // Assign numbers to the sorted list.
  1058    for (std::vector<const Type *>::const_iterator p = types.begin();
  1059         p != types.end();
  1060         ++p)
  1061      this->set_type_index((*p));
  1062  
  1063    return ret;
  1064  }
  1065  
  1066  // Sort packages.
  1067  
  1068  static bool
  1069  packages_compare(const Package* a, const Package* b)
  1070  {
  1071    if (a->package_name() < b->package_name())
  1072      return true;
  1073    else if (a->package_name() > b->package_name())
  1074      return false;
  1075  
  1076    if (a->pkgpath() < b->pkgpath())
  1077      return true;
  1078    else if (a->pkgpath() > b->pkgpath())
  1079      return false;
  1080  
  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())
  1084      return true;
  1085    else if (a->pkgpath_symbol() > b->pkgpath_symbol())
  1086      return false;
  1087  
  1088    return a < b;
  1089  }
  1090  
  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.
  1094  
  1095  void
  1096  Export::write_packages(const std::map<std::string, Package*>& packages)
  1097  {
  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();
  1102         ++p)
  1103      {
  1104        if (p->second->pkgpath_symbol()
  1105  	  != Gogo::pkgpath_for_symbol(p->second->pkgpath()))
  1106  	out.push_back(p->second);
  1107      }
  1108  
  1109    std::sort(out.begin(), out.end(), packages_compare);
  1110  
  1111    for (std::vector<Package*>::const_iterator p = out.begin();
  1112         p != out.end();
  1113         ++p)
  1114      {
  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");
  1122      }
  1123  }
  1124  
  1125  // Sort imported packages.
  1126  
  1127  static bool
  1128  import_compare(const std::pair<std::string, Package*>& a,
  1129  	       const std::pair<std::string, Package*>& b)
  1130  {
  1131    return a.first < b.first;
  1132  }
  1133  
  1134  // Write out the imported packages.
  1135  
  1136  void
  1137  Export::write_imports(const std::map<std::string, Package*>& imports,
  1138  		      const Unordered_set(const Package*)& all_imports)
  1139  {
  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();
  1144         p != imports.end();
  1145         ++p)
  1146      {
  1147        sorted_imports.push_back(std::make_pair(p->first, p->second));
  1148        seen.insert(p->second);
  1149      }
  1150  
  1151    std::sort(sorted_imports.begin(), sorted_imports.end(), import_compare);
  1152  
  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();
  1157         ++p)
  1158      {
  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");
  1166  
  1167        this->packages_[p->second] = package_index;
  1168        package_index++;
  1169      }
  1170  
  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();
  1176         ++p)
  1177      {
  1178        if (seen.find(*p) == seen.end())
  1179  	indirect_imports.push_back(*p);
  1180      }
  1181  
  1182    std::sort(indirect_imports.begin(), indirect_imports.end(),
  1183  	    packages_compare);
  1184  
  1185    for (std::vector<const Package*>::const_iterator p =
  1186  	 indirect_imports.begin();
  1187         p != indirect_imports.end();
  1188         ++p)
  1189      {
  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");
  1195  
  1196        this->packages_[*p] = package_index;
  1197        package_index++;
  1198      }
  1199  }
  1200  
  1201  void
  1202  Export::add_init_graph_edge(Init_graph* init_graph, unsigned src, unsigned sink)
  1203  {
  1204    Init_graph::iterator it = init_graph->find(src);
  1205    if (it != init_graph->end())
  1206      it->second.insert(sink);
  1207    else
  1208      {
  1209        std::set<unsigned> succs;
  1210        succs.insert(sink);
  1211        (*init_graph)[src] = succs;
  1212      }
  1213  }
  1214  
  1215  // Constructs the imported portion of the init graph, e.g. those
  1216  // edges that we read from imported packages.
  1217  
  1218  void
  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)
  1222  {
  1223    for (Import_init_set::const_iterator p = imported_init_fns.begin();
  1224         p != imported_init_fns.end();
  1225         ++p)
  1226      {
  1227        const Import_init* ii = *p;
  1228        if (ii->is_dummy())
  1229          continue;
  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();
  1236             ++pci)
  1237  	{
  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);
  1243  	}
  1244      }
  1245  }
  1246  
  1247  // Write out the initialization functions which need to run for this
  1248  // package.
  1249  
  1250  void
  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)
  1254  {
  1255    if (import_init_fn.empty() && imported_init_fns.empty()) return;
  1256  
  1257    // Maps a given init function to the its index in the exported "init" clause.
  1258    std::map<std::string, unsigned> init_idx;
  1259  
  1260    this->write_c_string("init");
  1261  
  1262    if (!import_init_fn.empty())
  1263      {
  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;
  1269      }
  1270  
  1271    if (imported_init_fns.empty())
  1272      {
  1273        this->write_c_string("\n");
  1274        return;
  1275      }
  1276  
  1277    typedef std::map<int, std::vector<std::string> > level_map;
  1278    Init_graph init_graph;
  1279    level_map inits_at_level;
  1280  
  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();
  1285         ++p)
  1286      {
  1287        const Import_init* ii = *p;
  1288  
  1289        if (ii->init_name() == import_init_fn)
  1290  	continue;
  1291  
  1292        this->write_c_string(" ");
  1293        this->write_string(ii->package_name());
  1294        this->write_c_string(" ");
  1295        this->write_string(ii->init_name());
  1296  
  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;
  1301  
  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)
  1308  	{
  1309  	  level_map::iterator it = inits_at_level.find(ii->priority());
  1310  	  if (it == inits_at_level.end())
  1311  	    {
  1312  	      std::vector<std::string> l;
  1313  	      l.push_back(ii->init_name());
  1314  	      inits_at_level[ii->priority()] = l;
  1315  	    }
  1316  	  else
  1317  	    it->second.push_back(ii->init_name());
  1318  	}
  1319      }
  1320    this->write_c_string("\n");
  1321  
  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);
  1325  
  1326    // Now add edges from the local init function to each of the
  1327    // imported fcns.
  1328    if (!import_init_fn.empty() && import_init_fn[0] != '~')
  1329      {
  1330        unsigned src = 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();
  1334             ++p)
  1335  	{
  1336            const Import_init* ii = *p;
  1337            if (ii->is_dummy())
  1338              continue;
  1339  	  unsigned sink = init_idx[ii->init_name()];
  1340  	  add_init_graph_edge(&init_graph, src, sink);
  1341  	}
  1342      }
  1343  
  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:
  1348    //
  1349    //       *A
  1350    //       /|
  1351    //      / |
  1352    //     B  *C
  1353    //       /|
  1354    //      / |
  1355    //    *D *E
  1356    //     | /|
  1357    //     |/ |
  1358    //    *F  *G
  1359    //
  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
  1366    //
  1367    //   init F F..import 1 G G..import 1 D D..import 2 E E..import 2;
  1368    //
  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.
  1375  
  1376    if (inits_at_level.size() > 0)
  1377      {
  1378        for (level_map::reverse_iterator it = inits_at_level.rbegin();
  1379             it != inits_at_level.rend(); ++it)
  1380  	{
  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)
  1387  	    {
  1388  	      unsigned src = init_idx[*sit];
  1389  	      level_map::iterator it2 = inits_at_level.find(level - 1);
  1390  	      if (it2 != inits_at_level.end())
  1391  		{
  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)
  1396  		    {
  1397  		      unsigned sink = init_idx[*mit];
  1398  		      add_init_graph_edge(&init_graph, src, sink);
  1399  		    }
  1400  		}
  1401  	    }
  1402  	}
  1403      }
  1404  
  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)
  1409      {
  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)
  1414  	{
  1415  	  this->write_c_string(" ");
  1416  	  this->write_unsigned(src);
  1417  	  unsigned sink = (*vi);
  1418  	  this->write_c_string(" ");
  1419  	  this->write_unsigned(sink);
  1420  	}
  1421      }
  1422    this->write_c_string("\n");
  1423  }
  1424  
  1425  // Write the types to the export stream.
  1426  
  1427  void
  1428  Export::write_types(int unexported_type_index)
  1429  {
  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();
  1434         ++p)
  1435      {
  1436        if (p->second >= 0)
  1437  	types.at(p->second) = p->first;
  1438      }
  1439  
  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;
  1444  
  1445    std::vector<size_t> type_sizes(static_cast<size_t>(this->type_index_));
  1446    type_sizes[0] = 0;
  1447  
  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)
  1451      {
  1452        this->write_type_definition(types[i], i);
  1453  
  1454        size_t cur_size = type_data.string().size();
  1455        type_sizes[i] = cur_size - start_size;
  1456        start_size = cur_size;
  1457      }
  1458  
  1459    // Back to original stream.
  1460    this->stream_ = orig_stream;
  1461  
  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.
  1469    char buf[100];
  1470    snprintf(buf, sizeof buf, "types %d %d", this->type_index_,
  1471  	   unexported_type_index);
  1472    this->write_c_string(buf);
  1473  
  1474    // Start at 1 because type index 0 is not used.
  1475    for (int i = 1; i < this->type_index_; ++i)
  1476      {
  1477        snprintf(buf, sizeof buf, " %lu",
  1478  	       static_cast<unsigned long>(type_sizes[i]));
  1479        this->write_c_string(buf);
  1480      }
  1481    this->write_c_string("\n");
  1482    this->write_string(type_data.string());
  1483  }
  1484  
  1485  // Write a single type to the export stream.
  1486  
  1487  void
  1488  Export::write_type_definition(const Type* type, int index)
  1489  {
  1490    this->write_c_string("type ");
  1491  
  1492    char buf[30];
  1493    snprintf(buf, sizeof buf, "%d ", index);
  1494    this->write_c_string(buf);
  1495  
  1496    const Named_type* nt = type->named_type();
  1497    if (nt != NULL)
  1498      {
  1499        const Named_object* no = nt->named_object();
  1500        const Package* package = no->package();
  1501  
  1502        this->write_c_string("\"");
  1503        if (package != NULL && !Gogo::is_hidden_name(no->name()))
  1504  	{
  1505  	  this->write_string(package->pkgpath());
  1506  	  this->write_c_string(".");
  1507  	}
  1508        this->write_string(nt->named_object()->name());
  1509        this->write_c_string("\" ");
  1510  
  1511        if (!nt->in_heap())
  1512  	this->write_c_string("notinheap ");
  1513  
  1514        if (nt->is_alias())
  1515  	this->write_c_string("= ");
  1516      }
  1517  
  1518    type->export_type(this);
  1519  
  1520    // Type::export_type will print a newline for a named type, but not
  1521    // otherwise.
  1522    if (nt == NULL)
  1523      this->write_c_string("\n");
  1524  }
  1525  
  1526  // Write a name to the export stream.
  1527  
  1528  void
  1529  Export::write_name(const std::string& name)
  1530  {
  1531    if (name.empty())
  1532      this->write_c_string("?");
  1533    else
  1534      this->write_string(Gogo::unpack_hidden_name(name));
  1535  }
  1536  
  1537  // Write an integer value to the export stream.
  1538  
  1539  void
  1540  Export::write_int(int value)
  1541  {
  1542    char buf[100];
  1543    snprintf(buf, sizeof buf, "%d", value);
  1544    this->write_c_string(buf);
  1545  }
  1546  
  1547  // Write an integer value to the export stream.
  1548  
  1549  void
  1550  Export::write_unsigned(unsigned value)
  1551  {
  1552    char buf[100];
  1553    snprintf(buf, sizeof buf, "%u", value);
  1554    this->write_c_string(buf);
  1555  }
  1556  
  1557  // Return the index of a package.
  1558  
  1559  int
  1560  Export::package_index(const Package* pkg) const
  1561  {
  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);
  1567    return index;
  1568  }
  1569  
  1570  // Return the index of the "unsafe" package.
  1571  
  1572  int
  1573  Export::unsafe_package_index() const
  1574  {
  1575    for (Unordered_map(const Package*, int)::const_iterator p =
  1576  	 this->packages_.begin();
  1577         p != this->packages_.end();
  1578         ++p)
  1579      {
  1580        if (p->first->pkgpath() == "unsafe")
  1581  	{
  1582  	  go_assert(p->second != 0);
  1583  	  return p->second;
  1584  	}
  1585      }
  1586    go_unreachable();
  1587  }
  1588  
  1589  // Return the index of a type.
  1590  
  1591  int
  1592  Export::type_index(const Type* type)
  1593  {
  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);
  1599    return index;
  1600  }
  1601  
  1602  // Export a type.
  1603  
  1604  void
  1605  Export::write_type(const Type* type)
  1606  {
  1607    int index = this->type_index(type);
  1608    char buf[30];
  1609    snprintf(buf, sizeof buf, "<type %d>", index);
  1610    this->write_c_string(buf);
  1611  }
  1612  
  1613  // Export a type to a function body.
  1614  
  1615  void
  1616  Export::write_type_to(const Type* type, Export_function_body* efb)
  1617  {
  1618    int index = this->type_index(type);
  1619    char buf[30];
  1620    snprintf(buf, sizeof buf, "<type %d>", index);
  1621    efb->write_c_string(buf);
  1622  }
  1623  
  1624  // Export escape note.
  1625  
  1626  void
  1627  Export::write_escape(std::string* note)
  1628  {
  1629    if (note != NULL && *note != "esc:0x0")
  1630      {
  1631        this->write_c_string(" ");
  1632        char buf[50];
  1633        go_assert(note->find("esc:") != std::string::npos);
  1634        snprintf(buf, sizeof buf, "<%s>", note->c_str());
  1635        this->write_c_string(buf);
  1636      }
  1637  }
  1638  
  1639  // Add the builtin types to the export table.
  1640  
  1641  void
  1642  Export::register_builtin_types(Gogo* gogo)
  1643  {
  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  }
  1665  
  1666  // Register one builtin type in the export table.
  1667  
  1668  void
  1669  Export::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
  1670  {
  1671    Named_object* named_object = gogo->lookup_global(name);
  1672    go_assert(named_object != NULL && named_object->is_type());
  1673    std::pair<Type_refs::iterator, bool> ins =
  1674      this->impl_->type_refs.insert(std::make_pair(named_object->type_value(), code));
  1675    go_assert(ins.second);
  1676  
  1677    // We also insert the underlying type.  We can see the underlying
  1678    // type at least for string and bool.  It's OK if this insert
  1679    // fails--we expect duplications here, and it doesn't matter when
  1680    // they occur.
  1681    Type* real_type = named_object->type_value()->real_type();
  1682    this->impl_->type_refs.insert(std::make_pair(real_type, code));
  1683  }
  1684  
  1685  // Class Export::Stream.
  1686  
  1687  Export::Stream::Stream()
  1688  {
  1689    this->sha1_helper_ = go_create_sha1_helper();
  1690    go_assert(this->sha1_helper_ != NULL);
  1691  }
  1692  
  1693  Export::Stream::~Stream()
  1694  {
  1695  }
  1696  
  1697  // Write bytes to the stream.  This keeps a checksum of bytes as they
  1698  // go by.
  1699  
  1700  void
  1701  Export::Stream::write_and_sum_bytes(const char* bytes, size_t length)
  1702  {
  1703    this->sha1_helper_->process_bytes(bytes, length);
  1704    this->do_write(bytes, length);
  1705  }
  1706  
  1707  // Get the checksum.
  1708  
  1709  std::string
  1710  Export::Stream::checksum()
  1711  {
  1712    std::string rval = this->sha1_helper_->finish();
  1713    delete this->sha1_helper_;
  1714    return rval;
  1715  }
  1716  
  1717  // Write the checksum string to the export data.
  1718  
  1719  void
  1720  Export::Stream::write_checksum(const std::string& s)
  1721  {
  1722    this->do_write(s.data(), s.length());
  1723  }
  1724  
  1725  // Class Stream_to_section.
  1726  
  1727  Stream_to_section::Stream_to_section(Backend* backend)
  1728      : backend_(backend)
  1729  {
  1730  }
  1731  
  1732  // Write data to a section.
  1733  
  1734  void
  1735  Stream_to_section::do_write(const char* bytes, size_t length)
  1736  {
  1737    this->backend_->write_export_data (bytes, length);
  1738  }
  1739  
  1740  // Class Export_function_body.
  1741  
  1742  // Record a temporary statement.
  1743  
  1744  unsigned int
  1745  Export_function_body::record_temporary(const Temporary_statement* temp)
  1746  {
  1747    unsigned int ret = this->next_temporary_index_;
  1748    if (ret > 0x7fffffff)
  1749      go_error_at(temp->location(),
  1750  		"too many temporary statements in export data");
  1751    ++this->next_temporary_index_;
  1752    std::pair<const Temporary_statement*, unsigned int> val(temp, ret);
  1753    std::pair<Unordered_map(const Temporary_statement*, unsigned int)::iterator,
  1754  	    bool> ins = this->temporary_indexes_.insert(val);
  1755    go_assert(ins.second);
  1756    return ret;
  1757  }
  1758  
  1759  // Return the index of a temporary statement.
  1760  
  1761  unsigned int
  1762  Export_function_body::temporary_index(const Temporary_statement* temp)
  1763  {
  1764    Unordered_map(const Temporary_statement*, unsigned int)::const_iterator p =
  1765      this->temporary_indexes_.find(temp);
  1766    go_assert(p != this->temporary_indexes_.end());
  1767    return p->second;
  1768  }
  1769  
  1770  // Return the index of an unnamed label.  If it doesn't already have
  1771  // an index, give it one.
  1772  
  1773  unsigned int
  1774  Export_function_body::unnamed_label_index(const Unnamed_label* label)
  1775  {
  1776    unsigned int next = this->next_label_index_;
  1777    std::pair<const Unnamed_label*, unsigned int> val(label, next);
  1778    std::pair<Unordered_map(const Unnamed_label*, unsigned int)::iterator,
  1779  	    bool> ins =
  1780      this->label_indexes_.insert(val);
  1781    if (!ins.second)
  1782      return ins.first->second;
  1783    else
  1784      {
  1785        if (next > 0x7fffffff)
  1786  	go_error_at(label->location(),
  1787  		    "too many unnamed labels in export data");
  1788        ++this->next_label_index_;
  1789        return next;
  1790      }
  1791  }