blob: bc56e4fcaf54d2674926f061d777ed9369a8ade6 [file] [log] [blame]
Ian Romanicka87ac252010-02-22 13:19:34 -08001/*
2 * Copyright © 2008, 2009 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#include <stdio.h>
24#include <stdarg.h>
Ian Romanicka87ac252010-02-22 13:19:34 -080025#include <string.h>
26#include <assert.h>
Ian Romanicka87ac252010-02-22 13:19:34 -080027
Kenneth Graunkeb2ba6fa2010-06-17 15:15:35 -070028extern "C" {
29#include <talloc.h>
Chia-I Wubfd7c9a2010-08-23 17:51:42 +080030#include "main/core.h" /* for struct __GLcontextRec */
Kenneth Graunkeb2ba6fa2010-06-17 15:15:35 -070031}
32
Ian Romanicka87ac252010-02-22 13:19:34 -080033#include "ast.h"
34#include "glsl_parser_extras.h"
Ian Romanickd59673c2010-02-25 17:17:23 -080035#include "glsl_parser.h"
Eric Anholt2f4fe152010-08-10 13:06:49 -070036#include "ir_optimization.h"
Ian Romanicka87ac252010-02-22 13:19:34 -080037
Ian Romanick2462a532010-07-18 15:59:43 -070038_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct __GLcontextRec *ctx,
39 GLenum target, void *mem_ctx)
40{
41 switch (target) {
42 case GL_VERTEX_SHADER: this->target = vertex_shader; break;
43 case GL_FRAGMENT_SHADER: this->target = fragment_shader; break;
44 case GL_GEOMETRY_SHADER: this->target = geometry_shader; break;
45 }
46
47 this->scanner = NULL;
48 this->translation_unit.make_empty();
49 this->symbols = new(mem_ctx) glsl_symbol_table;
50 this->info_log = talloc_strdup(mem_ctx, "");
51 this->error = false;
52 this->loop_or_switch_nesting = NULL;
53 this->ARB_texture_rectangle_enable = true;
54
55 if (ctx != NULL) {
56 this->extensions = &ctx->Extensions;
57
58 this->Const.MaxLights = ctx->Const.MaxLights;
59 this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes;
60 this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits;
61 this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits;
62 this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs;
63 this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents;
64 this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4;
65 this->Const.MaxVertexTextureImageUnits = ctx->Const.MaxVertexTextureImageUnits;
66 this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits;
67 this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
68 this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
69
70 this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
71 } else {
Kenneth Graunkeaa9f86a2010-07-22 16:20:36 -070072 /* If there is no GL context (standalone compiler), fill in constants
73 * with the minimum required values.
74 */
Ian Romanick2462a532010-07-18 15:59:43 -070075 static struct gl_extensions null_extensions;
76
77 memset(&null_extensions, 0, sizeof(null_extensions));
Ian Romanick4f397e12010-08-05 17:50:13 -070078 null_extensions.ARB_draw_buffers = GL_TRUE;
79 null_extensions.ARB_fragment_coord_conventions = GL_TRUE;
80 null_extensions.EXT_texture_array = GL_TRUE;
81 null_extensions.NV_texture_rectangle = GL_TRUE;
82
Ian Romanick2462a532010-07-18 15:59:43 -070083 this->extensions = &null_extensions;
Kenneth Graunkeaa9f86a2010-07-22 16:20:36 -070084
85 /* 1.10 minimums. */
86 this->Const.MaxLights = 8;
87 this->Const.MaxClipPlanes = 8;
88 this->Const.MaxTextureUnits = 2;
89
90 /* More than the 1.10 minimum to appease parser tests taken from
91 * apps that (hopefully) already checked the number of coords.
92 */
93 this->Const.MaxTextureCoords = 4;
94
95 this->Const.MaxVertexAttribs = 16;
96 this->Const.MaxVertexUniformComponents = 512;
97 this->Const.MaxVaryingFloats = 32;
98 this->Const.MaxVertexTextureImageUnits = 0;
99 this->Const.MaxCombinedTextureImageUnits = 2;
100 this->Const.MaxTextureImageUnits = 2;
101 this->Const.MaxFragmentUniformComponents = 64;
102
103 this->Const.MaxDrawBuffers = 2;
Ian Romanick2462a532010-07-18 15:59:43 -0700104 }
105}
106
Ian Romanick5bfe30a2010-04-07 16:44:30 -0700107const char *
108_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
109{
110 switch (target) {
111 case vertex_shader: return "vertex";
112 case fragment_shader: return "fragment";
113 case geometry_shader: return "geometry";
Eric Anholt81f49a72010-04-29 17:57:28 -0700114 case ir_shader: break;
Ian Romanick5bfe30a2010-04-07 16:44:30 -0700115 }
116
117 assert(!"Should not get here.");
Eric Anholt87a2ee82010-07-18 17:47:15 -0700118 return "unknown";
Ian Romanick5bfe30a2010-04-07 16:44:30 -0700119}
120
121
Ian Romanicka87ac252010-02-22 13:19:34 -0800122void
Ian Romanick1f585182010-03-11 14:08:33 -0800123_mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
124 const char *fmt, ...)
Ian Romanicka87ac252010-02-22 13:19:34 -0800125{
Ian Romanicka87ac252010-02-22 13:19:34 -0800126 va_list ap;
127
Ian Romanick71d0bbf2010-03-23 13:21:19 -0700128 state->error = true;
Ian Romanick1f585182010-03-11 14:08:33 -0800129
Kenneth Graunkeb2ba6fa2010-06-17 15:15:35 -0700130 assert(state->info_log != NULL);
131 state->info_log = talloc_asprintf_append(state->info_log,
132 "%u:%u(%u): error: ",
133 locp->source,
134 locp->first_line,
135 locp->first_column);
Ian Romanicka87ac252010-02-22 13:19:34 -0800136 va_start(ap, fmt);
Kenneth Graunkeb2ba6fa2010-06-17 15:15:35 -0700137 state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
Ian Romanicka87ac252010-02-22 13:19:34 -0800138 va_end(ap);
Kenneth Graunkeb2ba6fa2010-06-17 15:15:35 -0700139 state->info_log = talloc_strdup_append(state->info_log, "\n");
Ian Romanicka87ac252010-02-22 13:19:34 -0800140}
141
142
Ian Romanick56b8b212010-04-07 14:47:46 -0700143void
Eric Anholt3623df62010-04-29 18:00:33 -0700144_mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
Ian Romanick56b8b212010-04-07 14:47:46 -0700145 const char *fmt, ...)
146{
Ian Romanick56b8b212010-04-07 14:47:46 -0700147 va_list ap;
148
Kenneth Graunkeb2ba6fa2010-06-17 15:15:35 -0700149 assert(state->info_log != NULL);
150 state->info_log = talloc_asprintf_append(state->info_log,
151 "%u:%u(%u): warning: ",
152 locp->source,
153 locp->first_line,
154 locp->first_column);
Ian Romanick56b8b212010-04-07 14:47:46 -0700155 va_start(ap, fmt);
Kenneth Graunkeb2ba6fa2010-06-17 15:15:35 -0700156 state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
Ian Romanick56b8b212010-04-07 14:47:46 -0700157 va_end(ap);
Kenneth Graunkeb2ba6fa2010-06-17 15:15:35 -0700158 state->info_log = talloc_strdup_append(state->info_log, "\n");
Ian Romanick56b8b212010-04-07 14:47:46 -0700159}
160
161
Ian Romanicke7017612010-04-07 16:46:25 -0700162bool
163_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
164 const char *behavior, YYLTYPE *behavior_locp,
165 _mesa_glsl_parse_state *state)
166{
167 enum {
168 extension_disable,
169 extension_enable,
170 extension_require,
171 extension_warn
172 } ext_mode;
Ian Romanicke7017612010-04-07 16:46:25 -0700173
174 if (strcmp(behavior, "warn") == 0) {
175 ext_mode = extension_warn;
176 } else if (strcmp(behavior, "require") == 0) {
177 ext_mode = extension_require;
178 } else if (strcmp(behavior, "enable") == 0) {
179 ext_mode = extension_enable;
180 } else if (strcmp(behavior, "disable") == 0) {
181 ext_mode = extension_disable;
182 } else {
183 _mesa_glsl_error(behavior_locp, state,
184 "Unknown extension behavior `%s'",
185 behavior);
186 return false;
187 }
188
Ian Romanick887a8b02010-04-07 16:57:56 -0700189 bool unsupported = false;
190
Ian Romanicke7017612010-04-07 16:46:25 -0700191 if (strcmp(name, "all") == 0) {
192 if ((ext_mode == extension_enable) || (ext_mode == extension_require)) {
193 _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
194 (ext_mode == extension_enable)
195 ? "enable" : "require");
196 return false;
197 }
Ian Romanickeb56cea2010-04-23 13:32:23 -0700198 } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) {
Ian Romanickc77b2572010-04-07 16:59:46 -0700199 /* This extension is only supported in fragment shaders.
200 */
201 if (state->target != fragment_shader) {
202 unsupported = true;
203 } else {
204 state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
205 state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
206 }
Ian Romanickf50f0652010-06-30 17:30:03 -0700207 } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) {
208 state->ARB_fragment_coord_conventions_enable =
209 (ext_mode != extension_disable);
210 state->ARB_fragment_coord_conventions_warn =
211 (ext_mode == extension_warn);
212
213 unsupported = !state->extensions->ARB_fragment_coord_conventions;
Ian Romanickeb56cea2010-04-23 13:32:23 -0700214 } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) {
Ian Romanick0c824652010-04-07 17:13:44 -0700215 state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
216 state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
Ian Romanick667f4e12010-06-30 16:42:07 -0700217 } else if (strcmp(name, "GL_EXT_texture_array") == 0) {
218 state->EXT_texture_array_enable = (ext_mode != extension_disable);
219 state->EXT_texture_array_warn = (ext_mode == extension_warn);
220
221 unsupported = !state->extensions->EXT_texture_array;
Ian Romanicke7017612010-04-07 16:46:25 -0700222 } else {
Ian Romanick887a8b02010-04-07 16:57:56 -0700223 unsupported = true;
224 }
225
226 if (unsupported) {
227 static const char *const fmt = "extension `%s' unsupported in %s shader";
228
Ian Romanicke7017612010-04-07 16:46:25 -0700229 if (ext_mode == extension_require) {
Ian Romanick887a8b02010-04-07 16:57:56 -0700230 _mesa_glsl_error(name_locp, state, fmt,
231 name, _mesa_glsl_shader_target_name(state->target));
Ian Romanicke7017612010-04-07 16:46:25 -0700232 return false;
Ian Romanick1799a0c2010-04-07 14:50:36 -0700233 } else {
Ian Romanick887a8b02010-04-07 16:57:56 -0700234 _mesa_glsl_warning(name_locp, state, fmt,
235 name, _mesa_glsl_shader_target_name(state->target));
Ian Romanicke7017612010-04-07 16:46:25 -0700236 }
237 }
238
239 return true;
240}
241
Ian Romanicka87ac252010-02-22 13:19:34 -0800242void
243_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
244{
245 if (q->constant)
246 printf("const ");
247
248 if (q->invariant)
249 printf("invariant ");
250
251 if (q->attribute)
252 printf("attribute ");
253
254 if (q->varying)
255 printf("varying ");
256
257 if (q->in && q->out)
258 printf("inout ");
259 else {
260 if (q->in)
261 printf("in ");
262
263 if (q->out)
264 printf("out ");
265 }
266
267 if (q->centroid)
268 printf("centroid ");
269 if (q->uniform)
270 printf("uniform ");
271 if (q->smooth)
272 printf("smooth ");
273 if (q->flat)
274 printf("flat ");
275 if (q->noperspective)
276 printf("noperspective ");
277}
278
279
280void
281ast_node::print(void) const
282{
Ian Romanick03d3f3a2010-04-02 11:03:47 -0700283 printf("unhandled node ");
Ian Romanicka87ac252010-02-22 13:19:34 -0800284}
285
286
287ast_node::ast_node(void)
288{
Carl Worthec9675e2010-07-29 16:39:36 -0700289 this->location.source = 0;
290 this->location.line = 0;
291 this->location.column = 0;
Ian Romanicka87ac252010-02-22 13:19:34 -0800292}
293
Ian Romanicka87ac252010-02-22 13:19:34 -0800294
295static void
296ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
297{
298 if (is_array) {
299 printf("[ ");
300
301 if (array_size)
302 array_size->print();
303
304 printf("] ");
305 }
306}
307
308
Ian Romanicka87ac252010-02-22 13:19:34 -0800309void
310ast_compound_statement::print(void) const
311{
Ian Romanicka87ac252010-02-22 13:19:34 -0800312 printf("{\n");
313
Ian Romanick304ea902010-05-10 11:17:53 -0700314 foreach_list_const(n, &this->statements) {
315 ast_node *ast = exec_node_data(ast_node, n, link);
316 ast->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800317 }
318
319 printf("}\n");
320}
321
322
323ast_compound_statement::ast_compound_statement(int new_scope,
324 ast_node *statements)
325{
326 this->new_scope = new_scope;
Ian Romanicka87ac252010-02-22 13:19:34 -0800327
328 if (statements != NULL) {
Ian Romanick304ea902010-05-10 11:17:53 -0700329 this->statements.push_degenerate_list_at_head(&statements->link);
Ian Romanicka87ac252010-02-22 13:19:34 -0800330 }
331}
332
333
334void
335ast_expression::print(void) const
336{
Ian Romanicka87ac252010-02-22 13:19:34 -0800337 switch (oper) {
338 case ast_assign:
Ian Romanicka87ac252010-02-22 13:19:34 -0800339 case ast_mul_assign:
340 case ast_div_assign:
341 case ast_mod_assign:
342 case ast_add_assign:
343 case ast_sub_assign:
344 case ast_ls_assign:
345 case ast_rs_assign:
346 case ast_and_assign:
347 case ast_xor_assign:
348 case ast_or_assign:
349 subexpressions[0]->print();
Ian Romanick88349b22010-02-22 19:10:25 -0800350 printf("%s ", operator_string(oper));
Ian Romanicka87ac252010-02-22 13:19:34 -0800351 subexpressions[1]->print();
352 break;
353
354 case ast_field_selection:
355 subexpressions[0]->print();
356 printf(". %s ", primary_expression.identifier);
357 break;
358
359 case ast_plus:
360 case ast_neg:
361 case ast_bit_not:
362 case ast_logic_not:
363 case ast_pre_inc:
364 case ast_pre_dec:
Ian Romanick88349b22010-02-22 19:10:25 -0800365 printf("%s ", operator_string(oper));
Ian Romanicka87ac252010-02-22 13:19:34 -0800366 subexpressions[0]->print();
367 break;
368
369 case ast_post_inc:
370 case ast_post_dec:
371 subexpressions[0]->print();
Ian Romanick88349b22010-02-22 19:10:25 -0800372 printf("%s ", operator_string(oper));
Ian Romanicka87ac252010-02-22 13:19:34 -0800373 break;
374
375 case ast_conditional:
376 subexpressions[0]->print();
377 printf("? ");
378 subexpressions[1]->print();
379 printf(": ");
380 subexpressions[1]->print();
381 break;
382
383 case ast_array_index:
384 subexpressions[0]->print();
385 printf("[ ");
386 subexpressions[1]->print();
387 printf("] ");
388 break;
389
390 case ast_function_call: {
Ian Romanicka87ac252010-02-22 13:19:34 -0800391 subexpressions[0]->print();
392 printf("( ");
393
Ian Romanick304ea902010-05-10 11:17:53 -0700394 foreach_list_const (n, &this->expressions) {
Ian Romanick23849372010-05-14 16:06:41 -0700395 if (n != this->expressions.get_head())
396 printf(", ");
Ian Romanick304ea902010-05-10 11:17:53 -0700397
398 ast_node *ast = exec_node_data(ast_node, n, link);
399 ast->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800400 }
401
402 printf(") ");
403 break;
404 }
405
406 case ast_identifier:
407 printf("%s ", primary_expression.identifier);
408 break;
409
410 case ast_int_constant:
411 printf("%d ", primary_expression.int_constant);
412 break;
413
414 case ast_uint_constant:
415 printf("%u ", primary_expression.uint_constant);
416 break;
417
418 case ast_float_constant:
419 printf("%f ", primary_expression.float_constant);
420 break;
421
422 case ast_bool_constant:
423 printf("%s ",
424 primary_expression.bool_constant
425 ? "true" : "false");
426 break;
427
428 case ast_sequence: {
Ian Romanicka87ac252010-02-22 13:19:34 -0800429 printf("( ");
Ian Romanick304ea902010-05-10 11:17:53 -0700430 foreach_list_const(n, & this->expressions) {
431 if (n != this->expressions.get_head())
Ian Romanicka87ac252010-02-22 13:19:34 -0800432 printf(", ");
433
Ian Romanick304ea902010-05-10 11:17:53 -0700434 ast_node *ast = exec_node_data(ast_node, n, link);
435 ast->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800436 }
437 printf(") ");
438 break;
439 }
Ian Romanick88349b22010-02-22 19:10:25 -0800440
441 default:
442 assert(0);
443 break;
Ian Romanicka87ac252010-02-22 13:19:34 -0800444 }
445}
446
447ast_expression::ast_expression(int oper,
448 ast_expression *ex0,
449 ast_expression *ex1,
450 ast_expression *ex2)
451{
452 this->oper = ast_operators(oper);
453 this->subexpressions[0] = ex0;
454 this->subexpressions[1] = ex1;
455 this->subexpressions[2] = ex2;
Ian Romanicka87ac252010-02-22 13:19:34 -0800456}
457
458
459void
460ast_expression_statement::print(void) const
461{
462 if (expression)
463 expression->print();
464
465 printf("; ");
466}
467
468
469ast_expression_statement::ast_expression_statement(ast_expression *ex) :
470 expression(ex)
471{
472 /* empty */
473}
474
475
476void
477ast_function::print(void) const
478{
Ian Romanicka87ac252010-02-22 13:19:34 -0800479 return_type->print();
480 printf(" %s (", identifier);
481
Ian Romanick304ea902010-05-10 11:17:53 -0700482 foreach_list_const(n, & this->parameters) {
483 ast_node *ast = exec_node_data(ast_node, n, link);
484 ast->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800485 }
486
487 printf(")");
488}
489
490
491ast_function::ast_function(void)
Ian Romanick92318a92010-03-31 18:23:21 -0700492 : is_definition(false), signature(NULL)
Ian Romanicka87ac252010-02-22 13:19:34 -0800493{
Ian Romanick304ea902010-05-10 11:17:53 -0700494 /* empty */
Ian Romanicka87ac252010-02-22 13:19:34 -0800495}
496
497
498void
499ast_fully_specified_type::print(void) const
500{
501 _mesa_ast_type_qualifier_print(& qualifier);
502 specifier->print();
503}
504
505
506void
507ast_parameter_declarator::print(void) const
508{
509 type->print();
510 if (identifier)
511 printf("%s ", identifier);
512 ast_opt_array_size_print(is_array, array_size);
513}
514
515
516void
517ast_function_definition::print(void) const
518{
519 prototype->print();
520 body->print();
521}
522
523
524void
525ast_declaration::print(void) const
526{
527 printf("%s ", identifier);
528 ast_opt_array_size_print(is_array, array_size);
529
530 if (initializer) {
531 printf("= ");
532 initializer->print();
533 }
534}
535
536
537ast_declaration::ast_declaration(char *identifier, int is_array,
538 ast_expression *array_size,
539 ast_expression *initializer)
540{
541 this->identifier = identifier;
542 this->is_array = is_array;
543 this->array_size = array_size;
544 this->initializer = initializer;
545}
546
547
548void
549ast_declarator_list::print(void) const
550{
Ian Romanicka87ac252010-02-22 13:19:34 -0800551 assert(type || invariant);
552
553 if (type)
554 type->print();
555 else
556 printf("invariant ");
557
Ian Romanick304ea902010-05-10 11:17:53 -0700558 foreach_list_const (ptr, & this->declarations) {
559 if (ptr != this->declarations.get_head())
Ian Romanicka87ac252010-02-22 13:19:34 -0800560 printf(", ");
561
Ian Romanick304ea902010-05-10 11:17:53 -0700562 ast_node *ast = exec_node_data(ast_node, ptr, link);
563 ast->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800564 }
565
566 printf("; ");
567}
568
569
570ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
571{
572 this->type = type;
Ian Romanick38327062010-07-01 17:10:11 -0700573 this->invariant = false;
Ian Romanicka87ac252010-02-22 13:19:34 -0800574}
575
576void
577ast_jump_statement::print(void) const
578{
579 switch (mode) {
580 case ast_continue:
581 printf("continue; ");
582 break;
583 case ast_break:
584 printf("break; ");
585 break;
586 case ast_return:
587 printf("return ");
588 if (opt_return_value)
589 opt_return_value->print();
590
591 printf("; ");
592 break;
593 case ast_discard:
594 printf("discard; ");
595 break;
596 }
597}
598
599
600ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
601{
602 this->mode = ast_jump_modes(mode);
603
604 if (mode == ast_return)
605 opt_return_value = return_value;
606}
607
608
609void
610ast_selection_statement::print(void) const
611{
612 printf("if ( ");
613 condition->print();
614 printf(") ");
615
616 then_statement->print();
617
618 if (else_statement) {
619 printf("else ");
620 else_statement->print();
621 }
622
623}
624
625
626ast_selection_statement::ast_selection_statement(ast_expression *condition,
627 ast_node *then_statement,
628 ast_node *else_statement)
629{
630 this->condition = condition;
631 this->then_statement = then_statement;
632 this->else_statement = else_statement;
633}
634
635
636void
637ast_iteration_statement::print(void) const
638{
639 switch (mode) {
640 case ast_for:
641 printf("for( ");
642 if (init_statement)
643 init_statement->print();
644 printf("; ");
645
646 if (condition)
647 condition->print();
648 printf("; ");
649
650 if (rest_expression)
651 rest_expression->print();
652 printf(") ");
653
654 body->print();
655 break;
656
657 case ast_while:
658 printf("while ( ");
659 if (condition)
660 condition->print();
661 printf(") ");
662 body->print();
663 break;
664
665 case ast_do_while:
666 printf("do ");
667 body->print();
668 printf("while ( ");
669 if (condition)
670 condition->print();
671 printf("); ");
672 break;
673 }
674}
675
676
677ast_iteration_statement::ast_iteration_statement(int mode,
678 ast_node *init,
679 ast_node *condition,
680 ast_expression *rest_expression,
681 ast_node *body)
682{
683 this->mode = ast_iteration_modes(mode);
684 this->init_statement = init;
685 this->condition = condition;
686 this->rest_expression = rest_expression;
687 this->body = body;
688}
689
690
691void
692ast_struct_specifier::print(void) const
693{
Ian Romanicka87ac252010-02-22 13:19:34 -0800694 printf("struct %s { ", name);
Ian Romanick304ea902010-05-10 11:17:53 -0700695 foreach_list_const(n, &this->declarations) {
696 ast_node *ast = exec_node_data(ast_node, n, link);
697 ast->print();
Ian Romanicka87ac252010-02-22 13:19:34 -0800698 }
699 printf("} ");
700}
701
702
703ast_struct_specifier::ast_struct_specifier(char *identifier,
704 ast_node *declarator_list)
705{
706 name = identifier;
Ian Romanick304ea902010-05-10 11:17:53 -0700707 this->declarations.push_degenerate_list_at_head(&declarator_list->link);
Ian Romanicka87ac252010-02-22 13:19:34 -0800708}
Eric Anholt2f4fe152010-08-10 13:06:49 -0700709
710bool
711do_common_optimization(exec_list *ir, bool linked)
712{
713 GLboolean progress = GL_FALSE;
714
715 progress = do_sub_to_add_neg(ir) || progress;
716
717 if (linked) {
718 progress = do_function_inlining(ir) || progress;
719 progress = do_dead_functions(ir) || progress;
720 }
721 progress = do_structure_splitting(ir) || progress;
722 progress = do_if_simplification(ir) || progress;
723 progress = do_copy_propagation(ir) || progress;
724 if (linked)
725 progress = do_dead_code(ir) || progress;
726 else
727 progress = do_dead_code_unlinked(ir) || progress;
728 progress = do_dead_code_local(ir) || progress;
729 progress = do_tree_grafting(ir) || progress;
730 progress = do_constant_propagation(ir) || progress;
731 if (linked)
732 progress = do_constant_variable(ir) || progress;
733 else
734 progress = do_constant_variable_unlinked(ir) || progress;
735 progress = do_constant_folding(ir) || progress;
736 progress = do_algebraic(ir) || progress;
737 progress = do_if_return(ir) || progress;
738 progress = do_vec_index_to_swizzle(ir) || progress;
739 progress = do_swizzle_swizzle(ir) || progress;
Eric Anholt8f8cdbf2010-08-13 07:16:38 -0700740 progress = do_noop_swizzle(ir) || progress;
Eric Anholt2f4fe152010-08-10 13:06:49 -0700741
742 return progress;
743}
Eric Anholtb8384642010-08-18 16:56:39 -0700744
745extern "C" {
746
747/**
748 * To be called at GL teardown time, this frees compiler datastructures.
749 *
750 * After calling this, any previously compiled shaders and shader
751 * programs would be invalid. So this should happen at approximately
752 * program exit.
753 */
754void
755_mesa_destroy_shader_compiler(void)
756{
757 _mesa_destroy_shader_compiler_caches();
758
759 _mesa_glsl_release_types();
760}
761
762/**
763 * Releases compiler caches to trade off performance for memory.
764 *
765 * Intended to be used with glReleaseShaderCompiler().
766 */
767void
768_mesa_destroy_shader_compiler_caches(void)
769{
770 _mesa_glsl_release_functions();
771}
772
773}