1 // backend.h -- Go frontend interface to backend -*- C++ -*-
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.
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.
14 // The backend representation of a type.
17 // The backend represention of an expression.
20 // The backend representation of a statement.
23 // The backend representation of a function definition.
26 // The backend representation of a block.
29 // The backend representation of a variable.
32 // The backend representation of a label.
35 // The backend interface. This is a pure abstract class that a
36 // specific backend will implement.
41 virtual ~Backend() { }
43 // Name/type/location. Used for function parameters, struct fields,
45 struct Btyped_identifier
49 source_location location;
52 : name(), btype(NULL), location(UNKNOWN_LOCATION)
55 Btyped_identifier(const std::string& a_name, Btype* a_btype,
56 source_location a_location)
57 : name(a_name), btype(a_btype), location(a_location)
63 // Produce an error type. Actually the backend could probably just
64 // crash if this is called.
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.
74 // Get the unnamed boolean type.
78 // Get an unnamed integer type with the given signedness and number
81 integer_type(bool is_unsigned, int bits) = 0;
83 // Get an unnamed floating point type with the given number of bits
86 float_type(int bits) = 0;
88 // Get an unnamed complex type with the given number of bits (64 or 128).
90 complex_type(int bits) = 0;
92 // Get a pointer type.
94 pointer_type(Btype* to_type) = 0;
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.
100 function_type(const Btyped_identifier& receiver,
101 const std::vector<Btyped_identifier>& parameters,
102 const std::vector<Btyped_identifier>& results,
103 source_location location) = 0;
105 // Get a struct type.
107 struct_type(const std::vector<Btyped_identifier>& fields) = 0;
109 // Get an array type.
111 array_type(const Btype* element_type, const Bexpression* length) = 0;
115 // Create an error statement. This is used for cases which should
116 // not occur in a correct program, in order to keep the compilation
117 // going without crashing.
119 error_statement() = 0;
121 // Create an expression statement.
123 expression_statement(Bexpression*) = 0;
125 // Create a variable initialization statement. This initializes a
126 // local variable at the point in the program flow where it is
129 init_statement(Bvariable* var, Bexpression* init) = 0;
131 // Create an assignment statement.
133 assignment_statement(Bexpression* lhs, Bexpression* rhs,
134 source_location) = 0;
136 // Create a return statement, passing the representation of the
137 // function and the list of values to return.
139 return_statement(Bfunction*, const std::vector<Bexpression*>&,
140 source_location) = 0;
142 // Create an if statement. ELSE_BLOCK may be NULL.
144 if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
145 source_location) = 0;
147 // Create a switch statement where the case values are constants.
148 // CASES and STATEMENTS must have the same number of entries. If
149 // VALUE matches any of the list in CASES[i], which will all be
150 // integers, then STATEMENTS[i] is executed. STATEMENTS[i] will
151 // either end with a goto statement or will fall through into
152 // STATEMENTS[i + 1]. CASES[i] is empty for the default clause,
153 // which need not be last.
155 switch_statement(Bexpression* value,
156 const std::vector<std::vector<Bexpression*> >& cases,
157 const std::vector<Bstatement*>& statements,
158 source_location) = 0;
160 // Create a single statement from two statements.
162 compound_statement(Bstatement*, Bstatement*) = 0;
164 // Create a single statement from a list of statements.
166 statement_list(const std::vector<Bstatement*>&) = 0;
170 // Create a block. The frontend will call this function when it
171 // starts converting a block within a function. FUNCTION is the
172 // current function. ENCLOSING is the enclosing block; it will be
173 // NULL for the top-level block in a function. VARS is the list of
174 // local variables defined within this block; each entry will be
175 // created by the local_variable function. START_LOCATION is the
176 // location of the start of the block, more or less the location of
177 // the initial curly brace. END_LOCATION is the location of the end
178 // of the block, more or less the location of the final curly brace.
179 // The statements will be added after the block is created.
181 block(Bfunction* function, Bblock* enclosing,
182 const std::vector<Bvariable*>& vars,
183 source_location start_location, source_location end_location) = 0;
185 // Add the statements to a block. The block is created first. Then
186 // the statements are created. Then the statements are added to the
187 // block. This will called exactly once per block. The vector may
188 // be empty if there are no statements.
190 block_add_statements(Bblock*, const std::vector<Bstatement*>&) = 0;
192 // Return the block as a statement. This is used to include a block
193 // in a list of statements.
195 block_statement(Bblock*) = 0;
199 // Create an error variable. This is used for cases which should
200 // not occur in a correct program, in order to keep the compilation
201 // going without crashing.
203 error_variable() = 0;
205 // Create a global variable. PACKAGE_NAME is the name of the
206 // package where the variable is defined. UNIQUE_PREFIX is the
207 // prefix for that package, from the -fgo-prefix option. NAME is
208 // the name of the variable. BTYPE is the type of the variable.
209 // IS_EXTERNAL is true if the variable is defined in some other
210 // package. IS_HIDDEN is true if the variable is not exported (name
211 // begins with a lower case letter). LOCATION is where the variable
214 global_variable(const std::string& package_name,
215 const std::string& unique_prefix,
216 const std::string& name,
220 source_location location) = 0;
222 // A global variable will 1) be initialized to zero, or 2) be
223 // initialized to a constant value, or 3) be initialized in the init
224 // function. In case 2, the frontend will call
225 // global_variable_set_init to set the initial value. If this is
226 // not called, the backend should initialize a global variable to 0.
227 // The init function may then assign a value to it.
229 global_variable_set_init(Bvariable*, Bexpression*) = 0;
231 // Create a local variable. The frontend will create the local
232 // variables first, and then create the block which contains them.
233 // FUNCTION is the function in which the variable is defined. NAME
234 // is the name of the variable. TYPE is the type. LOCATION is
235 // where the variable is defined. For each local variable the
236 // frontend will call init_statement to set the initial value.
238 local_variable(Bfunction* function, const std::string& name, Btype* type,
239 source_location location) = 0;
241 // Create a function parameter. This is an incoming parameter, not
242 // a result parameter (result parameters are treated as local
243 // variables). The arguments are as for local_variable.
245 parameter_variable(Bfunction* function, const std::string& name,
246 Btype* type, source_location location) = 0;
248 // Create a temporary variable. A temporary variable has no name,
249 // just a type. We pass in FUNCTION and BLOCK in case they are
250 // needed. If INIT is not NULL, the variable should be initialized
251 // to that value. Otherwise the initial value is irrelevant--the
252 // backend does not have to explicitly initialize it to zero.
253 // ADDRESS_IS_TAKEN is true if the programs needs to take the
254 // address of this temporary variable. LOCATION is the location of
255 // the statement or expression which requires creating the temporary
256 // variable, and may not be very useful. This function should
257 // return a variable which can be referenced later and should set
258 // *PSTATEMENT to a statement which initializes the variable.
260 temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression* init,
261 bool address_is_taken, source_location location,
262 Bstatement** pstatement) = 0;
266 // Create a new label. NAME will be empty if this is a label
267 // created by the frontend for a loop construct. The location is
268 // where the the label is defined.
270 label(Bfunction*, const std::string& name, source_location) = 0;
272 // Create a statement which defines a label. This statement will be
273 // put into the codestream at the point where the label should be
276 label_definition_statement(Blabel*) = 0;
278 // Create a goto statement to a label.
280 goto_statement(Blabel*, source_location) = 0;
282 // Create an expression for the address of a label. This is used to
283 // get the return address of a deferred function which may call
286 label_address(Blabel*, source_location) = 0;
289 // The backend interface has to define this function.
291 extern Backend* go_get_backend();
293 // FIXME: Temporary helper functions while converting to new backend
296 extern Btype* tree_to_type(tree);
297 extern Bexpression* tree_to_expr(tree);
298 extern Bstatement* tree_to_stat(tree);
299 extern Bfunction* tree_to_function(tree);
300 extern Bblock* tree_to_block(tree);
301 extern tree type_to_tree(Btype*);
302 extern tree expr_to_tree(Bexpression*);
303 extern tree stat_to_tree(Bstatement*);
304 extern tree block_to_tree(Bblock*);
305 extern tree var_to_tree(Bvariable*);
307 #endif // !defined(GO_BACKEND_H)