Branch data Line data Source code
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 : 2673210 : operator()(const Type* type) const
51 : : {
52 : 2673210 : 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 : 5622912 : operator()(const Type* t1, const Type* t2) const
65 : : {
66 : 5621963 : 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 : 4251 : struct Export_impl {
83 : : Type_refs type_refs;
84 : : };
85 : :
86 : : // Constructor.
87 : :
88 : 4251 : Export::Export(Stream* stream)
89 : 4251 : : stream_(stream), type_index_(1), packages_(), impl_(new Export_impl)
90 : : {
91 : 4251 : go_assert(Export::checksum_len == Go_sha1_helper::checksum_len);
92 : 4251 : }
93 : :
94 : : // Destructor.
95 : :
96 : 4251 : Export::~Export()
97 : : {
98 : 8502 : delete this->impl_;
99 : 4251 : }
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 : 4251 : 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 : 4251 : : Traverse(traverse_expressions
113 : : | traverse_types),
114 : 4251 : exp_(exp), packages_(packages), exports_(exports), imports_(imports),
115 : 4251 : 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 : 4251 : Collect_export_references::expand_exports(std::vector<Named_object*>* fcns)
176 : : {
177 : 4251 : this->inline_fcn_worklist_ = fcns;
178 : 49665 : while (!this->inline_fcn_worklist_->empty())
179 : : {
180 : 45414 : Named_object* no = this->inline_fcn_worklist_->back();
181 : 45414 : this->inline_fcn_worklist_->pop_back();
182 : 45414 : std::pair<Unordered_set(Named_object*)::iterator, bool> ins =
183 : 45414 : this->checked_functions_.insert(no);
184 : 45414 : if (ins.second)
185 : : {
186 : : // This traversal may add new objects to this->exports_ and new
187 : : // functions to this->inline_fcn_worklist_.
188 : 41215 : no->func_value()->block()->traverse(this);
189 : : }
190 : : }
191 : 4251 : this->inline_fcn_worklist_ = NULL;
192 : 4251 : this->exports_finalized_ = true;
193 : 4251 : }
194 : :
195 : : bool
196 : 53695 : Collect_export_references::add_to_exports(Named_object* no)
197 : : {
198 : 53695 : std::pair<Unordered_set(Named_object*)::iterator, bool> ins =
199 : 53695 : 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 : 53695 : go_assert(!this->exports_finalized_ || !ins.second);
203 : 53695 : return ins.second;
204 : : }
205 : :
206 : : int
207 : 615087 : Collect_export_references::expression(Expression** pexpr)
208 : : {
209 : 615087 : const Expression* expr = *pexpr;
210 : :
211 : 615087 : const Var_expression* ve = expr->var_expression();
212 : 615087 : if (ve != NULL)
213 : : {
214 : 208113 : Named_object* no = ve->named_object();
215 : 208113 : if (no->is_variable() && no->var_value()->is_global())
216 : : {
217 : 20936 : const Package* var_package = no->package();
218 : 20936 : if (var_package != NULL)
219 : 3489 : this->imports_->insert(var_package);
220 : :
221 : 20936 : this->add_to_exports(no);
222 : 20936 : no->var_value()->set_is_referenced_by_inline();
223 : : }
224 : 208113 : return TRAVERSE_CONTINUE;
225 : : }
226 : :
227 : 406974 : const Func_expression* fe = expr->func_expression();
228 : 406974 : if (fe != NULL)
229 : : {
230 : 59233 : Named_object* no = fe->named_object();
231 : :
232 : 59233 : const Package* func_package = fe->named_object()->package();
233 : 59233 : if (func_package != NULL)
234 : 19049 : this->imports_->insert(func_package);
235 : :
236 : 59233 : if (no->is_function_declaration()
237 : 59233 : && no->func_declaration_value()->type()->is_builtin())
238 : : return TRAVERSE_CONTINUE;
239 : :
240 : 42853 : if (this->inline_fcn_worklist_ != NULL)
241 : : {
242 : 32759 : bool added = this->add_to_exports(no);
243 : :
244 : 32759 : if (no->is_function())
245 : 17560 : 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 : 32759 : if (added
252 : 18211 : && no->is_function()
253 : 39847 : && no->func_value()->export_for_inlining())
254 : 4199 : this->inline_fcn_worklist_->push_back(no);
255 : : }
256 : :
257 : 42853 : return TRAVERSE_CONTINUE;
258 : : }
259 : :
260 : 347741 : const Named_object* nco = expr->named_constant();
261 : 347741 : if (nco != 0)
262 : : {
263 : 38151 : const Named_constant *nc = nco->const_value();
264 : 38151 : Type::traverse(nc->type(), this);
265 : 38151 : return TRAVERSE_CONTINUE;
266 : : }
267 : :
268 : 309590 : const Call_expression* call = expr->call_expression();
269 : 58801 : if (call != NULL)
270 : : {
271 : 58801 : const Builtin_call_expression* bce = call->builtin_call_expression();
272 : 16380 : if (bce != NULL
273 : 16380 : && (bce->code() == Builtin_call_expression::BUILTIN_ADD
274 : 16380 : || 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 : 0 : const std::map<std::string, Package*>::const_iterator p =
280 : 0 : this->packages_.find("unsafe");
281 : 0 : go_assert(p != this->packages_.end());
282 : 0 : 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 : 4251 : Collect_export_references::prepare_expressions(const std::vector<Named_object*>& sorted_exports)
296 : : {
297 : 111891 : for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin();
298 : 111891 : p != sorted_exports.end();
299 : 107640 : ++p)
300 : : {
301 : 107640 : Named_object* no = *p;
302 : 107640 : if (no->classification() == Named_object::NAMED_OBJECT_CONST)
303 : : {
304 : 39525 : Expression* e = no->const_value()->expr();
305 : 39525 : if (e != NULL)
306 : 39525 : Expression::traverse(&e, this);
307 : : }
308 : : }
309 : 4251 : }
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 : 4251 : 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 : 111891 : for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin();
321 : 111891 : p != sorted_exports.end();
322 : 107640 : ++p)
323 : : {
324 : 107640 : Named_object* no = *p;
325 : 107640 : switch (no->classification())
326 : : {
327 : 39525 : case Named_object::NAMED_OBJECT_CONST:
328 : 39525 : {
329 : 39525 : Type* t = no->const_value()->type();
330 : 39525 : if (t != NULL && !t->is_abstract())
331 : 15584 : Type::traverse(t, this);
332 : : }
333 : : break;
334 : :
335 : 11409 : case Named_object::NAMED_OBJECT_TYPE:
336 : 11409 : Type::traverse(no->type_value()->real_type(), this);
337 : 11409 : this->traverse_named_type(no->type_value());
338 : 11409 : break;
339 : :
340 : 8440 : case Named_object::NAMED_OBJECT_VAR:
341 : 8440 : Type::traverse(no->var_value()->type(), this);
342 : 8440 : break;
343 : :
344 : 36548 : case Named_object::NAMED_OBJECT_FUNC:
345 : 36548 : {
346 : 36548 : Function* fn = no->func_value();
347 : 36548 : this->traverse_function_type(fn->type());
348 : 36548 : if (fn->export_for_inlining())
349 : 9453 : fn->block()->traverse(this);
350 : : }
351 : : break;
352 : :
353 : 11718 : case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
354 : 11718 : this->traverse_function_type(no->func_declaration_value()->type());
355 : 11718 : 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 : 4251 : }
364 : :
365 : : // Record referenced type, record package imports, and make sure we traverse
366 : : // methods of named types.
367 : :
368 : : int
369 : 1018367 : Collect_export_references::type(Type* type)
370 : : {
371 : : // Skip forwarders; don't try to give them a type index.
372 : 1236857 : 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 : 769416 : if (type->is_void_type())
379 : : return TRAVERSE_SKIP_COMPONENTS;
380 : :
381 : : // Skip the nil type, turns up in function bodies.
382 : 768735 : 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 : 761403 : if (type->is_abstract())
388 : : return TRAVERSE_SKIP_COMPONENTS;
389 : :
390 : 700679 : 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 : 230048 : if (type->classification() == Type::TYPE_INTERFACE)
403 : : {
404 : 11558 : Interface_type* it = type->interface_type();
405 : 11558 : const Typed_identifier_list* methods = it->local_methods();
406 : 11558 : if (methods != NULL)
407 : : {
408 : 51537 : for (Typed_identifier_list::const_iterator p = methods->begin();
409 : 51537 : p != methods->end();
410 : 39979 : ++p)
411 : : {
412 : 39979 : if (p->name().empty())
413 : 2716 : Type::traverse(p->type(), this);
414 : : else
415 : 74526 : this->traverse_function_type(p->type()->function_type());
416 : : }
417 : : }
418 : 11558 : return TRAVERSE_SKIP_COMPONENTS;
419 : : }
420 : :
421 : 218490 : Named_type* nt = type->named_type();
422 : 218490 : if (nt != NULL)
423 : 73269 : this->traverse_named_type(nt);
424 : :
425 : : return TRAVERSE_CONTINUE;
426 : : }
427 : :
428 : : void
429 : 84678 : Collect_export_references::traverse_named_type(Named_type* nt)
430 : : {
431 : 84678 : const Package* package = nt->named_object()->package();
432 : 84678 : if (package != NULL)
433 : 59569 : 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 : 84678 : const Bindings* methods = nt->local_methods();
439 : 84678 : if (methods != NULL)
440 : : {
441 : 116892 : for (Bindings::const_definitions_iterator pm =
442 : 46965 : methods->begin_definitions();
443 : 116892 : pm != methods->end_definitions();
444 : 69927 : ++pm)
445 : : {
446 : 69927 : Function* fn = (*pm)->func_value();
447 : 69927 : this->traverse_function_type(fn->type());
448 : 69927 : if (fn->export_for_inlining())
449 : 9966 : fn->block()->traverse(this);
450 : : }
451 : :
452 : 407978 : for (Bindings::const_declarations_iterator pm =
453 : 46965 : methods->begin_declarations();
454 : 407978 : pm != methods->end_declarations();
455 : 361013 : ++pm)
456 : : {
457 : 361013 : Named_object* mno = pm->second;
458 : 361013 : if (mno->is_function_declaration())
459 : 291086 : this->traverse_function_type(mno->func_declaration_value()->type());
460 : : }
461 : : }
462 : 84678 : }
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 : 446542 : Collect_export_references::traverse_function_type(Function_type* type)
469 : : {
470 : 446542 : go_assert(type != NULL);
471 : 446542 : if (this->remember_type(type))
472 : : return;
473 : 446542 : const Typed_identifier* receiver = type->receiver();
474 : 446542 : if (receiver != NULL)
475 : 361013 : Type::traverse(receiver->type(), this);
476 : 446542 : const Typed_identifier_list* parameters = type->parameters();
477 : 446542 : if (parameters != NULL)
478 : 226217 : parameters->traverse(this);
479 : 446542 : const Typed_identifier_list* results = type->results();
480 : 446542 : if (results != NULL)
481 : 340938 : results->traverse(this);
482 : : }
483 : :
484 : : // Return true if we should export NO.
485 : :
486 : : static bool
487 : 450057 : should_export(Named_object* no)
488 : : {
489 : : // We only export objects which are locally defined.
490 : 450057 : if (no->package() != NULL)
491 : : return false;
492 : :
493 : : // We don't export packages.
494 : 417386 : if (no->is_package())
495 : : return false;
496 : :
497 : : // We don't export hidden names.
498 : 378055 : if (Gogo::is_hidden_name(no->name()))
499 : : return false;
500 : :
501 : : // We don't export various special functions.
502 : 164821 : if (Gogo::special_name_pos(no->name()) != std::string::npos)
503 : : return false;
504 : :
505 : : // Methods are exported with the type, not here.
506 : 116705 : if (no->is_function()
507 : 116705 : && no->func_value()->type()->is_method())
508 : : return false;
509 : 86028 : if (no->is_function_declaration()
510 : 86028 : && 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 : 86028 : 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 : 1463448 : operator()(const Named_object* n1, const Named_object* n2) const
532 : : {
533 : 1463448 : if (n1 == n2)
534 : : return false;
535 : :
536 : 1463448 : if (n1->package() != n2->package())
537 : : {
538 : 323669 : if (n1->package() == NULL)
539 : : return true;
540 : 281314 : if (n2->package() == NULL)
541 : : return false;
542 : :
543 : : // Make sure we don't see the same pkgpath twice.
544 : 255608 : const std::string& p1(n1->package()->pkgpath());
545 : 255608 : const std::string& p2(n2->package()->pkgpath());
546 : 255608 : go_assert(p1 != p2);
547 : :
548 : 255608 : return p1 < p2;
549 : : }
550 : :
551 : 1139779 : if (n1->name() != n2->name())
552 : 1139774 : 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 : 5 : go_assert(n1->is_type() && n2->is_type());
558 : :
559 : 5 : unsigned int ind1;
560 : 5 : const Named_object* g1 = n1->type_value()->in_function(&ind1);
561 : 5 : unsigned int ind2;
562 : 5 : const Named_object* g2 = n2->type_value()->in_function(&ind2);
563 : :
564 : 5 : if (g1 == NULL)
565 : : {
566 : 0 : go_assert(g2 != NULL);
567 : : return true;
568 : : }
569 : 5 : else if (g2 == NULL)
570 : : return false;
571 : 5 : else if (g1 == g2)
572 : : {
573 : 0 : go_assert(ind1 != ind2);
574 : 0 : return ind1 < ind2;
575 : : }
576 : 5 : else if ((g1->package() != g2->package()) || (g1->name() != g2->name()))
577 : 4 : return Sort_bindings()(g1, g2);
578 : : else
579 : : {
580 : : // This case can happen if g1 or g2 is a method.
581 : 1 : if (g1 != NULL && g1->func_value()->is_method())
582 : : {
583 : 1 : const Typed_identifier* r = g1->func_value()->type()->receiver();
584 : 1 : g1 = r->type()->named_type()->named_object();
585 : : }
586 : 1 : if (g2 != NULL && g2->func_value()->is_method())
587 : : {
588 : 1 : const Typed_identifier* r = g2->func_value()->type()->receiver();
589 : 1 : g2 = r->type()->named_type()->named_object();
590 : : }
591 : 1 : 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 : 1977228 : operator()(const Type* t1, const Type* t2) const
602 : : {
603 : 1977228 : t1 = t1->forwarded();
604 : 1977228 : t2 = t2->forwarded();
605 : :
606 : 1977228 : const Named_type* nt1 = t1->named_type();
607 : 1977228 : const Named_type* nt2 = t2->named_type();
608 : 1977228 : if (nt1 != NULL)
609 : : {
610 : 608089 : if (nt2 != NULL)
611 : : {
612 : 463141 : Sort_bindings sb;
613 : 463141 : return sb(nt1->named_object(), nt2->named_object());
614 : : }
615 : : else
616 : : return true;
617 : : }
618 : 1369139 : else if (nt2 != NULL)
619 : : return false;
620 : 1293642 : if (t1->classification() != t2->classification())
621 : 448366 : return t1->classification() < t2->classification();
622 : 845276 : Gogo* gogo = go_get_gogo();
623 : 845276 : Backend_name b1;
624 : 845276 : gogo->type_descriptor_backend_name(t1, NULL, &b1);
625 : 845276 : Backend_name b2;
626 : 845276 : gogo->type_descriptor_backend_name(t2, NULL, &b2);
627 : :
628 : 845276 : std::string n1 = b1.name();
629 : 845276 : std::string n2 = b2.name();
630 : 845276 : if (n1 != n2)
631 : 844808 : 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 : 468 : if (t1 == t2)
641 : : return false;
642 : :
643 : 468 : Sort_types sort;
644 : 468 : Type_alias_identical identical;
645 : 468 : go_assert(!identical(t1, t2));
646 : :
647 : 468 : switch (t1->classification())
648 : : {
649 : : case Type::TYPE_ERROR:
650 : : return false;
651 : :
652 : 0 : case Type::TYPE_VOID:
653 : 0 : case Type::TYPE_BOOLEAN:
654 : 0 : case Type::TYPE_INTEGER:
655 : 0 : case Type::TYPE_FLOAT:
656 : 0 : case Type::TYPE_COMPLEX:
657 : 0 : case Type::TYPE_STRING:
658 : 0 : case Type::TYPE_SINK:
659 : 0 : case Type::TYPE_NIL:
660 : 0 : case Type::TYPE_CALL_MULTIPLE_RESULT:
661 : 0 : case Type::TYPE_NAMED:
662 : 0 : case Type::TYPE_FORWARD:
663 : 0 : default:
664 : 0 : go_unreachable();
665 : :
666 : 22 : case Type::TYPE_FUNCTION:
667 : 22 : {
668 : 22 : const Function_type* ft1 = t1->function_type();
669 : 22 : const Function_type* ft2 = t2->function_type();
670 : 22 : const Typed_identifier* r1 = ft1->receiver();
671 : 22 : const Typed_identifier* r2 = ft2->receiver();
672 : 22 : if (r1 == NULL)
673 : 22 : go_assert(r2 == NULL);
674 : : else
675 : : {
676 : 0 : go_assert(r2 != NULL);
677 : 0 : const Type* rt1 = r1->type()->forwarded();
678 : 0 : const Type* rt2 = r2->type()->forwarded();
679 : 0 : if (!identical(rt1, rt2))
680 : 0 : return sort(rt1, rt2);
681 : : }
682 : :
683 : 22 : const Typed_identifier_list* p1 = ft1->parameters();
684 : 22 : const Typed_identifier_list* p2 = ft2->parameters();
685 : 22 : if (p1 == NULL || p1->empty())
686 : 3 : go_assert(p2 == NULL || p2->empty());
687 : : else
688 : : {
689 : 19 : go_assert(p2 != NULL && !p2->empty());
690 : 19 : int i = compare_til(p1, p2);
691 : 19 : if (i < 0)
692 : : return false;
693 : 10 : else if (i > 0)
694 : : return true;
695 : : }
696 : :
697 : 3 : p1 = ft1->results();
698 : 3 : p2 = ft2->results();
699 : 3 : if (p1 == NULL || p1->empty())
700 : 0 : go_assert(p2 == NULL || p2->empty());
701 : : else
702 : : {
703 : 3 : go_assert(p2 != NULL && !p2->empty());
704 : 3 : int i = compare_til(p1, p2);
705 : 3 : if (i < 0)
706 : : return false;
707 : 3 : else if (i > 0)
708 : : return true;
709 : : }
710 : :
711 : 0 : go_unreachable();
712 : : }
713 : :
714 : 172 : case Type::TYPE_POINTER:
715 : 172 : {
716 : 172 : const Type* p1 = t1->points_to()->forwarded();
717 : 172 : const Type* p2 = t2->points_to()->forwarded();
718 : 172 : go_assert(!identical(p1, p2));
719 : 172 : return sort(p1, p2);
720 : : }
721 : :
722 : 0 : case Type::TYPE_STRUCT:
723 : 0 : {
724 : 0 : const Struct_type* s1 = t1->struct_type();
725 : 0 : const Struct_type* s2 = t2->struct_type();
726 : 0 : const Struct_field_list* f1 = s1->fields();
727 : 0 : const Struct_field_list* f2 = s2->fields();
728 : 0 : go_assert(f1 != NULL && f2 != NULL);
729 : 0 : Struct_field_list::const_iterator p1 = f1->begin();
730 : 0 : Struct_field_list::const_iterator p2 = f2->begin();
731 : 0 : for (; p2 != f2->end(); ++p1, ++p2)
732 : : {
733 : 0 : go_assert(p1 != f1->end());
734 : 0 : go_assert(p1->field_name() == p2->field_name());
735 : 0 : go_assert(p1->is_anonymous() == p2->is_anonymous());
736 : 0 : const Type* ft1 = p1->type()->forwarded();
737 : 0 : const Type* ft2 = p2->type()->forwarded();
738 : 0 : if (!identical(ft1, ft2))
739 : 0 : return sort(ft1, ft2);
740 : : }
741 : 0 : go_assert(p1 == f1->end());
742 : 0 : go_unreachable();
743 : : }
744 : :
745 : 243 : case Type::TYPE_ARRAY:
746 : 243 : {
747 : 486 : const Type* e1 = t1->array_type()->element_type()->forwarded();
748 : 486 : const Type* e2 = t2->array_type()->element_type()->forwarded();
749 : 243 : go_assert(!identical(e1, e2));
750 : 243 : return sort(e1, e2);
751 : : }
752 : :
753 : 6 : case Type::TYPE_MAP:
754 : 6 : {
755 : 6 : const Map_type* m1 = t1->map_type();
756 : 6 : const Map_type* m2 = t2->map_type();
757 : 6 : const Type* k1 = m1->key_type()->forwarded();
758 : 6 : const Type* k2 = m2->key_type()->forwarded();
759 : 6 : if (!identical(k1, k2))
760 : 0 : return sort(k1, k2);
761 : 6 : const Type* v1 = m1->val_type()->forwarded();
762 : 6 : const Type* v2 = m2->val_type()->forwarded();
763 : 6 : go_assert(!identical(v1, v2));
764 : 6 : return sort(v1, v2);
765 : : }
766 : :
767 : 0 : case Type::TYPE_CHANNEL:
768 : 0 : {
769 : 0 : const Type* e1 = t1->channel_type()->element_type()->forwarded();
770 : 0 : const Type* e2 = t2->channel_type()->element_type()->forwarded();
771 : 0 : go_assert(!identical(e1, e2));
772 : 0 : return sort(e1, e2);
773 : : }
774 : :
775 : 25 : case Type::TYPE_INTERFACE:
776 : 25 : {
777 : 25 : const Interface_type* it1 = t1->interface_type();
778 : 25 : const Interface_type* it2 = t2->interface_type();
779 : 25 : const Typed_identifier_list* m1 = it1->local_methods();
780 : 25 : 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 : 25 : if (m1 == NULL || m1->empty())
787 : : {
788 : 0 : go_assert(m2 != NULL && !m2->empty());
789 : : return true;
790 : : }
791 : 25 : else if (m2 == NULL || m2->empty())
792 : : {
793 : : go_assert(m1 != NULL && !m1->empty());
794 : : return false;
795 : : }
796 : :
797 : 25 : int i = compare_til(m1, m2);
798 : 25 : if (i < 0)
799 : : return false;
800 : 2 : else if (i > 0)
801 : : return true;
802 : : else
803 : 0 : go_unreachable();
804 : : }
805 : : }
806 : 845276 : }
807 : : };
808 : :
809 : : // Compare Typed_identifier_list's with Sort_types, returning -1, 0, +1.
810 : :
811 : : static int
812 : 47 : compare_til(
813 : : const Typed_identifier_list* til1,
814 : : const Typed_identifier_list* til2)
815 : : {
816 : 47 : Type_alias_identical identical;
817 : 47 : Sort_types sort;
818 : 47 : Typed_identifier_list::const_iterator p1 = til1->begin();
819 : 47 : Typed_identifier_list::const_iterator p2 = til2->begin();
820 : 54 : for (; p2 != til2->end(); ++p1, ++p2)
821 : : {
822 : 54 : if (p1 == til1->end())
823 : : return -1;
824 : 54 : const Type* t1 = p1->type()->forwarded();
825 : 54 : const Type* t2 = p2->type()->forwarded();
826 : 54 : if (!identical(t1, t2))
827 : : {
828 : 47 : if (sort(t1, t2))
829 : : return -1;
830 : : else
831 : : return +1;
832 : : }
833 : : }
834 : 0 : if (p1 != til1->end())
835 : : return +1;
836 : : return 0;
837 : : }
838 : :
839 : : // Export those identifiers marked for exporting.
840 : :
841 : : void
842 : 4251 : 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 : 4251 : if (saw_errors())
856 : 0 : 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 : 4251 : Unordered_set(Named_object*) exports;
863 : 4251 : std::vector<Named_object*> check_inline_refs;
864 : 4251 : 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 : 45466 : for (Unordered_set(Named_object*)::const_iterator p = functions_marked_inline->begin();
869 : 45466 : p != functions_marked_inline->end();
870 : 41215 : ++p)
871 : 41215 : check_inline_refs.push_back(*p);
872 : :
873 : 450520 : for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
874 : 450520 : p != bindings->end_definitions();
875 : 446269 : ++p)
876 : : {
877 : 446269 : if (should_export(*p))
878 : 84720 : exports.insert(*p);
879 : : }
880 : :
881 : 335125 : for (Bindings::const_declarations_iterator p =
882 : 4251 : bindings->begin_declarations();
883 : 335125 : p != bindings->end_declarations();
884 : 330874 : ++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 : 330874 : if (p->second->is_function_declaration()
889 : 330874 : && should_export(p->second))
890 : 595 : exports.insert(p->second);
891 : : }
892 : :
893 : : // Track all imported packages mentioned in export data.
894 : 4251 : Unordered_set(const Package*) all_imports;
895 : :
896 : 4251 : 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 : 4251 : 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 : 4251 : std::vector<Named_object*> sorted_exports;
906 : 4251 : sorted_exports.reserve(exports.size());
907 : :
908 : 111891 : for (Unordered_set(Named_object*)::const_iterator p = exports.begin();
909 : 111891 : p != exports.end();
910 : 107640 : ++p)
911 : : {
912 : 107640 : sorted_exports.push_back(*p);
913 : :
914 : 107640 : const Package* pkg = (*p)->package();
915 : 107640 : if (pkg != NULL)
916 : 14575 : all_imports.insert(pkg);
917 : : }
918 : :
919 : 4251 : 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 : 4251 : collect.prepare_types(sorted_exports);
924 : 4251 : 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 : 4251 : 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 : 4251 : this->write_bytes(Export::cur_magic, Export::magic_len);
935 : :
936 : : // The package name.
937 : 4251 : this->write_c_string("package ");
938 : 4251 : this->write_string(package_name);
939 : 4251 : this->write_c_string("\n");
940 : :
941 : : // The prefix or package path, used for all global symbols.
942 : 4251 : if (prefix.empty())
943 : : {
944 : 3641 : go_assert(!pkgpath.empty());
945 : 3641 : this->write_c_string("pkgpath ");
946 : 3641 : this->write_string(pkgpath);
947 : : }
948 : : else
949 : : {
950 : 610 : this->write_c_string("prefix ");
951 : 610 : this->write_string(prefix);
952 : : }
953 : 4251 : this->write_c_string("\n");
954 : :
955 : 4251 : this->write_packages(packages);
956 : :
957 : 4251 : this->write_imports(imports, all_imports);
958 : :
959 : 4251 : 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 : 4251 : this->write_types(unexported_type_index);
968 : :
969 : : // Write out the non-type export data.
970 : 111891 : for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin();
971 : 111891 : p != sorted_exports.end();
972 : 107640 : ++p)
973 : : {
974 : 107640 : if (!(*p)->is_type())
975 : 96231 : (*p)->export_named_object(this);
976 : : }
977 : :
978 : 4251 : std::string checksum = this->stream_->checksum();
979 : 4251 : std::string s = "checksum ";
980 : 4251 : for (std::string::const_iterator p = checksum.begin();
981 : 89271 : p != checksum.end();
982 : 85020 : ++p)
983 : : {
984 : 85020 : unsigned char c = *p;
985 : 85020 : unsigned int dig = c >> 4;
986 : 85020 : s += dig < 10 ? '0' + dig : 'A' + dig - 10;
987 : 85020 : dig = c & 0xf;
988 : 170040 : s += dig < 10 ? '0' + dig : 'A' + dig - 10;
989 : : }
990 : 4251 : s += "\n";
991 : 4251 : this->stream_->write_checksum(s);
992 : 12753 : }
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 : 712088 : Export::record_type(Type* type)
999 : : {
1000 : 712088 : type = type->forwarded();
1001 : 712088 : std::pair<Type_refs::iterator, bool> ins =
1002 : 712088 : this->impl_->type_refs.insert(std::make_pair(type, 0));
1003 : 712088 : return ins.second;
1004 : : }
1005 : :
1006 : : // Assign the specified type an index.
1007 : :
1008 : : void
1009 : 233149 : Export::set_type_index(const Type* type)
1010 : : {
1011 : 233149 : type = type->forwarded();
1012 : 233149 : Type_refs::iterator p = this->impl_->type_refs.find(type);
1013 : 233149 : go_assert(p != this->impl_->type_refs.end());
1014 : 233149 : int index = this->type_index_;
1015 : 233149 : ++this->type_index_;
1016 : 233149 : go_assert(p->second == 0);
1017 : 233149 : p->second = index;
1018 : 233149 : }
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 : 4251 : Export::assign_type_indices(const std::vector<Named_object*>& sorted_exports)
1028 : : {
1029 : : // Assign indexes to all the exported types.
1030 : 111891 : for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin();
1031 : 111891 : p != sorted_exports.end();
1032 : 107640 : ++p)
1033 : : {
1034 : 107640 : if (!(*p)->is_type())
1035 : 96231 : continue;
1036 : 11409 : this->record_type((*p)->type_value());
1037 : 11409 : this->set_type_index((*p)->type_value());
1038 : : }
1039 : 4251 : int ret = this->type_index_;
1040 : :
1041 : : // Collect export-referenced, non-builtin types.
1042 : 4251 : std::vector<const Type*> types;
1043 : 4251 : types.reserve(this->impl_->type_refs.size());
1044 : 394687 : for (Type_refs::const_iterator p = this->impl_->type_refs.begin();
1045 : 394687 : p != this->impl_->type_refs.end();
1046 : 390436 : ++p)
1047 : : {
1048 : 390436 : const Type* t = p->first;
1049 : 390436 : if (p->second != 0)
1050 : 168696 : continue;
1051 : 221740 : types.push_back(t);
1052 : : }
1053 : :
1054 : : // Sort the types.
1055 : 4251 : std::sort(types.begin(), types.end(), Sort_types());
1056 : :
1057 : : // Assign numbers to the sorted list.
1058 : 225991 : for (std::vector<const Type *>::const_iterator p = types.begin();
1059 : 225991 : p != types.end();
1060 : 221740 : ++p)
1061 : 221740 : this->set_type_index((*p));
1062 : :
1063 : 4251 : return ret;
1064 : 4251 : }
1065 : :
1066 : : // Sort packages.
1067 : :
1068 : : static bool
1069 : 13871 : packages_compare(const Package* a, const Package* b)
1070 : : {
1071 : 13871 : if (a->package_name() < b->package_name())
1072 : : return true;
1073 : 7621 : else if (a->package_name() > b->package_name())
1074 : : return false;
1075 : :
1076 : 11 : if (a->pkgpath() < b->pkgpath())
1077 : : return true;
1078 : 10 : 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 : 0 : if (a->pkgpath_symbol() < b->pkgpath_symbol())
1084 : : return true;
1085 : 0 : else if (a->pkgpath_symbol() > b->pkgpath_symbol())
1086 : : return false;
1087 : :
1088 : 0 : 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 : 4251 : Export::write_packages(const std::map<std::string, Package*>& packages)
1097 : : {
1098 : : // Sort for consistent output.
1099 : 4251 : std::vector<Package*> out;
1100 : 116813 : for (std::map<std::string, Package*>::const_iterator p = packages.begin();
1101 : 116813 : p != packages.end();
1102 : 112562 : ++p)
1103 : : {
1104 : 112562 : if (p->second->pkgpath_symbol()
1105 : 225124 : != Gogo::pkgpath_for_symbol(p->second->pkgpath()))
1106 : 792 : out.push_back(p->second);
1107 : : }
1108 : :
1109 : 4251 : std::sort(out.begin(), out.end(), packages_compare);
1110 : :
1111 : 5043 : for (std::vector<Package*>::const_iterator p = out.begin();
1112 : 5043 : p != out.end();
1113 : 792 : ++p)
1114 : : {
1115 : 792 : this->write_c_string("package ");
1116 : 792 : this->write_string((*p)->package_name());
1117 : 792 : this->write_c_string(" ");
1118 : 792 : this->write_string((*p)->pkgpath());
1119 : 792 : this->write_c_string(" ");
1120 : 792 : this->write_string((*p)->pkgpath_symbol());
1121 : 792 : this->write_c_string("\n");
1122 : : }
1123 : 4251 : }
1124 : :
1125 : : // Sort imported packages.
1126 : :
1127 : : static bool
1128 : 48631 : import_compare(const std::pair<std::string, Package*>& a,
1129 : : const std::pair<std::string, Package*>& b)
1130 : : {
1131 : 48631 : return a.first < b.first;
1132 : : }
1133 : :
1134 : : // Write out the imported packages.
1135 : :
1136 : : void
1137 : 4251 : 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 : 4251 : Unordered_set(const Package*) seen;
1142 : 4251 : std::vector<std::pair<std::string, Package*> > sorted_imports;
1143 : 4251 : for (std::map<std::string, Package*>::const_iterator p = imports.begin();
1144 : 26076 : p != imports.end();
1145 : 21825 : ++p)
1146 : : {
1147 : 21825 : sorted_imports.push_back(std::make_pair(p->first, p->second));
1148 : 21825 : seen.insert(p->second);
1149 : : }
1150 : :
1151 : 4251 : std::sort(sorted_imports.begin(), sorted_imports.end(), import_compare);
1152 : :
1153 : 4251 : int package_index = 1;
1154 : 4251 : for (std::vector<std::pair<std::string, Package*> >::const_iterator p =
1155 : 4251 : sorted_imports.begin();
1156 : 26076 : p != sorted_imports.end();
1157 : 21825 : ++p)
1158 : : {
1159 : 21825 : this->write_c_string("import ");
1160 : 21825 : this->write_string(p->second->package_name());
1161 : 21825 : this->write_c_string(" ");
1162 : 21825 : this->write_string(p->second->pkgpath());
1163 : 21825 : this->write_c_string(" \"");
1164 : 21825 : this->write_string(p->first);
1165 : 21825 : this->write_c_string("\"\n");
1166 : :
1167 : 21825 : this->packages_[p->second] = package_index;
1168 : 21825 : package_index++;
1169 : : }
1170 : :
1171 : : // Write out a separate list of indirectly imported packages.
1172 : 4251 : std::vector<const Package*> indirect_imports;
1173 : 20567 : for (Unordered_set(const Package*)::const_iterator p =
1174 : 4251 : all_imports.begin();
1175 : 20567 : p != all_imports.end();
1176 : 16316 : ++p)
1177 : : {
1178 : 16316 : if (seen.find(*p) == seen.end())
1179 : 6385 : indirect_imports.push_back(*p);
1180 : : }
1181 : :
1182 : 4251 : std::sort(indirect_imports.begin(), indirect_imports.end(),
1183 : : packages_compare);
1184 : :
1185 : 4251 : for (std::vector<const Package*>::const_iterator p =
1186 : 4251 : indirect_imports.begin();
1187 : 10636 : p != indirect_imports.end();
1188 : 6385 : ++p)
1189 : : {
1190 : 6385 : this->write_c_string("indirectimport ");
1191 : 6385 : this->write_string((*p)->package_name());
1192 : 6385 : this->write_c_string(" ");
1193 : 6385 : this->write_string((*p)->pkgpath());
1194 : 6385 : this->write_c_string("\n");
1195 : :
1196 : 6385 : this->packages_[*p] = package_index;
1197 : 6385 : package_index++;
1198 : : }
1199 : 4251 : }
1200 : :
1201 : : void
1202 : 1268904 : Export::add_init_graph_edge(Init_graph* init_graph, unsigned src, unsigned sink)
1203 : : {
1204 : 1268904 : Init_graph::iterator it = init_graph->find(src);
1205 : 1268904 : if (it != init_graph->end())
1206 : 1179155 : it->second.insert(sink);
1207 : : else
1208 : : {
1209 : 89749 : std::set<unsigned> succs;
1210 : 89749 : succs.insert(sink);
1211 : 89749 : (*init_graph)[src] = succs;
1212 : 89749 : }
1213 : 1268904 : }
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 : 3549 : 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 : 162204 : for (Import_init_set::const_iterator p = imported_init_fns.begin();
1224 : 162204 : p != imported_init_fns.end();
1225 : 158655 : ++p)
1226 : : {
1227 : 158655 : const Import_init* ii = *p;
1228 : 158655 : if (ii->is_dummy())
1229 : 64560 : continue;
1230 : 94095 : std::map<std::string, unsigned>::const_iterator srcit =
1231 : 94095 : init_idx.find(ii->init_name());
1232 : 94095 : go_assert(srcit != init_idx.end());
1233 : 94095 : unsigned src = srcit->second;
1234 : 1313774 : for (std::set<std::string>::const_iterator pci = ii->precursors().begin();
1235 : 1313774 : pci != ii->precursors().end();
1236 : 1219679 : ++pci)
1237 : : {
1238 : 1219679 : std::map<std::string, unsigned>::const_iterator it =
1239 : 1219679 : init_idx.find(*pci);
1240 : 1219679 : go_assert(it != init_idx.end());
1241 : 1219679 : unsigned sink = it->second;
1242 : 1219679 : add_init_graph_edge(init_graph, src, sink);
1243 : : }
1244 : : }
1245 : 3549 : }
1246 : :
1247 : : // Write out the initialization functions which need to run for this
1248 : : // package.
1249 : :
1250 : : void
1251 : 4251 : 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 : 4943 : 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 : 4241 : std::map<std::string, unsigned> init_idx;
1259 : :
1260 : 4241 : this->write_c_string("init");
1261 : :
1262 : 4241 : if (!import_init_fn.empty())
1263 : : {
1264 : 2615 : this->write_c_string(" ");
1265 : 2615 : this->write_string(package_name);
1266 : 2615 : this->write_c_string(" ");
1267 : 2615 : this->write_string(import_init_fn);
1268 : 2615 : init_idx[import_init_fn] = 0;
1269 : : }
1270 : :
1271 : 4241 : if (imported_init_fns.empty())
1272 : : {
1273 : 692 : this->write_c_string("\n");
1274 : 692 : return;
1275 : : }
1276 : :
1277 : 3549 : typedef std::map<int, std::vector<std::string> > level_map;
1278 : 3549 : Init_graph init_graph;
1279 : 3549 : 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 : 162204 : for (Import_init_set::const_iterator p = imported_init_fns.begin();
1284 : 162204 : p != imported_init_fns.end();
1285 : 158655 : ++p)
1286 : : {
1287 : 158655 : const Import_init* ii = *p;
1288 : :
1289 : 158655 : if (ii->init_name() == import_init_fn)
1290 : 0 : continue;
1291 : :
1292 : 158655 : this->write_c_string(" ");
1293 : 158655 : this->write_string(ii->package_name());
1294 : 158655 : this->write_c_string(" ");
1295 : 158655 : this->write_string(ii->init_name());
1296 : :
1297 : : // Populate init_idx.
1298 : 158655 : go_assert(init_idx.find(ii->init_name()) == init_idx.end());
1299 : 158655 : unsigned idx = init_idx.size();
1300 : 158655 : 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 : 158655 : if (ii->priority() > 0)
1308 : : {
1309 : 0 : level_map::iterator it = inits_at_level.find(ii->priority());
1310 : 0 : if (it == inits_at_level.end())
1311 : : {
1312 : 0 : std::vector<std::string> l;
1313 : 0 : l.push_back(ii->init_name());
1314 : 0 : inits_at_level[ii->priority()] = l;
1315 : 0 : }
1316 : : else
1317 : 0 : it->second.push_back(ii->init_name());
1318 : : }
1319 : : }
1320 : 3549 : 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 : 3549 : 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 : 3549 : if (!import_init_fn.empty() && import_init_fn[0] != '~')
1329 : : {
1330 : 1403 : unsigned src = 0;
1331 : 1403 : go_assert(init_idx[import_init_fn] == 0);
1332 : 82137 : for (Import_init_set::const_iterator p = imported_init_fns.begin();
1333 : 82137 : p != imported_init_fns.end();
1334 : 80734 : ++p)
1335 : : {
1336 : 80734 : const Import_init* ii = *p;
1337 : 80734 : if (ii->is_dummy())
1338 : 31509 : continue;
1339 : 49225 : unsigned sink = init_idx[ii->init_name()];
1340 : 49225 : 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 : 3549 : if (inits_at_level.size() > 0)
1377 : : {
1378 : 0 : for (level_map::reverse_iterator it = inits_at_level.rbegin();
1379 : 0 : it != inits_at_level.rend(); ++it)
1380 : : {
1381 : 0 : int level = it->first;
1382 : 0 : if (level < 2) break;
1383 : 0 : const std::vector<std::string>& fcns_at_level = it->second;
1384 : 0 : for (std::vector<std::string>::const_iterator sit =
1385 : 0 : fcns_at_level.begin();
1386 : 0 : sit != fcns_at_level.end(); ++sit)
1387 : : {
1388 : 0 : unsigned src = init_idx[*sit];
1389 : 0 : level_map::iterator it2 = inits_at_level.find(level - 1);
1390 : 0 : if (it2 != inits_at_level.end())
1391 : : {
1392 : 0 : const std::vector<std::string> fcns_at_lm1 = it2->second;
1393 : 0 : for (std::vector<std::string>::const_iterator mit =
1394 : 0 : fcns_at_lm1.begin();
1395 : 0 : mit != fcns_at_lm1.end(); ++mit)
1396 : : {
1397 : 0 : unsigned sink = init_idx[*mit];
1398 : 0 : add_init_graph_edge(&init_graph, src, sink);
1399 : : }
1400 : 0 : }
1401 : : }
1402 : : }
1403 : : }
1404 : :
1405 : : // Write out the resulting graph.
1406 : 3549 : this->write_c_string("init_graph");
1407 : 93298 : for (Init_graph::const_iterator ki = init_graph.begin();
1408 : 93298 : ki != init_graph.end(); ++ki)
1409 : : {
1410 : 89749 : unsigned src = ki->first;
1411 : 89749 : const std::set<unsigned>& successors = ki->second;
1412 : 1358653 : for (std::set<unsigned>::const_iterator vi = successors.begin();
1413 : 1358653 : vi != successors.end(); ++vi)
1414 : : {
1415 : 1268904 : this->write_c_string(" ");
1416 : 1268904 : this->write_unsigned(src);
1417 : 1268904 : unsigned sink = (*vi);
1418 : 1268904 : this->write_c_string(" ");
1419 : 1268904 : this->write_unsigned(sink);
1420 : : }
1421 : : }
1422 : 3549 : this->write_c_string("\n");
1423 : 4241 : }
1424 : :
1425 : : // Write the types to the export stream.
1426 : :
1427 : : void
1428 : 4251 : Export::write_types(int unexported_type_index)
1429 : : {
1430 : : // Map from type index to type.
1431 : 4251 : std::vector<const Type*> types(static_cast<size_t>(this->type_index_));
1432 : 394687 : for (Type_refs::const_iterator p = this->impl_->type_refs.begin();
1433 : 394687 : p != this->impl_->type_refs.end();
1434 : 390436 : ++p)
1435 : : {
1436 : 390436 : if (p->second >= 0)
1437 : 233149 : types.at(p->second) = p->first;
1438 : : }
1439 : :
1440 : : // Write the type information to a buffer.
1441 : 4251 : Stream_to_string type_data;
1442 : 4251 : Export::Stream* orig_stream = this->stream_;
1443 : 4251 : this->stream_ = &type_data;
1444 : :
1445 : 4251 : std::vector<size_t> type_sizes(static_cast<size_t>(this->type_index_));
1446 : 4251 : type_sizes[0] = 0;
1447 : :
1448 : : // Start at 1 because type index 0 is not used.
1449 : 4251 : size_t start_size = 0;
1450 : 237400 : for (int i = 1; i < this->type_index_; ++i)
1451 : : {
1452 : 233149 : this->write_type_definition(types[i], i);
1453 : :
1454 : 233149 : size_t cur_size = type_data.string().size();
1455 : 233149 : type_sizes[i] = cur_size - start_size;
1456 : 233149 : start_size = cur_size;
1457 : : }
1458 : :
1459 : : // Back to original stream.
1460 : 4251 : 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 : 4251 : char buf[100];
1470 : 4251 : snprintf(buf, sizeof buf, "types %d %d", this->type_index_,
1471 : : unexported_type_index);
1472 : 4251 : this->write_c_string(buf);
1473 : :
1474 : : // Start at 1 because type index 0 is not used.
1475 : 237400 : for (int i = 1; i < this->type_index_; ++i)
1476 : : {
1477 : 233149 : snprintf(buf, sizeof buf, " %lu",
1478 : 233149 : static_cast<unsigned long>(type_sizes[i]));
1479 : 233149 : this->write_c_string(buf);
1480 : : }
1481 : 4251 : this->write_c_string("\n");
1482 : 4251 : this->write_string(type_data.string());
1483 : 4251 : }
1484 : :
1485 : : // Write a single type to the export stream.
1486 : :
1487 : : void
1488 : 233149 : Export::write_type_definition(const Type* type, int index)
1489 : : {
1490 : 233149 : this->write_c_string("type ");
1491 : :
1492 : 233149 : char buf[30];
1493 : 233149 : snprintf(buf, sizeof buf, "%d ", index);
1494 : 233149 : this->write_c_string(buf);
1495 : :
1496 : 233149 : const Named_type* nt = type->named_type();
1497 : 233149 : if (nt != NULL)
1498 : : {
1499 : 76370 : const Named_object* no = nt->named_object();
1500 : 76370 : const Package* package = no->package();
1501 : :
1502 : 76370 : this->write_c_string("\"");
1503 : 76370 : if (package != NULL && !Gogo::is_hidden_name(no->name()))
1504 : : {
1505 : 43013 : this->write_string(package->pkgpath());
1506 : 43013 : this->write_c_string(".");
1507 : : }
1508 : 76370 : this->write_string(nt->named_object()->name());
1509 : 76370 : this->write_c_string("\" ");
1510 : :
1511 : 76370 : if (!nt->in_heap())
1512 : 509 : this->write_c_string("notinheap ");
1513 : :
1514 : 76370 : if (nt->is_alias())
1515 : 1276 : this->write_c_string("= ");
1516 : : }
1517 : :
1518 : 233149 : type->export_type(this);
1519 : :
1520 : : // Type::export_type will print a newline for a named type, but not
1521 : : // otherwise.
1522 : 233149 : if (nt == NULL)
1523 : 156779 : this->write_c_string("\n");
1524 : 233149 : }
1525 : :
1526 : : // Write a name to the export stream.
1527 : :
1528 : : void
1529 : 857650 : Export::write_name(const std::string& name)
1530 : : {
1531 : 857650 : if (name.empty())
1532 : 102350 : this->write_c_string("?");
1533 : : else
1534 : 755300 : this->write_string(Gogo::unpack_hidden_name(name));
1535 : 857650 : }
1536 : :
1537 : : // Write an integer value to the export stream.
1538 : :
1539 : : void
1540 : 0 : Export::write_int(int value)
1541 : : {
1542 : 0 : char buf[100];
1543 : 0 : snprintf(buf, sizeof buf, "%d", value);
1544 : 0 : this->write_c_string(buf);
1545 : 0 : }
1546 : :
1547 : : // Write an integer value to the export stream.
1548 : :
1549 : : void
1550 : 2537808 : Export::write_unsigned(unsigned value)
1551 : : {
1552 : 2537808 : char buf[100];
1553 : 2537808 : snprintf(buf, sizeof buf, "%u", value);
1554 : 2537808 : this->write_c_string(buf);
1555 : 2537808 : }
1556 : :
1557 : : // Return the index of a package.
1558 : :
1559 : : int
1560 : 19275 : Export::package_index(const Package* pkg) const
1561 : : {
1562 : 19275 : Unordered_map(const Package *, int)::const_iterator p =
1563 : 19275 : this->packages_.find(pkg);
1564 : 19275 : go_assert(p != this->packages_.end());
1565 : 19275 : int index = p->second;
1566 : 19275 : go_assert(index != 0);
1567 : 19275 : return index;
1568 : : }
1569 : :
1570 : : // Return the index of the "unsafe" package.
1571 : :
1572 : : int
1573 : 0 : Export::unsafe_package_index() const
1574 : : {
1575 : 0 : for (Unordered_map(const Package*, int)::const_iterator p =
1576 : 0 : this->packages_.begin();
1577 : 0 : p != this->packages_.end();
1578 : 0 : ++p)
1579 : : {
1580 : 0 : if (p->first->pkgpath() == "unsafe")
1581 : : {
1582 : 0 : go_assert(p->second != 0);
1583 : 0 : return p->second;
1584 : : }
1585 : : }
1586 : 0 : go_unreachable();
1587 : : }
1588 : :
1589 : : // Return the index of a type.
1590 : :
1591 : : int
1592 : 1549431 : Export::type_index(const Type* type)
1593 : : {
1594 : 1549431 : type = type->forwarded();
1595 : 1549431 : Type_refs::const_iterator p = this->impl_->type_refs.find(type);
1596 : 1549431 : go_assert(p != this->impl_->type_refs.end());
1597 : 1549431 : int index = p->second;
1598 : 1549431 : go_assert(index != 0);
1599 : 1549431 : return index;
1600 : : }
1601 : :
1602 : : // Export a type.
1603 : :
1604 : : void
1605 : 1517966 : Export::write_type(const Type* type)
1606 : : {
1607 : 1517966 : int index = this->type_index(type);
1608 : 1517966 : char buf[30];
1609 : 1517966 : snprintf(buf, sizeof buf, "<type %d>", index);
1610 : 1517966 : this->write_c_string(buf);
1611 : 1517966 : }
1612 : :
1613 : : // Export a type to a function body.
1614 : :
1615 : : void
1616 : 31465 : Export::write_type_to(const Type* type, Export_function_body* efb)
1617 : : {
1618 : 31465 : int index = this->type_index(type);
1619 : 31465 : char buf[30];
1620 : 31465 : snprintf(buf, sizeof buf, "<type %d>", index);
1621 : 31465 : efb->write_c_string(buf);
1622 : 31465 : }
1623 : :
1624 : : // Export escape note.
1625 : :
1626 : : void
1627 : 783270 : Export::write_escape(std::string* note)
1628 : : {
1629 : 783270 : if (note != NULL && *note != "esc:0x0")
1630 : : {
1631 : 327776 : this->write_c_string(" ");
1632 : 327776 : char buf[50];
1633 : 327776 : go_assert(note->find("esc:") != std::string::npos);
1634 : 327776 : snprintf(buf, sizeof buf, "<%s>", note->c_str());
1635 : 327776 : this->write_c_string(buf);
1636 : : }
1637 : 783270 : }
1638 : :
1639 : : // Add the builtin types to the export table.
1640 : :
1641 : : void
1642 : 4251 : Export::register_builtin_types(Gogo* gogo)
1643 : : {
1644 : 4251 : this->register_builtin_type(gogo, "int8", BUILTIN_INT8);
1645 : 4251 : this->register_builtin_type(gogo, "int16", BUILTIN_INT16);
1646 : 4251 : this->register_builtin_type(gogo, "int32", BUILTIN_INT32);
1647 : 4251 : this->register_builtin_type(gogo, "int64", BUILTIN_INT64);
1648 : 4251 : this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8);
1649 : 4251 : this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16);
1650 : 4251 : this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32);
1651 : 4251 : this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64);
1652 : 4251 : this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32);
1653 : 4251 : this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64);
1654 : 4251 : this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64);
1655 : 4251 : this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128);
1656 : 4251 : this->register_builtin_type(gogo, "int", BUILTIN_INT);
1657 : 4251 : this->register_builtin_type(gogo, "uint", BUILTIN_UINT);
1658 : 4251 : this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR);
1659 : 4251 : this->register_builtin_type(gogo, "bool", BUILTIN_BOOL);
1660 : 4251 : this->register_builtin_type(gogo, "string", BUILTIN_STRING);
1661 : 4251 : this->register_builtin_type(gogo, "error", BUILTIN_ERROR);
1662 : 4251 : this->register_builtin_type(gogo, "byte", BUILTIN_BYTE);
1663 : 4251 : this->register_builtin_type(gogo, "rune", BUILTIN_RUNE);
1664 : 4251 : this->register_builtin_type(gogo, "any", BUILTIN_ANY);
1665 : 4251 : }
1666 : :
1667 : : // Register one builtin type in the export table.
1668 : :
1669 : : void
1670 : 89271 : Export::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
1671 : : {
1672 : 89271 : Named_object* named_object = gogo->lookup_global(name);
1673 : 89271 : go_assert(named_object != NULL && named_object->is_type());
1674 : 89271 : std::pair<Type_refs::iterator, bool> ins =
1675 : 89271 : this->impl_->type_refs.insert(std::make_pair(named_object->type_value(), code));
1676 : 89271 : go_assert(ins.second);
1677 : :
1678 : : // We also insert the underlying type. We can see the underlying
1679 : : // type at least for string and bool. It's OK if this insert
1680 : : // fails--we expect duplications here, and it doesn't matter when
1681 : : // they occur.
1682 : 89271 : Type* real_type = named_object->type_value()->real_type();
1683 : 89271 : this->impl_->type_refs.insert(std::make_pair(real_type, code));
1684 : 89271 : }
1685 : :
1686 : : // Class Export::Stream.
1687 : :
1688 : 8502 : Export::Stream::Stream()
1689 : : {
1690 : 8502 : this->sha1_helper_ = go_create_sha1_helper();
1691 : 8502 : go_assert(this->sha1_helper_ != NULL);
1692 : 8502 : }
1693 : :
1694 : 8502 : Export::Stream::~Stream()
1695 : : {
1696 : 8502 : }
1697 : :
1698 : : // Write bytes to the stream. This keeps a checksum of bytes as they
1699 : : // go by.
1700 : :
1701 : : void
1702 : 16237294 : Export::Stream::write_and_sum_bytes(const char* bytes, size_t length)
1703 : : {
1704 : 16237294 : this->sha1_helper_->process_bytes(bytes, length);
1705 : 16237294 : this->do_write(bytes, length);
1706 : 16237294 : }
1707 : :
1708 : : // Get the checksum.
1709 : :
1710 : : std::string
1711 : 4251 : Export::Stream::checksum()
1712 : : {
1713 : 4251 : std::string rval = this->sha1_helper_->finish();
1714 : 4251 : delete this->sha1_helper_;
1715 : 4251 : return rval;
1716 : : }
1717 : :
1718 : : // Write the checksum string to the export data.
1719 : :
1720 : : void
1721 : 4251 : Export::Stream::write_checksum(const std::string& s)
1722 : : {
1723 : 4251 : this->do_write(s.data(), s.length());
1724 : 4251 : }
1725 : :
1726 : : // Class Stream_to_section.
1727 : :
1728 : 4251 : Stream_to_section::Stream_to_section(Backend* backend)
1729 : 4251 : : backend_(backend)
1730 : : {
1731 : 4251 : }
1732 : :
1733 : : // Write data to a section.
1734 : :
1735 : : void
1736 : 7156723 : Stream_to_section::do_write(const char* bytes, size_t length)
1737 : : {
1738 : 7156723 : this->backend_->write_export_data (bytes, length);
1739 : 7156723 : }
1740 : :
1741 : : // Class Export_function_body.
1742 : :
1743 : : // Record a temporary statement.
1744 : :
1745 : : unsigned int
1746 : 4501 : Export_function_body::record_temporary(const Temporary_statement* temp)
1747 : : {
1748 : 4501 : unsigned int ret = this->next_temporary_index_;
1749 : 4501 : if (ret > 0x7fffffff)
1750 : 0 : go_error_at(temp->location(),
1751 : : "too many temporary statements in export data");
1752 : 4501 : ++this->next_temporary_index_;
1753 : 4501 : std::pair<const Temporary_statement*, unsigned int> val(temp, ret);
1754 : 4501 : std::pair<Unordered_map(const Temporary_statement*, unsigned int)::iterator,
1755 : 4501 : bool> ins = this->temporary_indexes_.insert(val);
1756 : 4501 : go_assert(ins.second);
1757 : 4501 : return ret;
1758 : : }
1759 : :
1760 : : // Return the index of a temporary statement.
1761 : :
1762 : : unsigned int
1763 : 6731 : Export_function_body::temporary_index(const Temporary_statement* temp)
1764 : : {
1765 : 6731 : Unordered_map(const Temporary_statement*, unsigned int)::const_iterator p =
1766 : 6731 : this->temporary_indexes_.find(temp);
1767 : 6731 : go_assert(p != this->temporary_indexes_.end());
1768 : 6731 : return p->second;
1769 : : }
1770 : :
1771 : : // Return the index of an unnamed label. If it doesn't already have
1772 : : // an index, give it one.
1773 : :
1774 : : unsigned int
1775 : 3344 : Export_function_body::unnamed_label_index(const Unnamed_label* label)
1776 : : {
1777 : 3344 : unsigned int next = this->next_label_index_;
1778 : 3344 : std::pair<const Unnamed_label*, unsigned int> val(label, next);
1779 : 3344 : std::pair<Unordered_map(const Unnamed_label*, unsigned int)::iterator,
1780 : : bool> ins =
1781 : 3344 : this->label_indexes_.insert(val);
1782 : 3344 : if (!ins.second)
1783 : 1703 : return ins.first->second;
1784 : : else
1785 : : {
1786 : 1641 : if (next > 0x7fffffff)
1787 : 0 : go_error_at(label->location(),
1788 : : "too many unnamed labels in export data");
1789 : 1641 : ++this->next_label_index_;
1790 : 1641 : return next;
1791 : : }
1792 : : }
|