1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
3 // This file is part of GCC.
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
19 #ifndef RUST_BACKEND_H
20 #define RUST_BACKEND_H
26 #include "rust-location.h"
27 #include "rust-linemap.h"
28 #include "rust-diagnostics.h"
29 #include "util/rust-operators.h"
32 // Pointers to these types are created by the backend, passed to the
33 // frontend, and passed back to the backend. The types must be
34 // defined by the backend using these names.
36 // The backend representation of a variable.
39 // The backend interface. This is a pure abstract class that a
40 // specific backend will implement.
45 virtual ~Backend () {}
47 // Name/type/location. Used for function parameters, struct fields,
49 struct typed_identifier
56 : name (), type (NULL_TREE
), location (Linemap::unknown_location ())
59 typed_identifier (const std::string
&a_name
, tree a_type
,
61 : name (a_name
), type (a_type
), location (a_location
)
66 virtual void debug (tree
) = 0;
67 virtual void debug (Bvariable
*) = 0;
69 virtual tree
get_identifier_node (const std::string
&str
) = 0;
74 virtual tree
unit_type () = 0;
76 // Get the unnamed boolean type.
77 virtual tree
bool_type () = 0;
80 virtual tree
char_type () = 0;
83 virtual tree
wchar_type () = 0;
85 // Get the Host pointer size in bits
86 virtual int get_pointer_size () = 0;
88 // Get the raw str type const char*
89 virtual tree
raw_str_type () = 0;
91 // Get an unnamed integer type with the given signedness and number
93 virtual tree
integer_type (bool is_unsigned
, int bits
) = 0;
95 // Get an unnamed floating point type with the given number of bits
97 virtual tree
float_type (int bits
) = 0;
99 // Get an unnamed complex type with the given number of bits (64 or 128).
100 virtual tree
complex_type (int bits
) = 0;
102 // Get a pointer type.
103 virtual tree
pointer_type (tree to_type
) = 0;
105 // Get a reference type.
106 virtual tree
reference_type (tree to_type
) = 0;
108 // make type immutable
109 virtual tree
immutable_type (tree base
) = 0;
111 // Get a function type. The receiver, parameter, and results are
112 // generated from the types in the Function_type. The Function_type
113 // is provided so that the names are available. This should return
114 // not the type of a Go function (which is a pointer to a struct)
115 // but the type of a C function pointer (which will be used as the
116 // type of the first field of the struct). If there is more than
117 // one result, RESULT_STRUCT is a struct type to hold the results,
118 // and RESULTS may be ignored; if there are zero or one results,
119 // RESULT_STRUCT is NULL.
120 virtual tree
function_type (const typed_identifier
&receiver
,
121 const std::vector
<typed_identifier
> ¶meters
,
122 const std::vector
<typed_identifier
> &results
,
123 tree result_struct
, Location location
)
127 function_type_varadic (const typed_identifier
&receiver
,
128 const std::vector
<typed_identifier
> ¶meters
,
129 const std::vector
<typed_identifier
> &results
,
130 tree result_struct
, Location location
)
133 virtual tree
function_ptr_type (tree result
,
134 const std::vector
<tree
> &praameters
,
138 // Get a struct type.
139 virtual tree
struct_type (const std::vector
<typed_identifier
> &fields
) = 0;
142 virtual tree
union_type (const std::vector
<typed_identifier
> &fields
) = 0;
144 // Get an array type.
145 virtual tree
array_type (tree element_type
, tree length
) = 0;
147 // Return a named version of a type. The location is the location
148 // of the type definition. This will not be called for a type
149 // created via placeholder_pointer_type, placeholder_struct_type, or
150 // placeholder_array_type.. (It may be called for a pointer,
151 // struct, or array type in a case like "type P *byte; type Q P".)
152 virtual tree
named_type (const std::string
&name
, tree
, Location
) = 0;
154 // Return the size of a type.
155 virtual int64_t type_size (tree
) = 0;
157 // Return the alignment of a type.
158 virtual int64_t type_alignment (tree
) = 0;
160 // Return the alignment of a struct field of this type. This is
161 // normally the same as type_alignment, but not always.
162 virtual int64_t type_field_alignment (tree
) = 0;
164 // Return the offset of field INDEX in a struct type. INDEX is the
165 // entry in the FIELDS std::vector parameter of struct_type or
166 // set_placeholder_struct_type.
167 virtual int64_t type_field_offset (tree
, size_t index
) = 0;
171 // Return an expression for a zero value of the given type. This is
172 // used for cases such as local variable initialization and
173 // converting nil to other types.
174 virtual tree
zero_expression (tree
) = 0;
176 virtual tree
unit_expression () = 0;
178 // Create a reference to a variable.
179 virtual tree
var_expression (Bvariable
*var
, Location
) = 0;
181 // Return an expression for the multi-precision integer VAL in BTYPE.
182 virtual tree
integer_constant_expression (tree btype
, mpz_t val
) = 0;
184 // Return an expression for the floating point value VAL in BTYPE.
185 virtual tree
float_constant_expression (tree btype
, mpfr_t val
) = 0;
187 // Return an expression for the complex value VAL in BTYPE.
188 virtual tree
complex_constant_expression (tree btype
, mpc_t val
) = 0;
190 // Return an expression for the string value VAL.
191 virtual tree
string_constant_expression (const std::string
&val
) = 0;
193 // Get a char literal
194 virtual tree
char_constant_expression (char c
) = 0;
196 // Get a char literal
197 virtual tree
wchar_constant_expression (wchar_t c
) = 0;
199 // Return an expression for the boolean value VAL.
200 virtual tree
boolean_constant_expression (bool val
) = 0;
202 // Return an expression for the real part of BCOMPLEX.
203 virtual tree
real_part_expression (tree bcomplex
, Location
) = 0;
205 // Return an expression for the imaginary part of BCOMPLEX.
206 virtual tree
imag_part_expression (tree bcomplex
, Location
) = 0;
208 // Return an expression for the complex number (BREAL, BIMAG).
209 virtual tree
complex_expression (tree breal
, tree bimag
, Location
) = 0;
211 // Return an expression that converts EXPR to TYPE.
212 virtual tree
convert_expression (tree type
, tree expr
, Location
) = 0;
214 // Return an expression for the field at INDEX in BSTRUCT.
215 virtual tree
struct_field_expression (tree bstruct
, size_t index
, Location
)
218 // Create an expression that executes BSTAT before BEXPR.
219 virtual tree
compound_expression (tree bstat
, tree bexpr
, Location
) = 0;
221 // Return an expression that executes THEN_EXPR if CONDITION is true, or
222 // ELSE_EXPR otherwise and returns the result as type BTYPE, within the
223 // specified function FUNCTION. ELSE_EXPR may be NULL. BTYPE may be NULL.
224 virtual tree
conditional_expression (tree function
, tree btype
,
225 tree condition
, tree then_expr
,
226 tree else_expr
, Location
)
229 // Return an expression for the negation operation OP EXPR.
230 // Supported values of OP are enumerated in NegationOperator.
231 virtual tree
negation_expression (NegationOperator op
, tree expr
, Location
)
234 // Return an expression for the operation LEFT OP RIGHT.
235 // Supported values of OP are enumerated in ArithmeticOrLogicalOperator.
236 virtual tree
arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op
,
237 tree left
, tree right
,
241 // Return an expression for the operation LEFT OP RIGHT.
242 // Supported values of OP are enumerated in ArithmeticOrLogicalOperator.
243 // This function adds overflow checking and returns a list of statements to
244 // add to the current function context. The `receiver` variable refers to the
245 // variable which will contain the result of that operation.
247 arithmetic_or_logical_expression_checked (ArithmeticOrLogicalOperator op
,
248 tree left
, tree right
, Location loc
,
252 // Return an expression for the operation LEFT OP RIGHT.
253 // Supported values of OP are enumerated in ComparisonOperator.
254 virtual tree
comparison_expression (ComparisonOperator op
, tree left
,
255 tree right
, Location loc
)
258 // Return an expression for the operation LEFT OP RIGHT.
259 // Supported values of OP are enumerated in LazyBooleanOperator.
260 virtual tree
lazy_boolean_expression (LazyBooleanOperator op
, tree left
,
261 tree right
, Location
)
264 // Return an expression that constructs BTYPE with VALS. BTYPE must be the
265 // backend representation a of struct. VALS must be in the same order as the
266 // corresponding fields in BTYPE.
267 virtual tree
constructor_expression (tree btype
, bool is_variant
,
268 const std::vector
<tree
> &vals
, int,
272 // Return an expression that constructs an array of BTYPE with INDEXES and
273 // VALS. INDEXES and VALS must have the same amount of elements. Each index
274 // in INDEXES must be in the same order as the corresponding value in VALS.
276 array_constructor_expression (tree btype
,
277 const std::vector
<unsigned long> &indexes
,
278 const std::vector
<tree
> &vals
, Location
)
281 virtual tree
array_initializer (tree
, tree
, tree
, tree
, tree
, tree
*,
285 // Return an expression for ARRAY[INDEX] as an l-value. ARRAY is a valid
286 // fixed-length array, not a slice.
287 virtual tree
array_index_expression (tree array
, tree index
, Location
) = 0;
289 // Create an expression for a call to FN with ARGS, taking place within
291 virtual tree
call_expression (tree fn
, const std::vector
<tree
> &args
,
292 tree static_chain
, Location
)
297 // Create a variable initialization statement in the specified
298 // function. This initializes a local variable at the point in the
299 // program flow where it is declared.
300 virtual tree
init_statement (tree
, Bvariable
*var
, tree init
) = 0;
302 // Create an assignment statement within the specified function.
303 virtual tree
assignment_statement (tree lhs
, tree rhs
, Location
) = 0;
305 // Create a return statement, passing the representation of the
306 // function and the list of values to return.
307 virtual tree
return_statement (tree
, const std::vector
<tree
> &, Location
) = 0;
309 // Create an if statement within a function. ELSE_BLOCK may be NULL.
310 virtual tree
if_statement (tree
, tree condition
, tree then_block
,
311 tree else_block
, Location
)
314 // infinite loop expressions
315 virtual tree
loop_expression (tree body
, Location
) = 0;
318 virtual tree
exit_expression (tree condition
, Location
) = 0;
320 // Create a single statement from two statements.
321 virtual tree
compound_statement (tree
, tree
) = 0;
323 // Create a single statement from a list of statements.
324 virtual tree
statement_list (const std::vector
<tree
> &) = 0;
326 // Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if
327 // an exception occurs. EXCEPT_STMT may be NULL. FINALLY_STMT may be NULL and
328 // if not NULL, it will always be executed. This is used for handling defers
329 // in Go functions. In C++, the resulting code is of this form:
330 // try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; }
331 virtual tree
exception_handler_statement (tree bstat
, tree except_stmt
,
332 tree finally_stmt
, Location
)
337 // Create a block. The frontend will call this function when it
338 // starts converting a block within a function. FUNCTION is the
339 // current function. ENCLOSING is the enclosing block; it will be
340 // NULL for the top-level block in a function. VARS is the list of
341 // local variables defined within this block; each entry will be
342 // created by the local_variable function. START_LOCATION is the
343 // location of the start of the block, more or less the location of
344 // the initial curly brace. END_LOCATION is the location of the end
345 // of the block, more or less the location of the final curly brace.
346 // The statements will be added after the block is created.
347 virtual tree
block (tree function
, tree enclosing
,
348 const std::vector
<Bvariable
*> &vars
,
349 Location start_location
, Location end_location
)
352 // Add the statements to a block. The block is created first. Then
353 // the statements are created. Then the statements are added to the
354 // block. This will called exactly once per block. The vector may
355 // be empty if there are no statements.
356 virtual void block_add_statements (tree
, const std::vector
<tree
> &) = 0;
360 // Create an error variable. This is used for cases which should
361 // not occur in a correct program, in order to keep the compilation
362 // going without crashing.
363 virtual Bvariable
*error_variable () = 0;
365 // Create a global variable. NAME is the package-qualified name of
366 // the variable. ASM_NAME is the encoded identifier for the
367 // variable, incorporating the package, and made safe for the
368 // assembler. BTYPE is the type of the variable. IS_EXTERNAL is
369 // true if the variable is defined in some other package. IS_HIDDEN
370 // is true if the variable is not exported (name begins with a lower
371 // case letter). IN_UNIQUE_SECTION is true if the variable should
372 // be put into a unique section if possible; this is intended to
373 // permit the linker to garbage collect the variable if it is not
374 // referenced. LOCATION is where the variable was defined.
375 virtual Bvariable
*global_variable (const std::string
&name
,
376 const std::string
&asm_name
, tree btype
,
377 bool is_external
, bool is_hidden
,
378 bool in_unique_section
, Location location
)
381 // A global variable will 1) be initialized to zero, or 2) be
382 // initialized to a constant value, or 3) be initialized in the init
383 // function. In case 2, the frontend will call
384 // global_variable_set_init to set the initial value. If this is
385 // not called, the backend should initialize a global variable to 0.
386 // The init function may then assign a value to it.
387 virtual void global_variable_set_init (Bvariable
*, tree
) = 0;
389 // Create a local variable. The frontend will create the local
390 // variables first, and then create the block which contains them.
391 // FUNCTION is the function in which the variable is defined. NAME
392 // is the name of the variable. TYPE is the type. DECL_VAR, if not
393 // null, gives the location at which the value of this variable may
394 // be found, typically used to create an inner-scope reference to an
395 // outer-scope variable, to extend the lifetime of the variable beyond
396 // the inner scope. IS_ADDRESS_TAKEN is true if the address of this
397 // variable is taken (this implies that the address does not escape
398 // the function, as otherwise the variable would be on the heap).
399 // LOCATION is where the variable is defined. For each local variable
400 // the frontend will call init_statement to set the initial value.
401 virtual Bvariable
*local_variable (tree function
, const std::string
&name
,
402 tree type
, Bvariable
*decl_var
,
406 // Create a function parameter. This is an incoming parameter, not
407 // a result parameter (result parameters are treated as local
408 // variables). The arguments are as for local_variable.
409 virtual Bvariable
*parameter_variable (tree function
, const std::string
&name
,
410 tree type
, Location location
)
413 // Create a static chain parameter. This is the closure parameter.
414 virtual Bvariable
*static_chain_variable (tree function
,
415 const std::string
&name
, tree type
,
419 // Create a temporary variable. A temporary variable has no name,
420 // just a type. We pass in FUNCTION and BLOCK in case they are
421 // needed. If INIT is not NULL, the variable should be initialized
422 // to that value. Otherwise the initial value is irrelevant--the
423 // backend does not have to explicitly initialize it to zero.
424 // ADDRESS_IS_TAKEN is true if the programs needs to take the
425 // address of this temporary variable. LOCATION is the location of
426 // the statement or expression which requires creating the temporary
427 // variable, and may not be very useful. This function should
428 // return a variable which can be referenced later and should set
429 // *PSTATEMENT to a statement which initializes the variable.
430 virtual Bvariable
*temporary_variable (tree fndecl
, tree bind_tree
, tree type
,
431 tree init
, bool address_is_taken
,
432 Location location
, tree
*pstatement
)
437 // Create a new label. NAME will be empty if this is a label
438 // created by the frontend for a loop construct. The location is
439 // where the label is defined.
440 virtual tree
label (tree
, const std::string
&name
, Location
) = 0;
442 // Create a statement which defines a label. This statement will be
443 // put into the codestream at the point where the label should be
445 virtual tree
label_definition_statement (tree
) = 0;
447 // Create a goto statement to a label.
448 virtual tree
goto_statement (tree
, Location
) = 0;
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
453 virtual tree
label_address (tree
, Location
) = 0;
457 // Bit flags to pass to the function method.
459 // Set if this is a function declaration rather than a definition;
460 // the definition will be in another compilation unit.
461 static const unsigned int function_is_declaration
= 1 << 0;
463 // Set if the function should never be inlined because they call
464 // recover and must be visible for correct panic recovery.
465 static const unsigned int function_is_uninlinable
= 1 << 1;
467 // Set if the function does not return. This is set for the
468 // implementation of panic.
469 static const unsigned int function_does_not_return
= 1 << 2;
471 // Set if the function should be put in a unique section if
472 // possible. This is used for field tracking.
473 static const unsigned int function_in_unique_section
= 1 << 3;
475 // Declare or define a function of FNTYPE.
476 // NAME is the Go name of the function. ASM_NAME, if not the empty
477 // string, is the name that should be used in the symbol table; this
478 // will be non-empty if a magic extern comment is used. FLAGS is
479 // bit flags described above.
480 virtual tree
function (tree fntype
, const std::string
&name
,
481 const std::string
&asm_name
, unsigned int flags
,
485 // Create a statement that runs all deferred calls for FUNCTION. This should
486 // be a statement that looks like this in C++:
488 // try { DEFER_RETURN; } catch { CHECK_DEFER; goto finish; }
489 virtual tree
function_defer_statement (tree function
, tree undefer
,
490 tree check_defer
, Location
)
493 // Record PARAM_VARS as the variables to use for the parameters of FUNCTION.
494 // This will only be called for a function definition. Returns true on
495 // success, false on failure.
497 function_set_parameters (tree function
,
498 const std::vector
<Bvariable
*> ¶m_vars
)
503 // Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
504 // FUNCTION_DECLS, and VARIABLE_DECLS declared globally.
506 write_global_definitions (const std::vector
<tree
> &type_decls
,
507 const std::vector
<tree
> &constant_decls
,
508 const std::vector
<tree
> &function_decls
,
509 const std::vector
<Bvariable
*> &variable_decls
)
512 // Write SIZE bytes of export data from BYTES to the proper
513 // section in the output object file.
514 virtual void write_export_data (const char *bytes
, unsigned int size
) = 0;
517 #endif // RUST_BACKEND_H