OSDN Git Service

compiler: Fix parse of (<- chan <- chan <- int)(x).
[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), packages_()
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& pkgpath,
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 package path, used for all global symbols.
144   this->write_c_string("pkgpath ");
145   this->write_string(pkgpath);
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->package_name());
213       this->write_c_string(" ");
214       this->write_string(p->second->pkgpath());
215       this->write_c_string(" \"");
216       this->write_string(p->first);
217       this->write_c_string("\";\n");
218
219       this->packages_.insert(p->second);
220     }
221 }
222
223 // Write out the initialization functions which need to run for this
224 // package.
225
226 void
227 Export::write_imported_init_fns(
228     const std::string& package_name,
229     int priority,
230     const std::string& import_init_fn,
231     const std::set<Import_init>& imported_init_fns)
232 {
233   if (import_init_fn.empty() && imported_init_fns.empty())
234     return;
235
236   this->write_c_string("init");
237
238   if (!import_init_fn.empty())
239     {
240       this->write_c_string(" ");
241       this->write_string(package_name);
242       this->write_c_string(" ");
243       this->write_string(import_init_fn);
244       char buf[100];
245       snprintf(buf, sizeof buf, " %d", priority);
246       this->write_c_string(buf);
247     }
248
249   if (!imported_init_fns.empty())
250     {
251       // Sort the list of functions for more consistent output.
252       std::vector<Import_init> v;
253       for (std::set<Import_init>::const_iterator p = imported_init_fns.begin();
254            p != imported_init_fns.end();
255            ++p)
256         v.push_back(*p);
257       std::sort(v.begin(), v.end());
258
259       for (std::vector<Import_init>::const_iterator p = v.begin();
260            p != v.end();
261            ++p)
262         {
263           this->write_c_string(" ");
264           this->write_string(p->package_name());
265           this->write_c_string(" ");
266           this->write_string(p->init_name());
267           char buf[100];
268           snprintf(buf, sizeof buf, " %d", p->priority());
269           this->write_c_string(buf);
270         }
271     }
272
273   this->write_c_string(";\n");
274 }
275
276 // Write a name to the export stream.
277
278 void
279 Export::write_name(const std::string& name)
280 {
281   if (name.empty())
282     this->write_c_string("?");
283   else
284     this->write_string(Gogo::message_name(name));
285 }
286
287 // Export a type.  We have to ensure that on import we create a single
288 // Named_type node for each named type.  We do this by keeping a hash
289 // table mapping named types to reference numbers.  The first time we
290 // see a named type we assign it a reference number by making an entry
291 // in the hash table.  If we see it again, we just refer to the
292 // reference number.
293
294 // Named types are, of course, associated with packages.  Note that we
295 // may see a named type when importing one package, and then later see
296 // the same named type when importing a different package.  The home
297 // package may or may not be imported during this compilation.  The
298 // reference number scheme has to get this all right.  Basic approach
299 // taken from "On the Linearization of Graphs and Writing Symbol
300 // Files" by Robert Griesemer.
301
302 void
303 Export::write_type(const Type* type)
304 {
305   // We don't want to assign a reference number to a forward
306   // declaration to a type which was defined later.
307   type = type->forwarded();
308
309   Type_refs::const_iterator p = this->type_refs_.find(type);
310   if (p != this->type_refs_.end())
311     {
312       // This type was already in the table.
313       int index = p->second;
314       go_assert(index != 0);
315       char buf[30];
316       snprintf(buf, sizeof buf, "<type %d>", index);
317       this->write_c_string(buf);
318       return;
319     }
320
321   const Named_type* named_type = type->named_type();
322   const Forward_declaration_type* forward = type->forward_declaration_type();
323
324   int index = this->type_index_;
325   ++this->type_index_;
326
327   char buf[30];
328   snprintf(buf, sizeof buf, "<type %d ", index);
329   this->write_c_string(buf);
330
331   if (named_type != NULL || forward != NULL)
332     {
333       const Named_object* named_object;
334       if (named_type != NULL)
335         {
336           // The builtin types should have been predefined.
337           go_assert(!Linemap::is_predeclared_location(named_type->location())
338                      || (named_type->named_object()->package()->package_name()
339                          == "unsafe"));
340           named_object = named_type->named_object();
341         }
342       else
343         named_object = forward->named_object();
344
345       const Package* package = named_object->package();
346
347       std::string s = "\"";
348       if (package != NULL && !Gogo::is_hidden_name(named_object->name()))
349         {
350           s += package->pkgpath();
351           s += '.';
352         }
353       s += named_object->name();
354       s += "\" ";
355       this->write_string(s);
356
357       // It is possible that this type was imported indirectly, and is
358       // not in a package in the import list.  If we have not
359       // mentioned this package before, write out the package name
360       // here so that any package importing this one will know it.
361       if (package != NULL
362           && this->packages_.find(package) == this->packages_.end())
363         {
364           this->write_c_string("\"");
365           this->write_string(package->package_name());
366           this->packages_.insert(package);
367           this->write_c_string("\" ");
368         }
369
370       // We must add a named type to the table now, since the
371       // definition of the type may refer to the named type via a
372       // pointer.
373       this->type_refs_[type] = index;
374     }
375
376   type->export_type(this);
377
378   this->write_c_string(">");
379
380   if (named_type == NULL)
381     this->type_refs_[type] = index;
382 }
383
384 // Add the builtin types to the export table.
385
386 void
387 Export::register_builtin_types(Gogo* gogo)
388 {
389   this->register_builtin_type(gogo, "int8", BUILTIN_INT8);
390   this->register_builtin_type(gogo, "int16", BUILTIN_INT16);
391   this->register_builtin_type(gogo, "int32", BUILTIN_INT32);
392   this->register_builtin_type(gogo, "int64", BUILTIN_INT64);
393   this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8);
394   this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16);
395   this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32);
396   this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64);
397   this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32);
398   this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64);
399   this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64);
400   this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128);
401   this->register_builtin_type(gogo, "int", BUILTIN_INT);
402   this->register_builtin_type(gogo, "uint", BUILTIN_UINT);
403   this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR);
404   this->register_builtin_type(gogo, "bool", BUILTIN_BOOL);
405   this->register_builtin_type(gogo, "string", BUILTIN_STRING);
406   this->register_builtin_type(gogo, "error", BUILTIN_ERROR);
407   this->register_builtin_type(gogo, "byte", BUILTIN_BYTE);
408   this->register_builtin_type(gogo, "rune", BUILTIN_RUNE);
409 }
410
411 // Register one builtin type in the export table.
412
413 void
414 Export::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
415 {
416   Named_object* named_object = gogo->lookup_global(name);
417   go_assert(named_object != NULL && named_object->is_type());
418   std::pair<Type_refs::iterator, bool> ins =
419     this->type_refs_.insert(std::make_pair(named_object->type_value(), code));
420   go_assert(ins.second);
421
422   // We also insert the underlying type.  We can see the underlying
423   // type at least for string and bool.  We skip the type aliases byte
424   // and rune here.
425   if (code != BUILTIN_BYTE && code != BUILTIN_RUNE)
426     {
427       Type* real_type = named_object->type_value()->real_type();
428       ins = this->type_refs_.insert(std::make_pair(real_type, code));
429       go_assert(ins.second);
430     }
431 }
432
433 // Class Export::Stream.
434
435 Export::Stream::Stream()
436 {
437   this->checksum_ = new sha1_ctx;
438   memset(this->checksum_, 0, sizeof(sha1_ctx));
439   sha1_init_ctx(this->checksum_);
440 }
441
442 Export::Stream::~Stream()
443 {
444 }
445
446 // Write bytes to the stream.  This keeps a checksum of bytes as they
447 // go by.
448
449 void
450 Export::Stream::write_and_sum_bytes(const char* bytes, size_t length)
451 {
452   sha1_process_bytes(bytes, length, this->checksum_);
453   this->do_write(bytes, length);
454 }
455
456 // Get the checksum.
457
458 std::string
459 Export::Stream::checksum()
460 {
461   // Use a union to provide the required alignment.
462   union
463   {
464     char checksum[Export::v1_checksum_len];
465     long align;
466   } u;
467   sha1_finish_ctx(this->checksum_, u.checksum);
468   return std::string(u.checksum, Export::v1_checksum_len);
469 }
470
471 // Write the checksum string to the export data.
472
473 void
474 Export::Stream::write_checksum(const std::string& s)
475 {
476   this->do_write(s.data(), s.length());
477 }
478
479 // Class Stream_to_section.
480
481 Stream_to_section::Stream_to_section()
482 {
483 }
484
485 // Write data to a section.
486
487 void
488 Stream_to_section::do_write(const char* bytes, size_t length)
489 {
490   go_write_export_data (bytes, length);
491 }