OSDN Git Service

compiler: List imported packages in export information.
[pf3gnuchains/gcc-fork.git] / gcc / go / gofrontend / export.cc
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 "sha1.h"
10
11 #include "go-c.h"
12
13 #include "gogo.h"
14 #include "types.h"
15 #include "statements.h"
16 #include "export.h"
17
18 // This file handles exporting global declarations.
19
20 // Class Export.
21
22 // Version 1 magic number.
23
24 const int Export::v1_magic_len;
25
26 const char Export::v1_magic[Export::v1_magic_len] =
27   {
28     'v', '1', ';', '\n'
29   };
30
31 const int Export::v1_checksum_len;
32
33 // Constructor.
34
35 Export::Export(Stream* stream)
36   : stream_(stream), type_refs_(), type_index_(1)
37 {
38 }
39
40 // A functor to sort Named_object pointers by name.
41
42 struct Sort_bindings
43 {
44   bool
45   operator()(const Named_object* n1, const Named_object* n2) const
46   { return n1->name() < n2->name(); }
47 };
48
49 // Return true if we should export NO.
50
51 static bool
52 should_export(Named_object* no)
53 {
54   // We only export objects which are locally defined.
55   if (no->package() != NULL)
56     return false;
57
58   // We don't export packages.
59   if (no->is_package())
60     return false;
61
62   // We don't export hidden names.
63   if (Gogo::is_hidden_name(no->name()))
64     return false;
65
66   // We don't export nested functions.
67   if (no->is_function() && no->func_value()->enclosing() != NULL)
68     return false;
69
70   // We don't export thunks.
71   if (no->is_function() && Gogo::is_thunk(no))
72     return false;
73
74   // Methods are exported with the type, not here.
75   if (no->is_function()
76       && no->func_value()->type()->is_method())
77     return false;
78   if (no->is_function_declaration()
79       && no->func_declaration_value()->type()->is_method())
80     return false;
81
82   // Don't export dummy global variables created for initializers when
83   // used with sinks.
84   if (no->is_variable() && no->name()[0] == '_' && no->name()[1] == '.')
85     return false;
86
87   return true;
88 }
89
90 // Export those identifiers marked for exporting.
91
92 void
93 Export::export_globals(const std::string& package_name,
94                        const std::string& unique_prefix,
95                        int package_priority,
96                        const std::map<std::string, Package*>& imports,
97                        const std::string& import_init_fn,
98                        const std::set<Import_init>& imported_init_fns,
99                        const Bindings* bindings)
100 {
101   // If there have been any errors so far, don't try to export
102   // anything.  That way the export code doesn't have to worry about
103   // mismatched types or other confusions.
104   if (saw_errors())
105     return;
106
107   // Export the symbols in sorted order.  That will reduce cases where
108   // irrelevant changes to the source code affect the exported
109   // interface.
110   std::vector<Named_object*> exports;
111   exports.reserve(bindings->size_definitions());
112
113   for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
114        p != bindings->end_definitions();
115        ++p)
116     if (should_export(*p))
117       exports.push_back(*p);
118
119   for (Bindings::const_declarations_iterator p =
120          bindings->begin_declarations();
121        p != bindings->end_declarations();
122        ++p)
123     {
124       // We export a function declaration as it may be implemented in
125       // supporting C code.  We do not export type declarations.
126       if (p->second->is_function_declaration()
127           && should_export(p->second))
128         exports.push_back(p->second);
129     }
130
131   std::sort(exports.begin(), exports.end(), Sort_bindings());
132
133   // Although the export data is readable, at least this version is,
134   // it is conceptually a binary format.  Start with a four byte
135   // verison number.
136   this->write_bytes(Export::v1_magic, Export::v1_magic_len);
137
138   // The package name.
139   this->write_c_string("package ");
140   this->write_string(package_name);
141   this->write_c_string(";\n");
142
143   // The unique prefix.  This prefix is used for all global symbols.
144   this->write_c_string("prefix ");
145   this->write_string(unique_prefix);
146   this->write_c_string(";\n");
147
148   // The package priority.
149   char buf[100];
150   snprintf(buf, sizeof buf, "priority %d;\n", package_priority);
151   this->write_c_string(buf);
152
153   this->write_imports(imports);
154
155   this->write_imported_init_fns(package_name, package_priority, import_init_fn,
156                                 imported_init_fns);
157
158   // FIXME: It might be clever to add something about the processor
159   // and ABI being used, although ideally any problems in that area
160   // would be caught by the linker.
161
162   for (std::vector<Named_object*>::const_iterator p = exports.begin();
163        p != exports.end();
164        ++p)
165     (*p)->export_named_object(this);
166
167   std::string checksum = this->stream_->checksum();
168   std::string s = "checksum ";
169   for (std::string::const_iterator p = checksum.begin();
170        p != checksum.end();
171        ++p)
172     {
173       unsigned char c = *p;
174       unsigned int dig = c >> 4;
175       s += dig < 10 ? '0' + dig : 'A' + dig - 10;
176       dig = c & 0xf;
177       s += dig < 10 ? '0' + dig : 'A' + dig - 10;
178     }
179   s += ";\n";
180   this->stream_->write_checksum(s);
181 }
182
183 // Sort imported packages.
184
185 static bool
186 import_compare(const std::pair<std::string, Package*>& a,
187                const std::pair<std::string, Package*>& b)
188 {
189   return a.first < b.first;
190 }
191
192 // Write out the imported packages.
193
194 void
195 Export::write_imports(const std::map<std::string, Package*>& imports)
196 {
197   // Sort the imports for more consistent output.
198   std::vector<std::pair<std::string, Package*> > imp;
199   for (std::map<std::string, Package*>::const_iterator p = imports.begin();
200        p != imports.end();
201        ++p)
202     imp.push_back(std::make_pair(p->first, p->second));
203
204   std::sort(imp.begin(), imp.end(), import_compare);
205
206   for (std::vector<std::pair<std::string, Package*> >::const_iterator p =
207          imp.begin();
208        p != imp.end();
209        ++p)
210     {
211       this->write_c_string("import ");
212       this->write_string(p->second->name());
213       this->write_c_string(" ");
214       this->write_string(p->second->unique_prefix());
215       this->write_c_string(" \"");
216       this->write_string(p->first);
217       this->write_c_string("\";\n");
218     }
219 }
220
221 // Write out the initialization functions which need to run for this
222 // package.
223
224 void
225 Export::write_imported_init_fns(
226     const std::string& package_name,
227     int priority,
228     const std::string& import_init_fn,
229     const std::set<Import_init>& imported_init_fns)
230 {
231   if (import_init_fn.empty() && imported_init_fns.empty())
232     return;
233
234   this->write_c_string("init");
235
236   if (!import_init_fn.empty())
237     {
238       this->write_c_string(" ");
239       this->write_string(package_name);
240       this->write_c_string(" ");
241       this->write_string(import_init_fn);
242       char buf[100];
243       snprintf(buf, sizeof buf, " %d", priority);
244       this->write_c_string(buf);
245     }
246
247   if (!imported_init_fns.empty())
248     {
249       // Sort the list of functions for more consistent output.
250       std::vector<Import_init> v;
251       for (std::set<Import_init>::const_iterator p = imported_init_fns.begin();
252            p != imported_init_fns.end();
253            ++p)
254         v.push_back(*p);
255       std::sort(v.begin(), v.end());
256
257       for (std::vector<Import_init>::const_iterator p = v.begin();
258            p != v.end();
259            ++p)
260         {
261           this->write_c_string(" ");
262           this->write_string(p->package_name());
263           this->write_c_string(" ");
264           this->write_string(p->init_name());
265           char buf[100];
266           snprintf(buf, sizeof buf, " %d", p->priority());
267           this->write_c_string(buf);
268         }
269     }
270
271   this->write_c_string(";\n");
272 }
273
274 // Write a name to the export stream.
275
276 void
277 Export::write_name(const std::string& name)
278 {
279   if (name.empty())
280     this->write_c_string("?");
281   else
282     this->write_string(Gogo::message_name(name));
283 }
284
285 // Export a type.  We have to ensure that on import we create a single
286 // Named_type node for each named type.  We do this by keeping a hash
287 // table mapping named types to reference numbers.  The first time we
288 // see a named type we assign it a reference number by making an entry
289 // in the hash table.  If we see it again, we just refer to the
290 // reference number.
291
292 // Named types are, of course, associated with packages.  Note that we
293 // may see a named type when importing one package, and then later see
294 // the same named type when importing a different package.  The home
295 // package may or may not be imported during this compilation.  The
296 // reference number scheme has to get this all right.  Basic approach
297 // taken from "On the Linearization of Graphs and Writing Symbol
298 // Files" by Robert Griesemer.
299
300 void
301 Export::write_type(const Type* type)
302 {
303   // We don't want to assign a reference number to a forward
304   // declaration to a type which was defined later.
305   type = type->forwarded();
306
307   Type_refs::const_iterator p = this->type_refs_.find(type);
308   if (p != this->type_refs_.end())
309     {
310       // This type was already in the table.
311       int index = p->second;
312       go_assert(index != 0);
313       char buf[30];
314       snprintf(buf, sizeof buf, "<type %d>", index);
315       this->write_c_string(buf);
316       return;
317     }
318
319   const Named_type* named_type = type->named_type();
320   const Forward_declaration_type* forward = type->forward_declaration_type();
321
322   int index = this->type_index_;
323   ++this->type_index_;
324
325   char buf[30];
326   snprintf(buf, sizeof buf, "<type %d ", index);
327   this->write_c_string(buf);
328
329   if (named_type != NULL || forward != NULL)
330     {
331       const Named_object* named_object;
332       if (named_type != NULL)
333         {
334           // The builtin types should have been predefined.
335           go_assert(!Linemap::is_predeclared_location(named_type->location())
336                      || (named_type->named_object()->package()->name()
337                          == "unsafe"));
338           named_object = named_type->named_object();
339         }
340       else
341         named_object = forward->named_object();
342
343       const Package* package = named_object->package();
344
345       std::string s = "\"";
346       if (package != NULL && !Gogo::is_hidden_name(named_object->name()))
347         {
348           s += package->unique_prefix();
349           s += '.';
350           s += package->name();
351           s += '.';
352         }
353       s += named_object->name();
354       s += "\" ";
355       this->write_string(s);
356
357       // We must add a named type to the table now, since the
358       // definition of the type may refer to the named type via a
359       // pointer.
360       this->type_refs_[type] = index;
361     }
362
363   type->export_type(this);
364
365   this->write_c_string(">");
366
367   if (named_type == NULL)
368     this->type_refs_[type] = index;
369 }
370
371 // Add the builtin types to the export table.
372
373 void
374 Export::register_builtin_types(Gogo* gogo)
375 {
376   this->register_builtin_type(gogo, "int8", BUILTIN_INT8);
377   this->register_builtin_type(gogo, "int16", BUILTIN_INT16);
378   this->register_builtin_type(gogo, "int32", BUILTIN_INT32);
379   this->register_builtin_type(gogo, "int64", BUILTIN_INT64);
380   this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8);
381   this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16);
382   this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32);
383   this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64);
384   this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32);
385   this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64);
386   this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64);
387   this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128);
388   this->register_builtin_type(gogo, "int", BUILTIN_INT);
389   this->register_builtin_type(gogo, "uint", BUILTIN_UINT);
390   this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR);
391   this->register_builtin_type(gogo, "bool", BUILTIN_BOOL);
392   this->register_builtin_type(gogo, "string", BUILTIN_STRING);
393   this->register_builtin_type(gogo, "error", BUILTIN_ERROR);
394   this->register_builtin_type(gogo, "byte", BUILTIN_BYTE);
395   this->register_builtin_type(gogo, "rune", BUILTIN_RUNE);
396 }
397
398 // Register one builtin type in the export table.
399
400 void
401 Export::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
402 {
403   Named_object* named_object = gogo->lookup_global(name);
404   go_assert(named_object != NULL && named_object->is_type());
405   std::pair<Type_refs::iterator, bool> ins =
406     this->type_refs_.insert(std::make_pair(named_object->type_value(), code));
407   go_assert(ins.second);
408
409   // We also insert the underlying type.  We can see the underlying
410   // type at least for string and bool.  We skip the type aliases byte
411   // and rune here.
412   if (code != BUILTIN_BYTE && code != BUILTIN_RUNE)
413     {
414       Type* real_type = named_object->type_value()->real_type();
415       ins = this->type_refs_.insert(std::make_pair(real_type, code));
416       go_assert(ins.second);
417     }
418 }
419
420 // Class Export::Stream.
421
422 Export::Stream::Stream()
423 {
424   this->checksum_ = new sha1_ctx;
425   memset(this->checksum_, 0, sizeof(sha1_ctx));
426   sha1_init_ctx(this->checksum_);
427 }
428
429 Export::Stream::~Stream()
430 {
431 }
432
433 // Write bytes to the stream.  This keeps a checksum of bytes as they
434 // go by.
435
436 void
437 Export::Stream::write_and_sum_bytes(const char* bytes, size_t length)
438 {
439   sha1_process_bytes(bytes, length, this->checksum_);
440   this->do_write(bytes, length);
441 }
442
443 // Get the checksum.
444
445 std::string
446 Export::Stream::checksum()
447 {
448   // Use a union to provide the required alignment.
449   union
450   {
451     char checksum[Export::v1_checksum_len];
452     long align;
453   } u;
454   sha1_finish_ctx(this->checksum_, u.checksum);
455   return std::string(u.checksum, Export::v1_checksum_len);
456 }
457
458 // Write the checksum string to the export data.
459
460 void
461 Export::Stream::write_checksum(const std::string& s)
462 {
463   this->do_write(s.data(), s.length());
464 }
465
466 // Class Stream_to_section.
467
468 Stream_to_section::Stream_to_section()
469 {
470 }
471
472 // Write data to a section.
473
474 void
475 Stream_to_section::do_write(const char* bytes, size_t length)
476 {
477   go_write_export_data (bytes, length);
478 }