6470057a905e7e522907861d03b89878c8c3f2ac
[mesa.git] / ast_function.cpp
1 /*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <cstdio>
25 #include "glsl_symbol_table.h"
26 #include "ast.h"
27 #include "glsl_types.h"
28 #include "ir.h"
29
30 static ir_rvalue *
31 match_function_by_name(exec_list *instructions, const char *name,
32 YYLTYPE *loc, simple_node *parameters,
33 struct _mesa_glsl_parse_state *state)
34 {
35 ir_function *f = state->symbols->get_function(name);
36
37 if (f == NULL) {
38 _mesa_glsl_error(loc, state, "function `%s' undeclared", name);
39 return ir_call::get_error_instruction();
40 }
41
42 /* Once we've determined that the function being called might exist,
43 * process the parameters.
44 */
45 exec_list actual_parameters;
46 simple_node *const first = parameters;
47 if (first != NULL) {
48 simple_node *ptr = first;
49 do {
50 ir_instruction *const result =
51 ((ast_node *) ptr)->hir(instructions, state);
52 ptr = ptr->next;
53
54 actual_parameters.push_tail(result);
55 } while (ptr != first);
56 }
57
58 /* After processing the function's actual parameters, try to find an
59 * overload of the function that matches.
60 */
61 const ir_function_signature *sig =
62 f->matching_signature(& actual_parameters);
63 if (sig != NULL) {
64 /* FINISHME: The list of actual parameters needs to be modified to
65 * FINISHME: include any necessary conversions.
66 */
67 return new ir_call(sig, & actual_parameters);
68 } else {
69 /* FINISHME: Log a better error message here. G++ will show the types
70 * FINISHME: of the actual parameters and the set of candidate
71 * FINISHME: functions. A different error should also be logged when
72 * FINISHME: multiple functions match.
73 */
74 _mesa_glsl_error(loc, state, "no matching function for call to `%s'",
75 name);
76 return ir_call::get_error_instruction();
77 }
78 }
79
80
81 /**
82 * Perform automatic type conversion of constructor parameters
83 */
84 static ir_rvalue *
85 convert_component(ir_rvalue *src, const glsl_type *desired_type)
86 {
87 const unsigned a = desired_type->base_type;
88 const unsigned b = src->type->base_type;
89
90 if (src->type->is_error())
91 return src;
92
93 assert(a <= GLSL_TYPE_BOOL);
94 assert(b <= GLSL_TYPE_BOOL);
95
96 if ((a == b) || (src->type->is_integer() && desired_type->is_integer()))
97 return src;
98
99 switch (a) {
100 case GLSL_TYPE_UINT:
101 case GLSL_TYPE_INT:
102 if (b == GLSL_TYPE_FLOAT)
103 return new ir_expression(ir_unop_f2i, desired_type, src, NULL);
104 else {
105 assert(b == GLSL_TYPE_BOOL);
106 assert(!"FINISHME: Convert bool to int / uint.");
107 }
108 case GLSL_TYPE_FLOAT:
109 switch (b) {
110 case GLSL_TYPE_UINT:
111 return new ir_expression(ir_unop_u2f, desired_type, src, NULL);
112 case GLSL_TYPE_INT:
113 return new ir_expression(ir_unop_i2f, desired_type, src, NULL);
114 case GLSL_TYPE_BOOL:
115 assert(!"FINISHME: Convert bool to float.");
116 }
117 break;
118 case GLSL_TYPE_BOOL: {
119 int z = 0;
120 ir_constant *const zero = new ir_constant(src->type, &z);
121
122 return new ir_expression(ir_binop_nequal, desired_type, src, zero);
123 }
124 }
125
126 assert(!"Should not get here.");
127 return NULL;
128 }
129
130
131 /**
132 * Dereference a specific component from a scalar, vector, or matrix
133 */
134 static ir_rvalue *
135 dereference_component(ir_rvalue *src, unsigned component)
136 {
137 assert(component < src->type->components());
138
139 if (src->type->is_scalar()) {
140 return src;
141 } else if (src->type->is_vector()) {
142 return new ir_swizzle(src, component, 0, 0, 0, 1);
143 } else {
144 assert(src->type->is_matrix());
145
146 /* Dereference a row of the matrix, then call this function again to get
147 * a specific element from that row.
148 */
149 const int c = component / src->type->column_type()->vector_elements;
150 const int r = component % src->type->column_type()->vector_elements;
151 ir_constant *const col_index = new ir_constant(glsl_type::int_type, &c);
152 ir_dereference *const col = new ir_dereference(src, col_index);
153
154 col->type = src->type->column_type();
155
156 return dereference_component(col, r);
157 }
158
159 assert(!"Should not get here.");
160 return NULL;
161 }
162
163
164 ir_rvalue *
165 ast_function_expression::hir(exec_list *instructions,
166 struct _mesa_glsl_parse_state *state)
167 {
168 /* There are three sorts of function calls.
169 *
170 * 1. contstructors - The first subexpression is an ast_type_specifier.
171 * 2. methods - Only the .length() method of array types.
172 * 3. functions - Calls to regular old functions.
173 *
174 * Method calls are actually detected when the ast_field_selection
175 * expression is handled.
176 */
177 if (is_constructor()) {
178 const ast_type_specifier *type = (ast_type_specifier *) subexpressions[0];
179 YYLTYPE loc = type->get_location();
180
181 const glsl_type *const constructor_type =
182 state->symbols->get_type(type->type_name);
183
184
185 /* Constructors for samplers are illegal.
186 */
187 if (constructor_type->is_sampler()) {
188 _mesa_glsl_error(& loc, state, "cannot construct sampler type `%s'",
189 constructor_type->name);
190 return ir_call::get_error_instruction();
191 }
192
193
194 /* There are two kinds of constructor call. Constructors for built-in
195 * language types, such as mat4 and vec2, are free form. The only
196 * requirement is that the parameters must provide enough values of the
197 * correct scalar type. Constructors for arrays and structures must
198 * have the exact number of parameters with matching types in the
199 * correct order. These constructors follow essentially the same type
200 * matching rules as functions.
201 */
202 if (constructor_type->is_numeric() || constructor_type->is_boolean()) {
203 /* Constructing a numeric type has a couple steps. First all values
204 * passed to the constructor are broken into individual parameters
205 * and type converted to the base type of the thing being constructed.
206 *
207 * At that point we have some number of values that match the base
208 * type of the thing being constructed. Now the constructor can be
209 * treated like a function call. Each numeric type has a small set
210 * of constructor functions. The set of new parameters will either
211 * match one of those functions or the original constructor is
212 * invalid.
213 */
214 const glsl_type *const base_type = constructor_type->get_base_type();
215
216 /* Total number of components of the type being constructed.
217 */
218 const unsigned type_components = constructor_type->components();
219
220 /* Number of components from parameters that have actually been
221 * consumed. This is used to perform several kinds of error checking.
222 */
223 unsigned components_used = 0;
224
225 unsigned matrix_parameters = 0;
226 unsigned nonmatrix_parameters = 0;
227 exec_list actual_parameters;
228 simple_node *const first = subexpressions[1];
229
230 assert(first != NULL);
231
232 if (first != NULL) {
233 simple_node *ptr = first;
234 do {
235 ir_rvalue *const result =
236 ((ast_node *) ptr)->hir(instructions, state)->as_rvalue();
237 ptr = ptr->next;
238
239 /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
240 *
241 * "It is an error to provide extra arguments beyond this
242 * last used argument."
243 */
244 if (components_used >= type_components) {
245 _mesa_glsl_error(& loc, state, "too many parameters to `%s' "
246 "constructor",
247 constructor_type->name);
248 return ir_call::get_error_instruction();
249 }
250
251 if (!result->type->is_numeric() && !result->type->is_boolean()) {
252 _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
253 "non-numeric data type",
254 constructor_type->name);
255 return ir_call::get_error_instruction();
256 }
257
258 /* Count the number of matrix and nonmatrix parameters. This
259 * is used below to enforce some of the constructor rules.
260 */
261 if (result->type->is_matrix())
262 matrix_parameters++;
263 else
264 nonmatrix_parameters++;
265
266
267 /* Process each of the components of the parameter. Dereference
268 * each component individually, perform any type conversions, and
269 * add it to the parameter list for the constructor.
270 */
271 for (unsigned i = 0; i < result->type->components(); i++) {
272 if (components_used >= type_components)
273 break;
274
275 ir_rvalue *const component =
276 convert_component(dereference_component(result, i),
277 base_type);
278
279 /* All cases that could result in component->type being the
280 * error type should have already been caught above.
281 */
282 assert(component->type == base_type);
283
284 /* Don't actually generate constructor calls for scalars.
285 * Instead, do the usual component selection and conversion,
286 * and return the single component.
287 */
288 if (constructor_type->is_scalar())
289 return component;
290
291 actual_parameters.push_tail(component);
292 components_used++;
293 }
294 } while (ptr != first);
295 }
296
297 /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
298 *
299 * "It is an error to construct matrices from other matrices. This
300 * is reserved for future use."
301 */
302 if ((state->language_version <= 110) && (matrix_parameters > 0)
303 && constructor_type->is_matrix()) {
304 _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
305 "matrix in GLSL 1.10",
306 constructor_type->name);
307 return ir_call::get_error_instruction();
308 }
309
310 /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
311 *
312 * "If a matrix argument is given to a matrix constructor, it is
313 * an error to have any other arguments."
314 */
315 if ((matrix_parameters > 0)
316 && ((matrix_parameters + nonmatrix_parameters) > 1)
317 && constructor_type->is_matrix()) {
318 _mesa_glsl_error(& loc, state, "for matrix `%s' constructor, "
319 "matrix must be only parameter",
320 constructor_type->name);
321 return ir_call::get_error_instruction();
322 }
323
324 /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
325 *
326 * "In these cases, there must be enough components provided in the
327 * arguments to provide an initializer for every component in the
328 * constructed value."
329 */
330 if (components_used < type_components) {
331 _mesa_glsl_error(& loc, state, "too few components to construct "
332 "`%s'",
333 constructor_type->name);
334 return ir_call::get_error_instruction();
335 }
336
337 ir_function *f = state->symbols->get_function(constructor_type->name);
338 if (f == NULL) {
339 _mesa_glsl_error(& loc, state, "no constructor for type `%s'",
340 constructor_type->name);
341 return ir_call::get_error_instruction();
342 }
343
344 const ir_function_signature *sig =
345 f->matching_signature(& actual_parameters);
346 if (sig != NULL) {
347 return new ir_call(sig, & actual_parameters);
348 } else {
349 /* FINISHME: Log a better error message here. G++ will show the
350 * FINSIHME: types of the actual parameters and the set of
351 * FINSIHME: candidate functions. A different error should also be
352 * FINSIHME: logged when multiple functions match.
353 */
354 _mesa_glsl_error(& loc, state, "no matching constructor for `%s'",
355 constructor_type->name);
356 return ir_call::get_error_instruction();
357 }
358 }
359
360 return ir_call::get_error_instruction();
361 } else {
362 const ast_expression *id = subexpressions[0];
363 YYLTYPE loc = id->get_location();
364
365 return match_function_by_name(instructions,
366 id->primary_expression.identifier, & loc,
367 subexpressions[1], state);
368 }
369
370 return ir_call::get_error_instruction();
371 }