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.
14 // Pointers to these types are created by the backend, passed to the
15 // frontend, and passed back to the backend. The types must be
16 // defined by the backend using these names.
18 // The backend representation of a type.
21 // The backend represention of an expression.
24 // The backend representation of a statement.
27 // The backend representation of a function definition.
30 // The backend representation of a block.
33 // The backend representation of a variable.
36 // The backend representation of a label.
39 // A list of backend types.
40 typedef std::vector<Btype*> Btypes;
42 // The backend interface. This is a pure abstract class that a
43 // specific backend will implement.
48 virtual ~Backend() { }
52 // Produce an error type. Actually the backend could probably just
53 // crash if this is called.
57 // Get a void type. This is used in (at least) two ways: 1) as the
58 // return type of a function with no result parameters; 2)
59 // unsafe.Pointer is represented as *void.
63 // Get the unnamed boolean type.
67 // Get an unnamed integer type with the given signedness and number
70 integer_type(bool is_unsigned, int bits) = 0;
72 // Get an unnamed floating point type with the given number of bits.
74 float_type(int bits) = 0;
76 // Get the unnamed string type.
80 // Get a function type. The receiver, parameter, and results are
81 // generated from the types in the Function_type. The Function_type
82 // is provided so that the names are available.
84 function_type(const Function_type*, Btype* receiver,
85 const Btypes* parameters,
86 const Btypes* results) = 0;
88 // Get a struct type. The Struct_type is provided to get the field
91 struct_type(const Struct_type*, const Btypes* field_types) = 0;
95 array_type(const Btype* element_type, const Bexpression* length) = 0;
99 slice_type(const Btype* element_type) = 0;
103 map_type(const Btype* key_type, const Btype* value_type, source_location) = 0;
105 // Get a channel type.
107 channel_type(const Btype* element_type) = 0;
109 // Get an interface type. The Interface_type is provided to get the
112 interface_type(const Interface_type*, const Btypes* method_types) = 0;
116 // Create an error statement. This is used for cases which should
117 // not occur in a correct program, in order to keep the compilation
118 // going without crashing.
120 error_statement() = 0;
122 // Create an expression statement.
124 expression_statement(Bexpression*) = 0;
126 // Create a variable initialization statement. This initializes a
127 // local variable at the point in the program flow where it is
130 init_statement(Bvariable* var, Bexpression* init) = 0;
132 // Create an assignment statement.
134 assignment_statement(Bexpression* lhs, Bexpression* rhs,
135 source_location) = 0;
137 // Create a return statement, passing the representation of the
138 // function and the list of values to return.
140 return_statement(Bfunction*, const std::vector<Bexpression*>&,
141 source_location) = 0;
143 // Create an if statement. ELSE_BLOCK may be NULL.
145 if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
146 source_location) = 0;
148 // Create a switch statement where the case values are constants.
149 // CASES and STATEMENTS must have the same number of entries. If
150 // VALUE matches any of the list in CASES[i], which will all be
151 // integers, then STATEMENTS[i] is executed. STATEMENTS[i] will
152 // either end with a goto statement or will fall through into
153 // STATEMENTS[i + 1]. CASES[i] is empty for the default clause,
154 // which need not be last.
156 switch_statement(Bexpression* value,
157 const std::vector<std::vector<Bexpression*> >& cases,
158 const std::vector<Bstatement*>& statements,
159 source_location) = 0;
161 // Create a single statement from two statements.
163 compound_statement(Bstatement*, Bstatement*) = 0;
165 // Create a single statement from a list of statements.
167 statement_list(const std::vector<Bstatement*>&) = 0;
171 // Create a block. The frontend will call this function when it
172 // starts converting a block within a function. FUNCTION is the
173 // current function. ENCLOSING is the enclosing block; it will be
174 // NULL for the top-level block in a function. VARS is the list of
175 // local variables defined within this block; each entry will be
176 // created by the local_variable function. START_LOCATION is the
177 // location of the start of the block, more or less the location of
178 // the initial curly brace. END_LOCATION is the location of the end
179 // of the block, more or less the location of the final curly brace.
180 // The statements will be added after the block is created.
182 block(Bfunction* function, Bblock* enclosing,
183 const std::vector<Bvariable*>& vars,
184 source_location start_location, source_location end_location) = 0;
186 // Add the statements to a block. The block is created first. Then
187 // the statements are created. Then the statements are added to the
188 // block. This will called exactly once per block. The vector may
189 // be empty if there are no statements.
191 block_add_statements(Bblock*, const std::vector<Bstatement*>&) = 0;
193 // Return the block as a statement. This is used to include a block
194 // in a list of statements.
196 block_statement(Bblock*) = 0;
200 // Create an error variable. This is used for cases which should
201 // not occur in a correct program, in order to keep the compilation
202 // going without crashing.
204 error_variable() = 0;
206 // Create a global variable. PACKAGE_NAME is the name of the
207 // package where the variable is defined. UNIQUE_PREFIX is the
208 // prefix for that package, from the -fgo-prefix option. NAME is
209 // the name of the variable. BTYPE is the type of the variable.
210 // IS_EXTERNAL is true if the variable is defined in some other
211 // package. IS_HIDDEN is true if the variable is not exported (name
212 // begins with a lower case letter). LOCATION is where the variable
215 global_variable(const std::string& package_name,
216 const std::string& unique_prefix,
217 const std::string& name,
221 source_location location) = 0;
223 // A global variable will 1) be initialized to zero, or 2) be
224 // initialized to a constant value, or 3) be initialized in the init
225 // function. In case 2, the frontend will call
226 // global_variable_set_init to set the initial value. If this is
227 // not called, the backend should initialize a global variable to 0.
228 // The init function may then assign a value to it.
230 global_variable_set_init(Bvariable*, Bexpression*) = 0;
232 // Create a local variable. The frontend will create the local
233 // variables first, and then create the block which contains them.
234 // FUNCTION is the function in which the variable is defined. NAME
235 // is the name of the variable. TYPE is the type. LOCATION is
236 // where the variable is defined. For each local variable the
237 // frontend will call init_statement to set the initial value.
239 local_variable(Bfunction* function, const std::string& name, Btype* type,
240 source_location location) = 0;
242 // Create a function parameter. This is an incoming parameter, not
243 // a result parameter (result parameters are treated as local
244 // variables). The arguments are as for local_variable.
246 parameter_variable(Bfunction* function, const std::string& name,
247 Btype* type, source_location location) = 0;
251 // Create a new label. NAME will be empty if this is a label
252 // created by the frontend for a loop construct. The location is
253 // where the the label is defined.
255 label(Bfunction*, const std::string& name, source_location) = 0;
257 // Create a statement which defines a label. This statement will be
258 // put into the codestream at the point where the label should be
261 label_definition_statement(Blabel*) = 0;
263 // Create a goto statement to a label.
265 goto_statement(Blabel*, source_location) = 0;
267 // Create an expression for the address of a label. This is used to
268 // get the return address of a deferred function which may call
271 label_address(Blabel*, source_location) = 0;
274 // The backend interface has to define this function.
276 extern Backend* go_get_backend();
278 // FIXME: Temporary helper functions while converting to new backend
281 extern Btype* tree_to_type(tree);
282 extern Bexpression* tree_to_expr(tree);
283 extern Bstatement* tree_to_stat(tree);
284 extern Bfunction* tree_to_function(tree);
285 extern Bblock* tree_to_block(tree);
286 extern tree expr_to_tree(Bexpression*);
287 extern tree stat_to_tree(Bstatement*);
288 extern tree block_to_tree(Bblock*);
289 extern tree var_to_tree(Bvariable*);
291 #endif // !defined(GO_BACKEND_H)