annotate gcc/go/gofrontend/export.cc @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 // export.cc -- Export declarations in Go frontend.
kono
parents:
diff changeset
2
kono
parents:
diff changeset
3 // Copyright 2009 The Go Authors. All rights reserved.
kono
parents:
diff changeset
4 // Use of this source code is governed by a BSD-style
kono
parents:
diff changeset
5 // license that can be found in the LICENSE file.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 #include "go-system.h"
kono
parents:
diff changeset
8
kono
parents:
diff changeset
9 #include "go-sha1.h"
kono
parents:
diff changeset
10 #include "go-c.h"
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 #include "gogo.h"
kono
parents:
diff changeset
13 #include "types.h"
kono
parents:
diff changeset
14 #include "statements.h"
kono
parents:
diff changeset
15 #include "export.h"
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 #include "go-linemap.h"
kono
parents:
diff changeset
18 #include "backend.h"
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 // This file handles exporting global declarations.
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 // Class Export.
kono
parents:
diff changeset
23
kono
parents:
diff changeset
24 const int Export::magic_len;
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 // Current version magic string.
kono
parents:
diff changeset
27 const char Export::cur_magic[Export::magic_len] =
kono
parents:
diff changeset
28 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
29 'v', '3', ';', '\n'
111
kono
parents:
diff changeset
30 };
kono
parents:
diff changeset
31
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
32 // Magic strings for previous versions (still supported).
111
kono
parents:
diff changeset
33 const char Export::v1_magic[Export::magic_len] =
kono
parents:
diff changeset
34 {
kono
parents:
diff changeset
35 'v', '1', ';', '\n'
kono
parents:
diff changeset
36 };
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
37 const char Export::v2_magic[Export::magic_len] =
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
38 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
39 'v', '2', ';', '\n'
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
40 };
111
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 const int Export::checksum_len;
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 // Constructor.
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 Export::Export(Stream* stream)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
47 : stream_(stream), type_index_(1), packages_()
111
kono
parents:
diff changeset
48 {
kono
parents:
diff changeset
49 go_assert(Export::checksum_len == Go_sha1_helper::checksum_len);
kono
parents:
diff changeset
50 }
kono
parents:
diff changeset
51
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
52 // Type hash table operations, treating aliases as distinct.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
53
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
54 class Type_hash_alias_identical
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
55 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
56 public:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
57 unsigned int
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
58 operator()(const Type* type) const
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
59 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
60 return type->hash_for_method(NULL,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
61 (Type::COMPARE_ERRORS
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
62 | Type::COMPARE_TAGS
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
63 | Type::COMPARE_ALIASES));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
64 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
65 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
66
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
67 class Type_alias_identical
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
68 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
69 public:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
70 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
71 operator()(const Type* t1, const Type* t2) const
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
72 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
73 return Type::are_identical(t1, t2,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
74 (Type::COMPARE_ERRORS
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
75 | Type::COMPARE_TAGS
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
76 | Type::COMPARE_ALIASES),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
77 NULL);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
78 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
79 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
80
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
81 // Mapping from Type objects to a constant index. This would be nicer
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
82 // as a field in Export, but then export.h would have to #include
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
83 // types.h.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
84
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
85 typedef Unordered_map_hash(const Type*, int, Type_hash_alias_identical,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
86 Type_alias_identical) Type_refs;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
87
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
88 static Type_refs type_refs;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
89
111
kono
parents:
diff changeset
90 // A functor to sort Named_object pointers by name.
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 struct Sort_bindings
kono
parents:
diff changeset
93 {
kono
parents:
diff changeset
94 bool
kono
parents:
diff changeset
95 operator()(const Named_object* n1, const Named_object* n2) const
kono
parents:
diff changeset
96 { return n1->name() < n2->name(); }
kono
parents:
diff changeset
97 };
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 // Return true if we should export NO.
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 static bool
kono
parents:
diff changeset
102 should_export(Named_object* no)
kono
parents:
diff changeset
103 {
kono
parents:
diff changeset
104 // We only export objects which are locally defined.
kono
parents:
diff changeset
105 if (no->package() != NULL)
kono
parents:
diff changeset
106 return false;
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 // We don't export packages.
kono
parents:
diff changeset
109 if (no->is_package())
kono
parents:
diff changeset
110 return false;
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 // We don't export hidden names.
kono
parents:
diff changeset
113 if (Gogo::is_hidden_name(no->name()))
kono
parents:
diff changeset
114 return false;
kono
parents:
diff changeset
115
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
116 // We don't export various special functions.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
117 if (Gogo::is_special_name(no->name()))
111
kono
parents:
diff changeset
118 return false;
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 // Methods are exported with the type, not here.
kono
parents:
diff changeset
121 if (no->is_function()
kono
parents:
diff changeset
122 && no->func_value()->type()->is_method())
kono
parents:
diff changeset
123 return false;
kono
parents:
diff changeset
124 if (no->is_function_declaration()
kono
parents:
diff changeset
125 && no->func_declaration_value()->type()->is_method())
kono
parents:
diff changeset
126 return false;
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 // Don't export dummy global variables created for initializers when
kono
parents:
diff changeset
129 // used with sinks.
kono
parents:
diff changeset
130 if (no->is_variable() && no->name()[0] == '_' && no->name()[1] == '.')
kono
parents:
diff changeset
131 return false;
kono
parents:
diff changeset
132
kono
parents:
diff changeset
133 return true;
kono
parents:
diff changeset
134 }
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 // Export those identifiers marked for exporting.
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 void
kono
parents:
diff changeset
139 Export::export_globals(const std::string& package_name,
kono
parents:
diff changeset
140 const std::string& prefix,
kono
parents:
diff changeset
141 const std::string& pkgpath,
kono
parents:
diff changeset
142 const std::map<std::string, Package*>& packages,
kono
parents:
diff changeset
143 const std::map<std::string, Package*>& imports,
kono
parents:
diff changeset
144 const std::string& import_init_fn,
kono
parents:
diff changeset
145 const Import_init_set& imported_init_fns,
kono
parents:
diff changeset
146 const Bindings* bindings)
kono
parents:
diff changeset
147 {
kono
parents:
diff changeset
148 // If there have been any errors so far, don't try to export
kono
parents:
diff changeset
149 // anything. That way the export code doesn't have to worry about
kono
parents:
diff changeset
150 // mismatched types or other confusions.
kono
parents:
diff changeset
151 if (saw_errors())
kono
parents:
diff changeset
152 return;
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 // Export the symbols in sorted order. That will reduce cases where
kono
parents:
diff changeset
155 // irrelevant changes to the source code affect the exported
kono
parents:
diff changeset
156 // interface.
kono
parents:
diff changeset
157 std::vector<Named_object*> exports;
kono
parents:
diff changeset
158 exports.reserve(bindings->size_definitions());
kono
parents:
diff changeset
159
kono
parents:
diff changeset
160 for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
kono
parents:
diff changeset
161 p != bindings->end_definitions();
kono
parents:
diff changeset
162 ++p)
kono
parents:
diff changeset
163 if (should_export(*p))
kono
parents:
diff changeset
164 exports.push_back(*p);
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 for (Bindings::const_declarations_iterator p =
kono
parents:
diff changeset
167 bindings->begin_declarations();
kono
parents:
diff changeset
168 p != bindings->end_declarations();
kono
parents:
diff changeset
169 ++p)
kono
parents:
diff changeset
170 {
kono
parents:
diff changeset
171 // We export a function declaration as it may be implemented in
kono
parents:
diff changeset
172 // supporting C code. We do not export type declarations.
kono
parents:
diff changeset
173 if (p->second->is_function_declaration()
kono
parents:
diff changeset
174 && should_export(p->second))
kono
parents:
diff changeset
175 exports.push_back(p->second);
kono
parents:
diff changeset
176 }
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 std::sort(exports.begin(), exports.end(), Sort_bindings());
kono
parents:
diff changeset
179
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
180 // Assign indexes to all exported types and types referenced by
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
181 // exported types, and collect all packages mentioned.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
182 Unordered_set(const Package*) type_imports;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
183 int unexported_type_index = this->prepare_types(&exports, &type_imports);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
184
111
kono
parents:
diff changeset
185 // Although the export data is readable, at least this version is,
kono
parents:
diff changeset
186 // it is conceptually a binary format. Start with a four byte
kono
parents:
diff changeset
187 // version number.
kono
parents:
diff changeset
188 this->write_bytes(Export::cur_magic, Export::magic_len);
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 // The package name.
kono
parents:
diff changeset
191 this->write_c_string("package ");
kono
parents:
diff changeset
192 this->write_string(package_name);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
193 this->write_c_string("\n");
111
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 // The prefix or package path, used for all global symbols.
kono
parents:
diff changeset
196 if (prefix.empty())
kono
parents:
diff changeset
197 {
kono
parents:
diff changeset
198 go_assert(!pkgpath.empty());
kono
parents:
diff changeset
199 this->write_c_string("pkgpath ");
kono
parents:
diff changeset
200 this->write_string(pkgpath);
kono
parents:
diff changeset
201 }
kono
parents:
diff changeset
202 else
kono
parents:
diff changeset
203 {
kono
parents:
diff changeset
204 this->write_c_string("prefix ");
kono
parents:
diff changeset
205 this->write_string(prefix);
kono
parents:
diff changeset
206 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
207 this->write_c_string("\n");
111
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 this->write_packages(packages);
kono
parents:
diff changeset
210
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
211 this->write_imports(imports, type_imports);
111
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 this->write_imported_init_fns(package_name, import_init_fn,
kono
parents:
diff changeset
214 imported_init_fns);
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 // FIXME: It might be clever to add something about the processor
kono
parents:
diff changeset
217 // and ABI being used, although ideally any problems in that area
kono
parents:
diff changeset
218 // would be caught by the linker.
kono
parents:
diff changeset
219
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
220 // Write out all the types, both exported and not.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
221 this->write_types(unexported_type_index);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
222
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
223 // Write out the non-type export data.
111
kono
parents:
diff changeset
224 for (std::vector<Named_object*>::const_iterator p = exports.begin();
kono
parents:
diff changeset
225 p != exports.end();
kono
parents:
diff changeset
226 ++p)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
227 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
228 if (!(*p)->is_type())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
229 (*p)->export_named_object(this);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
230 }
111
kono
parents:
diff changeset
231
kono
parents:
diff changeset
232 std::string checksum = this->stream_->checksum();
kono
parents:
diff changeset
233 std::string s = "checksum ";
kono
parents:
diff changeset
234 for (std::string::const_iterator p = checksum.begin();
kono
parents:
diff changeset
235 p != checksum.end();
kono
parents:
diff changeset
236 ++p)
kono
parents:
diff changeset
237 {
kono
parents:
diff changeset
238 unsigned char c = *p;
kono
parents:
diff changeset
239 unsigned int dig = c >> 4;
kono
parents:
diff changeset
240 s += dig < 10 ? '0' + dig : 'A' + dig - 10;
kono
parents:
diff changeset
241 dig = c & 0xf;
kono
parents:
diff changeset
242 s += dig < 10 ? '0' + dig : 'A' + dig - 10;
kono
parents:
diff changeset
243 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
244 s += "\n";
111
kono
parents:
diff changeset
245 this->stream_->write_checksum(s);
kono
parents:
diff changeset
246 }
kono
parents:
diff changeset
247
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
248 // Traversal class to find referenced types.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
249
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
250 class Find_types_to_prepare : public Traverse
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
251 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
252 public:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
253 Find_types_to_prepare(Export* exp,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
254 Unordered_set(const Package*)* imports)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
255 : Traverse(traverse_types),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
256 exp_(exp), imports_(imports)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
257 { }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
258
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
259 int
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
260 type(Type* type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
261
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
262 // Traverse the components of a function type.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
263 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
264 traverse_function(Function_type*);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
265
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
266 // Traverse the methods of a named type, and register its package.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
267 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
268 traverse_named_type(Named_type*);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
269
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
270 private:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
271 // Exporters.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
272 Export* exp_;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
273 // List of packages we are building.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
274 Unordered_set(const Package*)* imports_;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
275 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
276
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
277 // Set type index of referenced type, record package imports, and make
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
278 // sure we traverse methods of named types.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
279
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
280 int
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
281 Find_types_to_prepare::type(Type* type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
282 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
283 // Skip forwarders; don't try to give them a type index.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
284 if (type->forward_declaration_type() != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
285 return TRAVERSE_CONTINUE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
286
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
287 // Skip the void type, which we'll see when exporting
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
288 // unsafe.Pointer. The void type is not itself exported, because
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
289 // Pointer_type::do_export checks for it.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
290 if (type->is_void_type())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
291 return TRAVERSE_SKIP_COMPONENTS;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
292
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
293 if (!this->exp_->set_type_index(type))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
294 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
295 // We've already seen this type.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
296 return TRAVERSE_SKIP_COMPONENTS;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
297 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
298
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
299 // At this stage of compilation traversing interface types traverses
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
300 // the final list of methods, but we export the locally defined
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
301 // methods. If there is an embedded interface type we need to make
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
302 // sure to export that. Check classification, rather than calling
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
303 // the interface_type method, because we want to handle named types
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
304 // below.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
305 if (type->classification() == Type::TYPE_INTERFACE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
306 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
307 Interface_type* it = type->interface_type();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
308 const Typed_identifier_list* methods = it->local_methods();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
309 if (methods != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
310 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
311 for (Typed_identifier_list::const_iterator p = methods->begin();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
312 p != methods->end();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
313 ++p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
314 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
315 if (p->name().empty())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
316 Type::traverse(p->type(), this);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
317 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
318 this->traverse_function(p->type()->function_type());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
319 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
320 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
321 return TRAVERSE_SKIP_COMPONENTS;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
322 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
323
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
324 Named_type* nt = type->named_type();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
325 if (nt != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
326 this->traverse_named_type(nt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
327
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
328 return TRAVERSE_CONTINUE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
329 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
330
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
331 // Traverse the types in a function type. We don't need the function
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
332 // type itself, just the receiver, parameter, and result types.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
333
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
334 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
335 Find_types_to_prepare::traverse_function(Function_type* type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
336 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
337 go_assert(type != NULL);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
338 if (this->remember_type(type))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
339 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
340 const Typed_identifier* receiver = type->receiver();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
341 if (receiver != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
342 Type::traverse(receiver->type(), this);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
343 const Typed_identifier_list* parameters = type->parameters();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
344 if (parameters != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
345 parameters->traverse(this);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
346 const Typed_identifier_list* results = type->results();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
347 if (results != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
348 results->traverse(this);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
349 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
350
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
351 // Traverse the methods of a named type, and record its package.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
352
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
353 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
354 Find_types_to_prepare::traverse_named_type(Named_type* nt)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
355 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
356 const Package* package = nt->named_object()->package();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
357 if (package != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
358 this->imports_->insert(package);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
359
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
360 // We have to traverse the methods of named types, because we are
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
361 // going to export them. This is not done by ordinary type
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
362 // traversal.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
363 const Bindings* methods = nt->local_methods();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
364 if (methods != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
365 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
366 for (Bindings::const_definitions_iterator pm =
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
367 methods->begin_definitions();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
368 pm != methods->end_definitions();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
369 ++pm)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
370 this->traverse_function((*pm)->func_value()->type());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
371
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
372 for (Bindings::const_declarations_iterator pm =
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
373 methods->begin_declarations();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
374 pm != methods->end_declarations();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
375 ++pm)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
376 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
377 Named_object* mno = pm->second;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
378 if (mno->is_function_declaration())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
379 this->traverse_function(mno->func_declaration_value()->type());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
380 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
381 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
382 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
383
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
384 // Prepare to export types by assigning a type index to every exported
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
385 // type and every type referenced by an exported type. Also collect
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
386 // all the packages we see in types, so that if we refer to any types
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
387 // from indirectly imported packages we can tell the importer about
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
388 // the package. This returns the number of exported types.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
389
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
390 int
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
391 Export::prepare_types(const std::vector<Named_object*>* exports,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
392 Unordered_set(const Package*)* imports)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
393 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
394 // Assign indexes to all the exported types.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
395 for (std::vector<Named_object*>::const_iterator p = exports->begin();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
396 p != exports->end();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
397 ++p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
398 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
399 if (!(*p)->is_type())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
400 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
401 this->set_type_index((*p)->type_value());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
402 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
403
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
404 int ret = this->type_index_;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
405
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
406 // Use a single instance of the traversal class because traversal
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
407 // classes keep track of which types they've already seen. That
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
408 // lets us avoid type reference loops.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
409 Find_types_to_prepare find(this, imports);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
410
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
411 // Traverse all the exported objects and assign indexes to all types.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
412 for (std::vector<Named_object*>::const_iterator p = exports->begin();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
413 p != exports->end();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
414 ++p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
415 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
416 Named_object* no = *p;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
417 switch (no->classification())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
418 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
419 case Named_object::NAMED_OBJECT_CONST:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
420 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
421 Type* t = no->const_value()->type();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
422 if (t != NULL && !t->is_abstract())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
423 Type::traverse(t, &find);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
424 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
425 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
426
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
427 case Named_object::NAMED_OBJECT_TYPE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
428 Type::traverse(no->type_value()->real_type(), &find);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
429 find.traverse_named_type(no->type_value());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
430 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
431
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
432 case Named_object::NAMED_OBJECT_VAR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
433 Type::traverse(no->var_value()->type(), &find);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
434 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
435
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
436 case Named_object::NAMED_OBJECT_FUNC:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
437 find.traverse_function(no->func_value()->type());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
438 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
439
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
440 case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
441 find.traverse_function(no->func_declaration_value()->type());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
442 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
443
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
444 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
445 // We shouldn't see anything else. If we do we'll give an
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
446 // error later when we try to actually export it.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
447 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
448 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
449 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
450
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
451 return ret;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
452 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
453
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
454 // Give a type an index if it doesn't already have one. Return true
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
455 // if we set the type index, false if it was already known.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
456
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
457 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
458 Export::set_type_index(Type* type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
459 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
460 type = type->forwarded();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
461
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
462 std::pair<Type_refs::iterator, bool> ins =
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
463 type_refs.insert(std::make_pair(type, 0));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
464 if (!ins.second)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
465 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
466 // We've already seen this type.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
467 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
468 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
469
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
470 int index = this->type_index_;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
471 ++this->type_index_;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
472 ins.first->second = index;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
473
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
474 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
475 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
476
111
kono
parents:
diff changeset
477 // Sort packages.
kono
parents:
diff changeset
478
kono
parents:
diff changeset
479 static bool
kono
parents:
diff changeset
480 packages_compare(const Package* a, const Package* b)
kono
parents:
diff changeset
481 {
kono
parents:
diff changeset
482 return a->package_name() < b->package_name();
kono
parents:
diff changeset
483 }
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485 // Write out all the known packages whose pkgpath symbol is not a
kono
parents:
diff changeset
486 // simple transformation of the pkgpath, so that the importing code
kono
parents:
diff changeset
487 // can reliably know it.
kono
parents:
diff changeset
488
kono
parents:
diff changeset
489 void
kono
parents:
diff changeset
490 Export::write_packages(const std::map<std::string, Package*>& packages)
kono
parents:
diff changeset
491 {
kono
parents:
diff changeset
492 // Sort for consistent output.
kono
parents:
diff changeset
493 std::vector<Package*> out;
kono
parents:
diff changeset
494 for (std::map<std::string, Package*>::const_iterator p = packages.begin();
kono
parents:
diff changeset
495 p != packages.end();
kono
parents:
diff changeset
496 ++p)
kono
parents:
diff changeset
497 {
kono
parents:
diff changeset
498 if (p->second->pkgpath_symbol()
kono
parents:
diff changeset
499 != Gogo::pkgpath_for_symbol(p->second->pkgpath()))
kono
parents:
diff changeset
500 out.push_back(p->second);
kono
parents:
diff changeset
501 }
kono
parents:
diff changeset
502
kono
parents:
diff changeset
503 std::sort(out.begin(), out.end(), packages_compare);
kono
parents:
diff changeset
504
kono
parents:
diff changeset
505 for (std::vector<Package*>::const_iterator p = out.begin();
kono
parents:
diff changeset
506 p != out.end();
kono
parents:
diff changeset
507 ++p)
kono
parents:
diff changeset
508 {
kono
parents:
diff changeset
509 this->write_c_string("package ");
kono
parents:
diff changeset
510 this->write_string((*p)->package_name());
kono
parents:
diff changeset
511 this->write_c_string(" ");
kono
parents:
diff changeset
512 this->write_string((*p)->pkgpath());
kono
parents:
diff changeset
513 this->write_c_string(" ");
kono
parents:
diff changeset
514 this->write_string((*p)->pkgpath_symbol());
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
515 this->write_c_string("\n");
111
kono
parents:
diff changeset
516 }
kono
parents:
diff changeset
517 }
kono
parents:
diff changeset
518
kono
parents:
diff changeset
519 // Sort imported packages.
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 static bool
kono
parents:
diff changeset
522 import_compare(const std::pair<std::string, Package*>& a,
kono
parents:
diff changeset
523 const std::pair<std::string, Package*>& b)
kono
parents:
diff changeset
524 {
kono
parents:
diff changeset
525 return a.first < b.first;
kono
parents:
diff changeset
526 }
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 // Write out the imported packages.
kono
parents:
diff changeset
529
kono
parents:
diff changeset
530 void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
531 Export::write_imports(const std::map<std::string, Package*>& imports,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
532 const Unordered_set(const Package*)& type_imports)
111
kono
parents:
diff changeset
533 {
kono
parents:
diff changeset
534 // Sort the imports for more consistent output.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
535 Unordered_set(const Package*) seen;
111
kono
parents:
diff changeset
536 std::vector<std::pair<std::string, Package*> > sorted_imports;
kono
parents:
diff changeset
537 for (std::map<std::string, Package*>::const_iterator p = imports.begin();
kono
parents:
diff changeset
538 p != imports.end();
kono
parents:
diff changeset
539 ++p)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
540 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
541 sorted_imports.push_back(std::make_pair(p->first, p->second));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
542 seen.insert(p->second);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
543 }
111
kono
parents:
diff changeset
544
kono
parents:
diff changeset
545 std::sort(sorted_imports.begin(), sorted_imports.end(), import_compare);
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 for (std::vector<std::pair<std::string, Package*> >::const_iterator p =
kono
parents:
diff changeset
548 sorted_imports.begin();
kono
parents:
diff changeset
549 p != sorted_imports.end();
kono
parents:
diff changeset
550 ++p)
kono
parents:
diff changeset
551 {
kono
parents:
diff changeset
552 this->write_c_string("import ");
kono
parents:
diff changeset
553 this->write_string(p->second->package_name());
kono
parents:
diff changeset
554 this->write_c_string(" ");
kono
parents:
diff changeset
555 this->write_string(p->second->pkgpath());
kono
parents:
diff changeset
556 this->write_c_string(" \"");
kono
parents:
diff changeset
557 this->write_string(p->first);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
558 this->write_c_string("\"\n");
111
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 this->packages_.insert(p->second);
kono
parents:
diff changeset
561 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
562
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
563 // Write out a separate list of indirectly imported packages.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
564 std::vector<const Package*> indirect_imports;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
565 for (Unordered_set(const Package*)::const_iterator p =
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
566 type_imports.begin();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
567 p != type_imports.end();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
568 ++p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
569 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
570 if (seen.find(*p) == seen.end())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
571 indirect_imports.push_back(*p);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
572 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
573
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
574 std::sort(indirect_imports.begin(), indirect_imports.end(),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
575 packages_compare);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
576
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
577 for (std::vector<const Package*>::const_iterator p =
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
578 indirect_imports.begin();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
579 p != indirect_imports.end();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
580 ++p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
581 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
582 this->write_c_string("indirectimport ");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
583 this->write_string((*p)->package_name());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
584 this->write_c_string(" ");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
585 this->write_string((*p)->pkgpath());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
586 this->write_c_string("\n");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
587 }
111
kono
parents:
diff changeset
588 }
kono
parents:
diff changeset
589
kono
parents:
diff changeset
590 void
kono
parents:
diff changeset
591 Export::add_init_graph_edge(Init_graph* init_graph, unsigned src, unsigned sink)
kono
parents:
diff changeset
592 {
kono
parents:
diff changeset
593 Init_graph::iterator it = init_graph->find(src);
kono
parents:
diff changeset
594 if (it != init_graph->end())
kono
parents:
diff changeset
595 it->second.insert(sink);
kono
parents:
diff changeset
596 else
kono
parents:
diff changeset
597 {
kono
parents:
diff changeset
598 std::set<unsigned> succs;
kono
parents:
diff changeset
599 succs.insert(sink);
kono
parents:
diff changeset
600 (*init_graph)[src] = succs;
kono
parents:
diff changeset
601 }
kono
parents:
diff changeset
602 }
kono
parents:
diff changeset
603
kono
parents:
diff changeset
604 // Constructs the imported portion of the init graph, e.g. those
kono
parents:
diff changeset
605 // edges that we read from imported packages.
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 void
kono
parents:
diff changeset
608 Export::populate_init_graph(Init_graph* init_graph,
kono
parents:
diff changeset
609 const Import_init_set& imported_init_fns,
kono
parents:
diff changeset
610 const std::map<std::string, unsigned>& init_idx)
kono
parents:
diff changeset
611 {
kono
parents:
diff changeset
612 for (Import_init_set::const_iterator p = imported_init_fns.begin();
kono
parents:
diff changeset
613 p != imported_init_fns.end();
kono
parents:
diff changeset
614 ++p)
kono
parents:
diff changeset
615 {
kono
parents:
diff changeset
616 const Import_init* ii = *p;
kono
parents:
diff changeset
617 std::map<std::string, unsigned>::const_iterator srcit =
kono
parents:
diff changeset
618 init_idx.find(ii->init_name());
kono
parents:
diff changeset
619 go_assert(srcit != init_idx.end());
kono
parents:
diff changeset
620 unsigned src = srcit->second;
kono
parents:
diff changeset
621 for (std::set<std::string>::const_iterator pci = ii->precursors().begin();
kono
parents:
diff changeset
622 pci != ii->precursors().end();
kono
parents:
diff changeset
623 ++pci)
kono
parents:
diff changeset
624 {
kono
parents:
diff changeset
625 std::map<std::string, unsigned>::const_iterator it =
kono
parents:
diff changeset
626 init_idx.find(*pci);
kono
parents:
diff changeset
627 go_assert(it != init_idx.end());
kono
parents:
diff changeset
628 unsigned sink = it->second;
kono
parents:
diff changeset
629 add_init_graph_edge(init_graph, src, sink);
kono
parents:
diff changeset
630 }
kono
parents:
diff changeset
631 }
kono
parents:
diff changeset
632 }
kono
parents:
diff changeset
633
kono
parents:
diff changeset
634 // Write out the initialization functions which need to run for this
kono
parents:
diff changeset
635 // package.
kono
parents:
diff changeset
636
kono
parents:
diff changeset
637 void
kono
parents:
diff changeset
638 Export::write_imported_init_fns(const std::string& package_name,
kono
parents:
diff changeset
639 const std::string& import_init_fn,
kono
parents:
diff changeset
640 const Import_init_set& imported_init_fns)
kono
parents:
diff changeset
641 {
kono
parents:
diff changeset
642 if (import_init_fn.empty() && imported_init_fns.empty()) return;
kono
parents:
diff changeset
643
kono
parents:
diff changeset
644 // Maps a given init function to the its index in the exported "init" clause.
kono
parents:
diff changeset
645 std::map<std::string, unsigned> init_idx;
kono
parents:
diff changeset
646
kono
parents:
diff changeset
647 this->write_c_string("init");
kono
parents:
diff changeset
648
kono
parents:
diff changeset
649 if (!import_init_fn.empty())
kono
parents:
diff changeset
650 {
kono
parents:
diff changeset
651 this->write_c_string(" ");
kono
parents:
diff changeset
652 this->write_string(package_name);
kono
parents:
diff changeset
653 this->write_c_string(" ");
kono
parents:
diff changeset
654 this->write_string(import_init_fn);
kono
parents:
diff changeset
655 init_idx[import_init_fn] = 0;
kono
parents:
diff changeset
656 }
kono
parents:
diff changeset
657
kono
parents:
diff changeset
658 if (imported_init_fns.empty())
kono
parents:
diff changeset
659 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
660 this->write_c_string("\n");
111
kono
parents:
diff changeset
661 return;
kono
parents:
diff changeset
662 }
kono
parents:
diff changeset
663
kono
parents:
diff changeset
664 typedef std::map<int, std::vector<std::string> > level_map;
kono
parents:
diff changeset
665 Init_graph init_graph;
kono
parents:
diff changeset
666 level_map inits_at_level;
kono
parents:
diff changeset
667
kono
parents:
diff changeset
668 // Walk through the set of import inits (already sorted by
kono
parents:
diff changeset
669 // init fcn name) and write them out to the exports.
kono
parents:
diff changeset
670 for (Import_init_set::const_iterator p = imported_init_fns.begin();
kono
parents:
diff changeset
671 p != imported_init_fns.end();
kono
parents:
diff changeset
672 ++p)
kono
parents:
diff changeset
673 {
kono
parents:
diff changeset
674 const Import_init* ii = *p;
kono
parents:
diff changeset
675
kono
parents:
diff changeset
676 if (ii->init_name() == import_init_fn)
kono
parents:
diff changeset
677 continue;
kono
parents:
diff changeset
678
kono
parents:
diff changeset
679 this->write_c_string(" ");
kono
parents:
diff changeset
680 this->write_string(ii->package_name());
kono
parents:
diff changeset
681 this->write_c_string(" ");
kono
parents:
diff changeset
682 this->write_string(ii->init_name());
kono
parents:
diff changeset
683
kono
parents:
diff changeset
684 // Populate init_idx.
kono
parents:
diff changeset
685 go_assert(init_idx.find(ii->init_name()) == init_idx.end());
kono
parents:
diff changeset
686 unsigned idx = init_idx.size();
kono
parents:
diff changeset
687 init_idx[ii->init_name()] = idx;
kono
parents:
diff changeset
688
kono
parents:
diff changeset
689 // If the init function has a non-negative priority value, this
kono
parents:
diff changeset
690 // is an indication that it was referred to in an older version
kono
parents:
diff changeset
691 // export data section (e.g. we read a legacy object
kono
parents:
diff changeset
692 // file). Record such init fcns so that we can fix up the graph
kono
parents:
diff changeset
693 // for them (handled later in this function).
kono
parents:
diff changeset
694 if (ii->priority() > 0)
kono
parents:
diff changeset
695 {
kono
parents:
diff changeset
696 level_map::iterator it = inits_at_level.find(ii->priority());
kono
parents:
diff changeset
697 if (it == inits_at_level.end())
kono
parents:
diff changeset
698 {
kono
parents:
diff changeset
699 std::vector<std::string> l;
kono
parents:
diff changeset
700 l.push_back(ii->init_name());
kono
parents:
diff changeset
701 inits_at_level[ii->priority()] = l;
kono
parents:
diff changeset
702 }
kono
parents:
diff changeset
703 else
kono
parents:
diff changeset
704 it->second.push_back(ii->init_name());
kono
parents:
diff changeset
705 }
kono
parents:
diff changeset
706 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
707 this->write_c_string("\n");
111
kono
parents:
diff changeset
708
kono
parents:
diff changeset
709 // Create the init graph. Start by populating the graph with
kono
parents:
diff changeset
710 // all the edges we inherited from imported packages.
kono
parents:
diff changeset
711 populate_init_graph(&init_graph, imported_init_fns, init_idx);
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 // Now add edges from the local init function to each of the
kono
parents:
diff changeset
714 // imported fcns.
kono
parents:
diff changeset
715 if (!import_init_fn.empty())
kono
parents:
diff changeset
716 {
kono
parents:
diff changeset
717 unsigned src = 0;
kono
parents:
diff changeset
718 go_assert(init_idx[import_init_fn] == 0);
kono
parents:
diff changeset
719 for (Import_init_set::const_iterator p = imported_init_fns.begin();
kono
parents:
diff changeset
720 p != imported_init_fns.end();
kono
parents:
diff changeset
721 ++p)
kono
parents:
diff changeset
722 {
kono
parents:
diff changeset
723 const Import_init* ii = *p;
kono
parents:
diff changeset
724 unsigned sink = init_idx[ii->init_name()];
kono
parents:
diff changeset
725 add_init_graph_edge(&init_graph, src, sink);
kono
parents:
diff changeset
726 }
kono
parents:
diff changeset
727 }
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 // In the scenario where one or more of the packages we imported
kono
parents:
diff changeset
730 // was written with the legacy export data format, add dummy edges
kono
parents:
diff changeset
731 // to capture the priority relationships. Here is a package import
kono
parents:
diff changeset
732 // graph as an example:
kono
parents:
diff changeset
733 //
kono
parents:
diff changeset
734 // *A
kono
parents:
diff changeset
735 // /|
kono
parents:
diff changeset
736 // / |
kono
parents:
diff changeset
737 // B *C
kono
parents:
diff changeset
738 // /|
kono
parents:
diff changeset
739 // / |
kono
parents:
diff changeset
740 // *D *E
kono
parents:
diff changeset
741 // | /|
kono
parents:
diff changeset
742 // |/ |
kono
parents:
diff changeset
743 // *F *G
kono
parents:
diff changeset
744 //
kono
parents:
diff changeset
745 // Let's suppose that the object for package "C" is from an old
kono
parents:
diff changeset
746 // gccgo, e.g. it has the old export data format. All other
kono
parents:
diff changeset
747 // packages are compiled with the new compiler and have the new
kono
parents:
diff changeset
748 // format. Packages with *'s have init functions. The scenario is
kono
parents:
diff changeset
749 // that we're compiling a package "A"; during this process we'll
kono
parents:
diff changeset
750 // read the export data for "C". It should look something like
kono
parents:
diff changeset
751 //
kono
parents:
diff changeset
752 // init F F..import 1 G G..import 1 D D..import 2 E E..import 2;
kono
parents:
diff changeset
753 //
kono
parents:
diff changeset
754 // To capture this information and convey it to the consumers of
kono
parents:
diff changeset
755 // "A", the code below adds edges to the graph from each priority K
kono
parents:
diff changeset
756 // function to every priority K-1 function for appropriate values
kono
parents:
diff changeset
757 // of K. This will potentially add more edges than we need (for
kono
parents:
diff changeset
758 // example, an edge from D to G), but given that we don't expect
kono
parents:
diff changeset
759 // to see large numbers of old objects, this will hopefully be OK.
kono
parents:
diff changeset
760
kono
parents:
diff changeset
761 if (inits_at_level.size() > 0)
kono
parents:
diff changeset
762 {
kono
parents:
diff changeset
763 for (level_map::reverse_iterator it = inits_at_level.rbegin();
kono
parents:
diff changeset
764 it != inits_at_level.rend(); ++it)
kono
parents:
diff changeset
765 {
kono
parents:
diff changeset
766 int level = it->first;
kono
parents:
diff changeset
767 if (level < 2) break;
kono
parents:
diff changeset
768 const std::vector<std::string>& fcns_at_level = it->second;
kono
parents:
diff changeset
769 for (std::vector<std::string>::const_iterator sit =
kono
parents:
diff changeset
770 fcns_at_level.begin();
kono
parents:
diff changeset
771 sit != fcns_at_level.end(); ++sit)
kono
parents:
diff changeset
772 {
kono
parents:
diff changeset
773 unsigned src = init_idx[*sit];
kono
parents:
diff changeset
774 level_map::iterator it2 = inits_at_level.find(level - 1);
kono
parents:
diff changeset
775 if (it2 != inits_at_level.end())
kono
parents:
diff changeset
776 {
kono
parents:
diff changeset
777 const std::vector<std::string> fcns_at_lm1 = it2->second;
kono
parents:
diff changeset
778 for (std::vector<std::string>::const_iterator mit =
kono
parents:
diff changeset
779 fcns_at_lm1.begin();
kono
parents:
diff changeset
780 mit != fcns_at_lm1.end(); ++mit)
kono
parents:
diff changeset
781 {
kono
parents:
diff changeset
782 unsigned sink = init_idx[*mit];
kono
parents:
diff changeset
783 add_init_graph_edge(&init_graph, src, sink);
kono
parents:
diff changeset
784 }
kono
parents:
diff changeset
785 }
kono
parents:
diff changeset
786 }
kono
parents:
diff changeset
787 }
kono
parents:
diff changeset
788 }
kono
parents:
diff changeset
789
kono
parents:
diff changeset
790 // Write out the resulting graph.
kono
parents:
diff changeset
791 this->write_c_string("init_graph");
kono
parents:
diff changeset
792 for (Init_graph::const_iterator ki = init_graph.begin();
kono
parents:
diff changeset
793 ki != init_graph.end(); ++ki)
kono
parents:
diff changeset
794 {
kono
parents:
diff changeset
795 unsigned src = ki->first;
kono
parents:
diff changeset
796 const std::set<unsigned>& successors = ki->second;
kono
parents:
diff changeset
797 for (std::set<unsigned>::const_iterator vi = successors.begin();
kono
parents:
diff changeset
798 vi != successors.end(); ++vi)
kono
parents:
diff changeset
799 {
kono
parents:
diff changeset
800 this->write_c_string(" ");
kono
parents:
diff changeset
801 this->write_unsigned(src);
kono
parents:
diff changeset
802 unsigned sink = (*vi);
kono
parents:
diff changeset
803 this->write_c_string(" ");
kono
parents:
diff changeset
804 this->write_unsigned(sink);
kono
parents:
diff changeset
805 }
kono
parents:
diff changeset
806 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
807 this->write_c_string("\n");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
808 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
809
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
810 // Write the types to the export stream.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
811
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
812 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
813 Export::write_types(int unexported_type_index)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
814 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
815 // Map from type index to type.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
816 std::vector<const Type*> types(static_cast<size_t>(this->type_index_));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
817 for (Type_refs::const_iterator p = type_refs.begin();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
818 p != type_refs.end();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
819 ++p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
820 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
821 if (p->second >= 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
822 types.at(p->second) = p->first;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
823 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
824
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
825 // Write the type information to a buffer.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
826 Stream_to_string type_data;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
827 Export::Stream* orig_stream = this->stream_;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
828 this->stream_ = &type_data;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
829
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
830 std::vector<size_t> type_sizes(static_cast<size_t>(this->type_index_));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
831 type_sizes[0] = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
832
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
833 // Start at 1 because type index 0 is not used.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
834 size_t start_size = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
835 for (int i = 1; i < this->type_index_; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
836 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
837 this->write_type_definition(types[i], i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
838
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
839 size_t cur_size = type_data.string().size();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
840 type_sizes[i] = cur_size - start_size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
841 start_size = cur_size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
842 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
843
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
844 // Back to original stream.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
845 this->stream_ = orig_stream;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
846
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
847 // The line "types MAXP1 EXPORTEDP1 SIZES..." appears before the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
848 // types. MAXP1 is one more than the maximum type index used; that
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
849 // is, it is the size of the array we need to allocate to hold all
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
850 // the values. Indexes 1 up to but not including EXPORTEDP1 are the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
851 // exported types. The other types are not exported. SIZES... is a
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
852 // list of MAXP1-1 entries listing the size of the type definition
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
853 // for each type, starting at index 1.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
854 char buf[100];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
855 snprintf(buf, sizeof buf, "types %d %d", this->type_index_,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
856 unexported_type_index);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
857 this->write_c_string(buf);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
858
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
859 // Start at 1 because type index 0 is not used.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
860 for (int i = 1; i < this->type_index_; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
861 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
862 snprintf(buf, sizeof buf, " %lu",
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
863 static_cast<unsigned long>(type_sizes[i]));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
864 this->write_c_string(buf);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
865 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
866 this->write_c_string("\n");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
867 this->write_string(type_data.string());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
868 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
869
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
870 // Write a single type to the export stream.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
871
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
872 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
873 Export::write_type_definition(const Type* type, int index)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
874 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
875 this->write_c_string("type ");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
876
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
877 char buf[30];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
878 snprintf(buf, sizeof buf, "%d ", index);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
879 this->write_c_string(buf);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
880
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
881 const Named_type* nt = type->named_type();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
882 if (nt != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
883 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
884 const Named_object* no = nt->named_object();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
885 const Package* package = no->package();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
886
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
887 this->write_c_string("\"");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
888 if (package != NULL && !Gogo::is_hidden_name(no->name()))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
889 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
890 this->write_string(package->pkgpath());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
891 this->write_c_string(".");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
892 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
893 this->write_string(nt->named_object()->name());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
894 this->write_c_string("\" ");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
895
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
896 if (nt->is_alias())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
897 this->write_c_string("= ");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
898 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
899
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
900 type->export_type(this);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
901
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
902 // Type::export_type will print a newline for a named type, but not
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
903 // otherwise.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
904 if (nt == NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
905 this->write_c_string("\n");
111
kono
parents:
diff changeset
906 }
kono
parents:
diff changeset
907
kono
parents:
diff changeset
908 // Write a name to the export stream.
kono
parents:
diff changeset
909
kono
parents:
diff changeset
910 void
kono
parents:
diff changeset
911 Export::write_name(const std::string& name)
kono
parents:
diff changeset
912 {
kono
parents:
diff changeset
913 if (name.empty())
kono
parents:
diff changeset
914 this->write_c_string("?");
kono
parents:
diff changeset
915 else
kono
parents:
diff changeset
916 this->write_string(Gogo::message_name(name));
kono
parents:
diff changeset
917 }
kono
parents:
diff changeset
918
kono
parents:
diff changeset
919 // Write an integer value to the export stream.
kono
parents:
diff changeset
920
kono
parents:
diff changeset
921 void
kono
parents:
diff changeset
922 Export::write_int(int value)
kono
parents:
diff changeset
923 {
kono
parents:
diff changeset
924 char buf[100];
kono
parents:
diff changeset
925 snprintf(buf, sizeof buf, "%d", value);
kono
parents:
diff changeset
926 this->write_c_string(buf);
kono
parents:
diff changeset
927 }
kono
parents:
diff changeset
928
kono
parents:
diff changeset
929 // Write an integer value to the export stream.
kono
parents:
diff changeset
930
kono
parents:
diff changeset
931 void
kono
parents:
diff changeset
932 Export::write_unsigned(unsigned value)
kono
parents:
diff changeset
933 {
kono
parents:
diff changeset
934 char buf[100];
kono
parents:
diff changeset
935 snprintf(buf, sizeof buf, "%u", value);
kono
parents:
diff changeset
936 this->write_c_string(buf);
kono
parents:
diff changeset
937 }
kono
parents:
diff changeset
938
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939 // Export a type.
111
kono
parents:
diff changeset
940
kono
parents:
diff changeset
941 void
kono
parents:
diff changeset
942 Export::write_type(const Type* type)
kono
parents:
diff changeset
943 {
kono
parents:
diff changeset
944 type = type->forwarded();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
945 Type_refs::const_iterator p = type_refs.find(type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
946 go_assert(p != type_refs.end());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
947 int index = p->second;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
948 go_assert(index != 0);
111
kono
parents:
diff changeset
949 char buf[30];
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
950 snprintf(buf, sizeof buf, "<type %d>", index);
111
kono
parents:
diff changeset
951 this->write_c_string(buf);
kono
parents:
diff changeset
952 }
kono
parents:
diff changeset
953
kono
parents:
diff changeset
954 // Export escape note.
kono
parents:
diff changeset
955
kono
parents:
diff changeset
956 void
kono
parents:
diff changeset
957 Export::write_escape(std::string* note)
kono
parents:
diff changeset
958 {
kono
parents:
diff changeset
959 if (note != NULL && *note != "esc:0x0")
kono
parents:
diff changeset
960 {
kono
parents:
diff changeset
961 this->write_c_string(" ");
kono
parents:
diff changeset
962 char buf[50];
kono
parents:
diff changeset
963 go_assert(note->find("esc:") != std::string::npos);
kono
parents:
diff changeset
964 snprintf(buf, sizeof buf, "<%s>", note->c_str());
kono
parents:
diff changeset
965 this->write_c_string(buf);
kono
parents:
diff changeset
966 }
kono
parents:
diff changeset
967 }
kono
parents:
diff changeset
968
kono
parents:
diff changeset
969 // Add the builtin types to the export table.
kono
parents:
diff changeset
970
kono
parents:
diff changeset
971 void
kono
parents:
diff changeset
972 Export::register_builtin_types(Gogo* gogo)
kono
parents:
diff changeset
973 {
kono
parents:
diff changeset
974 this->register_builtin_type(gogo, "int8", BUILTIN_INT8);
kono
parents:
diff changeset
975 this->register_builtin_type(gogo, "int16", BUILTIN_INT16);
kono
parents:
diff changeset
976 this->register_builtin_type(gogo, "int32", BUILTIN_INT32);
kono
parents:
diff changeset
977 this->register_builtin_type(gogo, "int64", BUILTIN_INT64);
kono
parents:
diff changeset
978 this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8);
kono
parents:
diff changeset
979 this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16);
kono
parents:
diff changeset
980 this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32);
kono
parents:
diff changeset
981 this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64);
kono
parents:
diff changeset
982 this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32);
kono
parents:
diff changeset
983 this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64);
kono
parents:
diff changeset
984 this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64);
kono
parents:
diff changeset
985 this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128);
kono
parents:
diff changeset
986 this->register_builtin_type(gogo, "int", BUILTIN_INT);
kono
parents:
diff changeset
987 this->register_builtin_type(gogo, "uint", BUILTIN_UINT);
kono
parents:
diff changeset
988 this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR);
kono
parents:
diff changeset
989 this->register_builtin_type(gogo, "bool", BUILTIN_BOOL);
kono
parents:
diff changeset
990 this->register_builtin_type(gogo, "string", BUILTIN_STRING);
kono
parents:
diff changeset
991 this->register_builtin_type(gogo, "error", BUILTIN_ERROR);
kono
parents:
diff changeset
992 this->register_builtin_type(gogo, "byte", BUILTIN_BYTE);
kono
parents:
diff changeset
993 this->register_builtin_type(gogo, "rune", BUILTIN_RUNE);
kono
parents:
diff changeset
994 }
kono
parents:
diff changeset
995
kono
parents:
diff changeset
996 // Register one builtin type in the export table.
kono
parents:
diff changeset
997
kono
parents:
diff changeset
998 void
kono
parents:
diff changeset
999 Export::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
kono
parents:
diff changeset
1000 {
kono
parents:
diff changeset
1001 Named_object* named_object = gogo->lookup_global(name);
kono
parents:
diff changeset
1002 go_assert(named_object != NULL && named_object->is_type());
kono
parents:
diff changeset
1003 std::pair<Type_refs::iterator, bool> ins =
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1004 type_refs.insert(std::make_pair(named_object->type_value(), code));
111
kono
parents:
diff changeset
1005 go_assert(ins.second);
kono
parents:
diff changeset
1006
kono
parents:
diff changeset
1007 // We also insert the underlying type. We can see the underlying
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1008 // type at least for string and bool. It's OK if this insert
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1009 // fails--we expect duplications here, and it doesn't matter when
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1010 // they occur.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1011 Type* real_type = named_object->type_value()->real_type();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1012 type_refs.insert(std::make_pair(real_type, code));
111
kono
parents:
diff changeset
1013 }
kono
parents:
diff changeset
1014
kono
parents:
diff changeset
1015 // Class Export::Stream.
kono
parents:
diff changeset
1016
kono
parents:
diff changeset
1017 Export::Stream::Stream()
kono
parents:
diff changeset
1018 {
kono
parents:
diff changeset
1019 this->sha1_helper_ = go_create_sha1_helper();
kono
parents:
diff changeset
1020 go_assert(this->sha1_helper_ != NULL);
kono
parents:
diff changeset
1021 }
kono
parents:
diff changeset
1022
kono
parents:
diff changeset
1023 Export::Stream::~Stream()
kono
parents:
diff changeset
1024 {
kono
parents:
diff changeset
1025 }
kono
parents:
diff changeset
1026
kono
parents:
diff changeset
1027 // Write bytes to the stream. This keeps a checksum of bytes as they
kono
parents:
diff changeset
1028 // go by.
kono
parents:
diff changeset
1029
kono
parents:
diff changeset
1030 void
kono
parents:
diff changeset
1031 Export::Stream::write_and_sum_bytes(const char* bytes, size_t length)
kono
parents:
diff changeset
1032 {
kono
parents:
diff changeset
1033 this->sha1_helper_->process_bytes(bytes, length);
kono
parents:
diff changeset
1034 this->do_write(bytes, length);
kono
parents:
diff changeset
1035 }
kono
parents:
diff changeset
1036
kono
parents:
diff changeset
1037 // Get the checksum.
kono
parents:
diff changeset
1038
kono
parents:
diff changeset
1039 std::string
kono
parents:
diff changeset
1040 Export::Stream::checksum()
kono
parents:
diff changeset
1041 {
kono
parents:
diff changeset
1042 std::string rval = this->sha1_helper_->finish();
kono
parents:
diff changeset
1043 delete this->sha1_helper_;
kono
parents:
diff changeset
1044 return rval;
kono
parents:
diff changeset
1045 }
kono
parents:
diff changeset
1046
kono
parents:
diff changeset
1047 // Write the checksum string to the export data.
kono
parents:
diff changeset
1048
kono
parents:
diff changeset
1049 void
kono
parents:
diff changeset
1050 Export::Stream::write_checksum(const std::string& s)
kono
parents:
diff changeset
1051 {
kono
parents:
diff changeset
1052 this->do_write(s.data(), s.length());
kono
parents:
diff changeset
1053 }
kono
parents:
diff changeset
1054
kono
parents:
diff changeset
1055 // Class Stream_to_section.
kono
parents:
diff changeset
1056
kono
parents:
diff changeset
1057 Stream_to_section::Stream_to_section(Backend* backend)
kono
parents:
diff changeset
1058 : backend_(backend)
kono
parents:
diff changeset
1059 {
kono
parents:
diff changeset
1060 }
kono
parents:
diff changeset
1061
kono
parents:
diff changeset
1062 // Write data to a section.
kono
parents:
diff changeset
1063
kono
parents:
diff changeset
1064 void
kono
parents:
diff changeset
1065 Stream_to_section::do_write(const char* bytes, size_t length)
kono
parents:
diff changeset
1066 {
kono
parents:
diff changeset
1067 this->backend_->write_export_data (bytes, length);
kono
parents:
diff changeset
1068 }