1 |
714 |
jeremybenn |
// backend.h -- Go frontend interface to backend -*- C++ -*-
|
2 |
|
|
|
3 |
|
|
// Copyright 2011 The Go Authors. All rights reserved.
|
4 |
|
|
// Use of this source code is governed by a BSD-style
|
5 |
|
|
// license that can be found in the LICENSE file.
|
6 |
|
|
|
7 |
|
|
#ifndef GO_BACKEND_H
|
8 |
|
|
#define GO_BACKEND_H
|
9 |
|
|
|
10 |
|
|
// Pointers to these types are created by the backend, passed to the
|
11 |
|
|
// frontend, and passed back to the backend. The types must be
|
12 |
|
|
// defined by the backend using these names.
|
13 |
|
|
|
14 |
|
|
// The backend representation of a type.
|
15 |
|
|
class Btype;
|
16 |
|
|
|
17 |
|
|
// The backend represention of an expression.
|
18 |
|
|
class Bexpression;
|
19 |
|
|
|
20 |
|
|
// The backend representation of a statement.
|
21 |
|
|
class Bstatement;
|
22 |
|
|
|
23 |
|
|
// The backend representation of a function definition.
|
24 |
|
|
class Bfunction;
|
25 |
|
|
|
26 |
|
|
// The backend representation of a block.
|
27 |
|
|
class Bblock;
|
28 |
|
|
|
29 |
|
|
// The backend representation of a variable.
|
30 |
|
|
class Bvariable;
|
31 |
|
|
|
32 |
|
|
// The backend representation of a label.
|
33 |
|
|
class Blabel;
|
34 |
|
|
|
35 |
|
|
// The backend interface. This is a pure abstract class that a
|
36 |
|
|
// specific backend will implement.
|
37 |
|
|
|
38 |
|
|
class Backend
|
39 |
|
|
{
|
40 |
|
|
public:
|
41 |
|
|
virtual ~Backend() { }
|
42 |
|
|
|
43 |
|
|
// Name/type/location. Used for function parameters, struct fields,
|
44 |
|
|
// interface methods.
|
45 |
|
|
struct Btyped_identifier
|
46 |
|
|
{
|
47 |
|
|
std::string name;
|
48 |
|
|
Btype* btype;
|
49 |
|
|
Location location;
|
50 |
|
|
|
51 |
|
|
Btyped_identifier()
|
52 |
|
|
: name(), btype(NULL), location(UNKNOWN_LOCATION)
|
53 |
|
|
{ }
|
54 |
|
|
|
55 |
|
|
Btyped_identifier(const std::string& a_name, Btype* a_btype,
|
56 |
|
|
Location a_location)
|
57 |
|
|
: name(a_name), btype(a_btype), location(a_location)
|
58 |
|
|
{ }
|
59 |
|
|
};
|
60 |
|
|
|
61 |
|
|
// Types.
|
62 |
|
|
|
63 |
|
|
// Produce an error type. Actually the backend could probably just
|
64 |
|
|
// crash if this is called.
|
65 |
|
|
virtual Btype*
|
66 |
|
|
error_type() = 0;
|
67 |
|
|
|
68 |
|
|
// Get a void type. This is used in (at least) two ways: 1) as the
|
69 |
|
|
// return type of a function with no result parameters; 2)
|
70 |
|
|
// unsafe.Pointer is represented as *void.
|
71 |
|
|
virtual Btype*
|
72 |
|
|
void_type() = 0;
|
73 |
|
|
|
74 |
|
|
// Get the unnamed boolean type.
|
75 |
|
|
virtual Btype*
|
76 |
|
|
bool_type() = 0;
|
77 |
|
|
|
78 |
|
|
// Get an unnamed integer type with the given signedness and number
|
79 |
|
|
// of bits.
|
80 |
|
|
virtual Btype*
|
81 |
|
|
integer_type(bool is_unsigned, int bits) = 0;
|
82 |
|
|
|
83 |
|
|
// Get an unnamed floating point type with the given number of bits
|
84 |
|
|
// (32 or 64).
|
85 |
|
|
virtual Btype*
|
86 |
|
|
float_type(int bits) = 0;
|
87 |
|
|
|
88 |
|
|
// Get an unnamed complex type with the given number of bits (64 or 128).
|
89 |
|
|
virtual Btype*
|
90 |
|
|
complex_type(int bits) = 0;
|
91 |
|
|
|
92 |
|
|
// Get a pointer type.
|
93 |
|
|
virtual Btype*
|
94 |
|
|
pointer_type(Btype* to_type) = 0;
|
95 |
|
|
|
96 |
|
|
// Get a function type. The receiver, parameter, and results are
|
97 |
|
|
// generated from the types in the Function_type. The Function_type
|
98 |
|
|
// is provided so that the names are available.
|
99 |
|
|
virtual Btype*
|
100 |
|
|
function_type(const Btyped_identifier& receiver,
|
101 |
|
|
const std::vector<Btyped_identifier>& parameters,
|
102 |
|
|
const std::vector<Btyped_identifier>& results,
|
103 |
|
|
Location location) = 0;
|
104 |
|
|
|
105 |
|
|
// Get a struct type.
|
106 |
|
|
virtual Btype*
|
107 |
|
|
struct_type(const std::vector<Btyped_identifier>& fields) = 0;
|
108 |
|
|
|
109 |
|
|
// Get an array type.
|
110 |
|
|
virtual Btype*
|
111 |
|
|
array_type(Btype* element_type, Bexpression* length) = 0;
|
112 |
|
|
|
113 |
|
|
// Create a placeholder pointer type. This is used for a named
|
114 |
|
|
// pointer type, since in Go a pointer type may refer to itself.
|
115 |
|
|
// NAME is the name of the type, and the location is where the named
|
116 |
|
|
// type is defined. This function is also used for unnamed function
|
117 |
|
|
// types with multiple results, in which case the type has no name
|
118 |
|
|
// and NAME will be empty. FOR_FUNCTION is true if this is for a Go
|
119 |
|
|
// function type, which corresponds to a C/C++ pointer to function
|
120 |
|
|
// type. The return value will later be passed as the first
|
121 |
|
|
// parameter to set_placeholder_pointer_type or
|
122 |
|
|
// set_placeholder_function_type.
|
123 |
|
|
virtual Btype*
|
124 |
|
|
placeholder_pointer_type(const std::string& name, Location,
|
125 |
|
|
bool for_function) = 0;
|
126 |
|
|
|
127 |
|
|
// Fill in a placeholder pointer type as a pointer. This takes a
|
128 |
|
|
// type returned by placeholder_pointer_type and arranges for it to
|
129 |
|
|
// point to the type that TO_TYPE points to (that is, PLACEHOLDER
|
130 |
|
|
// becomes the same type as TO_TYPE). Returns true on success,
|
131 |
|
|
// false on failure.
|
132 |
|
|
virtual bool
|
133 |
|
|
set_placeholder_pointer_type(Btype* placeholder, Btype* to_type) = 0;
|
134 |
|
|
|
135 |
|
|
// Fill in a placeholder pointer type as a function. This takes a
|
136 |
|
|
// type returned by placeholder_pointer_type and arranges for it to
|
137 |
|
|
// become a real Go function type (which corresponds to a C/C++
|
138 |
|
|
// pointer to function type). FT will be something returned by the
|
139 |
|
|
// function_type method. Returns true on success, false on failure.
|
140 |
|
|
virtual bool
|
141 |
|
|
set_placeholder_function_type(Btype* placeholder, Btype* ft) = 0;
|
142 |
|
|
|
143 |
|
|
// Create a placeholder struct type. This is used for a named
|
144 |
|
|
// struct type, as with placeholder_pointer_type. It is also used
|
145 |
|
|
// for interface types, in which case NAME will be the empty string.
|
146 |
|
|
virtual Btype*
|
147 |
|
|
placeholder_struct_type(const std::string& name, Location) = 0;
|
148 |
|
|
|
149 |
|
|
// Fill in a placeholder struct type. This takes a type returned by
|
150 |
|
|
// placeholder_struct_type and arranges for it to become a real
|
151 |
|
|
// struct type. The parameter is as for struct_type. Returns true
|
152 |
|
|
// on success, false on failure.
|
153 |
|
|
virtual bool
|
154 |
|
|
set_placeholder_struct_type(Btype* placeholder,
|
155 |
|
|
const std::vector<Btyped_identifier>& fields)
|
156 |
|
|
= 0;
|
157 |
|
|
|
158 |
|
|
// Create a placeholder array type. This is used for a named array
|
159 |
|
|
// type, as with placeholder_pointer_type, to handle cases like
|
160 |
|
|
// type A []*A.
|
161 |
|
|
virtual Btype*
|
162 |
|
|
placeholder_array_type(const std::string& name, Location) = 0;
|
163 |
|
|
|
164 |
|
|
// Fill in a placeholder array type. This takes a type returned by
|
165 |
|
|
// placeholder_array_type and arranges for it to become a real array
|
166 |
|
|
// type. The parameters are as for array_type. Returns true on
|
167 |
|
|
// success, false on failure.
|
168 |
|
|
virtual bool
|
169 |
|
|
set_placeholder_array_type(Btype* placeholder, Btype* element_type,
|
170 |
|
|
Bexpression* length) = 0;
|
171 |
|
|
|
172 |
|
|
// Return a named version of a type. The location is the location
|
173 |
|
|
// of the type definition. This will not be called for a type
|
174 |
|
|
// created via placeholder_pointer_type, placeholder_struct_type, or
|
175 |
|
|
// placeholder_array_type.. (It may be called for a pointer,
|
176 |
|
|
// struct, or array type in a case like "type P *byte; type Q P".)
|
177 |
|
|
virtual Btype*
|
178 |
|
|
named_type(const std::string& name, Btype*, Location) = 0;
|
179 |
|
|
|
180 |
|
|
// Create a marker for a circular pointer type. Go pointer and
|
181 |
|
|
// function types can refer to themselves in ways that are not
|
182 |
|
|
// permitted in C/C++. When a circular type is found, this function
|
183 |
|
|
// is called for the circular reference. This permits the backend
|
184 |
|
|
// to decide how to handle such a type. PLACEHOLDER is the
|
185 |
|
|
// placeholder type which has already been created; if the backend
|
186 |
|
|
// is prepared to handle a circular pointer type, it may simply
|
187 |
|
|
// return PLACEHOLDER. FOR_FUNCTION is true if this is for a
|
188 |
|
|
// function type.
|
189 |
|
|
//
|
190 |
|
|
// For "type P *P" the sequence of calls will be
|
191 |
|
|
// bt1 = placeholder_pointer_type();
|
192 |
|
|
// bt2 = circular_pointer_type(bt1, false);
|
193 |
|
|
// set_placeholder_pointer_type(bt1, bt2);
|
194 |
|
|
virtual Btype*
|
195 |
|
|
circular_pointer_type(Btype* placeholder, bool for_function) = 0;
|
196 |
|
|
|
197 |
|
|
// Return whether the argument could be a special type created by
|
198 |
|
|
// circular_pointer_type. This is used to introduce explicit type
|
199 |
|
|
// conversions where needed. If circular_pointer_type returns its
|
200 |
|
|
// PLACEHOLDER parameter, this may safely always return false.
|
201 |
|
|
virtual bool
|
202 |
|
|
is_circular_pointer_type(Btype*) = 0;
|
203 |
|
|
|
204 |
|
|
// Return the size of a type.
|
205 |
|
|
virtual size_t
|
206 |
|
|
type_size(Btype*) = 0;
|
207 |
|
|
|
208 |
|
|
// Return the alignment of a type.
|
209 |
|
|
virtual size_t
|
210 |
|
|
type_alignment(Btype*) = 0;
|
211 |
|
|
|
212 |
|
|
// Return the alignment of a struct field of this type. This is
|
213 |
|
|
// normally the same as type_alignment, but not always.
|
214 |
|
|
virtual size_t
|
215 |
|
|
type_field_alignment(Btype*) = 0;
|
216 |
|
|
|
217 |
|
|
// Return the offset of field INDEX in a struct type. INDEX is the
|
218 |
|
|
// entry in the FIELDS std::vector parameter of struct_type or
|
219 |
|
|
// set_placeholder_struct_type.
|
220 |
|
|
virtual size_t
|
221 |
|
|
type_field_offset(Btype*, size_t index) = 0;
|
222 |
|
|
|
223 |
|
|
// Expressions.
|
224 |
|
|
|
225 |
|
|
// Return an expression for a zero value of the given type. This is
|
226 |
|
|
// used for cases such as local variable initialization and
|
227 |
|
|
// converting nil to other types.
|
228 |
|
|
virtual Bexpression*
|
229 |
|
|
zero_expression(Btype*) = 0;
|
230 |
|
|
|
231 |
|
|
// Statements.
|
232 |
|
|
|
233 |
|
|
// Create an error statement. This is used for cases which should
|
234 |
|
|
// not occur in a correct program, in order to keep the compilation
|
235 |
|
|
// going without crashing.
|
236 |
|
|
virtual Bstatement*
|
237 |
|
|
error_statement() = 0;
|
238 |
|
|
|
239 |
|
|
// Create an expression statement.
|
240 |
|
|
virtual Bstatement*
|
241 |
|
|
expression_statement(Bexpression*) = 0;
|
242 |
|
|
|
243 |
|
|
// Create a variable initialization statement. This initializes a
|
244 |
|
|
// local variable at the point in the program flow where it is
|
245 |
|
|
// declared.
|
246 |
|
|
virtual Bstatement*
|
247 |
|
|
init_statement(Bvariable* var, Bexpression* init) = 0;
|
248 |
|
|
|
249 |
|
|
// Create an assignment statement.
|
250 |
|
|
virtual Bstatement*
|
251 |
|
|
assignment_statement(Bexpression* lhs, Bexpression* rhs,
|
252 |
|
|
Location) = 0;
|
253 |
|
|
|
254 |
|
|
// Create a return statement, passing the representation of the
|
255 |
|
|
// function and the list of values to return.
|
256 |
|
|
virtual Bstatement*
|
257 |
|
|
return_statement(Bfunction*, const std::vector<Bexpression*>&,
|
258 |
|
|
Location) = 0;
|
259 |
|
|
|
260 |
|
|
// Create an if statement. ELSE_BLOCK may be NULL.
|
261 |
|
|
virtual Bstatement*
|
262 |
|
|
if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
|
263 |
|
|
Location) = 0;
|
264 |
|
|
|
265 |
|
|
// Create a switch statement where the case values are constants.
|
266 |
|
|
// CASES and STATEMENTS must have the same number of entries. If
|
267 |
|
|
// VALUE matches any of the list in CASES[i], which will all be
|
268 |
|
|
// integers, then STATEMENTS[i] is executed. STATEMENTS[i] will
|
269 |
|
|
// either end with a goto statement or will fall through into
|
270 |
|
|
// STATEMENTS[i + 1]. CASES[i] is empty for the default clause,
|
271 |
|
|
// which need not be last.
|
272 |
|
|
virtual Bstatement*
|
273 |
|
|
switch_statement(Bexpression* value,
|
274 |
|
|
const std::vector<std::vector<Bexpression*> >& cases,
|
275 |
|
|
const std::vector<Bstatement*>& statements,
|
276 |
|
|
Location) = 0;
|
277 |
|
|
|
278 |
|
|
// Create a single statement from two statements.
|
279 |
|
|
virtual Bstatement*
|
280 |
|
|
compound_statement(Bstatement*, Bstatement*) = 0;
|
281 |
|
|
|
282 |
|
|
// Create a single statement from a list of statements.
|
283 |
|
|
virtual Bstatement*
|
284 |
|
|
statement_list(const std::vector<Bstatement*>&) = 0;
|
285 |
|
|
|
286 |
|
|
// Blocks.
|
287 |
|
|
|
288 |
|
|
// Create a block. The frontend will call this function when it
|
289 |
|
|
// starts converting a block within a function. FUNCTION is the
|
290 |
|
|
// current function. ENCLOSING is the enclosing block; it will be
|
291 |
|
|
// NULL for the top-level block in a function. VARS is the list of
|
292 |
|
|
// local variables defined within this block; each entry will be
|
293 |
|
|
// created by the local_variable function. START_LOCATION is the
|
294 |
|
|
// location of the start of the block, more or less the location of
|
295 |
|
|
// the initial curly brace. END_LOCATION is the location of the end
|
296 |
|
|
// of the block, more or less the location of the final curly brace.
|
297 |
|
|
// The statements will be added after the block is created.
|
298 |
|
|
virtual Bblock*
|
299 |
|
|
block(Bfunction* function, Bblock* enclosing,
|
300 |
|
|
const std::vector<Bvariable*>& vars,
|
301 |
|
|
Location start_location, Location end_location) = 0;
|
302 |
|
|
|
303 |
|
|
// Add the statements to a block. The block is created first. Then
|
304 |
|
|
// the statements are created. Then the statements are added to the
|
305 |
|
|
// block. This will called exactly once per block. The vector may
|
306 |
|
|
// be empty if there are no statements.
|
307 |
|
|
virtual void
|
308 |
|
|
block_add_statements(Bblock*, const std::vector<Bstatement*>&) = 0;
|
309 |
|
|
|
310 |
|
|
// Return the block as a statement. This is used to include a block
|
311 |
|
|
// in a list of statements.
|
312 |
|
|
virtual Bstatement*
|
313 |
|
|
block_statement(Bblock*) = 0;
|
314 |
|
|
|
315 |
|
|
// Variables.
|
316 |
|
|
|
317 |
|
|
// Create an error variable. This is used for cases which should
|
318 |
|
|
// not occur in a correct program, in order to keep the compilation
|
319 |
|
|
// going without crashing.
|
320 |
|
|
virtual Bvariable*
|
321 |
|
|
error_variable() = 0;
|
322 |
|
|
|
323 |
|
|
// Create a global variable. PACKAGE_NAME is the name of the
|
324 |
|
|
// package where the variable is defined. UNIQUE_PREFIX is the
|
325 |
|
|
// prefix for that package, from the -fgo-prefix option. NAME is
|
326 |
|
|
// the name of the variable. BTYPE is the type of the variable.
|
327 |
|
|
// IS_EXTERNAL is true if the variable is defined in some other
|
328 |
|
|
// package. IS_HIDDEN is true if the variable is not exported (name
|
329 |
|
|
// begins with a lower case letter). LOCATION is where the variable
|
330 |
|
|
// was defined.
|
331 |
|
|
virtual Bvariable*
|
332 |
|
|
global_variable(const std::string& package_name,
|
333 |
|
|
const std::string& unique_prefix,
|
334 |
|
|
const std::string& name,
|
335 |
|
|
Btype* btype,
|
336 |
|
|
bool is_external,
|
337 |
|
|
bool is_hidden,
|
338 |
|
|
Location location) = 0;
|
339 |
|
|
|
340 |
|
|
// A global variable will 1) be initialized to zero, or 2) be
|
341 |
|
|
// initialized to a constant value, or 3) be initialized in the init
|
342 |
|
|
// function. In case 2, the frontend will call
|
343 |
|
|
// global_variable_set_init to set the initial value. If this is
|
344 |
|
|
// not called, the backend should initialize a global variable to 0.
|
345 |
|
|
// The init function may then assign a value to it.
|
346 |
|
|
virtual void
|
347 |
|
|
global_variable_set_init(Bvariable*, Bexpression*) = 0;
|
348 |
|
|
|
349 |
|
|
// Create a local variable. The frontend will create the local
|
350 |
|
|
// variables first, and then create the block which contains them.
|
351 |
|
|
// FUNCTION is the function in which the variable is defined. NAME
|
352 |
|
|
// is the name of the variable. TYPE is the type. IS_ADDRESS_TAKEN
|
353 |
|
|
// is true if the address of this variable is taken (this implies
|
354 |
|
|
// that the address does not escape the function, as otherwise the
|
355 |
|
|
// variable would be on the heap). LOCATION is where the variable
|
356 |
|
|
// is defined. For each local variable the frontend will call
|
357 |
|
|
// init_statement to set the initial value.
|
358 |
|
|
virtual Bvariable*
|
359 |
|
|
local_variable(Bfunction* function, const std::string& name, Btype* type,
|
360 |
|
|
bool is_address_taken, Location location) = 0;
|
361 |
|
|
|
362 |
|
|
// Create a function parameter. This is an incoming parameter, not
|
363 |
|
|
// a result parameter (result parameters are treated as local
|
364 |
|
|
// variables). The arguments are as for local_variable.
|
365 |
|
|
virtual Bvariable*
|
366 |
|
|
parameter_variable(Bfunction* function, const std::string& name,
|
367 |
|
|
Btype* type, bool is_address_taken,
|
368 |
|
|
Location location) = 0;
|
369 |
|
|
|
370 |
|
|
// Create a temporary variable. A temporary variable has no name,
|
371 |
|
|
// just a type. We pass in FUNCTION and BLOCK in case they are
|
372 |
|
|
// needed. If INIT is not NULL, the variable should be initialized
|
373 |
|
|
// to that value. Otherwise the initial value is irrelevant--the
|
374 |
|
|
// backend does not have to explicitly initialize it to zero.
|
375 |
|
|
// ADDRESS_IS_TAKEN is true if the programs needs to take the
|
376 |
|
|
// address of this temporary variable. LOCATION is the location of
|
377 |
|
|
// the statement or expression which requires creating the temporary
|
378 |
|
|
// variable, and may not be very useful. This function should
|
379 |
|
|
// return a variable which can be referenced later and should set
|
380 |
|
|
// *PSTATEMENT to a statement which initializes the variable.
|
381 |
|
|
virtual Bvariable*
|
382 |
|
|
temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression* init,
|
383 |
|
|
bool address_is_taken, Location location,
|
384 |
|
|
Bstatement** pstatement) = 0;
|
385 |
|
|
|
386 |
|
|
// Create a named immutable initialized data structure. This is
|
387 |
|
|
// used for type descriptors and map descriptors. This returns a
|
388 |
|
|
// Bvariable because it corresponds to an initialized const global
|
389 |
|
|
// variable in C.
|
390 |
|
|
//
|
391 |
|
|
// NAME is the name to use for the initialized global variable which
|
392 |
|
|
// this call will create.
|
393 |
|
|
//
|
394 |
|
|
// IS_COMMON is true if NAME may be defined by several packages, and
|
395 |
|
|
// the linker should merge all such definitions. If IS_COMMON is
|
396 |
|
|
// false, NAME should be defined in only one file. In general
|
397 |
|
|
// IS_COMMON will be true for the type descriptor of an unnamed type
|
398 |
|
|
// or a builtin type.
|
399 |
|
|
//
|
400 |
|
|
// TYPE will be a struct type; the type of the returned expression
|
401 |
|
|
// must be a pointer to this struct type.
|
402 |
|
|
//
|
403 |
|
|
// We must create the named structure before we know its
|
404 |
|
|
// initializer, because the initializer may refer to its own
|
405 |
|
|
// address. After calling this the frontend will call
|
406 |
|
|
// immutable_struct_set_init.
|
407 |
|
|
virtual Bvariable*
|
408 |
|
|
immutable_struct(const std::string& name, bool is_common, Btype* type,
|
409 |
|
|
Location) = 0;
|
410 |
|
|
|
411 |
|
|
// Set the initial value of a variable created by immutable_struct.
|
412 |
|
|
// The NAME, IS_COMMON, TYPE, and location parameters are the same
|
413 |
|
|
// ones passed to immutable_struct. INITIALIZER will be a composite
|
414 |
|
|
// literal of type TYPE. It will not contain any function calls or
|
415 |
|
|
// anything else which can not be put into a read-only data section.
|
416 |
|
|
// It may contain the address of variables created by
|
417 |
|
|
// immutable_struct.
|
418 |
|
|
virtual void
|
419 |
|
|
immutable_struct_set_init(Bvariable*, const std::string& name,
|
420 |
|
|
bool is_common, Btype* type, Location,
|
421 |
|
|
Bexpression* initializer) = 0;
|
422 |
|
|
|
423 |
|
|
// Create a reference to a named immutable initialized data
|
424 |
|
|
// structure defined in some other package. This will be a
|
425 |
|
|
// structure created by a call to immutable_struct with the same
|
426 |
|
|
// NAME and TYPE and with IS_COMMON passed as false. This
|
427 |
|
|
// corresponds to an extern const global variable in C.
|
428 |
|
|
virtual Bvariable*
|
429 |
|
|
immutable_struct_reference(const std::string& name, Btype* type,
|
430 |
|
|
Location) = 0;
|
431 |
|
|
|
432 |
|
|
// Labels.
|
433 |
|
|
|
434 |
|
|
// Create a new label. NAME will be empty if this is a label
|
435 |
|
|
// created by the frontend for a loop construct. The location is
|
436 |
|
|
// where the the label is defined.
|
437 |
|
|
virtual Blabel*
|
438 |
|
|
label(Bfunction*, const std::string& name, Location) = 0;
|
439 |
|
|
|
440 |
|
|
// Create a statement which defines a label. This statement will be
|
441 |
|
|
// put into the codestream at the point where the label should be
|
442 |
|
|
// defined.
|
443 |
|
|
virtual Bstatement*
|
444 |
|
|
label_definition_statement(Blabel*) = 0;
|
445 |
|
|
|
446 |
|
|
// Create a goto statement to a label.
|
447 |
|
|
virtual Bstatement*
|
448 |
|
|
goto_statement(Blabel*, Location) = 0;
|
449 |
|
|
|
450 |
|
|
// Create an expression for the address of a label. This is used to
|
451 |
|
|
// get the return address of a deferred function which may call
|
452 |
|
|
// recover.
|
453 |
|
|
virtual Bexpression*
|
454 |
|
|
label_address(Blabel*, Location) = 0;
|
455 |
|
|
};
|
456 |
|
|
|
457 |
|
|
// The backend interface has to define this function.
|
458 |
|
|
|
459 |
|
|
extern Backend* go_get_backend();
|
460 |
|
|
|
461 |
|
|
// FIXME: Temporary helper functions while converting to new backend
|
462 |
|
|
// interface.
|
463 |
|
|
|
464 |
|
|
extern Btype* tree_to_type(tree);
|
465 |
|
|
extern Bexpression* tree_to_expr(tree);
|
466 |
|
|
extern Bstatement* tree_to_stat(tree);
|
467 |
|
|
extern Bfunction* tree_to_function(tree);
|
468 |
|
|
extern Bblock* tree_to_block(tree);
|
469 |
|
|
extern tree type_to_tree(Btype*);
|
470 |
|
|
extern tree expr_to_tree(Bexpression*);
|
471 |
|
|
extern tree stat_to_tree(Bstatement*);
|
472 |
|
|
extern tree block_to_tree(Bblock*);
|
473 |
|
|
extern tree var_to_tree(Bvariable*);
|
474 |
|
|
|
475 |
|
|
#endif // !defined(GO_BACKEND_H)
|