]>
Commit | Line | Data |
---|---|---|
a945c346 | 1 | // Copyright (C) 2020-2024 Free Software Foundation, Inc. |
15f04af3 PH |
2 | |
3 | // This file is part of GCC. | |
4 | ||
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 | |
8 | // version. | |
9 | ||
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 | |
13 | // for more details. | |
14 | ||
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/>. | |
18 | ||
19 | #ifndef RUST_BACKEND_H | |
20 | #define RUST_BACKEND_H | |
21 | ||
22 | #include <gmp.h> | |
23 | #include <mpfr.h> | |
24 | #include <mpc.h> | |
25 | ||
26 | #include "rust-location.h" | |
27 | #include "rust-linemap.h" | |
28 | #include "rust-diagnostics.h" | |
d6cb04bf | 29 | #include "util/rust-operators.h" |
15f04af3 PH |
30 | #include "tree.h" |
31 | ||
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. | |
35 | ||
36 | // The backend representation of a variable. | |
37 | class Bvariable; | |
38 | ||
39 | // The backend interface. This is a pure abstract class that a | |
40 | // specific backend will implement. | |
41 | ||
42 | class Backend | |
43 | { | |
44 | public: | |
45 | virtual ~Backend () {} | |
46 | ||
47 | // Name/type/location. Used for function parameters, struct fields, | |
48 | // interface methods. | |
49 | struct typed_identifier | |
50 | { | |
51 | std::string name; | |
52 | tree type; | |
53 | Location location; | |
54 | ||
55 | typed_identifier () | |
56 | : name (), type (NULL_TREE), location (Linemap::unknown_location ()) | |
57 | {} | |
58 | ||
59 | typed_identifier (const std::string &a_name, tree a_type, | |
60 | Location a_location) | |
61 | : name (a_name), type (a_type), location (a_location) | |
62 | {} | |
63 | }; | |
64 | ||
65 | // debug | |
66 | virtual void debug (tree) = 0; | |
67 | virtual void debug (Bvariable *) = 0; | |
68 | ||
69 | virtual tree get_identifier_node (const std::string &str) = 0; | |
70 | ||
71 | // Types. | |
72 | ||
73 | // get unit-type | |
74 | virtual tree unit_type () = 0; | |
75 | ||
76 | // Get the unnamed boolean type. | |
77 | virtual tree bool_type () = 0; | |
78 | ||
79 | // Get the char type | |
80 | virtual tree char_type () = 0; | |
81 | ||
82 | // Get the wchar type | |
83 | virtual tree wchar_type () = 0; | |
84 | ||
85 | // Get the Host pointer size in bits | |
86 | virtual int get_pointer_size () = 0; | |
87 | ||
88 | // Get the raw str type const char* | |
89 | virtual tree raw_str_type () = 0; | |
90 | ||
91 | // Get an unnamed integer type with the given signedness and number | |
92 | // of bits. | |
93 | virtual tree integer_type (bool is_unsigned, int bits) = 0; | |
94 | ||
95 | // Get an unnamed floating point type with the given number of bits | |
96 | // (32 or 64). | |
97 | virtual tree float_type (int bits) = 0; | |
98 | ||
99 | // Get an unnamed complex type with the given number of bits (64 or 128). | |
100 | virtual tree complex_type (int bits) = 0; | |
101 | ||
102 | // Get a pointer type. | |
103 | virtual tree pointer_type (tree to_type) = 0; | |
104 | ||
105 | // Get a reference type. | |
106 | virtual tree reference_type (tree to_type) = 0; | |
107 | ||
108 | // make type immutable | |
109 | virtual tree immutable_type (tree base) = 0; | |
110 | ||
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) | |
124 | = 0; | |
125 | ||
126 | virtual tree | |
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) | |
131 | = 0; | |
132 | ||
133 | virtual tree function_ptr_type (tree result, | |
134 | const std::vector<tree> &praameters, | |
135 | Location location) | |
136 | = 0; | |
137 | ||
138 | // Get a struct type. | |
139 | virtual tree struct_type (const std::vector<typed_identifier> &fields) = 0; | |
140 | ||
141 | // Get a union type. | |
142 | virtual tree union_type (const std::vector<typed_identifier> &fields) = 0; | |
143 | ||
144 | // Get an array type. | |
145 | virtual tree array_type (tree element_type, tree length) = 0; | |
146 | ||
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; | |
153 | ||
154 | // Return the size of a type. | |
155 | virtual int64_t type_size (tree) = 0; | |
156 | ||
157 | // Return the alignment of a type. | |
158 | virtual int64_t type_alignment (tree) = 0; | |
159 | ||
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; | |
163 | ||
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; | |
168 | ||
169 | // Expressions. | |
170 | ||
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; | |
175 | ||
176 | virtual tree unit_expression () = 0; | |
177 | ||
178 | // Create a reference to a variable. | |
179 | virtual tree var_expression (Bvariable *var, Location) = 0; | |
180 | ||
181 | // Return an expression for the multi-precision integer VAL in BTYPE. | |
182 | virtual tree integer_constant_expression (tree btype, mpz_t val) = 0; | |
183 | ||
184 | // Return an expression for the floating point value VAL in BTYPE. | |
185 | virtual tree float_constant_expression (tree btype, mpfr_t val) = 0; | |
186 | ||
187 | // Return an expression for the complex value VAL in BTYPE. | |
188 | virtual tree complex_constant_expression (tree btype, mpc_t val) = 0; | |
189 | ||
190 | // Return an expression for the string value VAL. | |
191 | virtual tree string_constant_expression (const std::string &val) = 0; | |
192 | ||
193 | // Get a char literal | |
194 | virtual tree char_constant_expression (char c) = 0; | |
195 | ||
196 | // Get a char literal | |
197 | virtual tree wchar_constant_expression (wchar_t c) = 0; | |
198 | ||
199 | // Return an expression for the boolean value VAL. | |
200 | virtual tree boolean_constant_expression (bool val) = 0; | |
201 | ||
202 | // Return an expression for the real part of BCOMPLEX. | |
203 | virtual tree real_part_expression (tree bcomplex, Location) = 0; | |
204 | ||
205 | // Return an expression for the imaginary part of BCOMPLEX. | |
206 | virtual tree imag_part_expression (tree bcomplex, Location) = 0; | |
207 | ||
208 | // Return an expression for the complex number (BREAL, BIMAG). | |
209 | virtual tree complex_expression (tree breal, tree bimag, Location) = 0; | |
210 | ||
211 | // Return an expression that converts EXPR to TYPE. | |
212 | virtual tree convert_expression (tree type, tree expr, Location) = 0; | |
213 | ||
214 | // Return an expression for the field at INDEX in BSTRUCT. | |
215 | virtual tree struct_field_expression (tree bstruct, size_t index, Location) | |
216 | = 0; | |
217 | ||
218 | // Create an expression that executes BSTAT before BEXPR. | |
219 | virtual tree compound_expression (tree bstat, tree bexpr, Location) = 0; | |
220 | ||
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) | |
227 | = 0; | |
228 | ||
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) | |
232 | = 0; | |
233 | ||
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, | |
9c87dc0a AC |
238 | Location loc) |
239 | = 0; | |
240 | ||
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. | |
246 | virtual tree | |
247 | arithmetic_or_logical_expression_checked (ArithmeticOrLogicalOperator op, | |
248 | tree left, tree right, Location loc, | |
249 | Bvariable *receiver) | |
15f04af3 PH |
250 | = 0; |
251 | ||
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, | |
9c87dc0a | 255 | tree right, Location loc) |
15f04af3 PH |
256 | = 0; |
257 | ||
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) | |
262 | = 0; | |
263 | ||
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, | |
269 | Location) | |
270 | = 0; | |
271 | ||
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. | |
275 | virtual tree | |
276 | array_constructor_expression (tree btype, | |
277 | const std::vector<unsigned long> &indexes, | |
278 | const std::vector<tree> &vals, Location) | |
279 | = 0; | |
280 | ||
281 | virtual tree array_initializer (tree, tree, tree, tree, tree, tree *, | |
282 | Location) | |
283 | = 0; | |
284 | ||
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; | |
288 | ||
289 | // Create an expression for a call to FN with ARGS, taking place within | |
290 | // caller CALLER. | |
291 | virtual tree call_expression (tree fn, const std::vector<tree> &args, | |
292 | tree static_chain, Location) | |
293 | = 0; | |
294 | ||
295 | // Statements. | |
296 | ||
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; | |
301 | ||
302 | // Create an assignment statement within the specified function. | |
303 | virtual tree assignment_statement (tree lhs, tree rhs, Location) = 0; | |
304 | ||
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; | |
308 | ||
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) | |
312 | = 0; | |
313 | ||
314 | // infinite loop expressions | |
315 | virtual tree loop_expression (tree body, Location) = 0; | |
316 | ||
317 | // exit expressions | |
318 | virtual tree exit_expression (tree condition, Location) = 0; | |
319 | ||
320 | // Create a single statement from two statements. | |
321 | virtual tree compound_statement (tree, tree) = 0; | |
322 | ||
323 | // Create a single statement from a list of statements. | |
324 | virtual tree statement_list (const std::vector<tree> &) = 0; | |
325 | ||
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) | |
333 | = 0; | |
334 | ||
335 | // Blocks. | |
336 | ||
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) | |
350 | = 0; | |
351 | ||
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; | |
357 | ||
358 | // Variables. | |
359 | ||
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; | |
364 | ||
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) | |
379 | = 0; | |
380 | ||
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; | |
388 | ||
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, | |
403 | Location location) | |
404 | = 0; | |
405 | ||
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) | |
411 | = 0; | |
412 | ||
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, | |
416 | Location location) | |
417 | = 0; | |
418 | ||
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. | |
9c87dc0a AC |
430 | virtual Bvariable *temporary_variable (tree fndecl, tree bind_tree, tree type, |
431 | tree init, bool address_is_taken, | |
15f04af3 PH |
432 | Location location, tree *pstatement) |
433 | = 0; | |
434 | ||
435 | // Labels. | |
436 | ||
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; | |
441 | ||
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 | |
444 | // defined. | |
445 | virtual tree label_definition_statement (tree) = 0; | |
446 | ||
447 | // Create a goto statement to a label. | |
448 | virtual tree goto_statement (tree, 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 tree label_address (tree, Location) = 0; | |
454 | ||
455 | // Functions. | |
456 | ||
457 | // Bit flags to pass to the function method. | |
458 | ||
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; | |
462 | ||
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; | |
466 | ||
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; | |
470 | ||
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; | |
474 | ||
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, | |
482 | Location) | |
483 | = 0; | |
484 | ||
485 | // Create a statement that runs all deferred calls for FUNCTION. This should | |
486 | // be a statement that looks like this in C++: | |
487 | // finish: | |
488 | // try { DEFER_RETURN; } catch { CHECK_DEFER; goto finish; } | |
489 | virtual tree function_defer_statement (tree function, tree undefer, | |
490 | tree check_defer, Location) | |
491 | = 0; | |
492 | ||
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. | |
496 | virtual bool | |
497 | function_set_parameters (tree function, | |
498 | const std::vector<Bvariable *> ¶m_vars) | |
499 | = 0; | |
500 | ||
501 | // Utility. | |
502 | ||
503 | // Write the definitions for all TYPE_DECLS, CONSTANT_DECLS, | |
504 | // FUNCTION_DECLS, and VARIABLE_DECLS declared globally. | |
505 | virtual void | |
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) | |
510 | = 0; | |
511 | ||
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; | |
515 | }; | |
516 | ||
517 | #endif // RUST_BACKEND_H |