annotate gcc/go/gofrontend/gogo.h @ 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 // gogo.h -- Go frontend parsed representation. -*- C++ -*-
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 #ifndef GO_GOGO_H
kono
parents:
diff changeset
8 #define GO_GOGO_H
kono
parents:
diff changeset
9
kono
parents:
diff changeset
10 #include "go-linemap.h"
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 class Traverse;
kono
parents:
diff changeset
13 class Statement_inserter;
kono
parents:
diff changeset
14 class Type;
kono
parents:
diff changeset
15 class Type_equal;
kono
parents:
diff changeset
16 class Typed_identifier;
kono
parents:
diff changeset
17 class Typed_identifier_list;
kono
parents:
diff changeset
18 class Function_type;
kono
parents:
diff changeset
19 class Expression;
kono
parents:
diff changeset
20 class Expression_list;
kono
parents:
diff changeset
21 class Statement;
kono
parents:
diff changeset
22 class Temporary_statement;
kono
parents:
diff changeset
23 class Block;
kono
parents:
diff changeset
24 class Function;
kono
parents:
diff changeset
25 class Bindings;
kono
parents:
diff changeset
26 class Bindings_snapshot;
kono
parents:
diff changeset
27 class Package;
kono
parents:
diff changeset
28 class Variable;
kono
parents:
diff changeset
29 class Pointer_type;
kono
parents:
diff changeset
30 class Struct_type;
kono
parents:
diff changeset
31 class Struct_field;
kono
parents:
diff changeset
32 class Struct_field_list;
kono
parents:
diff changeset
33 class Array_type;
kono
parents:
diff changeset
34 class Map_type;
kono
parents:
diff changeset
35 class Channel_type;
kono
parents:
diff changeset
36 class Interface_type;
kono
parents:
diff changeset
37 class Named_type;
kono
parents:
diff changeset
38 class Forward_declaration_type;
kono
parents:
diff changeset
39 class Named_object;
kono
parents:
diff changeset
40 class Label;
kono
parents:
diff changeset
41 class Translate_context;
kono
parents:
diff changeset
42 class Backend;
kono
parents:
diff changeset
43 class Export;
kono
parents:
diff changeset
44 class Import;
kono
parents:
diff changeset
45 class Bexpression;
kono
parents:
diff changeset
46 class Btype;
kono
parents:
diff changeset
47 class Bstatement;
kono
parents:
diff changeset
48 class Bblock;
kono
parents:
diff changeset
49 class Bvariable;
kono
parents:
diff changeset
50 class Blabel;
kono
parents:
diff changeset
51 class Bfunction;
kono
parents:
diff changeset
52 class Escape_context;
kono
parents:
diff changeset
53 class Node;
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 // This file declares the basic classes used to hold the internal
kono
parents:
diff changeset
56 // representation of Go which is built by the parser.
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 // An initialization function for an imported package. This is a
kono
parents:
diff changeset
59 // magic function which initializes variables and runs the "init"
kono
parents:
diff changeset
60 // function.
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 class Import_init
kono
parents:
diff changeset
63 {
kono
parents:
diff changeset
64 public:
kono
parents:
diff changeset
65 Import_init(const std::string& package_name, const std::string& init_name,
kono
parents:
diff changeset
66 int priority)
kono
parents:
diff changeset
67 : package_name_(package_name), init_name_(init_name), priority_(priority)
kono
parents:
diff changeset
68 { }
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 // The name of the package being imported.
kono
parents:
diff changeset
71 const std::string&
kono
parents:
diff changeset
72 package_name() const
kono
parents:
diff changeset
73 { return this->package_name_; }
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75 // The name of the package's init function.
kono
parents:
diff changeset
76 const std::string&
kono
parents:
diff changeset
77 init_name() const
kono
parents:
diff changeset
78 { return this->init_name_; }
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 // Older V1 export data uses a priority scheme to order
kono
parents:
diff changeset
81 // initialization functions; functions with a lower priority number
kono
parents:
diff changeset
82 // must be run first. This value will be set to -1 for current
kono
parents:
diff changeset
83 // generation objects, and will take on a non-negative value only
kono
parents:
diff changeset
84 // when importing a V1-vintage object.
kono
parents:
diff changeset
85 int
kono
parents:
diff changeset
86 priority() const
kono
parents:
diff changeset
87 { return this->priority_; }
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 // Reset priority.
kono
parents:
diff changeset
90 void
kono
parents:
diff changeset
91 set_priority(int new_priority)
kono
parents:
diff changeset
92 { this->priority_ = new_priority; }
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 // Record the fact that some other init fcn must be run before this init fcn.
kono
parents:
diff changeset
95 void
kono
parents:
diff changeset
96 record_precursor_fcn(std::string init_fcn_name)
kono
parents:
diff changeset
97 { this->precursor_functions_.insert(init_fcn_name); }
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 // Return the list of precursor fcns for this fcn (must be run before it).
kono
parents:
diff changeset
100 const std::set<std::string>&
kono
parents:
diff changeset
101 precursors() const
kono
parents:
diff changeset
102 { return this->precursor_functions_; }
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 private:
kono
parents:
diff changeset
105 // The name of the package being imported.
kono
parents:
diff changeset
106 std::string package_name_;
kono
parents:
diff changeset
107 // The name of the package's init function.
kono
parents:
diff changeset
108 std::string init_name_;
kono
parents:
diff changeset
109 // Names of init functions that must be run before this fcn.
kono
parents:
diff changeset
110 std::set<std::string> precursor_functions_;
kono
parents:
diff changeset
111 // Priority for this function. See note above on obsolescence.
kono
parents:
diff changeset
112 int priority_;
kono
parents:
diff changeset
113 };
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 // For sorting purposes.
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 struct Import_init_lt {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
118 bool operator()(const Import_init* i1, const Import_init* i2) const
111
kono
parents:
diff changeset
119 {
kono
parents:
diff changeset
120 return i1->init_name() < i2->init_name();
kono
parents:
diff changeset
121 }
kono
parents:
diff changeset
122 };
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 // Set of import init objects.
kono
parents:
diff changeset
125 class Import_init_set : public std::set<Import_init*, Import_init_lt> {
kono
parents:
diff changeset
126 };
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 inline bool
kono
parents:
diff changeset
129 priority_compare(const Import_init* i1, const Import_init* i2)
kono
parents:
diff changeset
130 {
kono
parents:
diff changeset
131 if (i1->priority() < i2->priority())
kono
parents:
diff changeset
132 return true;
kono
parents:
diff changeset
133 if (i1->priority() > i2->priority())
kono
parents:
diff changeset
134 return false;
kono
parents:
diff changeset
135 if (i1->package_name() != i2->package_name())
kono
parents:
diff changeset
136 return i1->package_name() < i2->package_name();
kono
parents:
diff changeset
137 return i1->init_name() < i2->init_name();
kono
parents:
diff changeset
138 }
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 // The holder for the internal representation of the entire
kono
parents:
diff changeset
141 // compilation unit.
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 class Gogo
kono
parents:
diff changeset
144 {
kono
parents:
diff changeset
145 public:
kono
parents:
diff changeset
146 // Create the IR, passing in the sizes of the types "int" and
kono
parents:
diff changeset
147 // "uintptr" in bits.
kono
parents:
diff changeset
148 Gogo(Backend* backend, Linemap *linemap, int int_type_size, int pointer_size);
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 // Get the backend generator.
kono
parents:
diff changeset
151 Backend*
kono
parents:
diff changeset
152 backend()
kono
parents:
diff changeset
153 { return this->backend_; }
kono
parents:
diff changeset
154
kono
parents:
diff changeset
155 // Get the Location generator.
kono
parents:
diff changeset
156 Linemap*
kono
parents:
diff changeset
157 linemap()
kono
parents:
diff changeset
158 { return this->linemap_; }
kono
parents:
diff changeset
159
kono
parents:
diff changeset
160 // Get the package name.
kono
parents:
diff changeset
161 const std::string&
kono
parents:
diff changeset
162 package_name() const;
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 // Set the package name.
kono
parents:
diff changeset
165 void
kono
parents:
diff changeset
166 set_package_name(const std::string&, Location);
kono
parents:
diff changeset
167
kono
parents:
diff changeset
168 // Return whether this is the "main" package.
kono
parents:
diff changeset
169 bool
kono
parents:
diff changeset
170 is_main_package() const;
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 // If necessary, adjust the name to use for a hidden symbol. We add
kono
parents:
diff changeset
173 // the package name, so that hidden symbols in different packages do
kono
parents:
diff changeset
174 // not collide.
kono
parents:
diff changeset
175 std::string
kono
parents:
diff changeset
176 pack_hidden_name(const std::string& name, bool is_exported) const
kono
parents:
diff changeset
177 {
kono
parents:
diff changeset
178 return (is_exported
kono
parents:
diff changeset
179 ? name
kono
parents:
diff changeset
180 : '.' + this->pkgpath() + '.' + name);
kono
parents:
diff changeset
181 }
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 // Unpack a name which may have been hidden. Returns the
kono
parents:
diff changeset
184 // user-visible name of the object.
kono
parents:
diff changeset
185 static std::string
kono
parents:
diff changeset
186 unpack_hidden_name(const std::string& name)
kono
parents:
diff changeset
187 { return name[0] != '.' ? name : name.substr(name.rfind('.') + 1); }
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 // Return whether a possibly packed name is hidden.
kono
parents:
diff changeset
190 static bool
kono
parents:
diff changeset
191 is_hidden_name(const std::string& name)
kono
parents:
diff changeset
192 { return name[0] == '.'; }
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 // Return the package path of a hidden name.
kono
parents:
diff changeset
195 static std::string
kono
parents:
diff changeset
196 hidden_name_pkgpath(const std::string& name)
kono
parents:
diff changeset
197 {
kono
parents:
diff changeset
198 go_assert(Gogo::is_hidden_name(name));
kono
parents:
diff changeset
199 return name.substr(1, name.rfind('.') - 1);
kono
parents:
diff changeset
200 }
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 // Given a name which may or may not have been hidden, return the
kono
parents:
diff changeset
203 // name to use within a mangled symbol name.
kono
parents:
diff changeset
204 static std::string
kono
parents:
diff changeset
205 mangle_possibly_hidden_name(const std::string& name)
kono
parents:
diff changeset
206 {
kono
parents:
diff changeset
207 // FIXME: This adds in pkgpath twice for hidden symbols, which is
kono
parents:
diff changeset
208 // less than ideal.
kono
parents:
diff changeset
209 std::string n;
kono
parents:
diff changeset
210 if (!Gogo::is_hidden_name(name))
kono
parents:
diff changeset
211 n = name;
kono
parents:
diff changeset
212 else
kono
parents:
diff changeset
213 {
kono
parents:
diff changeset
214 n = ".";
kono
parents:
diff changeset
215 std::string pkgpath = Gogo::hidden_name_pkgpath(name);
kono
parents:
diff changeset
216 n.append(Gogo::pkgpath_for_symbol(pkgpath));
kono
parents:
diff changeset
217 n.append(1, '.');
kono
parents:
diff changeset
218 n.append(Gogo::unpack_hidden_name(name));
kono
parents:
diff changeset
219 }
kono
parents:
diff changeset
220 return n;
kono
parents:
diff changeset
221 }
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 // Given a name which may or may not have been hidden, return the
kono
parents:
diff changeset
224 // name to use in an error message.
kono
parents:
diff changeset
225 static std::string
kono
parents:
diff changeset
226 message_name(const std::string& name);
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 // Return whether a name is the blank identifier _.
kono
parents:
diff changeset
229 static bool
kono
parents:
diff changeset
230 is_sink_name(const std::string& name)
kono
parents:
diff changeset
231 {
kono
parents:
diff changeset
232 return (name[0] == '.'
kono
parents:
diff changeset
233 && name[name.length() - 1] == '_'
kono
parents:
diff changeset
234 && name[name.length() - 2] == '.');
kono
parents:
diff changeset
235 }
kono
parents:
diff changeset
236
kono
parents:
diff changeset
237 // Convert a pkgpath into a string suitable for a symbol
kono
parents:
diff changeset
238 static std::string
kono
parents:
diff changeset
239 pkgpath_for_symbol(const std::string& pkgpath);
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 // Return the package path to use for reflect.Type.PkgPath.
kono
parents:
diff changeset
242 const std::string&
kono
parents:
diff changeset
243 pkgpath() const;
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 // Return the package path to use for a symbol name.
kono
parents:
diff changeset
246 const std::string&
kono
parents:
diff changeset
247 pkgpath_symbol() const;
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 // Set the package path from a command line option.
kono
parents:
diff changeset
250 void
kono
parents:
diff changeset
251 set_pkgpath(const std::string&);
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 // Set the prefix from a command line option.
kono
parents:
diff changeset
254 void
kono
parents:
diff changeset
255 set_prefix(const std::string&);
kono
parents:
diff changeset
256
kono
parents:
diff changeset
257 // Return whether pkgpath was set from a command line option.
kono
parents:
diff changeset
258 bool
kono
parents:
diff changeset
259 pkgpath_from_option() const
kono
parents:
diff changeset
260 { return this->pkgpath_from_option_; }
kono
parents:
diff changeset
261
kono
parents:
diff changeset
262 // Return the relative import path as set from the command line.
kono
parents:
diff changeset
263 // Returns an empty string if it was not set.
kono
parents:
diff changeset
264 const std::string&
kono
parents:
diff changeset
265 relative_import_path() const
kono
parents:
diff changeset
266 { return this->relative_import_path_; }
kono
parents:
diff changeset
267
kono
parents:
diff changeset
268 // Set the relative import path from a command line option.
kono
parents:
diff changeset
269 void
kono
parents:
diff changeset
270 set_relative_import_path(const std::string& s)
kono
parents:
diff changeset
271 { this->relative_import_path_ = s; }
kono
parents:
diff changeset
272
kono
parents:
diff changeset
273 // Set the C header file to write. This is used for the runtime
kono
parents:
diff changeset
274 // package.
kono
parents:
diff changeset
275 void
kono
parents:
diff changeset
276 set_c_header(const std::string& s)
kono
parents:
diff changeset
277 { this->c_header_ = s; }
kono
parents:
diff changeset
278
kono
parents:
diff changeset
279 // Return whether to check for division by zero in binary operations.
kono
parents:
diff changeset
280 bool
kono
parents:
diff changeset
281 check_divide_by_zero() const
kono
parents:
diff changeset
282 { return this->check_divide_by_zero_; }
kono
parents:
diff changeset
283
kono
parents:
diff changeset
284 // Set the option to check division by zero from a command line option.
kono
parents:
diff changeset
285 void
kono
parents:
diff changeset
286 set_check_divide_by_zero(bool b)
kono
parents:
diff changeset
287 { this->check_divide_by_zero_ = b; }
kono
parents:
diff changeset
288
kono
parents:
diff changeset
289 // Return whether to check for division overflow in binary operations.
kono
parents:
diff changeset
290 bool
kono
parents:
diff changeset
291 check_divide_overflow() const
kono
parents:
diff changeset
292 { return this->check_divide_overflow_; }
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 // Set the option to check division overflow from a command line option.
kono
parents:
diff changeset
295 void
kono
parents:
diff changeset
296 set_check_divide_overflow(bool b)
kono
parents:
diff changeset
297 { this->check_divide_overflow_ = b; }
kono
parents:
diff changeset
298
kono
parents:
diff changeset
299 // Return whether we are compiling the runtime package.
kono
parents:
diff changeset
300 bool
kono
parents:
diff changeset
301 compiling_runtime() const
kono
parents:
diff changeset
302 { return this->compiling_runtime_; }
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 // Set whether we are compiling the runtime package.
kono
parents:
diff changeset
305 void
kono
parents:
diff changeset
306 set_compiling_runtime(bool b)
kono
parents:
diff changeset
307 { this->compiling_runtime_ = b; }
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 // Return the level of escape analysis debug information to emit.
kono
parents:
diff changeset
310 int
kono
parents:
diff changeset
311 debug_escape_level() const
kono
parents:
diff changeset
312 { return this->debug_escape_level_; }
kono
parents:
diff changeset
313
kono
parents:
diff changeset
314 // Set the level of escape analysis debugging from a command line option.
kono
parents:
diff changeset
315 void
kono
parents:
diff changeset
316 set_debug_escape_level(int level)
kono
parents:
diff changeset
317 { this->debug_escape_level_ = level; }
kono
parents:
diff changeset
318
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
319 // Return the hash for debug escape analysis.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
320 std::string
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
321 debug_escape_hash() const
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
322 { return this->debug_escape_hash_; }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
323
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
324 // Set the hash value for debug escape analysis.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
325 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
326 set_debug_escape_hash(const std::string& s)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
327 { this->debug_escape_hash_ = s; }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
328
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
329 // Return the size threshold used to determine whether to issue
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
330 // a nil-check for a given pointer dereference. A threshold of -1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
331 // implies that all potentially faulting dereference ops should
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
332 // be nil-checked. A positive threshold of N implies that a deref
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
333 // of *P where P has size less than N doesn't need a nil check.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
334 int64_t
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
335 nil_check_size_threshold() const
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
336 { return this->nil_check_size_threshold_; }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
337
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
338 // Set the nil-check size threshold, as described above.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
339 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
340 set_nil_check_size_threshold(int64_t bytes)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
341 { this->nil_check_size_threshold_ = bytes; }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
342
111
kono
parents:
diff changeset
343 // Import a package. FILENAME is the file name argument, LOCAL_NAME
kono
parents:
diff changeset
344 // is the local name to give to the package. If LOCAL_NAME is empty
kono
parents:
diff changeset
345 // the declarations are added to the global scope.
kono
parents:
diff changeset
346 void
kono
parents:
diff changeset
347 import_package(const std::string& filename, const std::string& local_name,
kono
parents:
diff changeset
348 bool is_local_name_exported, bool must_exist, Location);
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 // Whether we are the global binding level.
kono
parents:
diff changeset
351 bool
kono
parents:
diff changeset
352 in_global_scope() const;
kono
parents:
diff changeset
353
kono
parents:
diff changeset
354 // Look up a name in the current binding contours.
kono
parents:
diff changeset
355 Named_object*
kono
parents:
diff changeset
356 lookup(const std::string&, Named_object** pfunction) const;
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 // Look up a name in the current block.
kono
parents:
diff changeset
359 Named_object*
kono
parents:
diff changeset
360 lookup_in_block(const std::string&) const;
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 // Look up a name in the global namespace--the universal scope.
kono
parents:
diff changeset
363 Named_object*
kono
parents:
diff changeset
364 lookup_global(const char*) const;
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 // Add a new imported package. REAL_NAME is the real name of the
kono
parents:
diff changeset
367 // package. ALIAS is the alias of the package; this may be the same
kono
parents:
diff changeset
368 // as REAL_NAME. This sets *PADD_TO_GLOBALS if symbols added to
kono
parents:
diff changeset
369 // this package should be added to the global namespace; this is
kono
parents:
diff changeset
370 // true if the alias is ".". LOCATION is the location of the import
kono
parents:
diff changeset
371 // statement. This returns the new package, or NULL on error.
kono
parents:
diff changeset
372 Package*
kono
parents:
diff changeset
373 add_imported_package(const std::string& real_name, const std::string& alias,
kono
parents:
diff changeset
374 bool is_alias_exported,
kono
parents:
diff changeset
375 const std::string& pkgpath,
kono
parents:
diff changeset
376 const std::string& pkgpath_symbol,
kono
parents:
diff changeset
377 Location location,
kono
parents:
diff changeset
378 bool* padd_to_globals);
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 // Register a package. This package may or may not be imported.
kono
parents:
diff changeset
381 // This returns the Package structure for the package, creating if
kono
parents:
diff changeset
382 // it necessary.
kono
parents:
diff changeset
383 Package*
kono
parents:
diff changeset
384 register_package(const std::string& pkgpath,
kono
parents:
diff changeset
385 const std::string& pkgpath_symbol, Location);
kono
parents:
diff changeset
386
kono
parents:
diff changeset
387 // Look up a package by pkgpath, and return its pkgpath_symbol.
kono
parents:
diff changeset
388 std::string
kono
parents:
diff changeset
389 pkgpath_symbol_for_package(const std::string&);
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 // Start compiling a function. ADD_METHOD_TO_TYPE is true if a
kono
parents:
diff changeset
392 // method function should be added to the type of its receiver.
kono
parents:
diff changeset
393 Named_object*
kono
parents:
diff changeset
394 start_function(const std::string& name, Function_type* type,
kono
parents:
diff changeset
395 bool add_method_to_type, Location);
kono
parents:
diff changeset
396
kono
parents:
diff changeset
397 // Finish compiling a function.
kono
parents:
diff changeset
398 void
kono
parents:
diff changeset
399 finish_function(Location);
kono
parents:
diff changeset
400
kono
parents:
diff changeset
401 // Return the current function.
kono
parents:
diff changeset
402 Named_object*
kono
parents:
diff changeset
403 current_function() const;
kono
parents:
diff changeset
404
kono
parents:
diff changeset
405 // Return the current block.
kono
parents:
diff changeset
406 Block*
kono
parents:
diff changeset
407 current_block();
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 // Start a new block. This is not initially associated with a
kono
parents:
diff changeset
410 // function.
kono
parents:
diff changeset
411 void
kono
parents:
diff changeset
412 start_block(Location);
kono
parents:
diff changeset
413
kono
parents:
diff changeset
414 // Finish the current block and return it.
kono
parents:
diff changeset
415 Block*
kono
parents:
diff changeset
416 finish_block(Location);
kono
parents:
diff changeset
417
kono
parents:
diff changeset
418 // Declare an erroneous name. This is used to avoid knock-on errors
kono
parents:
diff changeset
419 // after a parsing error.
kono
parents:
diff changeset
420 Named_object*
kono
parents:
diff changeset
421 add_erroneous_name(const std::string& name);
kono
parents:
diff changeset
422
kono
parents:
diff changeset
423 // Declare an unknown name. This is used while parsing. The name
kono
parents:
diff changeset
424 // must be resolved by the end of the parse. Unknown names are
kono
parents:
diff changeset
425 // always added at the package level.
kono
parents:
diff changeset
426 Named_object*
kono
parents:
diff changeset
427 add_unknown_name(const std::string& name, Location);
kono
parents:
diff changeset
428
kono
parents:
diff changeset
429 // Declare a function.
kono
parents:
diff changeset
430 Named_object*
kono
parents:
diff changeset
431 declare_function(const std::string&, Function_type*, Location);
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 // Declare a function at the package level. This is used for
kono
parents:
diff changeset
434 // functions generated for a type.
kono
parents:
diff changeset
435 Named_object*
kono
parents:
diff changeset
436 declare_package_function(const std::string&, Function_type*, Location);
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 // Add a label.
kono
parents:
diff changeset
439 Label*
kono
parents:
diff changeset
440 add_label_definition(const std::string&, Location);
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 // Add a label reference. ISSUE_GOTO_ERRORS is true if we should
kono
parents:
diff changeset
443 // report errors for a goto from the current location to the label
kono
parents:
diff changeset
444 // location.
kono
parents:
diff changeset
445 Label*
kono
parents:
diff changeset
446 add_label_reference(const std::string&, Location,
kono
parents:
diff changeset
447 bool issue_goto_errors);
kono
parents:
diff changeset
448
kono
parents:
diff changeset
449 // An analysis set is a list of functions paired with a boolean that indicates
kono
parents:
diff changeset
450 // whether the list of functions are recursive.
kono
parents:
diff changeset
451 typedef std::pair<std::vector<Named_object*>, bool> Analysis_set;
kono
parents:
diff changeset
452
kono
parents:
diff changeset
453 // Add a GROUP of possibly RECURSIVE functions to the Analysis_set for this
kono
parents:
diff changeset
454 // package.
kono
parents:
diff changeset
455 void
kono
parents:
diff changeset
456 add_analysis_set(const std::vector<Named_object*>& group, bool recursive)
kono
parents:
diff changeset
457 { this->analysis_sets_.push_back(std::make_pair(group, recursive)); }
kono
parents:
diff changeset
458
kono
parents:
diff changeset
459 // Return a snapshot of the current binding state.
kono
parents:
diff changeset
460 Bindings_snapshot*
kono
parents:
diff changeset
461 bindings_snapshot(Location);
kono
parents:
diff changeset
462
kono
parents:
diff changeset
463 // Add a statement to the current block.
kono
parents:
diff changeset
464 void
kono
parents:
diff changeset
465 add_statement(Statement*);
kono
parents:
diff changeset
466
kono
parents:
diff changeset
467 // Add a block to the current block.
kono
parents:
diff changeset
468 void
kono
parents:
diff changeset
469 add_block(Block*, Location);
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 // Add a constant.
kono
parents:
diff changeset
472 Named_object*
kono
parents:
diff changeset
473 add_constant(const Typed_identifier&, Expression*, int iota_value);
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 // Add a type.
kono
parents:
diff changeset
476 void
kono
parents:
diff changeset
477 add_type(const std::string&, Type*, Location);
kono
parents:
diff changeset
478
kono
parents:
diff changeset
479 // Add a named type. This is used for builtin types, and to add an
kono
parents:
diff changeset
480 // imported type to the global scope.
kono
parents:
diff changeset
481 void
kono
parents:
diff changeset
482 add_named_type(Named_type*);
kono
parents:
diff changeset
483
kono
parents:
diff changeset
484 // Declare a type.
kono
parents:
diff changeset
485 Named_object*
kono
parents:
diff changeset
486 declare_type(const std::string&, Location);
kono
parents:
diff changeset
487
kono
parents:
diff changeset
488 // Declare a type at the package level. This is used when the
kono
parents:
diff changeset
489 // parser sees an unknown name where a type name is required.
kono
parents:
diff changeset
490 Named_object*
kono
parents:
diff changeset
491 declare_package_type(const std::string&, Location);
kono
parents:
diff changeset
492
kono
parents:
diff changeset
493 // Define a type which was already declared.
kono
parents:
diff changeset
494 void
kono
parents:
diff changeset
495 define_type(Named_object*, Named_type*);
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 // Add a variable.
kono
parents:
diff changeset
498 Named_object*
kono
parents:
diff changeset
499 add_variable(const std::string&, Variable*);
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 // Add a sink--a reference to the blank identifier _.
kono
parents:
diff changeset
502 Named_object*
kono
parents:
diff changeset
503 add_sink();
kono
parents:
diff changeset
504
kono
parents:
diff changeset
505 // Add a type which needs to be verified. This is used for sink
kono
parents:
diff changeset
506 // types, just to give appropriate error messages.
kono
parents:
diff changeset
507 void
kono
parents:
diff changeset
508 add_type_to_verify(Type* type);
kono
parents:
diff changeset
509
kono
parents:
diff changeset
510 // Add a named object to the current namespace. This is used for
kono
parents:
diff changeset
511 // import . "package".
kono
parents:
diff changeset
512 void
kono
parents:
diff changeset
513 add_dot_import_object(Named_object*);
kono
parents:
diff changeset
514
kono
parents:
diff changeset
515 // Add an identifier to the list of names seen in the file block.
kono
parents:
diff changeset
516 void
kono
parents:
diff changeset
517 add_file_block_name(const std::string& name, Location location)
kono
parents:
diff changeset
518 { this->file_block_names_[name] = location; }
kono
parents:
diff changeset
519
kono
parents:
diff changeset
520 // Add a linkname, from the go:linkname compiler directive. This
kono
parents:
diff changeset
521 // changes the externally visible name of go_name to be ext_name.
kono
parents:
diff changeset
522 void
kono
parents:
diff changeset
523 add_linkname(const std::string& go_name, bool is_exported,
kono
parents:
diff changeset
524 const std::string& ext_name, Location location);
kono
parents:
diff changeset
525
kono
parents:
diff changeset
526 // Mark all local variables in current bindings as used. This is
kono
parents:
diff changeset
527 // used when there is a parse error to avoid useless errors.
kono
parents:
diff changeset
528 void
kono
parents:
diff changeset
529 mark_locals_used();
kono
parents:
diff changeset
530
kono
parents:
diff changeset
531 // Note that we've seen an interface type. This is used to build
kono
parents:
diff changeset
532 // all required interface method tables.
kono
parents:
diff changeset
533 void
kono
parents:
diff changeset
534 record_interface_type(Interface_type*);
kono
parents:
diff changeset
535
kono
parents:
diff changeset
536 // Note that we need an initialization function.
kono
parents:
diff changeset
537 void
kono
parents:
diff changeset
538 set_need_init_fn()
kono
parents:
diff changeset
539 { this->need_init_fn_ = true; }
kono
parents:
diff changeset
540
kono
parents:
diff changeset
541 // Return whether the current file imported the unsafe package.
kono
parents:
diff changeset
542 bool
kono
parents:
diff changeset
543 current_file_imported_unsafe() const
kono
parents:
diff changeset
544 { return this->current_file_imported_unsafe_; }
kono
parents:
diff changeset
545
kono
parents:
diff changeset
546 // Clear out all names in file scope. This is called when we start
kono
parents:
diff changeset
547 // parsing a new file.
kono
parents:
diff changeset
548 void
kono
parents:
diff changeset
549 clear_file_scope();
kono
parents:
diff changeset
550
kono
parents:
diff changeset
551 // Record that VAR1 must be initialized after VAR2. This is used
kono
parents:
diff changeset
552 // when VAR2 does not appear in VAR1's INIT or PREINIT.
kono
parents:
diff changeset
553 void
kono
parents:
diff changeset
554 record_var_depends_on(Variable* var1, Named_object* var2)
kono
parents:
diff changeset
555 {
kono
parents:
diff changeset
556 go_assert(this->var_deps_.find(var1) == this->var_deps_.end());
kono
parents:
diff changeset
557 this->var_deps_[var1] = var2;
kono
parents:
diff changeset
558 }
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 // Return the variable that VAR depends on, or NULL if none.
kono
parents:
diff changeset
561 Named_object*
kono
parents:
diff changeset
562 var_depends_on(Variable* var) const
kono
parents:
diff changeset
563 {
kono
parents:
diff changeset
564 Var_deps::const_iterator p = this->var_deps_.find(var);
kono
parents:
diff changeset
565 return p != this->var_deps_.end() ? p->second : NULL;
kono
parents:
diff changeset
566 }
kono
parents:
diff changeset
567
kono
parents:
diff changeset
568 // Queue up a type-specific function to be written out. This is
kono
parents:
diff changeset
569 // used when a type-specific function is needed when not at the top
kono
parents:
diff changeset
570 // level.
kono
parents:
diff changeset
571 void
kono
parents:
diff changeset
572 queue_specific_type_function(Type* type, Named_type* name, int64_t size,
kono
parents:
diff changeset
573 const std::string& hash_name,
kono
parents:
diff changeset
574 Function_type* hash_fntype,
kono
parents:
diff changeset
575 const std::string& equal_name,
kono
parents:
diff changeset
576 Function_type* equal_fntype);
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 // Write out queued specific type functions.
kono
parents:
diff changeset
579 void
kono
parents:
diff changeset
580 write_specific_type_functions();
kono
parents:
diff changeset
581
kono
parents:
diff changeset
582 // Whether we are done writing out specific type functions.
kono
parents:
diff changeset
583 bool
kono
parents:
diff changeset
584 specific_type_functions_are_written() const
kono
parents:
diff changeset
585 { return this->specific_type_functions_are_written_; }
kono
parents:
diff changeset
586
kono
parents:
diff changeset
587 // Add a pointer that needs to be added to the list of objects
kono
parents:
diff changeset
588 // traversed by the garbage collector. This should be an expression
kono
parents:
diff changeset
589 // of pointer type that points to static storage. It's not
kono
parents:
diff changeset
590 // necessary to add global variables to this list, just global
kono
parents:
diff changeset
591 // variable initializers that would otherwise not be seen.
kono
parents:
diff changeset
592 void
kono
parents:
diff changeset
593 add_gc_root(Expression* expr)
kono
parents:
diff changeset
594 {
kono
parents:
diff changeset
595 this->set_need_init_fn();
kono
parents:
diff changeset
596 this->gc_roots_.push_back(expr);
kono
parents:
diff changeset
597 }
kono
parents:
diff changeset
598
kono
parents:
diff changeset
599 // Traverse the tree. See the Traverse class.
kono
parents:
diff changeset
600 void
kono
parents:
diff changeset
601 traverse(Traverse*);
kono
parents:
diff changeset
602
kono
parents:
diff changeset
603 // Define the predeclared global names.
kono
parents:
diff changeset
604 void
kono
parents:
diff changeset
605 define_global_names();
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 // Verify and complete all types.
kono
parents:
diff changeset
608 void
kono
parents:
diff changeset
609 verify_types();
kono
parents:
diff changeset
610
kono
parents:
diff changeset
611 // Lower the parse tree.
kono
parents:
diff changeset
612 void
kono
parents:
diff changeset
613 lower_parse_tree();
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 // Lower all the statements in a block.
kono
parents:
diff changeset
616 void
kono
parents:
diff changeset
617 lower_block(Named_object* function, Block*);
kono
parents:
diff changeset
618
kono
parents:
diff changeset
619 // Lower an expression.
kono
parents:
diff changeset
620 void
kono
parents:
diff changeset
621 lower_expression(Named_object* function, Statement_inserter*, Expression**);
kono
parents:
diff changeset
622
kono
parents:
diff changeset
623 // Lower a constant.
kono
parents:
diff changeset
624 void
kono
parents:
diff changeset
625 lower_constant(Named_object*);
kono
parents:
diff changeset
626
kono
parents:
diff changeset
627 // Flatten all the statements in a block.
kono
parents:
diff changeset
628 void
kono
parents:
diff changeset
629 flatten_block(Named_object* function, Block*);
kono
parents:
diff changeset
630
kono
parents:
diff changeset
631 // Flatten an expression.
kono
parents:
diff changeset
632 void
kono
parents:
diff changeset
633 flatten_expression(Named_object* function, Statement_inserter*, Expression**);
kono
parents:
diff changeset
634
kono
parents:
diff changeset
635 // Create all necessary function descriptors.
kono
parents:
diff changeset
636 void
kono
parents:
diff changeset
637 create_function_descriptors();
kono
parents:
diff changeset
638
kono
parents:
diff changeset
639 // Finalize the method lists and build stub methods for named types.
kono
parents:
diff changeset
640 void
kono
parents:
diff changeset
641 finalize_methods();
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 // Work out the types to use for unspecified variables and
kono
parents:
diff changeset
644 // constants.
kono
parents:
diff changeset
645 void
kono
parents:
diff changeset
646 determine_types();
kono
parents:
diff changeset
647
kono
parents:
diff changeset
648 // Type check the program.
kono
parents:
diff changeset
649 void
kono
parents:
diff changeset
650 check_types();
kono
parents:
diff changeset
651
kono
parents:
diff changeset
652 // Check the types in a single block. This is used for complicated
kono
parents:
diff changeset
653 // go statements.
kono
parents:
diff changeset
654 void
kono
parents:
diff changeset
655 check_types_in_block(Block*);
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 // Check for return statements.
kono
parents:
diff changeset
658 void
kono
parents:
diff changeset
659 check_return_statements();
kono
parents:
diff changeset
660
kono
parents:
diff changeset
661 // Analyze the program flow for escape information.
kono
parents:
diff changeset
662 void
kono
parents:
diff changeset
663 analyze_escape();
kono
parents:
diff changeset
664
kono
parents:
diff changeset
665 // Discover the groups of possibly recursive functions in this package.
kono
parents:
diff changeset
666 void
kono
parents:
diff changeset
667 discover_analysis_sets();
kono
parents:
diff changeset
668
kono
parents:
diff changeset
669 // Build a connectivity graph between the objects in each analyzed function.
kono
parents:
diff changeset
670 void
kono
parents:
diff changeset
671 assign_connectivity(Escape_context*, Named_object*);
kono
parents:
diff changeset
672
kono
parents:
diff changeset
673 // Traverse the objects in the connecitivty graph from the sink, adjusting the
kono
parents:
diff changeset
674 // escape levels of each object.
kono
parents:
diff changeset
675 void
kono
parents:
diff changeset
676 propagate_escape(Escape_context*, Node*);
kono
parents:
diff changeset
677
kono
parents:
diff changeset
678 // Add notes about the escape level of a function's input and output
kono
parents:
diff changeset
679 // parameters for exporting and importing top level functions.
kono
parents:
diff changeset
680 void
kono
parents:
diff changeset
681 tag_function(Escape_context*, Named_object*);
kono
parents:
diff changeset
682
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
683 // Reclaim memory of escape analysis Nodes.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
684 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
685 reclaim_escape_nodes();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
686
111
kono
parents:
diff changeset
687 // Do all exports.
kono
parents:
diff changeset
688 void
kono
parents:
diff changeset
689 do_exports();
kono
parents:
diff changeset
690
kono
parents:
diff changeset
691 // Add an import control function for an imported package to the
kono
parents:
diff changeset
692 // list.
kono
parents:
diff changeset
693 void
kono
parents:
diff changeset
694 add_import_init_fn(const std::string& package_name,
kono
parents:
diff changeset
695 const std::string& init_name, int prio);
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 // Return the Import_init for a given init name.
kono
parents:
diff changeset
698 Import_init*
kono
parents:
diff changeset
699 lookup_init(const std::string& init_name);
kono
parents:
diff changeset
700
kono
parents:
diff changeset
701 // Turn short-cut operators (&&, ||) into explicit if statements.
kono
parents:
diff changeset
702 void
kono
parents:
diff changeset
703 remove_shortcuts();
kono
parents:
diff changeset
704
kono
parents:
diff changeset
705 // Use temporary variables to force order of evaluation.
kono
parents:
diff changeset
706 void
kono
parents:
diff changeset
707 order_evaluations();
kono
parents:
diff changeset
708
kono
parents:
diff changeset
709 // Add write barriers as needed.
kono
parents:
diff changeset
710 void
kono
parents:
diff changeset
711 add_write_barriers();
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 // Return whether an assignment that sets LHS to RHS needs a write
kono
parents:
diff changeset
714 // barrier.
kono
parents:
diff changeset
715 bool
kono
parents:
diff changeset
716 assign_needs_write_barrier(Expression* lhs);
kono
parents:
diff changeset
717
kono
parents:
diff changeset
718 // Return an assignment that sets LHS to RHS using a write barrier.
kono
parents:
diff changeset
719 // This returns an if statement that checks whether write barriers
kono
parents:
diff changeset
720 // are enabled. If not, it does LHS = RHS, otherwise it calls the
kono
parents:
diff changeset
721 // appropriate write barrier function.
kono
parents:
diff changeset
722 Statement*
kono
parents:
diff changeset
723 assign_with_write_barrier(Function*, Block*, Statement_inserter*,
kono
parents:
diff changeset
724 Expression* lhs, Expression* rhs, Location);
kono
parents:
diff changeset
725
kono
parents:
diff changeset
726 // Flatten parse tree.
kono
parents:
diff changeset
727 void
kono
parents:
diff changeset
728 flatten();
kono
parents:
diff changeset
729
kono
parents:
diff changeset
730 // Build thunks for functions which call recover.
kono
parents:
diff changeset
731 void
kono
parents:
diff changeset
732 build_recover_thunks();
kono
parents:
diff changeset
733
kono
parents:
diff changeset
734 // Return a declaration for __builtin_return_address or
kono
parents:
diff changeset
735 // __builtin_frame_address.
kono
parents:
diff changeset
736 static Named_object*
kono
parents:
diff changeset
737 declare_builtin_rf_address(const char* name);
kono
parents:
diff changeset
738
kono
parents:
diff changeset
739 // Simplify statements which might use thunks: go and defer
kono
parents:
diff changeset
740 // statements.
kono
parents:
diff changeset
741 void
kono
parents:
diff changeset
742 simplify_thunk_statements();
kono
parents:
diff changeset
743
kono
parents:
diff changeset
744 // Dump AST if -fgo-dump-ast is set
kono
parents:
diff changeset
745 void
kono
parents:
diff changeset
746 dump_ast(const char* basename);
kono
parents:
diff changeset
747
kono
parents:
diff changeset
748 // Dump Call Graph if -fgo-dump-calls is set.
kono
parents:
diff changeset
749 void
kono
parents:
diff changeset
750 dump_call_graph(const char* basename);
kono
parents:
diff changeset
751
kono
parents:
diff changeset
752 // Dump Connection Graphs if -fgo-dump-connections is set.
kono
parents:
diff changeset
753 void
kono
parents:
diff changeset
754 dump_connection_graphs(const char* basename);
kono
parents:
diff changeset
755
kono
parents:
diff changeset
756 // Convert named types to the backend representation.
kono
parents:
diff changeset
757 void
kono
parents:
diff changeset
758 convert_named_types();
kono
parents:
diff changeset
759
kono
parents:
diff changeset
760 // Convert named types in a list of bindings.
kono
parents:
diff changeset
761 void
kono
parents:
diff changeset
762 convert_named_types_in_bindings(Bindings*);
kono
parents:
diff changeset
763
kono
parents:
diff changeset
764 // True if named types have been converted to the backend
kono
parents:
diff changeset
765 // representation.
kono
parents:
diff changeset
766 bool
kono
parents:
diff changeset
767 named_types_are_converted() const
kono
parents:
diff changeset
768 { return this->named_types_are_converted_; }
kono
parents:
diff changeset
769
kono
parents:
diff changeset
770 // Give an error if the initialization of VAR depends on itself.
kono
parents:
diff changeset
771 void
kono
parents:
diff changeset
772 check_self_dep(Named_object*);
kono
parents:
diff changeset
773
kono
parents:
diff changeset
774 // Write out the global values.
kono
parents:
diff changeset
775 void
kono
parents:
diff changeset
776 write_globals();
kono
parents:
diff changeset
777
kono
parents:
diff changeset
778 // Build a call to the runtime error function.
kono
parents:
diff changeset
779 Expression*
kono
parents:
diff changeset
780 runtime_error(int code, Location);
kono
parents:
diff changeset
781
kono
parents:
diff changeset
782 // Build required interface method tables.
kono
parents:
diff changeset
783 void
kono
parents:
diff changeset
784 build_interface_method_tables();
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 // Return an expression which allocates memory to hold values of type TYPE.
kono
parents:
diff changeset
787 Expression*
kono
parents:
diff changeset
788 allocate_memory(Type *type, Location);
kono
parents:
diff changeset
789
kono
parents:
diff changeset
790 // Return the assembler name to use for an exported function, a
kono
parents:
diff changeset
791 // method, or a function/method declaration.
kono
parents:
diff changeset
792 std::string
kono
parents:
diff changeset
793 function_asm_name(const std::string& go_name, const Package*,
kono
parents:
diff changeset
794 const Type* receiver);
kono
parents:
diff changeset
795
kono
parents:
diff changeset
796 // Return the name to use for a function descriptor.
kono
parents:
diff changeset
797 std::string
kono
parents:
diff changeset
798 function_descriptor_name(Named_object*);
kono
parents:
diff changeset
799
kono
parents:
diff changeset
800 // Return the name to use for a generated stub method.
kono
parents:
diff changeset
801 std::string
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
802 stub_method_name(const Package*, const std::string& method_name);
111
kono
parents:
diff changeset
803
kono
parents:
diff changeset
804 // Return the names of the hash and equality functions for TYPE.
kono
parents:
diff changeset
805 void
kono
parents:
diff changeset
806 specific_type_function_names(const Type*, const Named_type*,
kono
parents:
diff changeset
807 std::string* hash_name,
kono
parents:
diff changeset
808 std::string* equal_name);
kono
parents:
diff changeset
809
kono
parents:
diff changeset
810 // Return the assembler name to use for a global variable.
kono
parents:
diff changeset
811 std::string
kono
parents:
diff changeset
812 global_var_asm_name(const std::string& go_name, const Package*);
kono
parents:
diff changeset
813
kono
parents:
diff changeset
814 // Return a name to use for an error case. This should only be used
kono
parents:
diff changeset
815 // after reporting an error, and is used to avoid useless knockon
kono
parents:
diff changeset
816 // errors.
kono
parents:
diff changeset
817 static std::string
kono
parents:
diff changeset
818 erroneous_name();
kono
parents:
diff changeset
819
kono
parents:
diff changeset
820 // Return whether the name indicates an error.
kono
parents:
diff changeset
821 static bool
kono
parents:
diff changeset
822 is_erroneous_name(const std::string&);
kono
parents:
diff changeset
823
kono
parents:
diff changeset
824 // Return a name to use for a thunk function. A thunk function is
kono
parents:
diff changeset
825 // one we create during the compilation, for a go statement or a
kono
parents:
diff changeset
826 // defer statement or a method expression.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
827 std::string
111
kono
parents:
diff changeset
828 thunk_name();
kono
parents:
diff changeset
829
kono
parents:
diff changeset
830 // Return whether an object is a thunk.
kono
parents:
diff changeset
831 static bool
kono
parents:
diff changeset
832 is_thunk(const Named_object*);
kono
parents:
diff changeset
833
kono
parents:
diff changeset
834 // Return the name to use for an init function.
kono
parents:
diff changeset
835 std::string
kono
parents:
diff changeset
836 init_function_name();
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 // Return the name to use for a nested function.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
839 std::string
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
840 nested_function_name(Named_object* enclosing);
111
kono
parents:
diff changeset
841
kono
parents:
diff changeset
842 // Return the name to use for a sink funciton.
kono
parents:
diff changeset
843 std::string
kono
parents:
diff changeset
844 sink_function_name();
kono
parents:
diff changeset
845
kono
parents:
diff changeset
846 // Return the name to use for an (erroneous) redefined function.
kono
parents:
diff changeset
847 std::string
kono
parents:
diff changeset
848 redefined_function_name();
kono
parents:
diff changeset
849
kono
parents:
diff changeset
850 // Return the name for use for a recover thunk.
kono
parents:
diff changeset
851 std::string
kono
parents:
diff changeset
852 recover_thunk_name(const std::string& name, const Type* rtype);
kono
parents:
diff changeset
853
kono
parents:
diff changeset
854 // Return the name to use for the GC root variable.
kono
parents:
diff changeset
855 std::string
kono
parents:
diff changeset
856 gc_root_name();
kono
parents:
diff changeset
857
kono
parents:
diff changeset
858 // Return the name to use for a composite literal or string
kono
parents:
diff changeset
859 // initializer.
kono
parents:
diff changeset
860 std::string
kono
parents:
diff changeset
861 initializer_name();
kono
parents:
diff changeset
862
kono
parents:
diff changeset
863 // Return the name of the variable used to represent the zero value
kono
parents:
diff changeset
864 // of a map.
kono
parents:
diff changeset
865 std::string
kono
parents:
diff changeset
866 map_zero_value_name();
kono
parents:
diff changeset
867
kono
parents:
diff changeset
868 // Get the name of the magic initialization function.
kono
parents:
diff changeset
869 const std::string&
kono
parents:
diff changeset
870 get_init_fn_name();
kono
parents:
diff changeset
871
kono
parents:
diff changeset
872 // Return the name for a type descriptor symbol.
kono
parents:
diff changeset
873 std::string
kono
parents:
diff changeset
874 type_descriptor_name(Type*, Named_type*);
kono
parents:
diff changeset
875
kono
parents:
diff changeset
876 // Return the assembler name for the GC symbol for a type.
kono
parents:
diff changeset
877 std::string
kono
parents:
diff changeset
878 gc_symbol_name(Type*);
kono
parents:
diff changeset
879
kono
parents:
diff changeset
880 // Return the assembler name for a ptrmask variable.
kono
parents:
diff changeset
881 std::string
kono
parents:
diff changeset
882 ptrmask_symbol_name(const std::string& ptrmask_sym_name);
kono
parents:
diff changeset
883
kono
parents:
diff changeset
884 // Return the name to use for an interface method table.
kono
parents:
diff changeset
885 std::string
kono
parents:
diff changeset
886 interface_method_table_name(Interface_type*, Type*, bool is_pointer);
kono
parents:
diff changeset
887
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
888 // Return whether NAME is a special name that can not be passed to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
889 // unpack_hidden_name. This is needed because various special names
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
890 // use "..SUFFIX", but unpack_hidden_name just looks for '.'.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
891 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
892 is_special_name(const std::string& name);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
893
111
kono
parents:
diff changeset
894 private:
kono
parents:
diff changeset
895 // During parsing, we keep a stack of functions. Each function on
kono
parents:
diff changeset
896 // the stack is one that we are currently parsing. For each
kono
parents:
diff changeset
897 // function, we keep track of the current stack of blocks.
kono
parents:
diff changeset
898 struct Open_function
kono
parents:
diff changeset
899 {
kono
parents:
diff changeset
900 // The function.
kono
parents:
diff changeset
901 Named_object* function;
kono
parents:
diff changeset
902 // The stack of active blocks in the function.
kono
parents:
diff changeset
903 std::vector<Block*> blocks;
kono
parents:
diff changeset
904 };
kono
parents:
diff changeset
905
kono
parents:
diff changeset
906 // The stack of functions.
kono
parents:
diff changeset
907 typedef std::vector<Open_function> Open_functions;
kono
parents:
diff changeset
908
kono
parents:
diff changeset
909 // Set up the built-in unsafe package.
kono
parents:
diff changeset
910 void
kono
parents:
diff changeset
911 import_unsafe(const std::string&, bool is_exported, Location);
kono
parents:
diff changeset
912
kono
parents:
diff changeset
913 // Return the current binding contour.
kono
parents:
diff changeset
914 Bindings*
kono
parents:
diff changeset
915 current_bindings();
kono
parents:
diff changeset
916
kono
parents:
diff changeset
917 const Bindings*
kono
parents:
diff changeset
918 current_bindings() const;
kono
parents:
diff changeset
919
kono
parents:
diff changeset
920 void
kono
parents:
diff changeset
921 write_c_header();
kono
parents:
diff changeset
922
kono
parents:
diff changeset
923 // Get the decl for the magic initialization function.
kono
parents:
diff changeset
924 Named_object*
kono
parents:
diff changeset
925 initialization_function_decl();
kono
parents:
diff changeset
926
kono
parents:
diff changeset
927 // Create the magic initialization function.
kono
parents:
diff changeset
928 Named_object*
kono
parents:
diff changeset
929 create_initialization_function(Named_object* fndecl, Bstatement* code_stmt);
kono
parents:
diff changeset
930
kono
parents:
diff changeset
931 // Initialize imported packages. BFUNCTION is the function
kono
parents:
diff changeset
932 // into which the package init calls will be placed.
kono
parents:
diff changeset
933 void
kono
parents:
diff changeset
934 init_imports(std::vector<Bstatement*>&, Bfunction* bfunction);
kono
parents:
diff changeset
935
kono
parents:
diff changeset
936 // Register variables with the garbage collector.
kono
parents:
diff changeset
937 void
kono
parents:
diff changeset
938 register_gc_vars(const std::vector<Named_object*>&,
kono
parents:
diff changeset
939 std::vector<Bstatement*>&,
kono
parents:
diff changeset
940 Bfunction* init_bfunction);
kono
parents:
diff changeset
941
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
942 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
943 propagate_writebarrierrec();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
944
111
kono
parents:
diff changeset
945 Named_object*
kono
parents:
diff changeset
946 write_barrier_variable();
kono
parents:
diff changeset
947
kono
parents:
diff changeset
948 Statement*
kono
parents:
diff changeset
949 check_write_barrier(Block*, Statement*, Statement*);
kono
parents:
diff changeset
950
kono
parents:
diff changeset
951 // Type used to map import names to packages.
kono
parents:
diff changeset
952 typedef std::map<std::string, Package*> Imports;
kono
parents:
diff changeset
953
kono
parents:
diff changeset
954 // Type used to map package names to packages.
kono
parents:
diff changeset
955 typedef std::map<std::string, Package*> Packages;
kono
parents:
diff changeset
956
kono
parents:
diff changeset
957 // Type used to map variables to the function calls that set them.
kono
parents:
diff changeset
958 // This is used for initialization dependency analysis.
kono
parents:
diff changeset
959 typedef std::map<Variable*, Named_object*> Var_deps;
kono
parents:
diff changeset
960
kono
parents:
diff changeset
961 // Type used to map identifiers in the file block to the location
kono
parents:
diff changeset
962 // where they were defined.
kono
parents:
diff changeset
963 typedef Unordered_map(std::string, Location) File_block_names;
kono
parents:
diff changeset
964
kono
parents:
diff changeset
965 // Type used to queue writing a type specific function.
kono
parents:
diff changeset
966 struct Specific_type_function
kono
parents:
diff changeset
967 {
kono
parents:
diff changeset
968 Type* type;
kono
parents:
diff changeset
969 Named_type* name;
kono
parents:
diff changeset
970 int64_t size;
kono
parents:
diff changeset
971 std::string hash_name;
kono
parents:
diff changeset
972 Function_type* hash_fntype;
kono
parents:
diff changeset
973 std::string equal_name;
kono
parents:
diff changeset
974 Function_type* equal_fntype;
kono
parents:
diff changeset
975
kono
parents:
diff changeset
976 Specific_type_function(Type* atype, Named_type* aname, int64_t asize,
kono
parents:
diff changeset
977 const std::string& ahash_name,
kono
parents:
diff changeset
978 Function_type* ahash_fntype,
kono
parents:
diff changeset
979 const std::string& aequal_name,
kono
parents:
diff changeset
980 Function_type* aequal_fntype)
kono
parents:
diff changeset
981 : type(atype), name(aname), size(asize), hash_name(ahash_name),
kono
parents:
diff changeset
982 hash_fntype(ahash_fntype), equal_name(aequal_name),
kono
parents:
diff changeset
983 equal_fntype(aequal_fntype)
kono
parents:
diff changeset
984 { }
kono
parents:
diff changeset
985 };
kono
parents:
diff changeset
986
kono
parents:
diff changeset
987 // Recompute init priorities.
kono
parents:
diff changeset
988 void
kono
parents:
diff changeset
989 recompute_init_priorities();
kono
parents:
diff changeset
990
kono
parents:
diff changeset
991 // Recursive helper used by the routine above.
kono
parents:
diff changeset
992 void
kono
parents:
diff changeset
993 update_init_priority(Import_init* ii,
kono
parents:
diff changeset
994 std::set<const Import_init *>* visited);
kono
parents:
diff changeset
995
kono
parents:
diff changeset
996 // The backend generator.
kono
parents:
diff changeset
997 Backend* backend_;
kono
parents:
diff changeset
998 // The object used to keep track of file names and line numbers.
kono
parents:
diff changeset
999 Linemap* linemap_;
kono
parents:
diff changeset
1000 // The package we are compiling.
kono
parents:
diff changeset
1001 Package* package_;
kono
parents:
diff changeset
1002 // The list of currently open functions during parsing.
kono
parents:
diff changeset
1003 Open_functions functions_;
kono
parents:
diff changeset
1004 // The global binding contour. This includes the builtin functions
kono
parents:
diff changeset
1005 // and the package we are compiling.
kono
parents:
diff changeset
1006 Bindings* globals_;
kono
parents:
diff changeset
1007 // The list of names we have seen in the file block.
kono
parents:
diff changeset
1008 File_block_names file_block_names_;
kono
parents:
diff changeset
1009 // Mapping from import file names to packages.
kono
parents:
diff changeset
1010 Imports imports_;
kono
parents:
diff changeset
1011 // Whether the magic unsafe package was imported.
kono
parents:
diff changeset
1012 bool imported_unsafe_;
kono
parents:
diff changeset
1013 // Whether the magic unsafe package was imported by the current file.
kono
parents:
diff changeset
1014 bool current_file_imported_unsafe_;
kono
parents:
diff changeset
1015 // Mapping from package names we have seen to packages. This does
kono
parents:
diff changeset
1016 // not include the package we are compiling.
kono
parents:
diff changeset
1017 Packages packages_;
kono
parents:
diff changeset
1018 // The functions named "init", if there are any.
kono
parents:
diff changeset
1019 std::vector<Named_object*> init_functions_;
kono
parents:
diff changeset
1020 // A mapping from variables to the function calls that initialize
kono
parents:
diff changeset
1021 // them, if it is not stored in the variable's init or preinit.
kono
parents:
diff changeset
1022 // This is used for dependency analysis.
kono
parents:
diff changeset
1023 Var_deps var_deps_;
kono
parents:
diff changeset
1024 // Whether we need a magic initialization function.
kono
parents:
diff changeset
1025 bool need_init_fn_;
kono
parents:
diff changeset
1026 // The name of the magic initialization function.
kono
parents:
diff changeset
1027 std::string init_fn_name_;
kono
parents:
diff changeset
1028 // A list of import control variables for packages that we import.
kono
parents:
diff changeset
1029 Import_init_set imported_init_fns_;
kono
parents:
diff changeset
1030 // The package path used for reflection data.
kono
parents:
diff changeset
1031 std::string pkgpath_;
kono
parents:
diff changeset
1032 // The package path to use for a symbol name.
kono
parents:
diff changeset
1033 std::string pkgpath_symbol_;
kono
parents:
diff changeset
1034 // The prefix to use for symbols, from the -fgo-prefix option.
kono
parents:
diff changeset
1035 std::string prefix_;
kono
parents:
diff changeset
1036 // Whether pkgpath_ has been set.
kono
parents:
diff changeset
1037 bool pkgpath_set_;
kono
parents:
diff changeset
1038 // Whether an explicit package path was set by -fgo-pkgpath.
kono
parents:
diff changeset
1039 bool pkgpath_from_option_;
kono
parents:
diff changeset
1040 // Whether an explicit prefix was set by -fgo-prefix.
kono
parents:
diff changeset
1041 bool prefix_from_option_;
kono
parents:
diff changeset
1042 // The relative import path, from the -fgo-relative-import-path
kono
parents:
diff changeset
1043 // option.
kono
parents:
diff changeset
1044 std::string relative_import_path_;
kono
parents:
diff changeset
1045 // The C header file to write, from the -fgo-c-header option.
kono
parents:
diff changeset
1046 std::string c_header_;
kono
parents:
diff changeset
1047 // Whether or not to check for division by zero, from the
kono
parents:
diff changeset
1048 // -fgo-check-divide-zero option.
kono
parents:
diff changeset
1049 bool check_divide_by_zero_;
kono
parents:
diff changeset
1050 // Whether or not to check for division overflow, from the
kono
parents:
diff changeset
1051 // -fgo-check-divide-overflow option.
kono
parents:
diff changeset
1052 bool check_divide_overflow_;
kono
parents:
diff changeset
1053 // Whether we are compiling the runtime package, from the
kono
parents:
diff changeset
1054 // -fgo-compiling-runtime option.
kono
parents:
diff changeset
1055 bool compiling_runtime_;
kono
parents:
diff changeset
1056 // The level of escape analysis debug information to emit, from the
kono
parents:
diff changeset
1057 // -fgo-debug-escape option.
kono
parents:
diff changeset
1058 int debug_escape_level_;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1059 // A hash value for debug escape analysis, from the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1060 // -fgo-debug-escape-hash option. The analysis is run only on
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1061 // functions with names that hash to the matching value.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1062 std::string debug_escape_hash_;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1063 // Nil-check size threshhold.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1064 int64_t nil_check_size_threshold_;
111
kono
parents:
diff changeset
1065 // A list of types to verify.
kono
parents:
diff changeset
1066 std::vector<Type*> verify_types_;
kono
parents:
diff changeset
1067 // A list of interface types defined while parsing.
kono
parents:
diff changeset
1068 std::vector<Interface_type*> interface_types_;
kono
parents:
diff changeset
1069 // Type specific functions to write out.
kono
parents:
diff changeset
1070 std::vector<Specific_type_function*> specific_type_functions_;
kono
parents:
diff changeset
1071 // Whether we are done writing out specific type functions.
kono
parents:
diff changeset
1072 bool specific_type_functions_are_written_;
kono
parents:
diff changeset
1073 // Whether named types have been converted.
kono
parents:
diff changeset
1074 bool named_types_are_converted_;
kono
parents:
diff changeset
1075 // A list containing groups of possibly mutually recursive functions to be
kono
parents:
diff changeset
1076 // considered during escape analysis.
kono
parents:
diff changeset
1077 std::vector<Analysis_set> analysis_sets_;
kono
parents:
diff changeset
1078 // A list of objects to add to the GC roots.
kono
parents:
diff changeset
1079 std::vector<Expression*> gc_roots_;
kono
parents:
diff changeset
1080 };
kono
parents:
diff changeset
1081
kono
parents:
diff changeset
1082 // A block of statements.
kono
parents:
diff changeset
1083
kono
parents:
diff changeset
1084 class Block
kono
parents:
diff changeset
1085 {
kono
parents:
diff changeset
1086 public:
kono
parents:
diff changeset
1087 Block(Block* enclosing, Location);
kono
parents:
diff changeset
1088
kono
parents:
diff changeset
1089 // Return the enclosing block.
kono
parents:
diff changeset
1090 const Block*
kono
parents:
diff changeset
1091 enclosing() const
kono
parents:
diff changeset
1092 { return this->enclosing_; }
kono
parents:
diff changeset
1093
kono
parents:
diff changeset
1094 // Return the bindings of the block.
kono
parents:
diff changeset
1095 Bindings*
kono
parents:
diff changeset
1096 bindings()
kono
parents:
diff changeset
1097 { return this->bindings_; }
kono
parents:
diff changeset
1098
kono
parents:
diff changeset
1099 const Bindings*
kono
parents:
diff changeset
1100 bindings() const
kono
parents:
diff changeset
1101 { return this->bindings_; }
kono
parents:
diff changeset
1102
kono
parents:
diff changeset
1103 // Look at the block's statements.
kono
parents:
diff changeset
1104 const std::vector<Statement*>*
kono
parents:
diff changeset
1105 statements() const
kono
parents:
diff changeset
1106 { return &this->statements_; }
kono
parents:
diff changeset
1107
kono
parents:
diff changeset
1108 // Return the start location. This is normally the location of the
kono
parents:
diff changeset
1109 // left curly brace which starts the block.
kono
parents:
diff changeset
1110 Location
kono
parents:
diff changeset
1111 start_location() const
kono
parents:
diff changeset
1112 { return this->start_location_; }
kono
parents:
diff changeset
1113
kono
parents:
diff changeset
1114 // Return the end location. This is normally the location of the
kono
parents:
diff changeset
1115 // right curly brace which ends the block.
kono
parents:
diff changeset
1116 Location
kono
parents:
diff changeset
1117 end_location() const
kono
parents:
diff changeset
1118 { return this->end_location_; }
kono
parents:
diff changeset
1119
kono
parents:
diff changeset
1120 // Add a statement to the block.
kono
parents:
diff changeset
1121 void
kono
parents:
diff changeset
1122 add_statement(Statement*);
kono
parents:
diff changeset
1123
kono
parents:
diff changeset
1124 // Add a statement to the front of the block.
kono
parents:
diff changeset
1125 void
kono
parents:
diff changeset
1126 add_statement_at_front(Statement*);
kono
parents:
diff changeset
1127
kono
parents:
diff changeset
1128 // Replace a statement in a block.
kono
parents:
diff changeset
1129 void
kono
parents:
diff changeset
1130 replace_statement(size_t index, Statement*);
kono
parents:
diff changeset
1131
kono
parents:
diff changeset
1132 // Add a Statement before statement number INDEX.
kono
parents:
diff changeset
1133 void
kono
parents:
diff changeset
1134 insert_statement_before(size_t index, Statement*);
kono
parents:
diff changeset
1135
kono
parents:
diff changeset
1136 // Add a Statement after statement number INDEX.
kono
parents:
diff changeset
1137 void
kono
parents:
diff changeset
1138 insert_statement_after(size_t index, Statement*);
kono
parents:
diff changeset
1139
kono
parents:
diff changeset
1140 // Set the end location of the block.
kono
parents:
diff changeset
1141 void
kono
parents:
diff changeset
1142 set_end_location(Location location)
kono
parents:
diff changeset
1143 { this->end_location_ = location; }
kono
parents:
diff changeset
1144
kono
parents:
diff changeset
1145 // Traverse the tree.
kono
parents:
diff changeset
1146 int
kono
parents:
diff changeset
1147 traverse(Traverse*);
kono
parents:
diff changeset
1148
kono
parents:
diff changeset
1149 // Set final types for unspecified variables and constants.
kono
parents:
diff changeset
1150 void
kono
parents:
diff changeset
1151 determine_types();
kono
parents:
diff changeset
1152
kono
parents:
diff changeset
1153 // Return true if execution of this block may fall through to the
kono
parents:
diff changeset
1154 // next block.
kono
parents:
diff changeset
1155 bool
kono
parents:
diff changeset
1156 may_fall_through() const;
kono
parents:
diff changeset
1157
kono
parents:
diff changeset
1158 // Convert the block to the backend representation.
kono
parents:
diff changeset
1159 Bblock*
kono
parents:
diff changeset
1160 get_backend(Translate_context*);
kono
parents:
diff changeset
1161
kono
parents:
diff changeset
1162 // Iterate over statements.
kono
parents:
diff changeset
1163
kono
parents:
diff changeset
1164 typedef std::vector<Statement*>::iterator iterator;
kono
parents:
diff changeset
1165
kono
parents:
diff changeset
1166 iterator
kono
parents:
diff changeset
1167 begin()
kono
parents:
diff changeset
1168 { return this->statements_.begin(); }
kono
parents:
diff changeset
1169
kono
parents:
diff changeset
1170 iterator
kono
parents:
diff changeset
1171 end()
kono
parents:
diff changeset
1172 { return this->statements_.end(); }
kono
parents:
diff changeset
1173
kono
parents:
diff changeset
1174 private:
kono
parents:
diff changeset
1175 // Enclosing block.
kono
parents:
diff changeset
1176 Block* enclosing_;
kono
parents:
diff changeset
1177 // Statements in the block.
kono
parents:
diff changeset
1178 std::vector<Statement*> statements_;
kono
parents:
diff changeset
1179 // Binding contour.
kono
parents:
diff changeset
1180 Bindings* bindings_;
kono
parents:
diff changeset
1181 // Location of start of block.
kono
parents:
diff changeset
1182 Location start_location_;
kono
parents:
diff changeset
1183 // Location of end of block.
kono
parents:
diff changeset
1184 Location end_location_;
kono
parents:
diff changeset
1185 };
kono
parents:
diff changeset
1186
kono
parents:
diff changeset
1187 // A function.
kono
parents:
diff changeset
1188
kono
parents:
diff changeset
1189 class Function
kono
parents:
diff changeset
1190 {
kono
parents:
diff changeset
1191 public:
kono
parents:
diff changeset
1192 Function(Function_type* type, Named_object*, Block*, Location);
kono
parents:
diff changeset
1193
kono
parents:
diff changeset
1194 // Return the function's type.
kono
parents:
diff changeset
1195 Function_type*
kono
parents:
diff changeset
1196 type() const
kono
parents:
diff changeset
1197 { return this->type_; }
kono
parents:
diff changeset
1198
kono
parents:
diff changeset
1199 // Return the enclosing function if there is one.
kono
parents:
diff changeset
1200 Named_object*
kono
parents:
diff changeset
1201 enclosing() const
kono
parents:
diff changeset
1202 { return this->enclosing_; }
kono
parents:
diff changeset
1203
kono
parents:
diff changeset
1204 // Set the enclosing function. This is used when building thunks
kono
parents:
diff changeset
1205 // for functions which call recover.
kono
parents:
diff changeset
1206 void
kono
parents:
diff changeset
1207 set_enclosing(Named_object* enclosing)
kono
parents:
diff changeset
1208 {
kono
parents:
diff changeset
1209 go_assert(this->enclosing_ == NULL);
kono
parents:
diff changeset
1210 this->enclosing_ = enclosing;
kono
parents:
diff changeset
1211 }
kono
parents:
diff changeset
1212
kono
parents:
diff changeset
1213 // The result variables.
kono
parents:
diff changeset
1214 typedef std::vector<Named_object*> Results;
kono
parents:
diff changeset
1215
kono
parents:
diff changeset
1216 // Create the result variables in the outer block.
kono
parents:
diff changeset
1217 void
kono
parents:
diff changeset
1218 create_result_variables(Gogo*);
kono
parents:
diff changeset
1219
kono
parents:
diff changeset
1220 // Update the named result variables when cloning a function which
kono
parents:
diff changeset
1221 // calls recover.
kono
parents:
diff changeset
1222 void
kono
parents:
diff changeset
1223 update_result_variables();
kono
parents:
diff changeset
1224
kono
parents:
diff changeset
1225 // Return the result variables.
kono
parents:
diff changeset
1226 Results*
kono
parents:
diff changeset
1227 result_variables()
kono
parents:
diff changeset
1228 { return this->results_; }
kono
parents:
diff changeset
1229
kono
parents:
diff changeset
1230 bool
kono
parents:
diff changeset
1231 is_sink() const
kono
parents:
diff changeset
1232 { return this->is_sink_; }
kono
parents:
diff changeset
1233
kono
parents:
diff changeset
1234 void
kono
parents:
diff changeset
1235 set_is_sink()
kono
parents:
diff changeset
1236 { this->is_sink_ = true; }
kono
parents:
diff changeset
1237
kono
parents:
diff changeset
1238 // Whether the result variables have names.
kono
parents:
diff changeset
1239 bool
kono
parents:
diff changeset
1240 results_are_named() const
kono
parents:
diff changeset
1241 { return this->results_are_named_; }
kono
parents:
diff changeset
1242
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1243 // Return the assembler name.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1244 const std::string&
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1245 asm_name() const
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1246 { return this->asm_name_; }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1247
111
kono
parents:
diff changeset
1248 // Set the assembler name.
kono
parents:
diff changeset
1249 void
kono
parents:
diff changeset
1250 set_asm_name(const std::string& asm_name)
kono
parents:
diff changeset
1251 { this->asm_name_ = asm_name; }
kono
parents:
diff changeset
1252
kono
parents:
diff changeset
1253 // Return the pragmas for this function.
kono
parents:
diff changeset
1254 unsigned int
kono
parents:
diff changeset
1255 pragmas() const
kono
parents:
diff changeset
1256 { return this->pragmas_; }
kono
parents:
diff changeset
1257
kono
parents:
diff changeset
1258 // Set the pragmas for this function.
kono
parents:
diff changeset
1259 void
kono
parents:
diff changeset
1260 set_pragmas(unsigned int pragmas)
kono
parents:
diff changeset
1261 {
kono
parents:
diff changeset
1262 this->pragmas_ = pragmas;
kono
parents:
diff changeset
1263 }
kono
parents:
diff changeset
1264
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1265 // Return the index to use for a nested function.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1266 unsigned int
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1267 next_nested_function_index()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1268 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1269 ++this->nested_functions_;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1270 return this->nested_functions_;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1271 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1272
111
kono
parents:
diff changeset
1273 // Whether this method should not be included in the type
kono
parents:
diff changeset
1274 // descriptor.
kono
parents:
diff changeset
1275 bool
kono
parents:
diff changeset
1276 nointerface() const;
kono
parents:
diff changeset
1277
kono
parents:
diff changeset
1278 // Record that this method should not be included in the type
kono
parents:
diff changeset
1279 // descriptor.
kono
parents:
diff changeset
1280 void
kono
parents:
diff changeset
1281 set_nointerface();
kono
parents:
diff changeset
1282
kono
parents:
diff changeset
1283 // Record that this function is a stub method created for an unnamed
kono
parents:
diff changeset
1284 // type.
kono
parents:
diff changeset
1285 void
kono
parents:
diff changeset
1286 set_is_unnamed_type_stub_method()
kono
parents:
diff changeset
1287 {
kono
parents:
diff changeset
1288 go_assert(this->is_method());
kono
parents:
diff changeset
1289 this->is_unnamed_type_stub_method_ = true;
kono
parents:
diff changeset
1290 }
kono
parents:
diff changeset
1291
kono
parents:
diff changeset
1292 // Return the amount of enclosed variables in this closure.
kono
parents:
diff changeset
1293 size_t
kono
parents:
diff changeset
1294 closure_field_count() const
kono
parents:
diff changeset
1295 { return this->closure_fields_.size(); }
kono
parents:
diff changeset
1296
kono
parents:
diff changeset
1297 // Add a new field to the closure variable.
kono
parents:
diff changeset
1298 void
kono
parents:
diff changeset
1299 add_closure_field(Named_object* var, Location loc)
kono
parents:
diff changeset
1300 { this->closure_fields_.push_back(std::make_pair(var, loc)); }
kono
parents:
diff changeset
1301
kono
parents:
diff changeset
1302 // Whether this function needs a closure.
kono
parents:
diff changeset
1303 bool
kono
parents:
diff changeset
1304 needs_closure() const
kono
parents:
diff changeset
1305 { return !this->closure_fields_.empty(); }
kono
parents:
diff changeset
1306
kono
parents:
diff changeset
1307 // Return the closure variable, creating it if necessary. This is
kono
parents:
diff changeset
1308 // passed to the function as a static chain parameter.
kono
parents:
diff changeset
1309 Named_object*
kono
parents:
diff changeset
1310 closure_var();
kono
parents:
diff changeset
1311
kono
parents:
diff changeset
1312 // Set the closure variable. This is used when building thunks for
kono
parents:
diff changeset
1313 // functions which call recover.
kono
parents:
diff changeset
1314 void
kono
parents:
diff changeset
1315 set_closure_var(Named_object* v)
kono
parents:
diff changeset
1316 {
kono
parents:
diff changeset
1317 go_assert(this->closure_var_ == NULL);
kono
parents:
diff changeset
1318 this->closure_var_ = v;
kono
parents:
diff changeset
1319 }
kono
parents:
diff changeset
1320
kono
parents:
diff changeset
1321 // Return the variable for a reference to field INDEX in the closure
kono
parents:
diff changeset
1322 // variable.
kono
parents:
diff changeset
1323 Named_object*
kono
parents:
diff changeset
1324 enclosing_var(unsigned int index)
kono
parents:
diff changeset
1325 {
kono
parents:
diff changeset
1326 go_assert(index < this->closure_fields_.size());
kono
parents:
diff changeset
1327 return closure_fields_[index].first;
kono
parents:
diff changeset
1328 }
kono
parents:
diff changeset
1329
kono
parents:
diff changeset
1330 // Set the type of the closure variable if there is one.
kono
parents:
diff changeset
1331 void
kono
parents:
diff changeset
1332 set_closure_type();
kono
parents:
diff changeset
1333
kono
parents:
diff changeset
1334 // Get the block of statements associated with the function.
kono
parents:
diff changeset
1335 Block*
kono
parents:
diff changeset
1336 block() const
kono
parents:
diff changeset
1337 { return this->block_; }
kono
parents:
diff changeset
1338
kono
parents:
diff changeset
1339 // Get the location of the start of the function.
kono
parents:
diff changeset
1340 Location
kono
parents:
diff changeset
1341 location() const
kono
parents:
diff changeset
1342 { return this->location_; }
kono
parents:
diff changeset
1343
kono
parents:
diff changeset
1344 // Return whether this function is actually a method.
kono
parents:
diff changeset
1345 bool
kono
parents:
diff changeset
1346 is_method() const;
kono
parents:
diff changeset
1347
kono
parents:
diff changeset
1348 // Add a label definition to the function.
kono
parents:
diff changeset
1349 Label*
kono
parents:
diff changeset
1350 add_label_definition(Gogo*, const std::string& label_name, Location);
kono
parents:
diff changeset
1351
kono
parents:
diff changeset
1352 // Add a label reference to a function. ISSUE_GOTO_ERRORS is true
kono
parents:
diff changeset
1353 // if we should report errors for a goto from the current location
kono
parents:
diff changeset
1354 // to the label location.
kono
parents:
diff changeset
1355 Label*
kono
parents:
diff changeset
1356 add_label_reference(Gogo*, const std::string& label_name,
kono
parents:
diff changeset
1357 Location, bool issue_goto_errors);
kono
parents:
diff changeset
1358
kono
parents:
diff changeset
1359 // Warn about labels that are defined but not used.
kono
parents:
diff changeset
1360 void
kono
parents:
diff changeset
1361 check_labels() const;
kono
parents:
diff changeset
1362
kono
parents:
diff changeset
1363 // Note that a new local type has been added. Return its index.
kono
parents:
diff changeset
1364 unsigned int
kono
parents:
diff changeset
1365 new_local_type_index()
kono
parents:
diff changeset
1366 { return this->local_type_count_++; }
kono
parents:
diff changeset
1367
kono
parents:
diff changeset
1368 // Whether this function calls the predeclared recover function.
kono
parents:
diff changeset
1369 bool
kono
parents:
diff changeset
1370 calls_recover() const
kono
parents:
diff changeset
1371 { return this->calls_recover_; }
kono
parents:
diff changeset
1372
kono
parents:
diff changeset
1373 // Record that this function calls the predeclared recover function.
kono
parents:
diff changeset
1374 // This is set during the lowering pass.
kono
parents:
diff changeset
1375 void
kono
parents:
diff changeset
1376 set_calls_recover()
kono
parents:
diff changeset
1377 { this->calls_recover_ = true; }
kono
parents:
diff changeset
1378
kono
parents:
diff changeset
1379 // Whether this is a recover thunk function.
kono
parents:
diff changeset
1380 bool
kono
parents:
diff changeset
1381 is_recover_thunk() const
kono
parents:
diff changeset
1382 { return this->is_recover_thunk_; }
kono
parents:
diff changeset
1383
kono
parents:
diff changeset
1384 // Record that this is a thunk built for a function which calls
kono
parents:
diff changeset
1385 // recover.
kono
parents:
diff changeset
1386 void
kono
parents:
diff changeset
1387 set_is_recover_thunk()
kono
parents:
diff changeset
1388 { this->is_recover_thunk_ = true; }
kono
parents:
diff changeset
1389
kono
parents:
diff changeset
1390 // Whether this function already has a recover thunk.
kono
parents:
diff changeset
1391 bool
kono
parents:
diff changeset
1392 has_recover_thunk() const
kono
parents:
diff changeset
1393 { return this->has_recover_thunk_; }
kono
parents:
diff changeset
1394
kono
parents:
diff changeset
1395 // Record that this function already has a recover thunk.
kono
parents:
diff changeset
1396 void
kono
parents:
diff changeset
1397 set_has_recover_thunk()
kono
parents:
diff changeset
1398 { this->has_recover_thunk_ = true; }
kono
parents:
diff changeset
1399
kono
parents:
diff changeset
1400 // Record that this function is a thunk created for a defer
kono
parents:
diff changeset
1401 // statement that calls the __go_set_defer_retaddr runtime function.
kono
parents:
diff changeset
1402 void
kono
parents:
diff changeset
1403 set_calls_defer_retaddr()
kono
parents:
diff changeset
1404 { this->calls_defer_retaddr_ = true; }
kono
parents:
diff changeset
1405
kono
parents:
diff changeset
1406 // Whether this is a type hash or equality function created by the
kono
parents:
diff changeset
1407 // compiler.
kono
parents:
diff changeset
1408 bool
kono
parents:
diff changeset
1409 is_type_specific_function()
kono
parents:
diff changeset
1410 { return this->is_type_specific_function_; }
kono
parents:
diff changeset
1411
kono
parents:
diff changeset
1412 // Record that this function is a type hash or equality function
kono
parents:
diff changeset
1413 // created by the compiler.
kono
parents:
diff changeset
1414 void
kono
parents:
diff changeset
1415 set_is_type_specific_function()
kono
parents:
diff changeset
1416 { this->is_type_specific_function_ = true; }
kono
parents:
diff changeset
1417
kono
parents:
diff changeset
1418 // Mark the function as going into a unique section.
kono
parents:
diff changeset
1419 void
kono
parents:
diff changeset
1420 set_in_unique_section()
kono
parents:
diff changeset
1421 { this->in_unique_section_ = true; }
kono
parents:
diff changeset
1422
kono
parents:
diff changeset
1423 // Swap with another function. Used only for the thunk which calls
kono
parents:
diff changeset
1424 // recover.
kono
parents:
diff changeset
1425 void
kono
parents:
diff changeset
1426 swap_for_recover(Function *);
kono
parents:
diff changeset
1427
kono
parents:
diff changeset
1428 // Traverse the tree.
kono
parents:
diff changeset
1429 int
kono
parents:
diff changeset
1430 traverse(Traverse*);
kono
parents:
diff changeset
1431
kono
parents:
diff changeset
1432 // Determine types in the function.
kono
parents:
diff changeset
1433 void
kono
parents:
diff changeset
1434 determine_types();
kono
parents:
diff changeset
1435
kono
parents:
diff changeset
1436 // Return an expression for the function descriptor, given the named
kono
parents:
diff changeset
1437 // object for this function. This may only be called for functions
kono
parents:
diff changeset
1438 // without a closure. This will be an immutable struct with one
kono
parents:
diff changeset
1439 // field that points to the function's code.
kono
parents:
diff changeset
1440 Expression*
kono
parents:
diff changeset
1441 descriptor(Gogo*, Named_object*);
kono
parents:
diff changeset
1442
kono
parents:
diff changeset
1443 // Set the descriptor for this function. This is used when a
kono
parents:
diff changeset
1444 // function declaration is followed by a function definition.
kono
parents:
diff changeset
1445 void
kono
parents:
diff changeset
1446 set_descriptor(Expression* descriptor)
kono
parents:
diff changeset
1447 {
kono
parents:
diff changeset
1448 go_assert(this->descriptor_ == NULL);
kono
parents:
diff changeset
1449 this->descriptor_ = descriptor;
kono
parents:
diff changeset
1450 }
kono
parents:
diff changeset
1451
kono
parents:
diff changeset
1452 // Return the backend representation.
kono
parents:
diff changeset
1453 Bfunction*
kono
parents:
diff changeset
1454 get_or_make_decl(Gogo*, Named_object*);
kono
parents:
diff changeset
1455
kono
parents:
diff changeset
1456 // Return the function's decl after it has been built.
kono
parents:
diff changeset
1457 Bfunction*
kono
parents:
diff changeset
1458 get_decl() const;
kono
parents:
diff changeset
1459
kono
parents:
diff changeset
1460 // Set the function decl to hold a backend representation of the function
kono
parents:
diff changeset
1461 // code.
kono
parents:
diff changeset
1462 void
kono
parents:
diff changeset
1463 build(Gogo*, Named_object*);
kono
parents:
diff changeset
1464
kono
parents:
diff changeset
1465 // Get the statement that assigns values to this function's result struct.
kono
parents:
diff changeset
1466 Bstatement*
kono
parents:
diff changeset
1467 return_value(Gogo*, Named_object*, Location) const;
kono
parents:
diff changeset
1468
kono
parents:
diff changeset
1469 // Get an expression for the variable holding the defer stack.
kono
parents:
diff changeset
1470 Expression*
kono
parents:
diff changeset
1471 defer_stack(Location);
kono
parents:
diff changeset
1472
kono
parents:
diff changeset
1473 // Export the function.
kono
parents:
diff changeset
1474 void
kono
parents:
diff changeset
1475 export_func(Export*, const std::string& name) const;
kono
parents:
diff changeset
1476
kono
parents:
diff changeset
1477 // Export a function with a type.
kono
parents:
diff changeset
1478 static void
kono
parents:
diff changeset
1479 export_func_with_type(Export*, const std::string& name,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1480 const Function_type*, bool nointerface);
111
kono
parents:
diff changeset
1481
kono
parents:
diff changeset
1482 // Import a function.
kono
parents:
diff changeset
1483 static void
kono
parents:
diff changeset
1484 import_func(Import*, std::string* pname, Typed_identifier** receiver,
kono
parents:
diff changeset
1485 Typed_identifier_list** pparameters,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1486 Typed_identifier_list** presults, bool* is_varargs,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1487 bool* nointerface);
111
kono
parents:
diff changeset
1488
kono
parents:
diff changeset
1489 private:
kono
parents:
diff changeset
1490 // Type for mapping from label names to Label objects.
kono
parents:
diff changeset
1491 typedef Unordered_map(std::string, Label*) Labels;
kono
parents:
diff changeset
1492
kono
parents:
diff changeset
1493 void
kono
parents:
diff changeset
1494 build_defer_wrapper(Gogo*, Named_object*, Bstatement**, Bstatement**);
kono
parents:
diff changeset
1495
kono
parents:
diff changeset
1496 typedef std::vector<std::pair<Named_object*,
kono
parents:
diff changeset
1497 Location> > Closure_fields;
kono
parents:
diff changeset
1498
kono
parents:
diff changeset
1499 // The function's type.
kono
parents:
diff changeset
1500 Function_type* type_;
kono
parents:
diff changeset
1501 // The enclosing function. This is NULL when there isn't one, which
kono
parents:
diff changeset
1502 // is the normal case.
kono
parents:
diff changeset
1503 Named_object* enclosing_;
kono
parents:
diff changeset
1504 // The result variables, if any.
kono
parents:
diff changeset
1505 Results* results_;
kono
parents:
diff changeset
1506 // If there is a closure, this is the list of variables which appear
kono
parents:
diff changeset
1507 // in the closure. This is created by the parser, and then resolved
kono
parents:
diff changeset
1508 // to a real type when we lower parse trees.
kono
parents:
diff changeset
1509 Closure_fields closure_fields_;
kono
parents:
diff changeset
1510 // The closure variable, passed as a parameter using the static
kono
parents:
diff changeset
1511 // chain parameter. Normally NULL.
kono
parents:
diff changeset
1512 Named_object* closure_var_;
kono
parents:
diff changeset
1513 // The outer block of statements in the function.
kono
parents:
diff changeset
1514 Block* block_;
kono
parents:
diff changeset
1515 // The source location of the start of the function.
kono
parents:
diff changeset
1516 Location location_;
kono
parents:
diff changeset
1517 // Labels defined or referenced in the function.
kono
parents:
diff changeset
1518 Labels labels_;
kono
parents:
diff changeset
1519 // The number of local types defined in this function.
kono
parents:
diff changeset
1520 unsigned int local_type_count_;
kono
parents:
diff changeset
1521 // The assembler name: this is the name that will be put in the object file.
kono
parents:
diff changeset
1522 // Set by the go:linkname compiler directive. This is normally empty.
kono
parents:
diff changeset
1523 std::string asm_name_;
kono
parents:
diff changeset
1524 // The function descriptor, if any.
kono
parents:
diff changeset
1525 Expression* descriptor_;
kono
parents:
diff changeset
1526 // The function decl.
kono
parents:
diff changeset
1527 Bfunction* fndecl_;
kono
parents:
diff changeset
1528 // The defer stack variable. A pointer to this variable is used to
kono
parents:
diff changeset
1529 // distinguish the defer stack for one function from another. This
kono
parents:
diff changeset
1530 // is NULL unless we actually need a defer stack.
kono
parents:
diff changeset
1531 Temporary_statement* defer_stack_;
kono
parents:
diff changeset
1532 // Pragmas for this function. This is a set of GOPRAGMA bits.
kono
parents:
diff changeset
1533 unsigned int pragmas_;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1534 // Number of nested functions defined within this function.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1535 unsigned int nested_functions_;
111
kono
parents:
diff changeset
1536 // True if this function is sink-named. No code is generated.
kono
parents:
diff changeset
1537 bool is_sink_ : 1;
kono
parents:
diff changeset
1538 // True if the result variables are named.
kono
parents:
diff changeset
1539 bool results_are_named_ : 1;
kono
parents:
diff changeset
1540 // True if this function is a stub method created for an unnamed
kono
parents:
diff changeset
1541 // type.
kono
parents:
diff changeset
1542 bool is_unnamed_type_stub_method_ : 1;
kono
parents:
diff changeset
1543 // True if this function calls the predeclared recover function.
kono
parents:
diff changeset
1544 bool calls_recover_ : 1;
kono
parents:
diff changeset
1545 // True if this a thunk built for a function which calls recover.
kono
parents:
diff changeset
1546 bool is_recover_thunk_ : 1;
kono
parents:
diff changeset
1547 // True if this function already has a recover thunk.
kono
parents:
diff changeset
1548 bool has_recover_thunk_ : 1;
kono
parents:
diff changeset
1549 // True if this is a thunk built for a defer statement that calls
kono
parents:
diff changeset
1550 // the __go_set_defer_retaddr runtime function.
kono
parents:
diff changeset
1551 bool calls_defer_retaddr_ : 1;
kono
parents:
diff changeset
1552 // True if this is a function built by the compiler to as a hash or
kono
parents:
diff changeset
1553 // equality function for some type.
kono
parents:
diff changeset
1554 bool is_type_specific_function_ : 1;
kono
parents:
diff changeset
1555 // True if this function should be put in a unique section. This is
kono
parents:
diff changeset
1556 // turned on for field tracking.
kono
parents:
diff changeset
1557 bool in_unique_section_ : 1;
kono
parents:
diff changeset
1558 };
kono
parents:
diff changeset
1559
kono
parents:
diff changeset
1560 // A snapshot of the current binding state.
kono
parents:
diff changeset
1561
kono
parents:
diff changeset
1562 class Bindings_snapshot
kono
parents:
diff changeset
1563 {
kono
parents:
diff changeset
1564 public:
kono
parents:
diff changeset
1565 Bindings_snapshot(const Block*, Location);
kono
parents:
diff changeset
1566
kono
parents:
diff changeset
1567 // Report any errors appropriate for a goto from the current binding
kono
parents:
diff changeset
1568 // state of B to this one.
kono
parents:
diff changeset
1569 void
kono
parents:
diff changeset
1570 check_goto_from(const Block* b, Location);
kono
parents:
diff changeset
1571
kono
parents:
diff changeset
1572 // Report any errors appropriate for a goto from this binding state
kono
parents:
diff changeset
1573 // to the current state of B.
kono
parents:
diff changeset
1574 void
kono
parents:
diff changeset
1575 check_goto_to(const Block* b);
kono
parents:
diff changeset
1576
kono
parents:
diff changeset
1577 private:
kono
parents:
diff changeset
1578 bool
kono
parents:
diff changeset
1579 check_goto_block(Location, const Block*, const Block*, size_t*);
kono
parents:
diff changeset
1580
kono
parents:
diff changeset
1581 void
kono
parents:
diff changeset
1582 check_goto_defs(Location, const Block*, size_t, size_t);
kono
parents:
diff changeset
1583
kono
parents:
diff changeset
1584 // The current block.
kono
parents:
diff changeset
1585 const Block* block_;
kono
parents:
diff changeset
1586 // The number of names currently defined in each open block.
kono
parents:
diff changeset
1587 // Element 0 is this->block_, element 1 is
kono
parents:
diff changeset
1588 // this->block_->enclosing(), etc.
kono
parents:
diff changeset
1589 std::vector<size_t> counts_;
kono
parents:
diff changeset
1590 // The location where this snapshot was taken.
kono
parents:
diff changeset
1591 Location location_;
kono
parents:
diff changeset
1592 };
kono
parents:
diff changeset
1593
kono
parents:
diff changeset
1594 // A function declaration.
kono
parents:
diff changeset
1595
kono
parents:
diff changeset
1596 class Function_declaration
kono
parents:
diff changeset
1597 {
kono
parents:
diff changeset
1598 public:
kono
parents:
diff changeset
1599 Function_declaration(Function_type* fntype, Location location)
kono
parents:
diff changeset
1600 : fntype_(fntype), location_(location), asm_name_(), descriptor_(NULL),
kono
parents:
diff changeset
1601 fndecl_(NULL), pragmas_(0)
kono
parents:
diff changeset
1602 { }
kono
parents:
diff changeset
1603
kono
parents:
diff changeset
1604 Function_type*
kono
parents:
diff changeset
1605 type() const
kono
parents:
diff changeset
1606 { return this->fntype_; }
kono
parents:
diff changeset
1607
kono
parents:
diff changeset
1608 Location
kono
parents:
diff changeset
1609 location() const
kono
parents:
diff changeset
1610 { return this->location_; }
kono
parents:
diff changeset
1611
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1612 // Return whether this function declaration is a method.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1613 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1614 is_method() const;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1615
111
kono
parents:
diff changeset
1616 const std::string&
kono
parents:
diff changeset
1617 asm_name() const
kono
parents:
diff changeset
1618 { return this->asm_name_; }
kono
parents:
diff changeset
1619
kono
parents:
diff changeset
1620 // Set the assembler name.
kono
parents:
diff changeset
1621 void
kono
parents:
diff changeset
1622 set_asm_name(const std::string& asm_name)
kono
parents:
diff changeset
1623 { this->asm_name_ = asm_name; }
kono
parents:
diff changeset
1624
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1625 // Return the pragmas for this function.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1626 unsigned int
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1627 pragmas() const
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1628 { return this->pragmas_; }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1629
111
kono
parents:
diff changeset
1630 // Set the pragmas for this function.
kono
parents:
diff changeset
1631 void
kono
parents:
diff changeset
1632 set_pragmas(unsigned int pragmas)
kono
parents:
diff changeset
1633 {
kono
parents:
diff changeset
1634 this->pragmas_ = pragmas;
kono
parents:
diff changeset
1635 }
kono
parents:
diff changeset
1636
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1637 // Whether this method should not be included in the type
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1638 // descriptor.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1639 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1640 nointerface() const;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1641
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1642 // Record that this method should not be included in the type
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1643 // descriptor.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1644 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1645 set_nointerface();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1646
111
kono
parents:
diff changeset
1647 // Return an expression for the function descriptor, given the named
kono
parents:
diff changeset
1648 // object for this function. This may only be called for functions
kono
parents:
diff changeset
1649 // without a closure. This will be an immutable struct with one
kono
parents:
diff changeset
1650 // field that points to the function's code.
kono
parents:
diff changeset
1651 Expression*
kono
parents:
diff changeset
1652 descriptor(Gogo*, Named_object*);
kono
parents:
diff changeset
1653
kono
parents:
diff changeset
1654 // Return true if we have created a descriptor for this declaration.
kono
parents:
diff changeset
1655 bool
kono
parents:
diff changeset
1656 has_descriptor() const
kono
parents:
diff changeset
1657 { return this->descriptor_ != NULL; }
kono
parents:
diff changeset
1658
kono
parents:
diff changeset
1659 // Return a backend representation.
kono
parents:
diff changeset
1660 Bfunction*
kono
parents:
diff changeset
1661 get_or_make_decl(Gogo*, Named_object*);
kono
parents:
diff changeset
1662
kono
parents:
diff changeset
1663 // If there is a descriptor, build it into the backend
kono
parents:
diff changeset
1664 // representation.
kono
parents:
diff changeset
1665 void
kono
parents:
diff changeset
1666 build_backend_descriptor(Gogo*);
kono
parents:
diff changeset
1667
kono
parents:
diff changeset
1668 // Export a function declaration.
kono
parents:
diff changeset
1669 void
kono
parents:
diff changeset
1670 export_func(Export* exp, const std::string& name) const
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1671 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1672 Function::export_func_with_type(exp, name, this->fntype_,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1673 this->is_method() && this->nointerface());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1674 }
111
kono
parents:
diff changeset
1675
kono
parents:
diff changeset
1676 // Check that the types used in this declaration's signature are defined.
kono
parents:
diff changeset
1677 void
kono
parents:
diff changeset
1678 check_types() const;
kono
parents:
diff changeset
1679
kono
parents:
diff changeset
1680 private:
kono
parents:
diff changeset
1681 // The type of the function.
kono
parents:
diff changeset
1682 Function_type* fntype_;
kono
parents:
diff changeset
1683 // The location of the declaration.
kono
parents:
diff changeset
1684 Location location_;
kono
parents:
diff changeset
1685 // The assembler name: this is the name to use in references to the
kono
parents:
diff changeset
1686 // function. This is normally empty.
kono
parents:
diff changeset
1687 std::string asm_name_;
kono
parents:
diff changeset
1688 // The function descriptor, if any.
kono
parents:
diff changeset
1689 Expression* descriptor_;
kono
parents:
diff changeset
1690 // The function decl if needed.
kono
parents:
diff changeset
1691 Bfunction* fndecl_;
kono
parents:
diff changeset
1692 // Pragmas for this function. This is a set of GOPRAGMA bits.
kono
parents:
diff changeset
1693 unsigned int pragmas_;
kono
parents:
diff changeset
1694 };
kono
parents:
diff changeset
1695
kono
parents:
diff changeset
1696 // A variable.
kono
parents:
diff changeset
1697
kono
parents:
diff changeset
1698 class Variable
kono
parents:
diff changeset
1699 {
kono
parents:
diff changeset
1700 public:
kono
parents:
diff changeset
1701 Variable(Type*, Expression*, bool is_global, bool is_parameter,
kono
parents:
diff changeset
1702 bool is_receiver, Location);
kono
parents:
diff changeset
1703
kono
parents:
diff changeset
1704 // Get the type of the variable.
kono
parents:
diff changeset
1705 Type*
kono
parents:
diff changeset
1706 type();
kono
parents:
diff changeset
1707
kono
parents:
diff changeset
1708 Type*
kono
parents:
diff changeset
1709 type() const;
kono
parents:
diff changeset
1710
kono
parents:
diff changeset
1711 // Return whether the type is defined yet.
kono
parents:
diff changeset
1712 bool
kono
parents:
diff changeset
1713 has_type() const;
kono
parents:
diff changeset
1714
kono
parents:
diff changeset
1715 // Get the initial value.
kono
parents:
diff changeset
1716 Expression*
kono
parents:
diff changeset
1717 init() const
kono
parents:
diff changeset
1718 { return this->init_; }
kono
parents:
diff changeset
1719
kono
parents:
diff changeset
1720 // Return whether there are any preinit statements.
kono
parents:
diff changeset
1721 bool
kono
parents:
diff changeset
1722 has_pre_init() const
kono
parents:
diff changeset
1723 { return this->preinit_ != NULL; }
kono
parents:
diff changeset
1724
kono
parents:
diff changeset
1725 // Return the preinit statements if any.
kono
parents:
diff changeset
1726 Block*
kono
parents:
diff changeset
1727 preinit() const
kono
parents:
diff changeset
1728 { return this->preinit_; }
kono
parents:
diff changeset
1729
kono
parents:
diff changeset
1730 // Return whether this is a global variable.
kono
parents:
diff changeset
1731 bool
kono
parents:
diff changeset
1732 is_global() const
kono
parents:
diff changeset
1733 { return this->is_global_; }
kono
parents:
diff changeset
1734
kono
parents:
diff changeset
1735 // Return whether this is a function parameter.
kono
parents:
diff changeset
1736 bool
kono
parents:
diff changeset
1737 is_parameter() const
kono
parents:
diff changeset
1738 { return this->is_parameter_; }
kono
parents:
diff changeset
1739
kono
parents:
diff changeset
1740 // Return whether this is a closure (static chain) parameter.
kono
parents:
diff changeset
1741 bool
kono
parents:
diff changeset
1742 is_closure() const
kono
parents:
diff changeset
1743 { return this->is_closure_; }
kono
parents:
diff changeset
1744
kono
parents:
diff changeset
1745 // Change this parameter to be a closure.
kono
parents:
diff changeset
1746 void
kono
parents:
diff changeset
1747 set_is_closure()
kono
parents:
diff changeset
1748 {
kono
parents:
diff changeset
1749 this->is_closure_ = true;
kono
parents:
diff changeset
1750 }
kono
parents:
diff changeset
1751
kono
parents:
diff changeset
1752 // Return whether this is the receiver parameter of a method.
kono
parents:
diff changeset
1753 bool
kono
parents:
diff changeset
1754 is_receiver() const
kono
parents:
diff changeset
1755 { return this->is_receiver_; }
kono
parents:
diff changeset
1756
kono
parents:
diff changeset
1757 // Change this parameter to be a receiver. This is used when
kono
parents:
diff changeset
1758 // creating the thunks created for functions which call recover.
kono
parents:
diff changeset
1759 void
kono
parents:
diff changeset
1760 set_is_receiver()
kono
parents:
diff changeset
1761 {
kono
parents:
diff changeset
1762 go_assert(this->is_parameter_);
kono
parents:
diff changeset
1763 this->is_receiver_ = true;
kono
parents:
diff changeset
1764 }
kono
parents:
diff changeset
1765
kono
parents:
diff changeset
1766 // Change this parameter to not be a receiver. This is used when
kono
parents:
diff changeset
1767 // creating the thunks created for functions which call recover.
kono
parents:
diff changeset
1768 void
kono
parents:
diff changeset
1769 set_is_not_receiver()
kono
parents:
diff changeset
1770 {
kono
parents:
diff changeset
1771 go_assert(this->is_parameter_);
kono
parents:
diff changeset
1772 this->is_receiver_ = false;
kono
parents:
diff changeset
1773 }
kono
parents:
diff changeset
1774
kono
parents:
diff changeset
1775 // Return whether this is the varargs parameter of a function.
kono
parents:
diff changeset
1776 bool
kono
parents:
diff changeset
1777 is_varargs_parameter() const
kono
parents:
diff changeset
1778 { return this->is_varargs_parameter_; }
kono
parents:
diff changeset
1779
kono
parents:
diff changeset
1780 // Whether this variable's address is taken.
kono
parents:
diff changeset
1781 bool
kono
parents:
diff changeset
1782 is_address_taken() const
kono
parents:
diff changeset
1783 { return this->is_address_taken_; }
kono
parents:
diff changeset
1784
kono
parents:
diff changeset
1785 // Whether this variable should live in the heap.
kono
parents:
diff changeset
1786 bool
kono
parents:
diff changeset
1787 is_in_heap() const
kono
parents:
diff changeset
1788 {
kono
parents:
diff changeset
1789 return this->is_address_taken_
kono
parents:
diff changeset
1790 && this->escapes_
kono
parents:
diff changeset
1791 && !this->is_global_;
kono
parents:
diff changeset
1792 }
kono
parents:
diff changeset
1793
kono
parents:
diff changeset
1794 // Note that something takes the address of this variable.
kono
parents:
diff changeset
1795 void
kono
parents:
diff changeset
1796 set_address_taken()
kono
parents:
diff changeset
1797 { this->is_address_taken_ = true; }
kono
parents:
diff changeset
1798
kono
parents:
diff changeset
1799 // Return whether the address is taken but does not escape.
kono
parents:
diff changeset
1800 bool
kono
parents:
diff changeset
1801 is_non_escaping_address_taken() const
kono
parents:
diff changeset
1802 { return this->is_non_escaping_address_taken_; }
kono
parents:
diff changeset
1803
kono
parents:
diff changeset
1804 // Note that something takes the address of this variable such that
kono
parents:
diff changeset
1805 // the address does not escape the function.
kono
parents:
diff changeset
1806 void
kono
parents:
diff changeset
1807 set_non_escaping_address_taken()
kono
parents:
diff changeset
1808 { this->is_non_escaping_address_taken_ = true; }
kono
parents:
diff changeset
1809
kono
parents:
diff changeset
1810 // Return whether this variable escapes the function it is declared in.
kono
parents:
diff changeset
1811 bool
kono
parents:
diff changeset
1812 escapes()
kono
parents:
diff changeset
1813 { return this->escapes_; }
kono
parents:
diff changeset
1814
kono
parents:
diff changeset
1815 // Note that this variable does not escape the function it is declared in.
kono
parents:
diff changeset
1816 void
kono
parents:
diff changeset
1817 set_does_not_escape()
kono
parents:
diff changeset
1818 { this->escapes_ = false; }
kono
parents:
diff changeset
1819
kono
parents:
diff changeset
1820 // Get the source location of the variable's declaration.
kono
parents:
diff changeset
1821 Location
kono
parents:
diff changeset
1822 location() const
kono
parents:
diff changeset
1823 { return this->location_; }
kono
parents:
diff changeset
1824
kono
parents:
diff changeset
1825 // Record that this is the varargs parameter of a function.
kono
parents:
diff changeset
1826 void
kono
parents:
diff changeset
1827 set_is_varargs_parameter()
kono
parents:
diff changeset
1828 {
kono
parents:
diff changeset
1829 go_assert(this->is_parameter_);
kono
parents:
diff changeset
1830 this->is_varargs_parameter_ = true;
kono
parents:
diff changeset
1831 }
kono
parents:
diff changeset
1832
kono
parents:
diff changeset
1833 // Return whether the variable has been used.
kono
parents:
diff changeset
1834 bool
kono
parents:
diff changeset
1835 is_used() const
kono
parents:
diff changeset
1836 { return this->is_used_; }
kono
parents:
diff changeset
1837
kono
parents:
diff changeset
1838 // Mark that the variable has been used.
kono
parents:
diff changeset
1839 void
kono
parents:
diff changeset
1840 set_is_used()
kono
parents:
diff changeset
1841 { this->is_used_ = true; }
kono
parents:
diff changeset
1842
kono
parents:
diff changeset
1843 // Clear the initial value; used for error handling and write barriers.
kono
parents:
diff changeset
1844 void
kono
parents:
diff changeset
1845 clear_init()
kono
parents:
diff changeset
1846 { this->init_ = NULL; }
kono
parents:
diff changeset
1847
kono
parents:
diff changeset
1848 // Set the initial value; used for converting shortcuts.
kono
parents:
diff changeset
1849 void
kono
parents:
diff changeset
1850 set_init(Expression* init)
kono
parents:
diff changeset
1851 { this->init_ = init; }
kono
parents:
diff changeset
1852
kono
parents:
diff changeset
1853 // Get the preinit block, a block of statements to be run before the
kono
parents:
diff changeset
1854 // initialization expression.
kono
parents:
diff changeset
1855 Block*
kono
parents:
diff changeset
1856 preinit_block(Gogo*);
kono
parents:
diff changeset
1857
kono
parents:
diff changeset
1858 // Add a statement to be run before the initialization expression.
kono
parents:
diff changeset
1859 // This is only used for global variables.
kono
parents:
diff changeset
1860 void
kono
parents:
diff changeset
1861 add_preinit_statement(Gogo*, Statement*);
kono
parents:
diff changeset
1862
kono
parents:
diff changeset
1863 // Lower the initialization expression after parsing is complete.
kono
parents:
diff changeset
1864 void
kono
parents:
diff changeset
1865 lower_init_expression(Gogo*, Named_object*, Statement_inserter*);
kono
parents:
diff changeset
1866
kono
parents:
diff changeset
1867 // Flatten the initialization expression after ordering evaluations.
kono
parents:
diff changeset
1868 void
kono
parents:
diff changeset
1869 flatten_init_expression(Gogo*, Named_object*, Statement_inserter*);
kono
parents:
diff changeset
1870
kono
parents:
diff changeset
1871 // A special case: the init value is used only to determine the
kono
parents:
diff changeset
1872 // type. This is used if the variable is defined using := with the
kono
parents:
diff changeset
1873 // comma-ok form of a map index or a receive expression. The init
kono
parents:
diff changeset
1874 // value is actually the map index expression or receive expression.
kono
parents:
diff changeset
1875 // We use this because we may not know the right type at parse time.
kono
parents:
diff changeset
1876 void
kono
parents:
diff changeset
1877 set_type_from_init_tuple()
kono
parents:
diff changeset
1878 { this->type_from_init_tuple_ = true; }
kono
parents:
diff changeset
1879
kono
parents:
diff changeset
1880 // Another special case: the init value is used only to determine
kono
parents:
diff changeset
1881 // the type. This is used if the variable is defined using := with
kono
parents:
diff changeset
1882 // a range clause. The init value is the range expression. The
kono
parents:
diff changeset
1883 // type of the variable is the index type of the range expression
kono
parents:
diff changeset
1884 // (i.e., the first value returned by a range).
kono
parents:
diff changeset
1885 void
kono
parents:
diff changeset
1886 set_type_from_range_index()
kono
parents:
diff changeset
1887 { this->type_from_range_index_ = true; }
kono
parents:
diff changeset
1888
kono
parents:
diff changeset
1889 // Another special case: like set_type_from_range_index, but the
kono
parents:
diff changeset
1890 // type is the value type of the range expression (i.e., the second
kono
parents:
diff changeset
1891 // value returned by a range).
kono
parents:
diff changeset
1892 void
kono
parents:
diff changeset
1893 set_type_from_range_value()
kono
parents:
diff changeset
1894 { this->type_from_range_value_ = true; }
kono
parents:
diff changeset
1895
kono
parents:
diff changeset
1896 // Another special case: the init value is used only to determine
kono
parents:
diff changeset
1897 // the type. This is used if the variable is defined using := with
kono
parents:
diff changeset
1898 // a case in a select statement. The init value is the channel.
kono
parents:
diff changeset
1899 // The type of the variable is the channel's element type.
kono
parents:
diff changeset
1900 void
kono
parents:
diff changeset
1901 set_type_from_chan_element()
kono
parents:
diff changeset
1902 { this->type_from_chan_element_ = true; }
kono
parents:
diff changeset
1903
kono
parents:
diff changeset
1904 // After we lower the select statement, we once again set the type
kono
parents:
diff changeset
1905 // from the initialization expression.
kono
parents:
diff changeset
1906 void
kono
parents:
diff changeset
1907 clear_type_from_chan_element()
kono
parents:
diff changeset
1908 {
kono
parents:
diff changeset
1909 go_assert(this->type_from_chan_element_);
kono
parents:
diff changeset
1910 this->type_from_chan_element_ = false;
kono
parents:
diff changeset
1911 }
kono
parents:
diff changeset
1912
kono
parents:
diff changeset
1913 // TRUE if this variable was created for a type switch clause.
kono
parents:
diff changeset
1914 bool
kono
parents:
diff changeset
1915 is_type_switch_var() const
kono
parents:
diff changeset
1916 { return this->is_type_switch_var_; }
kono
parents:
diff changeset
1917
kono
parents:
diff changeset
1918 // Note that this variable was created for a type switch clause.
kono
parents:
diff changeset
1919 void
kono
parents:
diff changeset
1920 set_is_type_switch_var()
kono
parents:
diff changeset
1921 { this->is_type_switch_var_ = true; }
kono
parents:
diff changeset
1922
kono
parents:
diff changeset
1923 // Mark the variable as going into a unique section.
kono
parents:
diff changeset
1924 void
kono
parents:
diff changeset
1925 set_in_unique_section()
kono
parents:
diff changeset
1926 {
kono
parents:
diff changeset
1927 go_assert(this->is_global_);
kono
parents:
diff changeset
1928 this->in_unique_section_ = true;
kono
parents:
diff changeset
1929 }
kono
parents:
diff changeset
1930
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1931 // Return the top-level declaration for this variable.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1932 Statement*
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1933 toplevel_decl()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1934 { return this->toplevel_decl_; }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1935
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1936 // Set the top-level declaration for this variable. Only used for local
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1937 // variables
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1938 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1939 set_toplevel_decl(Statement* s)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1940 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1941 go_assert(!this->is_global_ && !this->is_parameter_ && !this->is_receiver_);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1942 this->toplevel_decl_ = s;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1943 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1944
111
kono
parents:
diff changeset
1945 // Traverse the initializer expression.
kono
parents:
diff changeset
1946 int
kono
parents:
diff changeset
1947 traverse_expression(Traverse*, unsigned int traverse_mask);
kono
parents:
diff changeset
1948
kono
parents:
diff changeset
1949 // Determine the type of the variable if necessary.
kono
parents:
diff changeset
1950 void
kono
parents:
diff changeset
1951 determine_type();
kono
parents:
diff changeset
1952
kono
parents:
diff changeset
1953 // Get the backend representation of the variable.
kono
parents:
diff changeset
1954 Bvariable*
kono
parents:
diff changeset
1955 get_backend_variable(Gogo*, Named_object*, const Package*,
kono
parents:
diff changeset
1956 const std::string&);
kono
parents:
diff changeset
1957
kono
parents:
diff changeset
1958 // Get the initial value of the variable. This may only
kono
parents:
diff changeset
1959 // be called if has_pre_init() returns false.
kono
parents:
diff changeset
1960 Bexpression*
kono
parents:
diff changeset
1961 get_init(Gogo*, Named_object* function);
kono
parents:
diff changeset
1962
kono
parents:
diff changeset
1963 // Return a series of statements which sets the value of the
kono
parents:
diff changeset
1964 // variable in DECL. This should only be called is has_pre_init()
kono
parents:
diff changeset
1965 // returns true. DECL may be NULL for a sink variable.
kono
parents:
diff changeset
1966 Bstatement*
kono
parents:
diff changeset
1967 get_init_block(Gogo*, Named_object* function, Bvariable* decl);
kono
parents:
diff changeset
1968
kono
parents:
diff changeset
1969 // Export the variable.
kono
parents:
diff changeset
1970 void
kono
parents:
diff changeset
1971 export_var(Export*, const std::string& name) const;
kono
parents:
diff changeset
1972
kono
parents:
diff changeset
1973 // Import a variable.
kono
parents:
diff changeset
1974 static void
kono
parents:
diff changeset
1975 import_var(Import*, std::string* pname, Type** ptype);
kono
parents:
diff changeset
1976
kono
parents:
diff changeset
1977 private:
kono
parents:
diff changeset
1978 // The type of a tuple.
kono
parents:
diff changeset
1979 Type*
kono
parents:
diff changeset
1980 type_from_tuple(Expression*, bool) const;
kono
parents:
diff changeset
1981
kono
parents:
diff changeset
1982 // The type of a range.
kono
parents:
diff changeset
1983 Type*
kono
parents:
diff changeset
1984 type_from_range(Expression*, bool, bool) const;
kono
parents:
diff changeset
1985
kono
parents:
diff changeset
1986 // The element type of a channel.
kono
parents:
diff changeset
1987 Type*
kono
parents:
diff changeset
1988 type_from_chan_element(Expression*, bool) const;
kono
parents:
diff changeset
1989
kono
parents:
diff changeset
1990 // The variable's type. This may be NULL if the type is set from
kono
parents:
diff changeset
1991 // the expression.
kono
parents:
diff changeset
1992 Type* type_;
kono
parents:
diff changeset
1993 // The initial value. This may be NULL if the variable should be
kono
parents:
diff changeset
1994 // initialized to the default value for the type.
kono
parents:
diff changeset
1995 Expression* init_;
kono
parents:
diff changeset
1996 // Statements to run before the init statement.
kono
parents:
diff changeset
1997 Block* preinit_;
kono
parents:
diff changeset
1998 // Location of variable definition.
kono
parents:
diff changeset
1999 Location location_;
kono
parents:
diff changeset
2000 // Backend representation.
kono
parents:
diff changeset
2001 Bvariable* backend_;
kono
parents:
diff changeset
2002 // Whether this is a global variable.
kono
parents:
diff changeset
2003 bool is_global_ : 1;
kono
parents:
diff changeset
2004 // Whether this is a function parameter.
kono
parents:
diff changeset
2005 bool is_parameter_ : 1;
kono
parents:
diff changeset
2006 // Whether this is a closure parameter.
kono
parents:
diff changeset
2007 bool is_closure_ : 1;
kono
parents:
diff changeset
2008 // Whether this is the receiver parameter of a method.
kono
parents:
diff changeset
2009 bool is_receiver_ : 1;
kono
parents:
diff changeset
2010 // Whether this is the varargs parameter of a function.
kono
parents:
diff changeset
2011 bool is_varargs_parameter_ : 1;
kono
parents:
diff changeset
2012 // Whether this variable is ever referenced.
kono
parents:
diff changeset
2013 bool is_used_ : 1;
kono
parents:
diff changeset
2014 // Whether something takes the address of this variable. For a
kono
parents:
diff changeset
2015 // local variable this implies that the variable has to be on the
kono
parents:
diff changeset
2016 // heap if it escapes from its function.
kono
parents:
diff changeset
2017 bool is_address_taken_ : 1;
kono
parents:
diff changeset
2018 // Whether something takes the address of this variable such that
kono
parents:
diff changeset
2019 // the address does not escape the function.
kono
parents:
diff changeset
2020 bool is_non_escaping_address_taken_ : 1;
kono
parents:
diff changeset
2021 // True if we have seen this variable in a traversal.
kono
parents:
diff changeset
2022 bool seen_ : 1;
kono
parents:
diff changeset
2023 // True if we have lowered the initialization expression.
kono
parents:
diff changeset
2024 bool init_is_lowered_ : 1;
kono
parents:
diff changeset
2025 // True if we have flattened the initialization expression.
kono
parents:
diff changeset
2026 bool init_is_flattened_ : 1;
kono
parents:
diff changeset
2027 // True if init is a tuple used to set the type.
kono
parents:
diff changeset
2028 bool type_from_init_tuple_ : 1;
kono
parents:
diff changeset
2029 // True if init is a range clause and the type is the index type.
kono
parents:
diff changeset
2030 bool type_from_range_index_ : 1;
kono
parents:
diff changeset
2031 // True if init is a range clause and the type is the value type.
kono
parents:
diff changeset
2032 bool type_from_range_value_ : 1;
kono
parents:
diff changeset
2033 // True if init is a channel and the type is the channel's element type.
kono
parents:
diff changeset
2034 bool type_from_chan_element_ : 1;
kono
parents:
diff changeset
2035 // True if this is a variable created for a type switch case.
kono
parents:
diff changeset
2036 bool is_type_switch_var_ : 1;
kono
parents:
diff changeset
2037 // True if we have determined types.
kono
parents:
diff changeset
2038 bool determined_type_ : 1;
kono
parents:
diff changeset
2039 // True if this variable should be put in a unique section. This is
kono
parents:
diff changeset
2040 // used for field tracking.
kono
parents:
diff changeset
2041 bool in_unique_section_ : 1;
kono
parents:
diff changeset
2042 // Whether this variable escapes the function it is created in. This is
kono
parents:
diff changeset
2043 // true until shown otherwise.
kono
parents:
diff changeset
2044 bool escapes_ : 1;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2045 // The top-level declaration for this variable. Only used for local
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2046 // variables. Must be a Temporary_statement if not NULL.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2047 Statement* toplevel_decl_;
111
kono
parents:
diff changeset
2048 };
kono
parents:
diff changeset
2049
kono
parents:
diff changeset
2050 // A variable which is really the name for a function return value, or
kono
parents:
diff changeset
2051 // part of one.
kono
parents:
diff changeset
2052
kono
parents:
diff changeset
2053 class Result_variable
kono
parents:
diff changeset
2054 {
kono
parents:
diff changeset
2055 public:
kono
parents:
diff changeset
2056 Result_variable(Type* type, Function* function, int index,
kono
parents:
diff changeset
2057 Location location)
kono
parents:
diff changeset
2058 : type_(type), function_(function), index_(index), location_(location),
kono
parents:
diff changeset
2059 backend_(NULL), is_address_taken_(false),
kono
parents:
diff changeset
2060 is_non_escaping_address_taken_(false), escapes_(true)
kono
parents:
diff changeset
2061 { }
kono
parents:
diff changeset
2062
kono
parents:
diff changeset
2063 // Get the type of the result variable.
kono
parents:
diff changeset
2064 Type*
kono
parents:
diff changeset
2065 type() const
kono
parents:
diff changeset
2066 { return this->type_; }
kono
parents:
diff changeset
2067
kono
parents:
diff changeset
2068 // Get the function that this is associated with.
kono
parents:
diff changeset
2069 Function*
kono
parents:
diff changeset
2070 function() const
kono
parents:
diff changeset
2071 { return this->function_; }
kono
parents:
diff changeset
2072
kono
parents:
diff changeset
2073 // Index in the list of function results.
kono
parents:
diff changeset
2074 int
kono
parents:
diff changeset
2075 index() const
kono
parents:
diff changeset
2076 { return this->index_; }
kono
parents:
diff changeset
2077
kono
parents:
diff changeset
2078 // The location of the variable definition.
kono
parents:
diff changeset
2079 Location
kono
parents:
diff changeset
2080 location() const
kono
parents:
diff changeset
2081 { return this->location_; }
kono
parents:
diff changeset
2082
kono
parents:
diff changeset
2083 // Whether this variable's address is taken.
kono
parents:
diff changeset
2084 bool
kono
parents:
diff changeset
2085 is_address_taken() const
kono
parents:
diff changeset
2086 { return this->is_address_taken_; }
kono
parents:
diff changeset
2087
kono
parents:
diff changeset
2088 // Note that something takes the address of this variable.
kono
parents:
diff changeset
2089 void
kono
parents:
diff changeset
2090 set_address_taken()
kono
parents:
diff changeset
2091 { this->is_address_taken_ = true; }
kono
parents:
diff changeset
2092
kono
parents:
diff changeset
2093 // Return whether the address is taken but does not escape.
kono
parents:
diff changeset
2094 bool
kono
parents:
diff changeset
2095 is_non_escaping_address_taken() const
kono
parents:
diff changeset
2096 { return this->is_non_escaping_address_taken_; }
kono
parents:
diff changeset
2097
kono
parents:
diff changeset
2098 // Note that something takes the address of this variable such that
kono
parents:
diff changeset
2099 // the address does not escape the function.
kono
parents:
diff changeset
2100 void
kono
parents:
diff changeset
2101 set_non_escaping_address_taken()
kono
parents:
diff changeset
2102 { this->is_non_escaping_address_taken_ = true; }
kono
parents:
diff changeset
2103
kono
parents:
diff changeset
2104 // Return whether this variable escapes the function it is declared in.
kono
parents:
diff changeset
2105 bool
kono
parents:
diff changeset
2106 escapes()
kono
parents:
diff changeset
2107 { return this->escapes_; }
kono
parents:
diff changeset
2108
kono
parents:
diff changeset
2109 // Note that this variable does not escape the function it is declared in.
kono
parents:
diff changeset
2110 void
kono
parents:
diff changeset
2111 set_does_not_escape()
kono
parents:
diff changeset
2112 { this->escapes_ = false; }
kono
parents:
diff changeset
2113
kono
parents:
diff changeset
2114 // Whether this variable should live in the heap.
kono
parents:
diff changeset
2115 bool
kono
parents:
diff changeset
2116 is_in_heap() const
kono
parents:
diff changeset
2117 {
kono
parents:
diff changeset
2118 return this->is_address_taken_
kono
parents:
diff changeset
2119 && this->escapes_;
kono
parents:
diff changeset
2120 }
kono
parents:
diff changeset
2121
kono
parents:
diff changeset
2122 // Set the function. This is used when cloning functions which call
kono
parents:
diff changeset
2123 // recover.
kono
parents:
diff changeset
2124 void
kono
parents:
diff changeset
2125 set_function(Function* function)
kono
parents:
diff changeset
2126 { this->function_ = function; }
kono
parents:
diff changeset
2127
kono
parents:
diff changeset
2128 // Get the backend representation of the variable.
kono
parents:
diff changeset
2129 Bvariable*
kono
parents:
diff changeset
2130 get_backend_variable(Gogo*, Named_object*, const std::string&);
kono
parents:
diff changeset
2131
kono
parents:
diff changeset
2132 private:
kono
parents:
diff changeset
2133 // Type of result variable.
kono
parents:
diff changeset
2134 Type* type_;
kono
parents:
diff changeset
2135 // Function with which this is associated.
kono
parents:
diff changeset
2136 Function* function_;
kono
parents:
diff changeset
2137 // Index in list of results.
kono
parents:
diff changeset
2138 int index_;
kono
parents:
diff changeset
2139 // Where the result variable is defined.
kono
parents:
diff changeset
2140 Location location_;
kono
parents:
diff changeset
2141 // Backend representation.
kono
parents:
diff changeset
2142 Bvariable* backend_;
kono
parents:
diff changeset
2143 // Whether something takes the address of this variable.
kono
parents:
diff changeset
2144 bool is_address_taken_;
kono
parents:
diff changeset
2145 // Whether something takes the address of this variable such that
kono
parents:
diff changeset
2146 // the address does not escape the function.
kono
parents:
diff changeset
2147 bool is_non_escaping_address_taken_;
kono
parents:
diff changeset
2148 // Whether this variable escapes the function it is created in. This is
kono
parents:
diff changeset
2149 // true until shown otherwise.
kono
parents:
diff changeset
2150 bool escapes_;
kono
parents:
diff changeset
2151 };
kono
parents:
diff changeset
2152
kono
parents:
diff changeset
2153 // The value we keep for a named constant. This lets us hold a type
kono
parents:
diff changeset
2154 // and an expression.
kono
parents:
diff changeset
2155
kono
parents:
diff changeset
2156 class Named_constant
kono
parents:
diff changeset
2157 {
kono
parents:
diff changeset
2158 public:
kono
parents:
diff changeset
2159 Named_constant(Type* type, Expression* expr, int iota_value,
kono
parents:
diff changeset
2160 Location location)
kono
parents:
diff changeset
2161 : type_(type), expr_(expr), iota_value_(iota_value), location_(location),
kono
parents:
diff changeset
2162 lowering_(false), is_sink_(false), bconst_(NULL)
kono
parents:
diff changeset
2163 { }
kono
parents:
diff changeset
2164
kono
parents:
diff changeset
2165 Type*
kono
parents:
diff changeset
2166 type() const
kono
parents:
diff changeset
2167 { return this->type_; }
kono
parents:
diff changeset
2168
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2169 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2170 set_type(Type* t);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2171
111
kono
parents:
diff changeset
2172 Expression*
kono
parents:
diff changeset
2173 expr() const
kono
parents:
diff changeset
2174 { return this->expr_; }
kono
parents:
diff changeset
2175
kono
parents:
diff changeset
2176 int
kono
parents:
diff changeset
2177 iota_value() const
kono
parents:
diff changeset
2178 { return this->iota_value_; }
kono
parents:
diff changeset
2179
kono
parents:
diff changeset
2180 Location
kono
parents:
diff changeset
2181 location() const
kono
parents:
diff changeset
2182 { return this->location_; }
kono
parents:
diff changeset
2183
kono
parents:
diff changeset
2184 // Whether we are lowering.
kono
parents:
diff changeset
2185 bool
kono
parents:
diff changeset
2186 lowering() const
kono
parents:
diff changeset
2187 { return this->lowering_; }
kono
parents:
diff changeset
2188
kono
parents:
diff changeset
2189 // Set that we are lowering.
kono
parents:
diff changeset
2190 void
kono
parents:
diff changeset
2191 set_lowering()
kono
parents:
diff changeset
2192 { this->lowering_ = true; }
kono
parents:
diff changeset
2193
kono
parents:
diff changeset
2194 // We are no longer lowering.
kono
parents:
diff changeset
2195 void
kono
parents:
diff changeset
2196 clear_lowering()
kono
parents:
diff changeset
2197 { this->lowering_ = false; }
kono
parents:
diff changeset
2198
kono
parents:
diff changeset
2199 bool
kono
parents:
diff changeset
2200 is_sink() const
kono
parents:
diff changeset
2201 { return this->is_sink_; }
kono
parents:
diff changeset
2202
kono
parents:
diff changeset
2203 void
kono
parents:
diff changeset
2204 set_is_sink()
kono
parents:
diff changeset
2205 { this->is_sink_ = true; }
kono
parents:
diff changeset
2206
kono
parents:
diff changeset
2207 // Traverse the expression.
kono
parents:
diff changeset
2208 int
kono
parents:
diff changeset
2209 traverse_expression(Traverse*);
kono
parents:
diff changeset
2210
kono
parents:
diff changeset
2211 // Determine the type of the constant if necessary.
kono
parents:
diff changeset
2212 void
kono
parents:
diff changeset
2213 determine_type();
kono
parents:
diff changeset
2214
kono
parents:
diff changeset
2215 // Indicate that we found and reported an error for this constant.
kono
parents:
diff changeset
2216 void
kono
parents:
diff changeset
2217 set_error();
kono
parents:
diff changeset
2218
kono
parents:
diff changeset
2219 // Export the constant.
kono
parents:
diff changeset
2220 void
kono
parents:
diff changeset
2221 export_const(Export*, const std::string& name) const;
kono
parents:
diff changeset
2222
kono
parents:
diff changeset
2223 // Import a constant.
kono
parents:
diff changeset
2224 static void
kono
parents:
diff changeset
2225 import_const(Import*, std::string*, Type**, Expression**);
kono
parents:
diff changeset
2226
kono
parents:
diff changeset
2227 // Get the backend representation of the constant value.
kono
parents:
diff changeset
2228 Bexpression*
kono
parents:
diff changeset
2229 get_backend(Gogo*, Named_object*);
kono
parents:
diff changeset
2230
kono
parents:
diff changeset
2231 private:
kono
parents:
diff changeset
2232 // The type of the constant.
kono
parents:
diff changeset
2233 Type* type_;
kono
parents:
diff changeset
2234 // The expression for the constant.
kono
parents:
diff changeset
2235 Expression* expr_;
kono
parents:
diff changeset
2236 // If the predeclared constant iota is used in EXPR_, this is the
kono
parents:
diff changeset
2237 // value it will have. We do this because at parse time we don't
kono
parents:
diff changeset
2238 // know whether the name "iota" will refer to the predeclared
kono
parents:
diff changeset
2239 // constant or to something else. We put in the right value in when
kono
parents:
diff changeset
2240 // we lower.
kono
parents:
diff changeset
2241 int iota_value_;
kono
parents:
diff changeset
2242 // The location of the definition.
kono
parents:
diff changeset
2243 Location location_;
kono
parents:
diff changeset
2244 // Whether we are currently lowering this constant.
kono
parents:
diff changeset
2245 bool lowering_;
kono
parents:
diff changeset
2246 // Whether this constant is blank named and needs only type checking.
kono
parents:
diff changeset
2247 bool is_sink_;
kono
parents:
diff changeset
2248 // The backend representation of the constant value.
kono
parents:
diff changeset
2249 Bexpression* bconst_;
kono
parents:
diff changeset
2250 };
kono
parents:
diff changeset
2251
kono
parents:
diff changeset
2252 // A type declaration.
kono
parents:
diff changeset
2253
kono
parents:
diff changeset
2254 class Type_declaration
kono
parents:
diff changeset
2255 {
kono
parents:
diff changeset
2256 public:
kono
parents:
diff changeset
2257 Type_declaration(Location location)
kono
parents:
diff changeset
2258 : location_(location), in_function_(NULL), in_function_index_(0),
kono
parents:
diff changeset
2259 methods_(), issued_warning_(false)
kono
parents:
diff changeset
2260 { }
kono
parents:
diff changeset
2261
kono
parents:
diff changeset
2262 // Return the location.
kono
parents:
diff changeset
2263 Location
kono
parents:
diff changeset
2264 location() const
kono
parents:
diff changeset
2265 { return this->location_; }
kono
parents:
diff changeset
2266
kono
parents:
diff changeset
2267 // Return the function in which this type is declared. This will
kono
parents:
diff changeset
2268 // return NULL for a type declared in global scope.
kono
parents:
diff changeset
2269 Named_object*
kono
parents:
diff changeset
2270 in_function(unsigned int* pindex)
kono
parents:
diff changeset
2271 {
kono
parents:
diff changeset
2272 *pindex = this->in_function_index_;
kono
parents:
diff changeset
2273 return this->in_function_;
kono
parents:
diff changeset
2274 }
kono
parents:
diff changeset
2275
kono
parents:
diff changeset
2276 // Set the function in which this type is declared.
kono
parents:
diff changeset
2277 void
kono
parents:
diff changeset
2278 set_in_function(Named_object* f, unsigned int index)
kono
parents:
diff changeset
2279 {
kono
parents:
diff changeset
2280 this->in_function_ = f;
kono
parents:
diff changeset
2281 this->in_function_index_ = index;
kono
parents:
diff changeset
2282 }
kono
parents:
diff changeset
2283
kono
parents:
diff changeset
2284 // Add a method to this type. This is used when methods are defined
kono
parents:
diff changeset
2285 // before the type.
kono
parents:
diff changeset
2286 Named_object*
kono
parents:
diff changeset
2287 add_method(const std::string& name, Function* function);
kono
parents:
diff changeset
2288
kono
parents:
diff changeset
2289 // Add a method declaration to this type.
kono
parents:
diff changeset
2290 Named_object*
kono
parents:
diff changeset
2291 add_method_declaration(const std::string& name, Package*,
kono
parents:
diff changeset
2292 Function_type* type, Location location);
kono
parents:
diff changeset
2293
kono
parents:
diff changeset
2294 // Add an already created object as a method.
kono
parents:
diff changeset
2295 void
kono
parents:
diff changeset
2296 add_existing_method(Named_object* no)
kono
parents:
diff changeset
2297 { this->methods_.push_back(no); }
kono
parents:
diff changeset
2298
kono
parents:
diff changeset
2299 // Return whether any methods were defined.
kono
parents:
diff changeset
2300 bool
kono
parents:
diff changeset
2301 has_methods() const;
kono
parents:
diff changeset
2302
kono
parents:
diff changeset
2303 // Return the methods.
kono
parents:
diff changeset
2304 const std::vector<Named_object*>*
kono
parents:
diff changeset
2305 methods() const
kono
parents:
diff changeset
2306 { return &this->methods_; }
kono
parents:
diff changeset
2307
kono
parents:
diff changeset
2308 // Define methods when the real type is known.
kono
parents:
diff changeset
2309 void
kono
parents:
diff changeset
2310 define_methods(Named_type*);
kono
parents:
diff changeset
2311
kono
parents:
diff changeset
2312 // This is called if we are trying to use this type. It returns
kono
parents:
diff changeset
2313 // true if we should issue a warning.
kono
parents:
diff changeset
2314 bool
kono
parents:
diff changeset
2315 using_type();
kono
parents:
diff changeset
2316
kono
parents:
diff changeset
2317 private:
kono
parents:
diff changeset
2318 // The location of the type declaration.
kono
parents:
diff changeset
2319 Location location_;
kono
parents:
diff changeset
2320 // If this type is declared in a function, a pointer back to the
kono
parents:
diff changeset
2321 // function in which it is defined.
kono
parents:
diff changeset
2322 Named_object* in_function_;
kono
parents:
diff changeset
2323 // The index of this type in IN_FUNCTION_.
kono
parents:
diff changeset
2324 unsigned int in_function_index_;
kono
parents:
diff changeset
2325 // Methods defined before the type is defined.
kono
parents:
diff changeset
2326 std::vector<Named_object*> methods_;
kono
parents:
diff changeset
2327 // True if we have issued a warning about a use of this type
kono
parents:
diff changeset
2328 // declaration when it is undefined.
kono
parents:
diff changeset
2329 bool issued_warning_;
kono
parents:
diff changeset
2330 };
kono
parents:
diff changeset
2331
kono
parents:
diff changeset
2332 // An unknown object. These are created by the parser for forward
kono
parents:
diff changeset
2333 // references to names which have not been seen before. In a correct
kono
parents:
diff changeset
2334 // program, these will always point to a real definition by the end of
kono
parents:
diff changeset
2335 // the parse. Because they point to another Named_object, these may
kono
parents:
diff changeset
2336 // only be referenced by Unknown_expression objects.
kono
parents:
diff changeset
2337
kono
parents:
diff changeset
2338 class Unknown_name
kono
parents:
diff changeset
2339 {
kono
parents:
diff changeset
2340 public:
kono
parents:
diff changeset
2341 Unknown_name(Location location)
kono
parents:
diff changeset
2342 : location_(location), real_named_object_(NULL)
kono
parents:
diff changeset
2343 { }
kono
parents:
diff changeset
2344
kono
parents:
diff changeset
2345 // Return the location where this name was first seen.
kono
parents:
diff changeset
2346 Location
kono
parents:
diff changeset
2347 location() const
kono
parents:
diff changeset
2348 { return this->location_; }
kono
parents:
diff changeset
2349
kono
parents:
diff changeset
2350 // Return the real named object that this points to, or NULL if it
kono
parents:
diff changeset
2351 // was never resolved.
kono
parents:
diff changeset
2352 Named_object*
kono
parents:
diff changeset
2353 real_named_object() const
kono
parents:
diff changeset
2354 { return this->real_named_object_; }
kono
parents:
diff changeset
2355
kono
parents:
diff changeset
2356 // Set the real named object that this points to.
kono
parents:
diff changeset
2357 void
kono
parents:
diff changeset
2358 set_real_named_object(Named_object* no);
kono
parents:
diff changeset
2359
kono
parents:
diff changeset
2360 private:
kono
parents:
diff changeset
2361 // The location where this name was first seen.
kono
parents:
diff changeset
2362 Location location_;
kono
parents:
diff changeset
2363 // The real named object when it is known.
kono
parents:
diff changeset
2364 Named_object*
kono
parents:
diff changeset
2365 real_named_object_;
kono
parents:
diff changeset
2366 };
kono
parents:
diff changeset
2367
kono
parents:
diff changeset
2368 // A named object named. This is the result of a declaration. We
kono
parents:
diff changeset
2369 // don't use a superclass because they all have to be handled
kono
parents:
diff changeset
2370 // differently.
kono
parents:
diff changeset
2371
kono
parents:
diff changeset
2372 class Named_object
kono
parents:
diff changeset
2373 {
kono
parents:
diff changeset
2374 public:
kono
parents:
diff changeset
2375 enum Classification
kono
parents:
diff changeset
2376 {
kono
parents:
diff changeset
2377 // An uninitialized Named_object. We should never see this.
kono
parents:
diff changeset
2378 NAMED_OBJECT_UNINITIALIZED,
kono
parents:
diff changeset
2379 // An erroneous name. This indicates a parse error, to avoid
kono
parents:
diff changeset
2380 // later errors about undefined references.
kono
parents:
diff changeset
2381 NAMED_OBJECT_ERRONEOUS,
kono
parents:
diff changeset
2382 // An unknown name. This is used for forward references. In a
kono
parents:
diff changeset
2383 // correct program, these will all be resolved by the end of the
kono
parents:
diff changeset
2384 // parse.
kono
parents:
diff changeset
2385 NAMED_OBJECT_UNKNOWN,
kono
parents:
diff changeset
2386 // A const.
kono
parents:
diff changeset
2387 NAMED_OBJECT_CONST,
kono
parents:
diff changeset
2388 // A type.
kono
parents:
diff changeset
2389 NAMED_OBJECT_TYPE,
kono
parents:
diff changeset
2390 // A forward type declaration.
kono
parents:
diff changeset
2391 NAMED_OBJECT_TYPE_DECLARATION,
kono
parents:
diff changeset
2392 // A var.
kono
parents:
diff changeset
2393 NAMED_OBJECT_VAR,
kono
parents:
diff changeset
2394 // A result variable in a function.
kono
parents:
diff changeset
2395 NAMED_OBJECT_RESULT_VAR,
kono
parents:
diff changeset
2396 // The blank identifier--the special variable named _.
kono
parents:
diff changeset
2397 NAMED_OBJECT_SINK,
kono
parents:
diff changeset
2398 // A func.
kono
parents:
diff changeset
2399 NAMED_OBJECT_FUNC,
kono
parents:
diff changeset
2400 // A forward func declaration.
kono
parents:
diff changeset
2401 NAMED_OBJECT_FUNC_DECLARATION,
kono
parents:
diff changeset
2402 // A package.
kono
parents:
diff changeset
2403 NAMED_OBJECT_PACKAGE
kono
parents:
diff changeset
2404 };
kono
parents:
diff changeset
2405
kono
parents:
diff changeset
2406 // Return the classification.
kono
parents:
diff changeset
2407 Classification
kono
parents:
diff changeset
2408 classification() const
kono
parents:
diff changeset
2409 { return this->classification_; }
kono
parents:
diff changeset
2410
kono
parents:
diff changeset
2411 // Classifiers.
kono
parents:
diff changeset
2412
kono
parents:
diff changeset
2413 bool
kono
parents:
diff changeset
2414 is_erroneous() const
kono
parents:
diff changeset
2415 { return this->classification_ == NAMED_OBJECT_ERRONEOUS; }
kono
parents:
diff changeset
2416
kono
parents:
diff changeset
2417 bool
kono
parents:
diff changeset
2418 is_unknown() const
kono
parents:
diff changeset
2419 { return this->classification_ == NAMED_OBJECT_UNKNOWN; }
kono
parents:
diff changeset
2420
kono
parents:
diff changeset
2421 bool
kono
parents:
diff changeset
2422 is_const() const
kono
parents:
diff changeset
2423 { return this->classification_ == NAMED_OBJECT_CONST; }
kono
parents:
diff changeset
2424
kono
parents:
diff changeset
2425 bool
kono
parents:
diff changeset
2426 is_type() const
kono
parents:
diff changeset
2427 { return this->classification_ == NAMED_OBJECT_TYPE; }
kono
parents:
diff changeset
2428
kono
parents:
diff changeset
2429 bool
kono
parents:
diff changeset
2430 is_type_declaration() const
kono
parents:
diff changeset
2431 { return this->classification_ == NAMED_OBJECT_TYPE_DECLARATION; }
kono
parents:
diff changeset
2432
kono
parents:
diff changeset
2433 bool
kono
parents:
diff changeset
2434 is_variable() const
kono
parents:
diff changeset
2435 { return this->classification_ == NAMED_OBJECT_VAR; }
kono
parents:
diff changeset
2436
kono
parents:
diff changeset
2437 bool
kono
parents:
diff changeset
2438 is_result_variable() const
kono
parents:
diff changeset
2439 { return this->classification_ == NAMED_OBJECT_RESULT_VAR; }
kono
parents:
diff changeset
2440
kono
parents:
diff changeset
2441 bool
kono
parents:
diff changeset
2442 is_sink() const
kono
parents:
diff changeset
2443 { return this->classification_ == NAMED_OBJECT_SINK; }
kono
parents:
diff changeset
2444
kono
parents:
diff changeset
2445 bool
kono
parents:
diff changeset
2446 is_function() const
kono
parents:
diff changeset
2447 { return this->classification_ == NAMED_OBJECT_FUNC; }
kono
parents:
diff changeset
2448
kono
parents:
diff changeset
2449 bool
kono
parents:
diff changeset
2450 is_function_declaration() const
kono
parents:
diff changeset
2451 { return this->classification_ == NAMED_OBJECT_FUNC_DECLARATION; }
kono
parents:
diff changeset
2452
kono
parents:
diff changeset
2453 bool
kono
parents:
diff changeset
2454 is_package() const
kono
parents:
diff changeset
2455 { return this->classification_ == NAMED_OBJECT_PACKAGE; }
kono
parents:
diff changeset
2456
kono
parents:
diff changeset
2457 // Creators.
kono
parents:
diff changeset
2458
kono
parents:
diff changeset
2459 static Named_object*
kono
parents:
diff changeset
2460 make_erroneous_name(const std::string& name)
kono
parents:
diff changeset
2461 { return new Named_object(name, NULL, NAMED_OBJECT_ERRONEOUS); }
kono
parents:
diff changeset
2462
kono
parents:
diff changeset
2463 static Named_object*
kono
parents:
diff changeset
2464 make_unknown_name(const std::string& name, Location);
kono
parents:
diff changeset
2465
kono
parents:
diff changeset
2466 static Named_object*
kono
parents:
diff changeset
2467 make_constant(const Typed_identifier&, const Package*, Expression*,
kono
parents:
diff changeset
2468 int iota_value);
kono
parents:
diff changeset
2469
kono
parents:
diff changeset
2470 static Named_object*
kono
parents:
diff changeset
2471 make_type(const std::string&, const Package*, Type*, Location);
kono
parents:
diff changeset
2472
kono
parents:
diff changeset
2473 static Named_object*
kono
parents:
diff changeset
2474 make_type_declaration(const std::string&, const Package*, Location);
kono
parents:
diff changeset
2475
kono
parents:
diff changeset
2476 static Named_object*
kono
parents:
diff changeset
2477 make_variable(const std::string&, const Package*, Variable*);
kono
parents:
diff changeset
2478
kono
parents:
diff changeset
2479 static Named_object*
kono
parents:
diff changeset
2480 make_result_variable(const std::string&, Result_variable*);
kono
parents:
diff changeset
2481
kono
parents:
diff changeset
2482 static Named_object*
kono
parents:
diff changeset
2483 make_sink();
kono
parents:
diff changeset
2484
kono
parents:
diff changeset
2485 static Named_object*
kono
parents:
diff changeset
2486 make_function(const std::string&, const Package*, Function*);
kono
parents:
diff changeset
2487
kono
parents:
diff changeset
2488 static Named_object*
kono
parents:
diff changeset
2489 make_function_declaration(const std::string&, const Package*, Function_type*,
kono
parents:
diff changeset
2490 Location);
kono
parents:
diff changeset
2491
kono
parents:
diff changeset
2492 static Named_object*
kono
parents:
diff changeset
2493 make_package(const std::string& alias, Package* package);
kono
parents:
diff changeset
2494
kono
parents:
diff changeset
2495 // Getters.
kono
parents:
diff changeset
2496
kono
parents:
diff changeset
2497 Unknown_name*
kono
parents:
diff changeset
2498 unknown_value()
kono
parents:
diff changeset
2499 {
kono
parents:
diff changeset
2500 go_assert(this->classification_ == NAMED_OBJECT_UNKNOWN);
kono
parents:
diff changeset
2501 return this->u_.unknown_value;
kono
parents:
diff changeset
2502 }
kono
parents:
diff changeset
2503
kono
parents:
diff changeset
2504 const Unknown_name*
kono
parents:
diff changeset
2505 unknown_value() const
kono
parents:
diff changeset
2506 {
kono
parents:
diff changeset
2507 go_assert(this->classification_ == NAMED_OBJECT_UNKNOWN);
kono
parents:
diff changeset
2508 return this->u_.unknown_value;
kono
parents:
diff changeset
2509 }
kono
parents:
diff changeset
2510
kono
parents:
diff changeset
2511 Named_constant*
kono
parents:
diff changeset
2512 const_value()
kono
parents:
diff changeset
2513 {
kono
parents:
diff changeset
2514 go_assert(this->classification_ == NAMED_OBJECT_CONST);
kono
parents:
diff changeset
2515 return this->u_.const_value;
kono
parents:
diff changeset
2516 }
kono
parents:
diff changeset
2517
kono
parents:
diff changeset
2518 const Named_constant*
kono
parents:
diff changeset
2519 const_value() const
kono
parents:
diff changeset
2520 {
kono
parents:
diff changeset
2521 go_assert(this->classification_ == NAMED_OBJECT_CONST);
kono
parents:
diff changeset
2522 return this->u_.const_value;
kono
parents:
diff changeset
2523 }
kono
parents:
diff changeset
2524
kono
parents:
diff changeset
2525 Named_type*
kono
parents:
diff changeset
2526 type_value()
kono
parents:
diff changeset
2527 {
kono
parents:
diff changeset
2528 go_assert(this->classification_ == NAMED_OBJECT_TYPE);
kono
parents:
diff changeset
2529 return this->u_.type_value;
kono
parents:
diff changeset
2530 }
kono
parents:
diff changeset
2531
kono
parents:
diff changeset
2532 const Named_type*
kono
parents:
diff changeset
2533 type_value() const
kono
parents:
diff changeset
2534 {
kono
parents:
diff changeset
2535 go_assert(this->classification_ == NAMED_OBJECT_TYPE);
kono
parents:
diff changeset
2536 return this->u_.type_value;
kono
parents:
diff changeset
2537 }
kono
parents:
diff changeset
2538
kono
parents:
diff changeset
2539 Type_declaration*
kono
parents:
diff changeset
2540 type_declaration_value()
kono
parents:
diff changeset
2541 {
kono
parents:
diff changeset
2542 go_assert(this->classification_ == NAMED_OBJECT_TYPE_DECLARATION);
kono
parents:
diff changeset
2543 return this->u_.type_declaration;
kono
parents:
diff changeset
2544 }
kono
parents:
diff changeset
2545
kono
parents:
diff changeset
2546 const Type_declaration*
kono
parents:
diff changeset
2547 type_declaration_value() const
kono
parents:
diff changeset
2548 {
kono
parents:
diff changeset
2549 go_assert(this->classification_ == NAMED_OBJECT_TYPE_DECLARATION);
kono
parents:
diff changeset
2550 return this->u_.type_declaration;
kono
parents:
diff changeset
2551 }
kono
parents:
diff changeset
2552
kono
parents:
diff changeset
2553 Variable*
kono
parents:
diff changeset
2554 var_value()
kono
parents:
diff changeset
2555 {
kono
parents:
diff changeset
2556 go_assert(this->classification_ == NAMED_OBJECT_VAR);
kono
parents:
diff changeset
2557 return this->u_.var_value;
kono
parents:
diff changeset
2558 }
kono
parents:
diff changeset
2559
kono
parents:
diff changeset
2560 const Variable*
kono
parents:
diff changeset
2561 var_value() const
kono
parents:
diff changeset
2562 {
kono
parents:
diff changeset
2563 go_assert(this->classification_ == NAMED_OBJECT_VAR);
kono
parents:
diff changeset
2564 return this->u_.var_value;
kono
parents:
diff changeset
2565 }
kono
parents:
diff changeset
2566
kono
parents:
diff changeset
2567 Result_variable*
kono
parents:
diff changeset
2568 result_var_value()
kono
parents:
diff changeset
2569 {
kono
parents:
diff changeset
2570 go_assert(this->classification_ == NAMED_OBJECT_RESULT_VAR);
kono
parents:
diff changeset
2571 return this->u_.result_var_value;
kono
parents:
diff changeset
2572 }
kono
parents:
diff changeset
2573
kono
parents:
diff changeset
2574 const Result_variable*
kono
parents:
diff changeset
2575 result_var_value() const
kono
parents:
diff changeset
2576 {
kono
parents:
diff changeset
2577 go_assert(this->classification_ == NAMED_OBJECT_RESULT_VAR);
kono
parents:
diff changeset
2578 return this->u_.result_var_value;
kono
parents:
diff changeset
2579 }
kono
parents:
diff changeset
2580
kono
parents:
diff changeset
2581 Function*
kono
parents:
diff changeset
2582 func_value()
kono
parents:
diff changeset
2583 {
kono
parents:
diff changeset
2584 go_assert(this->classification_ == NAMED_OBJECT_FUNC);
kono
parents:
diff changeset
2585 return this->u_.func_value;
kono
parents:
diff changeset
2586 }
kono
parents:
diff changeset
2587
kono
parents:
diff changeset
2588 const Function*
kono
parents:
diff changeset
2589 func_value() const
kono
parents:
diff changeset
2590 {
kono
parents:
diff changeset
2591 go_assert(this->classification_ == NAMED_OBJECT_FUNC);
kono
parents:
diff changeset
2592 return this->u_.func_value;
kono
parents:
diff changeset
2593 }
kono
parents:
diff changeset
2594
kono
parents:
diff changeset
2595 Function_declaration*
kono
parents:
diff changeset
2596 func_declaration_value()
kono
parents:
diff changeset
2597 {
kono
parents:
diff changeset
2598 go_assert(this->classification_ == NAMED_OBJECT_FUNC_DECLARATION);
kono
parents:
diff changeset
2599 return this->u_.func_declaration_value;
kono
parents:
diff changeset
2600 }
kono
parents:
diff changeset
2601
kono
parents:
diff changeset
2602 const Function_declaration*
kono
parents:
diff changeset
2603 func_declaration_value() const
kono
parents:
diff changeset
2604 {
kono
parents:
diff changeset
2605 go_assert(this->classification_ == NAMED_OBJECT_FUNC_DECLARATION);
kono
parents:
diff changeset
2606 return this->u_.func_declaration_value;
kono
parents:
diff changeset
2607 }
kono
parents:
diff changeset
2608
kono
parents:
diff changeset
2609 Package*
kono
parents:
diff changeset
2610 package_value()
kono
parents:
diff changeset
2611 {
kono
parents:
diff changeset
2612 go_assert(this->classification_ == NAMED_OBJECT_PACKAGE);
kono
parents:
diff changeset
2613 return this->u_.package_value;
kono
parents:
diff changeset
2614 }
kono
parents:
diff changeset
2615
kono
parents:
diff changeset
2616 const Package*
kono
parents:
diff changeset
2617 package_value() const
kono
parents:
diff changeset
2618 {
kono
parents:
diff changeset
2619 go_assert(this->classification_ == NAMED_OBJECT_PACKAGE);
kono
parents:
diff changeset
2620 return this->u_.package_value;
kono
parents:
diff changeset
2621 }
kono
parents:
diff changeset
2622
kono
parents:
diff changeset
2623 const std::string&
kono
parents:
diff changeset
2624 name() const
kono
parents:
diff changeset
2625 { return this->name_; }
kono
parents:
diff changeset
2626
kono
parents:
diff changeset
2627 // Return the name to use in an error message. The difference is
kono
parents:
diff changeset
2628 // that if this Named_object is defined in a different package, this
kono
parents:
diff changeset
2629 // will return PACKAGE.NAME.
kono
parents:
diff changeset
2630 std::string
kono
parents:
diff changeset
2631 message_name() const;
kono
parents:
diff changeset
2632
kono
parents:
diff changeset
2633 const Package*
kono
parents:
diff changeset
2634 package() const
kono
parents:
diff changeset
2635 { return this->package_; }
kono
parents:
diff changeset
2636
kono
parents:
diff changeset
2637 // Resolve an unknown value if possible. This returns the same
kono
parents:
diff changeset
2638 // Named_object or a new one.
kono
parents:
diff changeset
2639 Named_object*
kono
parents:
diff changeset
2640 resolve()
kono
parents:
diff changeset
2641 {
kono
parents:
diff changeset
2642 Named_object* ret = this;
kono
parents:
diff changeset
2643 if (this->is_unknown())
kono
parents:
diff changeset
2644 {
kono
parents:
diff changeset
2645 Named_object* r = this->unknown_value()->real_named_object();
kono
parents:
diff changeset
2646 if (r != NULL)
kono
parents:
diff changeset
2647 ret = r;
kono
parents:
diff changeset
2648 }
kono
parents:
diff changeset
2649 return ret;
kono
parents:
diff changeset
2650 }
kono
parents:
diff changeset
2651
kono
parents:
diff changeset
2652 const Named_object*
kono
parents:
diff changeset
2653 resolve() const
kono
parents:
diff changeset
2654 {
kono
parents:
diff changeset
2655 const Named_object* ret = this;
kono
parents:
diff changeset
2656 if (this->is_unknown())
kono
parents:
diff changeset
2657 {
kono
parents:
diff changeset
2658 const Named_object* r = this->unknown_value()->real_named_object();
kono
parents:
diff changeset
2659 if (r != NULL)
kono
parents:
diff changeset
2660 ret = r;
kono
parents:
diff changeset
2661 }
kono
parents:
diff changeset
2662 return ret;
kono
parents:
diff changeset
2663 }
kono
parents:
diff changeset
2664
kono
parents:
diff changeset
2665 // The location where this object was defined or referenced.
kono
parents:
diff changeset
2666 Location
kono
parents:
diff changeset
2667 location() const;
kono
parents:
diff changeset
2668
kono
parents:
diff changeset
2669 // Convert a variable to the backend representation.
kono
parents:
diff changeset
2670 Bvariable*
kono
parents:
diff changeset
2671 get_backend_variable(Gogo*, Named_object* function);
kono
parents:
diff changeset
2672
kono
parents:
diff changeset
2673 // Return the external identifier for this object.
kono
parents:
diff changeset
2674 std::string
kono
parents:
diff changeset
2675 get_id(Gogo*);
kono
parents:
diff changeset
2676
kono
parents:
diff changeset
2677 // Get the backend representation of this object.
kono
parents:
diff changeset
2678 void
kono
parents:
diff changeset
2679 get_backend(Gogo*, std::vector<Bexpression*>&, std::vector<Btype*>&,
kono
parents:
diff changeset
2680 std::vector<Bfunction*>&);
kono
parents:
diff changeset
2681
kono
parents:
diff changeset
2682 // Define a type declaration.
kono
parents:
diff changeset
2683 void
kono
parents:
diff changeset
2684 set_type_value(Named_type*);
kono
parents:
diff changeset
2685
kono
parents:
diff changeset
2686 // Define a function declaration.
kono
parents:
diff changeset
2687 void
kono
parents:
diff changeset
2688 set_function_value(Function*);
kono
parents:
diff changeset
2689
kono
parents:
diff changeset
2690 // Declare an unknown name as a type declaration.
kono
parents:
diff changeset
2691 void
kono
parents:
diff changeset
2692 declare_as_type();
kono
parents:
diff changeset
2693
kono
parents:
diff changeset
2694 // Export this object.
kono
parents:
diff changeset
2695 void
kono
parents:
diff changeset
2696 export_named_object(Export*) const;
kono
parents:
diff changeset
2697
kono
parents:
diff changeset
2698 // Mark this named object as an invalid redefinition of another object.
kono
parents:
diff changeset
2699 void
kono
parents:
diff changeset
2700 set_is_redefinition()
kono
parents:
diff changeset
2701 { this->is_redefinition_ = true; }
kono
parents:
diff changeset
2702
kono
parents:
diff changeset
2703 // Return whether or not this object is a invalid redefinition of another
kono
parents:
diff changeset
2704 // object.
kono
parents:
diff changeset
2705 bool
kono
parents:
diff changeset
2706 is_redefinition() const
kono
parents:
diff changeset
2707 { return this->is_redefinition_; }
kono
parents:
diff changeset
2708
kono
parents:
diff changeset
2709 private:
kono
parents:
diff changeset
2710 Named_object(const std::string&, const Package*, Classification);
kono
parents:
diff changeset
2711
kono
parents:
diff changeset
2712 // The name of the object.
kono
parents:
diff changeset
2713 std::string name_;
kono
parents:
diff changeset
2714 // The package that this object is in. This is NULL if it is in the
kono
parents:
diff changeset
2715 // file we are compiling.
kono
parents:
diff changeset
2716 const Package* package_;
kono
parents:
diff changeset
2717 // The type of object this is.
kono
parents:
diff changeset
2718 Classification classification_;
kono
parents:
diff changeset
2719 // The real data.
kono
parents:
diff changeset
2720 union
kono
parents:
diff changeset
2721 {
kono
parents:
diff changeset
2722 Unknown_name* unknown_value;
kono
parents:
diff changeset
2723 Named_constant* const_value;
kono
parents:
diff changeset
2724 Named_type* type_value;
kono
parents:
diff changeset
2725 Type_declaration* type_declaration;
kono
parents:
diff changeset
2726 Variable* var_value;
kono
parents:
diff changeset
2727 Result_variable* result_var_value;
kono
parents:
diff changeset
2728 Function* func_value;
kono
parents:
diff changeset
2729 Function_declaration* func_declaration_value;
kono
parents:
diff changeset
2730 Package* package_value;
kono
parents:
diff changeset
2731 } u_;
kono
parents:
diff changeset
2732 // True if this object is an invalid redefinition of another object.
kono
parents:
diff changeset
2733 bool is_redefinition_;
kono
parents:
diff changeset
2734 };
kono
parents:
diff changeset
2735
kono
parents:
diff changeset
2736 // A binding contour. This binds names to objects.
kono
parents:
diff changeset
2737
kono
parents:
diff changeset
2738 class Bindings
kono
parents:
diff changeset
2739 {
kono
parents:
diff changeset
2740 public:
kono
parents:
diff changeset
2741 // Type for mapping from names to objects.
kono
parents:
diff changeset
2742 typedef Unordered_map(std::string, Named_object*) Contour;
kono
parents:
diff changeset
2743
kono
parents:
diff changeset
2744 Bindings(Bindings* enclosing);
kono
parents:
diff changeset
2745
kono
parents:
diff changeset
2746 // Add an erroneous name.
kono
parents:
diff changeset
2747 Named_object*
kono
parents:
diff changeset
2748 add_erroneous_name(const std::string& name)
kono
parents:
diff changeset
2749 { return this->add_named_object(Named_object::make_erroneous_name(name)); }
kono
parents:
diff changeset
2750
kono
parents:
diff changeset
2751 // Add an unknown name.
kono
parents:
diff changeset
2752 Named_object*
kono
parents:
diff changeset
2753 add_unknown_name(const std::string& name, Location location)
kono
parents:
diff changeset
2754 {
kono
parents:
diff changeset
2755 return this->add_named_object(Named_object::make_unknown_name(name,
kono
parents:
diff changeset
2756 location));
kono
parents:
diff changeset
2757 }
kono
parents:
diff changeset
2758
kono
parents:
diff changeset
2759 // Add a constant.
kono
parents:
diff changeset
2760 Named_object*
kono
parents:
diff changeset
2761 add_constant(const Typed_identifier& tid, const Package* package,
kono
parents:
diff changeset
2762 Expression* expr, int iota_value)
kono
parents:
diff changeset
2763 {
kono
parents:
diff changeset
2764 return this->add_named_object(Named_object::make_constant(tid, package,
kono
parents:
diff changeset
2765 expr,
kono
parents:
diff changeset
2766 iota_value));
kono
parents:
diff changeset
2767 }
kono
parents:
diff changeset
2768
kono
parents:
diff changeset
2769 // Add a type.
kono
parents:
diff changeset
2770 Named_object*
kono
parents:
diff changeset
2771 add_type(const std::string& name, const Package* package, Type* type,
kono
parents:
diff changeset
2772 Location location)
kono
parents:
diff changeset
2773 {
kono
parents:
diff changeset
2774 return this->add_named_object(Named_object::make_type(name, package, type,
kono
parents:
diff changeset
2775 location));
kono
parents:
diff changeset
2776 }
kono
parents:
diff changeset
2777
kono
parents:
diff changeset
2778 // Add a named type. This is used for builtin types, and to add an
kono
parents:
diff changeset
2779 // imported type to the global scope.
kono
parents:
diff changeset
2780 Named_object*
kono
parents:
diff changeset
2781 add_named_type(Named_type* named_type);
kono
parents:
diff changeset
2782
kono
parents:
diff changeset
2783 // Add a type declaration.
kono
parents:
diff changeset
2784 Named_object*
kono
parents:
diff changeset
2785 add_type_declaration(const std::string& name, const Package* package,
kono
parents:
diff changeset
2786 Location location)
kono
parents:
diff changeset
2787 {
kono
parents:
diff changeset
2788 Named_object* no = Named_object::make_type_declaration(name, package,
kono
parents:
diff changeset
2789 location);
kono
parents:
diff changeset
2790 return this->add_named_object(no);
kono
parents:
diff changeset
2791 }
kono
parents:
diff changeset
2792
kono
parents:
diff changeset
2793 // Add a variable.
kono
parents:
diff changeset
2794 Named_object*
kono
parents:
diff changeset
2795 add_variable(const std::string& name, const Package* package,
kono
parents:
diff changeset
2796 Variable* variable)
kono
parents:
diff changeset
2797 {
kono
parents:
diff changeset
2798 return this->add_named_object(Named_object::make_variable(name, package,
kono
parents:
diff changeset
2799 variable));
kono
parents:
diff changeset
2800 }
kono
parents:
diff changeset
2801
kono
parents:
diff changeset
2802 // Add a result variable.
kono
parents:
diff changeset
2803 Named_object*
kono
parents:
diff changeset
2804 add_result_variable(const std::string& name, Result_variable* result)
kono
parents:
diff changeset
2805 {
kono
parents:
diff changeset
2806 return this->add_named_object(Named_object::make_result_variable(name,
kono
parents:
diff changeset
2807 result));
kono
parents:
diff changeset
2808 }
kono
parents:
diff changeset
2809
kono
parents:
diff changeset
2810 // Add a function.
kono
parents:
diff changeset
2811 Named_object*
kono
parents:
diff changeset
2812 add_function(const std::string& name, const Package*, Function* function);
kono
parents:
diff changeset
2813
kono
parents:
diff changeset
2814 // Add a function declaration.
kono
parents:
diff changeset
2815 Named_object*
kono
parents:
diff changeset
2816 add_function_declaration(const std::string& name, const Package* package,
kono
parents:
diff changeset
2817 Function_type* type, Location location);
kono
parents:
diff changeset
2818
kono
parents:
diff changeset
2819 // Add a package. The location is the location of the import
kono
parents:
diff changeset
2820 // statement.
kono
parents:
diff changeset
2821 Named_object*
kono
parents:
diff changeset
2822 add_package(const std::string& alias, Package* package)
kono
parents:
diff changeset
2823 {
kono
parents:
diff changeset
2824 Named_object* no = Named_object::make_package(alias, package);
kono
parents:
diff changeset
2825 return this->add_named_object(no);
kono
parents:
diff changeset
2826 }
kono
parents:
diff changeset
2827
kono
parents:
diff changeset
2828 // Define a type which was already declared.
kono
parents:
diff changeset
2829 void
kono
parents:
diff changeset
2830 define_type(Named_object*, Named_type*);
kono
parents:
diff changeset
2831
kono
parents:
diff changeset
2832 // Add a method to the list of objects. This is not added to the
kono
parents:
diff changeset
2833 // lookup table.
kono
parents:
diff changeset
2834 void
kono
parents:
diff changeset
2835 add_method(Named_object*);
kono
parents:
diff changeset
2836
kono
parents:
diff changeset
2837 // Add a named object to this binding.
kono
parents:
diff changeset
2838 Named_object*
kono
parents:
diff changeset
2839 add_named_object(Named_object* no)
kono
parents:
diff changeset
2840 { return this->add_named_object_to_contour(&this->bindings_, no); }
kono
parents:
diff changeset
2841
kono
parents:
diff changeset
2842 // Clear all names in file scope from the bindings.
kono
parents:
diff changeset
2843 void
kono
parents:
diff changeset
2844 clear_file_scope(Gogo*);
kono
parents:
diff changeset
2845
kono
parents:
diff changeset
2846 // Look up a name in this binding contour and in any enclosing
kono
parents:
diff changeset
2847 // binding contours. This returns NULL if the name is not found.
kono
parents:
diff changeset
2848 Named_object*
kono
parents:
diff changeset
2849 lookup(const std::string&) const;
kono
parents:
diff changeset
2850
kono
parents:
diff changeset
2851 // Look up a name in this binding contour without looking in any
kono
parents:
diff changeset
2852 // enclosing binding contours. Returns NULL if the name is not found.
kono
parents:
diff changeset
2853 Named_object*
kono
parents:
diff changeset
2854 lookup_local(const std::string&) const;
kono
parents:
diff changeset
2855
kono
parents:
diff changeset
2856 // Remove a name.
kono
parents:
diff changeset
2857 void
kono
parents:
diff changeset
2858 remove_binding(Named_object*);
kono
parents:
diff changeset
2859
kono
parents:
diff changeset
2860 // Mark all variables as used. This is used for some types of parse
kono
parents:
diff changeset
2861 // error.
kono
parents:
diff changeset
2862 void
kono
parents:
diff changeset
2863 mark_locals_used();
kono
parents:
diff changeset
2864
kono
parents:
diff changeset
2865 // Traverse the tree. See the Traverse class.
kono
parents:
diff changeset
2866 int
kono
parents:
diff changeset
2867 traverse(Traverse*, bool is_global);
kono
parents:
diff changeset
2868
kono
parents:
diff changeset
2869 // Iterate over definitions. This does not include things which
kono
parents:
diff changeset
2870 // were only declared.
kono
parents:
diff changeset
2871
kono
parents:
diff changeset
2872 typedef std::vector<Named_object*>::const_iterator
kono
parents:
diff changeset
2873 const_definitions_iterator;
kono
parents:
diff changeset
2874
kono
parents:
diff changeset
2875 const_definitions_iterator
kono
parents:
diff changeset
2876 begin_definitions() const
kono
parents:
diff changeset
2877 { return this->named_objects_.begin(); }
kono
parents:
diff changeset
2878
kono
parents:
diff changeset
2879 const_definitions_iterator
kono
parents:
diff changeset
2880 end_definitions() const
kono
parents:
diff changeset
2881 { return this->named_objects_.end(); }
kono
parents:
diff changeset
2882
kono
parents:
diff changeset
2883 // Return the number of definitions.
kono
parents:
diff changeset
2884 size_t
kono
parents:
diff changeset
2885 size_definitions() const
kono
parents:
diff changeset
2886 { return this->named_objects_.size(); }
kono
parents:
diff changeset
2887
kono
parents:
diff changeset
2888 // Return whether there are no definitions.
kono
parents:
diff changeset
2889 bool
kono
parents:
diff changeset
2890 empty_definitions() const
kono
parents:
diff changeset
2891 { return this->named_objects_.empty(); }
kono
parents:
diff changeset
2892
kono
parents:
diff changeset
2893 // Iterate over declarations. This is everything that has been
kono
parents:
diff changeset
2894 // declared, which includes everything which has been defined.
kono
parents:
diff changeset
2895
kono
parents:
diff changeset
2896 typedef Contour::const_iterator const_declarations_iterator;
kono
parents:
diff changeset
2897
kono
parents:
diff changeset
2898 const_declarations_iterator
kono
parents:
diff changeset
2899 begin_declarations() const
kono
parents:
diff changeset
2900 { return this->bindings_.begin(); }
kono
parents:
diff changeset
2901
kono
parents:
diff changeset
2902 const_declarations_iterator
kono
parents:
diff changeset
2903 end_declarations() const
kono
parents:
diff changeset
2904 { return this->bindings_.end(); }
kono
parents:
diff changeset
2905
kono
parents:
diff changeset
2906 // Return the number of declarations.
kono
parents:
diff changeset
2907 size_t
kono
parents:
diff changeset
2908 size_declarations() const
kono
parents:
diff changeset
2909 { return this->bindings_.size(); }
kono
parents:
diff changeset
2910
kono
parents:
diff changeset
2911 // Return whether there are no declarations.
kono
parents:
diff changeset
2912 bool
kono
parents:
diff changeset
2913 empty_declarations() const
kono
parents:
diff changeset
2914 { return this->bindings_.empty(); }
kono
parents:
diff changeset
2915
kono
parents:
diff changeset
2916 // Return the first declaration.
kono
parents:
diff changeset
2917 Named_object*
kono
parents:
diff changeset
2918 first_declaration()
kono
parents:
diff changeset
2919 { return this->bindings_.empty() ? NULL : this->bindings_.begin()->second; }
kono
parents:
diff changeset
2920
kono
parents:
diff changeset
2921 private:
kono
parents:
diff changeset
2922 Named_object*
kono
parents:
diff changeset
2923 add_named_object_to_contour(Contour*, Named_object*);
kono
parents:
diff changeset
2924
kono
parents:
diff changeset
2925 Named_object*
kono
parents:
diff changeset
2926 new_definition(Named_object*, Named_object*);
kono
parents:
diff changeset
2927
kono
parents:
diff changeset
2928 // Enclosing bindings.
kono
parents:
diff changeset
2929 Bindings* enclosing_;
kono
parents:
diff changeset
2930 // The list of objects.
kono
parents:
diff changeset
2931 std::vector<Named_object*> named_objects_;
kono
parents:
diff changeset
2932 // The mapping from names to objects.
kono
parents:
diff changeset
2933 Contour bindings_;
kono
parents:
diff changeset
2934 };
kono
parents:
diff changeset
2935
kono
parents:
diff changeset
2936 // A label.
kono
parents:
diff changeset
2937
kono
parents:
diff changeset
2938 class Label
kono
parents:
diff changeset
2939 {
kono
parents:
diff changeset
2940 public:
kono
parents:
diff changeset
2941 Label(const std::string& name)
kono
parents:
diff changeset
2942 : name_(name), location_(Linemap::unknown_location()), snapshot_(NULL),
kono
parents:
diff changeset
2943 refs_(), is_used_(false), blabel_(NULL), depth_(DEPTH_UNKNOWN)
kono
parents:
diff changeset
2944 { }
kono
parents:
diff changeset
2945
kono
parents:
diff changeset
2946 // Return the label's name.
kono
parents:
diff changeset
2947 const std::string&
kono
parents:
diff changeset
2948 name() const
kono
parents:
diff changeset
2949 { return this->name_; }
kono
parents:
diff changeset
2950
kono
parents:
diff changeset
2951 // Return whether the label has been defined.
kono
parents:
diff changeset
2952 bool
kono
parents:
diff changeset
2953 is_defined() const
kono
parents:
diff changeset
2954 { return !Linemap::is_unknown_location(this->location_); }
kono
parents:
diff changeset
2955
kono
parents:
diff changeset
2956 // Return whether the label has been used.
kono
parents:
diff changeset
2957 bool
kono
parents:
diff changeset
2958 is_used() const
kono
parents:
diff changeset
2959 { return this->is_used_; }
kono
parents:
diff changeset
2960
kono
parents:
diff changeset
2961 // Record that the label is used.
kono
parents:
diff changeset
2962 void
kono
parents:
diff changeset
2963 set_is_used()
kono
parents:
diff changeset
2964 { this->is_used_ = true; }
kono
parents:
diff changeset
2965
kono
parents:
diff changeset
2966 // Return whether this label is looping.
kono
parents:
diff changeset
2967 bool
kono
parents:
diff changeset
2968 looping() const
kono
parents:
diff changeset
2969 { return this->depth_ == DEPTH_LOOPING; }
kono
parents:
diff changeset
2970
kono
parents:
diff changeset
2971 // Set this label as looping.
kono
parents:
diff changeset
2972 void
kono
parents:
diff changeset
2973 set_looping()
kono
parents:
diff changeset
2974 { this->depth_ = DEPTH_LOOPING; }
kono
parents:
diff changeset
2975
kono
parents:
diff changeset
2976 // Return whether this label is nonlooping.
kono
parents:
diff changeset
2977 bool
kono
parents:
diff changeset
2978 nonlooping() const
kono
parents:
diff changeset
2979 { return this->depth_ == DEPTH_NONLOOPING; }
kono
parents:
diff changeset
2980
kono
parents:
diff changeset
2981 // Set this label as nonlooping.
kono
parents:
diff changeset
2982 void
kono
parents:
diff changeset
2983 set_nonlooping()
kono
parents:
diff changeset
2984 { this->depth_ = DEPTH_NONLOOPING; }
kono
parents:
diff changeset
2985
kono
parents:
diff changeset
2986 // Return the location of the definition.
kono
parents:
diff changeset
2987 Location
kono
parents:
diff changeset
2988 location() const
kono
parents:
diff changeset
2989 { return this->location_; }
kono
parents:
diff changeset
2990
kono
parents:
diff changeset
2991 // Return the bindings snapshot.
kono
parents:
diff changeset
2992 Bindings_snapshot*
kono
parents:
diff changeset
2993 snapshot() const
kono
parents:
diff changeset
2994 { return this->snapshot_; }
kono
parents:
diff changeset
2995
kono
parents:
diff changeset
2996 // Add a snapshot of a goto which refers to this label.
kono
parents:
diff changeset
2997 void
kono
parents:
diff changeset
2998 add_snapshot_ref(Bindings_snapshot* snapshot)
kono
parents:
diff changeset
2999 {
kono
parents:
diff changeset
3000 go_assert(Linemap::is_unknown_location(this->location_));
kono
parents:
diff changeset
3001 this->refs_.push_back(snapshot);
kono
parents:
diff changeset
3002 }
kono
parents:
diff changeset
3003
kono
parents:
diff changeset
3004 // Return the list of snapshots of goto statements which refer to
kono
parents:
diff changeset
3005 // this label.
kono
parents:
diff changeset
3006 const std::vector<Bindings_snapshot*>&
kono
parents:
diff changeset
3007 refs() const
kono
parents:
diff changeset
3008 { return this->refs_; }
kono
parents:
diff changeset
3009
kono
parents:
diff changeset
3010 // Clear the references.
kono
parents:
diff changeset
3011 void
kono
parents:
diff changeset
3012 clear_refs();
kono
parents:
diff changeset
3013
kono
parents:
diff changeset
3014 // Define the label at LOCATION with the given bindings snapshot.
kono
parents:
diff changeset
3015 void
kono
parents:
diff changeset
3016 define(Location location, Bindings_snapshot* snapshot)
kono
parents:
diff changeset
3017 {
kono
parents:
diff changeset
3018 if (this->is_dummy_label())
kono
parents:
diff changeset
3019 return;
kono
parents:
diff changeset
3020 go_assert(Linemap::is_unknown_location(this->location_)
kono
parents:
diff changeset
3021 && this->snapshot_ == NULL);
kono
parents:
diff changeset
3022 this->location_ = location;
kono
parents:
diff changeset
3023 this->snapshot_ = snapshot;
kono
parents:
diff changeset
3024 }
kono
parents:
diff changeset
3025
kono
parents:
diff changeset
3026 // Return the backend representation for this label.
kono
parents:
diff changeset
3027 Blabel*
kono
parents:
diff changeset
3028 get_backend_label(Translate_context*);
kono
parents:
diff changeset
3029
kono
parents:
diff changeset
3030 // Return an expression for the address of this label. This is used
kono
parents:
diff changeset
3031 // to get the return address of a deferred function to see whether
kono
parents:
diff changeset
3032 // the function may call recover.
kono
parents:
diff changeset
3033 Bexpression*
kono
parents:
diff changeset
3034 get_addr(Translate_context*, Location location);
kono
parents:
diff changeset
3035
kono
parents:
diff changeset
3036 // Return a dummy label, representing any instance of the blank label.
kono
parents:
diff changeset
3037 static Label*
kono
parents:
diff changeset
3038 create_dummy_label();
kono
parents:
diff changeset
3039
kono
parents:
diff changeset
3040 // Return TRUE if this is a dummy label.
kono
parents:
diff changeset
3041 bool
kono
parents:
diff changeset
3042 is_dummy_label() const
kono
parents:
diff changeset
3043 { return this->name_ == "_"; }
kono
parents:
diff changeset
3044
kono
parents:
diff changeset
3045 // A classification of a label's looping depth.
kono
parents:
diff changeset
3046 enum Loop_depth
kono
parents:
diff changeset
3047 {
kono
parents:
diff changeset
3048 DEPTH_UNKNOWN,
kono
parents:
diff changeset
3049 // A label never jumped to.
kono
parents:
diff changeset
3050 DEPTH_NONLOOPING,
kono
parents:
diff changeset
3051 // A label jumped to.
kono
parents:
diff changeset
3052 DEPTH_LOOPING
kono
parents:
diff changeset
3053 };
kono
parents:
diff changeset
3054
kono
parents:
diff changeset
3055 private:
kono
parents:
diff changeset
3056 // The name of the label.
kono
parents:
diff changeset
3057 std::string name_;
kono
parents:
diff changeset
3058 // The location of the definition. This is 0 if the label has not
kono
parents:
diff changeset
3059 // yet been defined.
kono
parents:
diff changeset
3060 Location location_;
kono
parents:
diff changeset
3061 // A snapshot of the set of bindings defined at this label, used to
kono
parents:
diff changeset
3062 // issue errors about invalid goto statements.
kono
parents:
diff changeset
3063 Bindings_snapshot* snapshot_;
kono
parents:
diff changeset
3064 // A list of snapshots of goto statements which refer to this label.
kono
parents:
diff changeset
3065 std::vector<Bindings_snapshot*> refs_;
kono
parents:
diff changeset
3066 // Whether the label has been used.
kono
parents:
diff changeset
3067 bool is_used_;
kono
parents:
diff changeset
3068 // The backend representation.
kono
parents:
diff changeset
3069 Blabel* blabel_;
kono
parents:
diff changeset
3070 // The looping depth of this label, for escape analysis.
kono
parents:
diff changeset
3071 Loop_depth depth_;
kono
parents:
diff changeset
3072 };
kono
parents:
diff changeset
3073
kono
parents:
diff changeset
3074 // An unnamed label. These are used when lowering loops.
kono
parents:
diff changeset
3075
kono
parents:
diff changeset
3076 class Unnamed_label
kono
parents:
diff changeset
3077 {
kono
parents:
diff changeset
3078 public:
kono
parents:
diff changeset
3079 Unnamed_label(Location location)
kono
parents:
diff changeset
3080 : location_(location), derived_from_(NULL), blabel_(NULL)
kono
parents:
diff changeset
3081 { }
kono
parents:
diff changeset
3082
kono
parents:
diff changeset
3083 // Get the location where the label is defined.
kono
parents:
diff changeset
3084 Location
kono
parents:
diff changeset
3085 location() const
kono
parents:
diff changeset
3086 { return this->location_; }
kono
parents:
diff changeset
3087
kono
parents:
diff changeset
3088 // Set the location where the label is defined.
kono
parents:
diff changeset
3089 void
kono
parents:
diff changeset
3090 set_location(Location location)
kono
parents:
diff changeset
3091 { this->location_ = location; }
kono
parents:
diff changeset
3092
kono
parents:
diff changeset
3093 // Get the top level statement this unnamed label is derived from.
kono
parents:
diff changeset
3094 Statement*
kono
parents:
diff changeset
3095 derived_from() const
kono
parents:
diff changeset
3096 { return this->derived_from_; }
kono
parents:
diff changeset
3097
kono
parents:
diff changeset
3098 // Set the top level statement this unnamed label is derived from.
kono
parents:
diff changeset
3099 void
kono
parents:
diff changeset
3100 set_derived_from(Statement* s)
kono
parents:
diff changeset
3101 { this->derived_from_ = s; }
kono
parents:
diff changeset
3102
kono
parents:
diff changeset
3103 // Return a statement which defines this label.
kono
parents:
diff changeset
3104 Bstatement*
kono
parents:
diff changeset
3105 get_definition(Translate_context*);
kono
parents:
diff changeset
3106
kono
parents:
diff changeset
3107 // Return a goto to this label from LOCATION.
kono
parents:
diff changeset
3108 Bstatement*
kono
parents:
diff changeset
3109 get_goto(Translate_context*, Location location);
kono
parents:
diff changeset
3110
kono
parents:
diff changeset
3111 private:
kono
parents:
diff changeset
3112 // Return the backend representation.
kono
parents:
diff changeset
3113 Blabel*
kono
parents:
diff changeset
3114 get_blabel(Translate_context*);
kono
parents:
diff changeset
3115
kono
parents:
diff changeset
3116 // The location where the label is defined.
kono
parents:
diff changeset
3117 Location location_;
kono
parents:
diff changeset
3118 // The top-level statement this unnamed label was derived/lowered from.
kono
parents:
diff changeset
3119 // This is NULL is this label is not the top-level of a lowered statement.
kono
parents:
diff changeset
3120 Statement* derived_from_;
kono
parents:
diff changeset
3121 // The backend representation of this label.
kono
parents:
diff changeset
3122 Blabel* blabel_;
kono
parents:
diff changeset
3123 };
kono
parents:
diff changeset
3124
kono
parents:
diff changeset
3125 // An alias for an imported package.
kono
parents:
diff changeset
3126
kono
parents:
diff changeset
3127 class Package_alias
kono
parents:
diff changeset
3128 {
kono
parents:
diff changeset
3129 public:
kono
parents:
diff changeset
3130 Package_alias(Location location)
kono
parents:
diff changeset
3131 : location_(location), used_(0)
kono
parents:
diff changeset
3132 { }
kono
parents:
diff changeset
3133
kono
parents:
diff changeset
3134 // The location of the import statement.
kono
parents:
diff changeset
3135 Location
kono
parents:
diff changeset
3136 location()
kono
parents:
diff changeset
3137 { return this->location_; }
kono
parents:
diff changeset
3138
kono
parents:
diff changeset
3139 // How many symbols from the package were used under this alias.
kono
parents:
diff changeset
3140 size_t
kono
parents:
diff changeset
3141 used() const
kono
parents:
diff changeset
3142 { return this->used_; }
kono
parents:
diff changeset
3143
kono
parents:
diff changeset
3144 // Note that some symbol was used under this alias.
kono
parents:
diff changeset
3145 void
kono
parents:
diff changeset
3146 note_usage()
kono
parents:
diff changeset
3147 { this->used_++; }
kono
parents:
diff changeset
3148
kono
parents:
diff changeset
3149 private:
kono
parents:
diff changeset
3150 // The location of the import statement.
kono
parents:
diff changeset
3151 Location location_;
kono
parents:
diff changeset
3152 // The amount of times some name from this package was used under this alias.
kono
parents:
diff changeset
3153 size_t used_;
kono
parents:
diff changeset
3154 };
kono
parents:
diff changeset
3155
kono
parents:
diff changeset
3156 // An imported package.
kono
parents:
diff changeset
3157
kono
parents:
diff changeset
3158 class Package
kono
parents:
diff changeset
3159 {
kono
parents:
diff changeset
3160 public:
kono
parents:
diff changeset
3161 Package(const std::string& pkgpath, const std::string& pkgpath_symbol,
kono
parents:
diff changeset
3162 Location location);
kono
parents:
diff changeset
3163
kono
parents:
diff changeset
3164 // Get the package path used for all symbols exported from this
kono
parents:
diff changeset
3165 // package.
kono
parents:
diff changeset
3166 const std::string&
kono
parents:
diff changeset
3167 pkgpath() const
kono
parents:
diff changeset
3168 { return this->pkgpath_; }
kono
parents:
diff changeset
3169
kono
parents:
diff changeset
3170 // Return the package path to use for a symbol name.
kono
parents:
diff changeset
3171 std::string
kono
parents:
diff changeset
3172 pkgpath_symbol() const;
kono
parents:
diff changeset
3173
kono
parents:
diff changeset
3174 // Set the package path symbol.
kono
parents:
diff changeset
3175 void
kono
parents:
diff changeset
3176 set_pkgpath_symbol(const std::string&);
kono
parents:
diff changeset
3177
kono
parents:
diff changeset
3178 // Return the location of the most recent import statement.
kono
parents:
diff changeset
3179 Location
kono
parents:
diff changeset
3180 location() const
kono
parents:
diff changeset
3181 { return this->location_; }
kono
parents:
diff changeset
3182
kono
parents:
diff changeset
3183 // Return whether we know the name of this package yet.
kono
parents:
diff changeset
3184 bool
kono
parents:
diff changeset
3185 has_package_name() const
kono
parents:
diff changeset
3186 { return !this->package_name_.empty(); }
kono
parents:
diff changeset
3187
kono
parents:
diff changeset
3188 // The name that this package uses in its package clause. This may
kono
parents:
diff changeset
3189 // be different from the name in the associated Named_object if the
kono
parents:
diff changeset
3190 // import statement used an alias.
kono
parents:
diff changeset
3191 const std::string&
kono
parents:
diff changeset
3192 package_name() const
kono
parents:
diff changeset
3193 {
kono
parents:
diff changeset
3194 go_assert(!this->package_name_.empty());
kono
parents:
diff changeset
3195 return this->package_name_;
kono
parents:
diff changeset
3196 }
kono
parents:
diff changeset
3197
kono
parents:
diff changeset
3198 // Return the bindings.
kono
parents:
diff changeset
3199 Bindings*
kono
parents:
diff changeset
3200 bindings()
kono
parents:
diff changeset
3201 { return this->bindings_; }
kono
parents:
diff changeset
3202
kono
parents:
diff changeset
3203 // Type used to map import names to package aliases.
kono
parents:
diff changeset
3204 typedef std::map<std::string, Package_alias*> Aliases;
kono
parents:
diff changeset
3205
kono
parents:
diff changeset
3206 // Return the set of package aliases.
kono
parents:
diff changeset
3207 const Aliases&
kono
parents:
diff changeset
3208 aliases() const
kono
parents:
diff changeset
3209 { return this->aliases_; }
kono
parents:
diff changeset
3210
kono
parents:
diff changeset
3211 // Note that some symbol from this package was used and qualified by ALIAS.
kono
parents:
diff changeset
3212 // For dot imports, the ALIAS should be ".PACKAGE_NAME".
kono
parents:
diff changeset
3213 void
kono
parents:
diff changeset
3214 note_usage(const std::string& alias) const;
kono
parents:
diff changeset
3215
kono
parents:
diff changeset
3216 // Note that USAGE might be a fake usage of this package.
kono
parents:
diff changeset
3217 void
kono
parents:
diff changeset
3218 note_fake_usage(Expression* usage) const
kono
parents:
diff changeset
3219 { this->fake_uses_.insert(usage); }
kono
parents:
diff changeset
3220
kono
parents:
diff changeset
3221 // Forget a given USAGE of this package.
kono
parents:
diff changeset
3222 void
kono
parents:
diff changeset
3223 forget_usage(Expression* usage) const;
kono
parents:
diff changeset
3224
kono
parents:
diff changeset
3225 // Clear the used field for the next file.
kono
parents:
diff changeset
3226 void
kono
parents:
diff changeset
3227 clear_used();
kono
parents:
diff changeset
3228
kono
parents:
diff changeset
3229 // Look up a name in the package. Returns NULL if the name is not
kono
parents:
diff changeset
3230 // found.
kono
parents:
diff changeset
3231 Named_object*
kono
parents:
diff changeset
3232 lookup(const std::string& name) const
kono
parents:
diff changeset
3233 { return this->bindings_->lookup(name); }
kono
parents:
diff changeset
3234
kono
parents:
diff changeset
3235 // Set the name of the package.
kono
parents:
diff changeset
3236 void
kono
parents:
diff changeset
3237 set_package_name(const std::string& name, Location);
kono
parents:
diff changeset
3238
kono
parents:
diff changeset
3239 // Set the location of the package. This is used to record the most
kono
parents:
diff changeset
3240 // recent import location.
kono
parents:
diff changeset
3241 void
kono
parents:
diff changeset
3242 set_location(Location location)
kono
parents:
diff changeset
3243 { this->location_ = location; }
kono
parents:
diff changeset
3244
kono
parents:
diff changeset
3245 // Add a package name as an ALIAS for this package.
kono
parents:
diff changeset
3246 Package_alias*
kono
parents:
diff changeset
3247 add_alias(const std::string& alias, Location);
kono
parents:
diff changeset
3248
kono
parents:
diff changeset
3249 // Add a constant to the package.
kono
parents:
diff changeset
3250 Named_object*
kono
parents:
diff changeset
3251 add_constant(const Typed_identifier& tid, Expression* expr)
kono
parents:
diff changeset
3252 { return this->bindings_->add_constant(tid, this, expr, 0); }
kono
parents:
diff changeset
3253
kono
parents:
diff changeset
3254 // Add a type to the package.
kono
parents:
diff changeset
3255 Named_object*
kono
parents:
diff changeset
3256 add_type(const std::string& name, Type* type, Location location)
kono
parents:
diff changeset
3257 { return this->bindings_->add_type(name, this, type, location); }
kono
parents:
diff changeset
3258
kono
parents:
diff changeset
3259 // Add a type declaration to the package.
kono
parents:
diff changeset
3260 Named_object*
kono
parents:
diff changeset
3261 add_type_declaration(const std::string& name, Location location)
kono
parents:
diff changeset
3262 { return this->bindings_->add_type_declaration(name, this, location); }
kono
parents:
diff changeset
3263
kono
parents:
diff changeset
3264 // Add a variable to the package.
kono
parents:
diff changeset
3265 Named_object*
kono
parents:
diff changeset
3266 add_variable(const std::string& name, Variable* variable)
kono
parents:
diff changeset
3267 { return this->bindings_->add_variable(name, this, variable); }
kono
parents:
diff changeset
3268
kono
parents:
diff changeset
3269 // Add a function declaration to the package.
kono
parents:
diff changeset
3270 Named_object*
kono
parents:
diff changeset
3271 add_function_declaration(const std::string& name, Function_type* type,
kono
parents:
diff changeset
3272 Location loc)
kono
parents:
diff changeset
3273 { return this->bindings_->add_function_declaration(name, this, type, loc); }
kono
parents:
diff changeset
3274
kono
parents:
diff changeset
3275 // Determine types of constants.
kono
parents:
diff changeset
3276 void
kono
parents:
diff changeset
3277 determine_types();
kono
parents:
diff changeset
3278
kono
parents:
diff changeset
3279 private:
kono
parents:
diff changeset
3280 // The package path for type reflection data.
kono
parents:
diff changeset
3281 std::string pkgpath_;
kono
parents:
diff changeset
3282 // The package path for symbol names.
kono
parents:
diff changeset
3283 std::string pkgpath_symbol_;
kono
parents:
diff changeset
3284 // The name that this package uses in the package clause. This may
kono
parents:
diff changeset
3285 // be the empty string if it is not yet known.
kono
parents:
diff changeset
3286 std::string package_name_;
kono
parents:
diff changeset
3287 // The names in this package.
kono
parents:
diff changeset
3288 Bindings* bindings_;
kono
parents:
diff changeset
3289 // The location of the most recent import statement.
kono
parents:
diff changeset
3290 Location location_;
kono
parents:
diff changeset
3291 // The set of aliases associated with this package.
kono
parents:
diff changeset
3292 Aliases aliases_;
kono
parents:
diff changeset
3293 // A set of possibly fake uses of this package. This is mutable because we
kono
parents:
diff changeset
3294 // can track fake uses of a package even if we have a const pointer to it.
kono
parents:
diff changeset
3295 mutable std::set<Expression*> fake_uses_;
kono
parents:
diff changeset
3296 };
kono
parents:
diff changeset
3297
kono
parents:
diff changeset
3298 // Return codes for the traversal functions. This is not an enum
kono
parents:
diff changeset
3299 // because we want to be able to declare traversal functions in other
kono
parents:
diff changeset
3300 // header files without including this one.
kono
parents:
diff changeset
3301
kono
parents:
diff changeset
3302 // Continue traversal as usual.
kono
parents:
diff changeset
3303 const int TRAVERSE_CONTINUE = -1;
kono
parents:
diff changeset
3304
kono
parents:
diff changeset
3305 // Exit traversal.
kono
parents:
diff changeset
3306 const int TRAVERSE_EXIT = 0;
kono
parents:
diff changeset
3307
kono
parents:
diff changeset
3308 // Continue traversal, but skip components of the current object.
kono
parents:
diff changeset
3309 // E.g., if this is returned by Traverse::statement, we do not
kono
parents:
diff changeset
3310 // traverse the expressions in the statement even if
kono
parents:
diff changeset
3311 // traverse_expressions is set in the traverse_mask.
kono
parents:
diff changeset
3312 const int TRAVERSE_SKIP_COMPONENTS = 1;
kono
parents:
diff changeset
3313
kono
parents:
diff changeset
3314 // This class is used when traversing the parse tree. The caller uses
kono
parents:
diff changeset
3315 // a subclass which overrides functions as desired.
kono
parents:
diff changeset
3316
kono
parents:
diff changeset
3317 class Traverse
kono
parents:
diff changeset
3318 {
kono
parents:
diff changeset
3319 public:
kono
parents:
diff changeset
3320 // These bitmasks say what to traverse.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3321 static const unsigned int traverse_variables = 0x1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3322 static const unsigned int traverse_constants = 0x2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3323 static const unsigned int traverse_functions = 0x4;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3324 static const unsigned int traverse_blocks = 0x8;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3325 static const unsigned int traverse_statements = 0x10;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3326 static const unsigned int traverse_expressions = 0x20;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3327 static const unsigned int traverse_types = 0x40;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3328 static const unsigned int traverse_func_declarations = 0x80;
111
kono
parents:
diff changeset
3329
kono
parents:
diff changeset
3330 Traverse(unsigned int traverse_mask)
kono
parents:
diff changeset
3331 : traverse_mask_(traverse_mask), types_seen_(NULL), expressions_seen_(NULL)
kono
parents:
diff changeset
3332 { }
kono
parents:
diff changeset
3333
kono
parents:
diff changeset
3334 virtual ~Traverse();
kono
parents:
diff changeset
3335
kono
parents:
diff changeset
3336 // The bitmask of what to traverse.
kono
parents:
diff changeset
3337 unsigned int
kono
parents:
diff changeset
3338 traverse_mask() const
kono
parents:
diff changeset
3339 { return this->traverse_mask_; }
kono
parents:
diff changeset
3340
kono
parents:
diff changeset
3341 // Record that we are going to traverse a type. This returns true
kono
parents:
diff changeset
3342 // if the type has already been seen in this traversal. This is
kono
parents:
diff changeset
3343 // required because types, unlike expressions, can form a circular
kono
parents:
diff changeset
3344 // graph.
kono
parents:
diff changeset
3345 bool
kono
parents:
diff changeset
3346 remember_type(const Type*);
kono
parents:
diff changeset
3347
kono
parents:
diff changeset
3348 // Record that we are going to see an expression. This returns true
kono
parents:
diff changeset
3349 // if the expression has already been seen in this traversal. This
kono
parents:
diff changeset
3350 // is only needed for cases where multiple expressions can point to
kono
parents:
diff changeset
3351 // a single one.
kono
parents:
diff changeset
3352 bool
kono
parents:
diff changeset
3353 remember_expression(const Expression*);
kono
parents:
diff changeset
3354
kono
parents:
diff changeset
3355 // These functions return one of the TRAVERSE codes defined above.
kono
parents:
diff changeset
3356
kono
parents:
diff changeset
3357 // If traverse_variables is set in the mask, this is called for
kono
parents:
diff changeset
3358 // every variable in the tree.
kono
parents:
diff changeset
3359 virtual int
kono
parents:
diff changeset
3360 variable(Named_object*);
kono
parents:
diff changeset
3361
kono
parents:
diff changeset
3362 // If traverse_constants is set in the mask, this is called for
kono
parents:
diff changeset
3363 // every named constant in the tree. The bool parameter is true for
kono
parents:
diff changeset
3364 // a global constant.
kono
parents:
diff changeset
3365 virtual int
kono
parents:
diff changeset
3366 constant(Named_object*, bool);
kono
parents:
diff changeset
3367
kono
parents:
diff changeset
3368 // If traverse_functions is set in the mask, this is called for
kono
parents:
diff changeset
3369 // every function in the tree.
kono
parents:
diff changeset
3370 virtual int
kono
parents:
diff changeset
3371 function(Named_object*);
kono
parents:
diff changeset
3372
kono
parents:
diff changeset
3373 // If traverse_blocks is set in the mask, this is called for every
kono
parents:
diff changeset
3374 // block in the tree.
kono
parents:
diff changeset
3375 virtual int
kono
parents:
diff changeset
3376 block(Block*);
kono
parents:
diff changeset
3377
kono
parents:
diff changeset
3378 // If traverse_statements is set in the mask, this is called for
kono
parents:
diff changeset
3379 // every statement in the tree.
kono
parents:
diff changeset
3380 virtual int
kono
parents:
diff changeset
3381 statement(Block*, size_t* index, Statement*);
kono
parents:
diff changeset
3382
kono
parents:
diff changeset
3383 // If traverse_expressions is set in the mask, this is called for
kono
parents:
diff changeset
3384 // every expression in the tree.
kono
parents:
diff changeset
3385 virtual int
kono
parents:
diff changeset
3386 expression(Expression**);
kono
parents:
diff changeset
3387
kono
parents:
diff changeset
3388 // If traverse_types is set in the mask, this is called for every
kono
parents:
diff changeset
3389 // type in the tree.
kono
parents:
diff changeset
3390 virtual int
kono
parents:
diff changeset
3391 type(Type*);
kono
parents:
diff changeset
3392
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3393 // If traverse_func_declarations is set in the mask, this is called
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3394 // for every function declarations in the tree.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3395 virtual int
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3396 function_declaration(Named_object*);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3397
111
kono
parents:
diff changeset
3398 private:
kono
parents:
diff changeset
3399 // A hash table for types we have seen during this traversal. Note
kono
parents:
diff changeset
3400 // that this uses the default hash functions for pointers rather
kono
parents:
diff changeset
3401 // than Type_hash_identical and Type_identical. This is because for
kono
parents:
diff changeset
3402 // traversal we care about seeing a specific type structure. If
kono
parents:
diff changeset
3403 // there are two separate instances of identical types, we want to
kono
parents:
diff changeset
3404 // traverse both.
kono
parents:
diff changeset
3405 typedef Unordered_set(const Type*) Types_seen;
kono
parents:
diff changeset
3406
kono
parents:
diff changeset
3407 typedef Unordered_set(const Expression*) Expressions_seen;
kono
parents:
diff changeset
3408
kono
parents:
diff changeset
3409 // Bitmask of what sort of objects to traverse.
kono
parents:
diff changeset
3410 unsigned int traverse_mask_;
kono
parents:
diff changeset
3411 // Types which have been seen in this traversal.
kono
parents:
diff changeset
3412 Types_seen* types_seen_;
kono
parents:
diff changeset
3413 // Expressions which have been seen in this traversal.
kono
parents:
diff changeset
3414 Expressions_seen* expressions_seen_;
kono
parents:
diff changeset
3415 };
kono
parents:
diff changeset
3416
kono
parents:
diff changeset
3417 // A class which makes it easier to insert new statements before the
kono
parents:
diff changeset
3418 // current statement during a traversal.
kono
parents:
diff changeset
3419
kono
parents:
diff changeset
3420 class Statement_inserter
kono
parents:
diff changeset
3421 {
kono
parents:
diff changeset
3422 public:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3423 typedef Unordered_set(Statement*) Statements;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3424
111
kono
parents:
diff changeset
3425 // Empty constructor.
kono
parents:
diff changeset
3426 Statement_inserter()
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3427 : block_(NULL), pindex_(NULL), gogo_(NULL), var_(NULL),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3428 statements_added_(NULL)
111
kono
parents:
diff changeset
3429 { }
kono
parents:
diff changeset
3430
kono
parents:
diff changeset
3431 // Constructor for a statement in a block.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3432 Statement_inserter(Block* block, size_t *pindex, Statements *added = NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3433 : block_(block), pindex_(pindex), gogo_(NULL), var_(NULL),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3434 statements_added_(added)
111
kono
parents:
diff changeset
3435 { }
kono
parents:
diff changeset
3436
kono
parents:
diff changeset
3437 // Constructor for a global variable.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3438 Statement_inserter(Gogo* gogo, Variable* var, Statements *added = NULL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3439 : block_(NULL), pindex_(NULL), gogo_(gogo), var_(var),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3440 statements_added_(added)
111
kono
parents:
diff changeset
3441 { go_assert(var->is_global()); }
kono
parents:
diff changeset
3442
kono
parents:
diff changeset
3443 // We use the default copy constructor and assignment operator.
kono
parents:
diff changeset
3444
kono
parents:
diff changeset
3445 // Insert S before the statement we are traversing, or before the
kono
parents:
diff changeset
3446 // initialization expression of a global variable.
kono
parents:
diff changeset
3447 void
kono
parents:
diff changeset
3448 insert(Statement* s);
kono
parents:
diff changeset
3449
kono
parents:
diff changeset
3450 private:
kono
parents:
diff changeset
3451 // The block that the statement is in.
kono
parents:
diff changeset
3452 Block* block_;
kono
parents:
diff changeset
3453 // The index of the statement that we are traversing.
kono
parents:
diff changeset
3454 size_t* pindex_;
kono
parents:
diff changeset
3455 // The IR, needed when looking at an initializer expression for a
kono
parents:
diff changeset
3456 // global variable.
kono
parents:
diff changeset
3457 Gogo* gogo_;
kono
parents:
diff changeset
3458 // The global variable, when looking at an initializer expression.
kono
parents:
diff changeset
3459 Variable* var_;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3460 // If non-null, a set to record new statements inserted (non-owned).
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3461 Statements* statements_added_;
111
kono
parents:
diff changeset
3462 };
kono
parents:
diff changeset
3463
kono
parents:
diff changeset
3464 // When translating the gogo IR into the backend data structure, this
kono
parents:
diff changeset
3465 // is the context we pass down the blocks and statements.
kono
parents:
diff changeset
3466
kono
parents:
diff changeset
3467 class Translate_context
kono
parents:
diff changeset
3468 {
kono
parents:
diff changeset
3469 public:
kono
parents:
diff changeset
3470 Translate_context(Gogo* gogo, Named_object* function, Block* block,
kono
parents:
diff changeset
3471 Bblock* bblock)
kono
parents:
diff changeset
3472 : gogo_(gogo), backend_(gogo->backend()), function_(function),
kono
parents:
diff changeset
3473 block_(block), bblock_(bblock), is_const_(false)
kono
parents:
diff changeset
3474 { }
kono
parents:
diff changeset
3475
kono
parents:
diff changeset
3476 // Accessors.
kono
parents:
diff changeset
3477
kono
parents:
diff changeset
3478 Gogo*
kono
parents:
diff changeset
3479 gogo()
kono
parents:
diff changeset
3480 { return this->gogo_; }
kono
parents:
diff changeset
3481
kono
parents:
diff changeset
3482 Backend*
kono
parents:
diff changeset
3483 backend()
kono
parents:
diff changeset
3484 { return this->backend_; }
kono
parents:
diff changeset
3485
kono
parents:
diff changeset
3486 Named_object*
kono
parents:
diff changeset
3487 function()
kono
parents:
diff changeset
3488 { return this->function_; }
kono
parents:
diff changeset
3489
kono
parents:
diff changeset
3490 Block*
kono
parents:
diff changeset
3491 block()
kono
parents:
diff changeset
3492 { return this->block_; }
kono
parents:
diff changeset
3493
kono
parents:
diff changeset
3494 Bblock*
kono
parents:
diff changeset
3495 bblock()
kono
parents:
diff changeset
3496 { return this->bblock_; }
kono
parents:
diff changeset
3497
kono
parents:
diff changeset
3498 bool
kono
parents:
diff changeset
3499 is_const()
kono
parents:
diff changeset
3500 { return this->is_const_; }
kono
parents:
diff changeset
3501
kono
parents:
diff changeset
3502 // Make a constant context.
kono
parents:
diff changeset
3503 void
kono
parents:
diff changeset
3504 set_is_const()
kono
parents:
diff changeset
3505 { this->is_const_ = true; }
kono
parents:
diff changeset
3506
kono
parents:
diff changeset
3507 private:
kono
parents:
diff changeset
3508 // The IR for the entire compilation unit.
kono
parents:
diff changeset
3509 Gogo* gogo_;
kono
parents:
diff changeset
3510 // The generator for the backend data structures.
kono
parents:
diff changeset
3511 Backend* backend_;
kono
parents:
diff changeset
3512 // The function we are currently translating. NULL if not in a
kono
parents:
diff changeset
3513 // function, e.g., the initializer of a global variable.
kono
parents:
diff changeset
3514 Named_object* function_;
kono
parents:
diff changeset
3515 // The block we are currently translating. NULL if not in a
kono
parents:
diff changeset
3516 // function.
kono
parents:
diff changeset
3517 Block *block_;
kono
parents:
diff changeset
3518 // The backend representation of the current block. NULL if block_
kono
parents:
diff changeset
3519 // is NULL.
kono
parents:
diff changeset
3520 Bblock* bblock_;
kono
parents:
diff changeset
3521 // Whether this is being evaluated in a constant context. This is
kono
parents:
diff changeset
3522 // used for type descriptor initializers.
kono
parents:
diff changeset
3523 bool is_const_;
kono
parents:
diff changeset
3524 };
kono
parents:
diff changeset
3525
kono
parents:
diff changeset
3526 // Runtime error codes. These must match the values in
kono
parents:
diff changeset
3527 // libgo/runtime/go-runtime-error.c.
kono
parents:
diff changeset
3528
kono
parents:
diff changeset
3529 // Slice index out of bounds: negative or larger than the length of
kono
parents:
diff changeset
3530 // the slice.
kono
parents:
diff changeset
3531 static const int RUNTIME_ERROR_SLICE_INDEX_OUT_OF_BOUNDS = 0;
kono
parents:
diff changeset
3532
kono
parents:
diff changeset
3533 // Array index out of bounds.
kono
parents:
diff changeset
3534 static const int RUNTIME_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS = 1;
kono
parents:
diff changeset
3535
kono
parents:
diff changeset
3536 // String index out of bounds.
kono
parents:
diff changeset
3537 static const int RUNTIME_ERROR_STRING_INDEX_OUT_OF_BOUNDS = 2;
kono
parents:
diff changeset
3538
kono
parents:
diff changeset
3539 // Slice slice out of bounds: negative or larger than the length of
kono
parents:
diff changeset
3540 // the slice or high bound less than low bound.
kono
parents:
diff changeset
3541 static const int RUNTIME_ERROR_SLICE_SLICE_OUT_OF_BOUNDS = 3;
kono
parents:
diff changeset
3542
kono
parents:
diff changeset
3543 // Array slice out of bounds.
kono
parents:
diff changeset
3544 static const int RUNTIME_ERROR_ARRAY_SLICE_OUT_OF_BOUNDS = 4;
kono
parents:
diff changeset
3545
kono
parents:
diff changeset
3546 // String slice out of bounds.
kono
parents:
diff changeset
3547 static const int RUNTIME_ERROR_STRING_SLICE_OUT_OF_BOUNDS = 5;
kono
parents:
diff changeset
3548
kono
parents:
diff changeset
3549 // Dereference of nil pointer. This is used when there is a
kono
parents:
diff changeset
3550 // dereference of a pointer to a very large struct or array, to ensure
kono
parents:
diff changeset
3551 // that a gigantic array is not used a proxy to access random memory
kono
parents:
diff changeset
3552 // locations.
kono
parents:
diff changeset
3553 static const int RUNTIME_ERROR_NIL_DEREFERENCE = 6;
kono
parents:
diff changeset
3554
kono
parents:
diff changeset
3555 // Slice length or capacity out of bounds in make: negative or
kono
parents:
diff changeset
3556 // overflow or length greater than capacity.
kono
parents:
diff changeset
3557 static const int RUNTIME_ERROR_MAKE_SLICE_OUT_OF_BOUNDS = 7;
kono
parents:
diff changeset
3558
kono
parents:
diff changeset
3559 // Map capacity out of bounds in make: negative or overflow.
kono
parents:
diff changeset
3560 static const int RUNTIME_ERROR_MAKE_MAP_OUT_OF_BOUNDS = 8;
kono
parents:
diff changeset
3561
kono
parents:
diff changeset
3562 // Channel capacity out of bounds in make: negative or overflow.
kono
parents:
diff changeset
3563 static const int RUNTIME_ERROR_MAKE_CHAN_OUT_OF_BOUNDS = 9;
kono
parents:
diff changeset
3564
kono
parents:
diff changeset
3565 // Division by zero.
kono
parents:
diff changeset
3566 static const int RUNTIME_ERROR_DIVISION_BY_ZERO = 10;
kono
parents:
diff changeset
3567
kono
parents:
diff changeset
3568 // Go statement with nil function.
kono
parents:
diff changeset
3569 static const int RUNTIME_ERROR_GO_NIL = 11;
kono
parents:
diff changeset
3570
kono
parents:
diff changeset
3571 // This is used by some of the langhooks.
kono
parents:
diff changeset
3572 extern Gogo* go_get_gogo();
kono
parents:
diff changeset
3573
kono
parents:
diff changeset
3574 // Whether we have seen any errors. FIXME: Replace with a backend
kono
parents:
diff changeset
3575 // interface.
kono
parents:
diff changeset
3576 extern bool saw_errors();
kono
parents:
diff changeset
3577
kono
parents:
diff changeset
3578 #endif // !defined(GO_GOGO_H)