glsl2: Move the compiler to the subdirectory it will live in in Mesa.
[mesa.git] / src / glsl / glsl_parser_extras.cpp
1 /*
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>
25 #include <string.h>
26 #include <assert.h>
27
28 extern "C" {
29 #include <talloc.h>
30 }
31
32 #include "ast.h"
33 #include "glsl_parser_extras.h"
34 #include "glsl_parser.h"
35
36 const char *
37 _mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
38 {
39 switch (target) {
40 case vertex_shader: return "vertex";
41 case fragment_shader: return "fragment";
42 case geometry_shader: return "geometry";
43 case ir_shader: break;
44 }
45
46 assert(!"Should not get here.");
47 }
48
49
50 void
51 _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
52 const char *fmt, ...)
53 {
54 va_list ap;
55
56 state->error = true;
57
58 assert(state->info_log != NULL);
59 state->info_log = talloc_asprintf_append(state->info_log,
60 "%u:%u(%u): error: ",
61 locp->source,
62 locp->first_line,
63 locp->first_column);
64 va_start(ap, fmt);
65 state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
66 va_end(ap);
67 state->info_log = talloc_strdup_append(state->info_log, "\n");
68 }
69
70
71 void
72 _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
73 const char *fmt, ...)
74 {
75 va_list ap;
76
77 assert(state->info_log != NULL);
78 state->info_log = talloc_asprintf_append(state->info_log,
79 "%u:%u(%u): warning: ",
80 locp->source,
81 locp->first_line,
82 locp->first_column);
83 va_start(ap, fmt);
84 state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
85 va_end(ap);
86 state->info_log = talloc_strdup_append(state->info_log, "\n");
87 }
88
89
90 bool
91 _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
92 const char *behavior, YYLTYPE *behavior_locp,
93 _mesa_glsl_parse_state *state)
94 {
95 enum {
96 extension_disable,
97 extension_enable,
98 extension_require,
99 extension_warn
100 } ext_mode;
101
102 if (strcmp(behavior, "warn") == 0) {
103 ext_mode = extension_warn;
104 } else if (strcmp(behavior, "require") == 0) {
105 ext_mode = extension_require;
106 } else if (strcmp(behavior, "enable") == 0) {
107 ext_mode = extension_enable;
108 } else if (strcmp(behavior, "disable") == 0) {
109 ext_mode = extension_disable;
110 } else {
111 _mesa_glsl_error(behavior_locp, state,
112 "Unknown extension behavior `%s'",
113 behavior);
114 return false;
115 }
116
117 bool unsupported = false;
118
119 if (strcmp(name, "all") == 0) {
120 if ((ext_mode == extension_enable) || (ext_mode == extension_require)) {
121 _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
122 (ext_mode == extension_enable)
123 ? "enable" : "require");
124 return false;
125 }
126 } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) {
127 /* This extension is only supported in fragment shaders.
128 */
129 if (state->target != fragment_shader) {
130 unsupported = true;
131 } else {
132 state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
133 state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
134 }
135 } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) {
136 state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
137 state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
138 } else {
139 unsupported = true;
140 }
141
142 if (unsupported) {
143 static const char *const fmt = "extension `%s' unsupported in %s shader";
144
145 if (ext_mode == extension_require) {
146 _mesa_glsl_error(name_locp, state, fmt,
147 name, _mesa_glsl_shader_target_name(state->target));
148 return false;
149 } else {
150 _mesa_glsl_warning(name_locp, state, fmt,
151 name, _mesa_glsl_shader_target_name(state->target));
152 }
153 }
154
155 return true;
156 }
157
158 void
159 _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
160 {
161 if (q->constant)
162 printf("const ");
163
164 if (q->invariant)
165 printf("invariant ");
166
167 if (q->attribute)
168 printf("attribute ");
169
170 if (q->varying)
171 printf("varying ");
172
173 if (q->in && q->out)
174 printf("inout ");
175 else {
176 if (q->in)
177 printf("in ");
178
179 if (q->out)
180 printf("out ");
181 }
182
183 if (q->centroid)
184 printf("centroid ");
185 if (q->uniform)
186 printf("uniform ");
187 if (q->smooth)
188 printf("smooth ");
189 if (q->flat)
190 printf("flat ");
191 if (q->noperspective)
192 printf("noperspective ");
193 }
194
195
196 void
197 ast_node::print(void) const
198 {
199 printf("unhandled node ");
200 }
201
202
203 ast_node::ast_node(void)
204 {
205 /* empty */
206 }
207
208
209 static void
210 ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
211 {
212 if (is_array) {
213 printf("[ ");
214
215 if (array_size)
216 array_size->print();
217
218 printf("] ");
219 }
220 }
221
222
223 void
224 ast_compound_statement::print(void) const
225 {
226 printf("{\n");
227
228 foreach_list_const(n, &this->statements) {
229 ast_node *ast = exec_node_data(ast_node, n, link);
230 ast->print();
231 }
232
233 printf("}\n");
234 }
235
236
237 ast_compound_statement::ast_compound_statement(int new_scope,
238 ast_node *statements)
239 {
240 this->new_scope = new_scope;
241
242 if (statements != NULL) {
243 this->statements.push_degenerate_list_at_head(&statements->link);
244 }
245 }
246
247
248 void
249 ast_expression::print(void) const
250 {
251 switch (oper) {
252 case ast_assign:
253 case ast_mul_assign:
254 case ast_div_assign:
255 case ast_mod_assign:
256 case ast_add_assign:
257 case ast_sub_assign:
258 case ast_ls_assign:
259 case ast_rs_assign:
260 case ast_and_assign:
261 case ast_xor_assign:
262 case ast_or_assign:
263 subexpressions[0]->print();
264 printf("%s ", operator_string(oper));
265 subexpressions[1]->print();
266 break;
267
268 case ast_field_selection:
269 subexpressions[0]->print();
270 printf(". %s ", primary_expression.identifier);
271 break;
272
273 case ast_plus:
274 case ast_neg:
275 case ast_bit_not:
276 case ast_logic_not:
277 case ast_pre_inc:
278 case ast_pre_dec:
279 printf("%s ", operator_string(oper));
280 subexpressions[0]->print();
281 break;
282
283 case ast_post_inc:
284 case ast_post_dec:
285 subexpressions[0]->print();
286 printf("%s ", operator_string(oper));
287 break;
288
289 case ast_conditional:
290 subexpressions[0]->print();
291 printf("? ");
292 subexpressions[1]->print();
293 printf(": ");
294 subexpressions[1]->print();
295 break;
296
297 case ast_array_index:
298 subexpressions[0]->print();
299 printf("[ ");
300 subexpressions[1]->print();
301 printf("] ");
302 break;
303
304 case ast_function_call: {
305 subexpressions[0]->print();
306 printf("( ");
307
308 foreach_list_const (n, &this->expressions) {
309 if (n != this->expressions.get_head())
310 printf(", ");
311
312 ast_node *ast = exec_node_data(ast_node, n, link);
313 ast->print();
314 }
315
316 printf(") ");
317 break;
318 }
319
320 case ast_identifier:
321 printf("%s ", primary_expression.identifier);
322 break;
323
324 case ast_int_constant:
325 printf("%d ", primary_expression.int_constant);
326 break;
327
328 case ast_uint_constant:
329 printf("%u ", primary_expression.uint_constant);
330 break;
331
332 case ast_float_constant:
333 printf("%f ", primary_expression.float_constant);
334 break;
335
336 case ast_bool_constant:
337 printf("%s ",
338 primary_expression.bool_constant
339 ? "true" : "false");
340 break;
341
342 case ast_sequence: {
343 printf("( ");
344 foreach_list_const(n, & this->expressions) {
345 if (n != this->expressions.get_head())
346 printf(", ");
347
348 ast_node *ast = exec_node_data(ast_node, n, link);
349 ast->print();
350 }
351 printf(") ");
352 break;
353 }
354
355 default:
356 assert(0);
357 break;
358 }
359 }
360
361 ast_expression::ast_expression(int oper,
362 ast_expression *ex0,
363 ast_expression *ex1,
364 ast_expression *ex2)
365 {
366 this->oper = ast_operators(oper);
367 this->subexpressions[0] = ex0;
368 this->subexpressions[1] = ex1;
369 this->subexpressions[2] = ex2;
370 }
371
372
373 void
374 ast_expression_statement::print(void) const
375 {
376 if (expression)
377 expression->print();
378
379 printf("; ");
380 }
381
382
383 ast_expression_statement::ast_expression_statement(ast_expression *ex) :
384 expression(ex)
385 {
386 /* empty */
387 }
388
389
390 void
391 ast_function::print(void) const
392 {
393 return_type->print();
394 printf(" %s (", identifier);
395
396 foreach_list_const(n, & this->parameters) {
397 ast_node *ast = exec_node_data(ast_node, n, link);
398 ast->print();
399 }
400
401 printf(")");
402 }
403
404
405 ast_function::ast_function(void)
406 : is_definition(false), signature(NULL)
407 {
408 /* empty */
409 }
410
411
412 void
413 ast_fully_specified_type::print(void) const
414 {
415 _mesa_ast_type_qualifier_print(& qualifier);
416 specifier->print();
417 }
418
419
420 void
421 ast_parameter_declarator::print(void) const
422 {
423 type->print();
424 if (identifier)
425 printf("%s ", identifier);
426 ast_opt_array_size_print(is_array, array_size);
427 }
428
429
430 void
431 ast_function_definition::print(void) const
432 {
433 prototype->print();
434 body->print();
435 }
436
437
438 void
439 ast_declaration::print(void) const
440 {
441 printf("%s ", identifier);
442 ast_opt_array_size_print(is_array, array_size);
443
444 if (initializer) {
445 printf("= ");
446 initializer->print();
447 }
448 }
449
450
451 ast_declaration::ast_declaration(char *identifier, int is_array,
452 ast_expression *array_size,
453 ast_expression *initializer)
454 {
455 this->identifier = identifier;
456 this->is_array = is_array;
457 this->array_size = array_size;
458 this->initializer = initializer;
459 }
460
461
462 void
463 ast_declarator_list::print(void) const
464 {
465 assert(type || invariant);
466
467 if (type)
468 type->print();
469 else
470 printf("invariant ");
471
472 foreach_list_const (ptr, & this->declarations) {
473 if (ptr != this->declarations.get_head())
474 printf(", ");
475
476 ast_node *ast = exec_node_data(ast_node, ptr, link);
477 ast->print();
478 }
479
480 printf("; ");
481 }
482
483
484 ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
485 {
486 this->type = type;
487 }
488
489 void
490 ast_jump_statement::print(void) const
491 {
492 switch (mode) {
493 case ast_continue:
494 printf("continue; ");
495 break;
496 case ast_break:
497 printf("break; ");
498 break;
499 case ast_return:
500 printf("return ");
501 if (opt_return_value)
502 opt_return_value->print();
503
504 printf("; ");
505 break;
506 case ast_discard:
507 printf("discard; ");
508 break;
509 }
510 }
511
512
513 ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
514 {
515 this->mode = ast_jump_modes(mode);
516
517 if (mode == ast_return)
518 opt_return_value = return_value;
519 }
520
521
522 void
523 ast_selection_statement::print(void) const
524 {
525 printf("if ( ");
526 condition->print();
527 printf(") ");
528
529 then_statement->print();
530
531 if (else_statement) {
532 printf("else ");
533 else_statement->print();
534 }
535
536 }
537
538
539 ast_selection_statement::ast_selection_statement(ast_expression *condition,
540 ast_node *then_statement,
541 ast_node *else_statement)
542 {
543 this->condition = condition;
544 this->then_statement = then_statement;
545 this->else_statement = else_statement;
546 }
547
548
549 void
550 ast_iteration_statement::print(void) const
551 {
552 switch (mode) {
553 case ast_for:
554 printf("for( ");
555 if (init_statement)
556 init_statement->print();
557 printf("; ");
558
559 if (condition)
560 condition->print();
561 printf("; ");
562
563 if (rest_expression)
564 rest_expression->print();
565 printf(") ");
566
567 body->print();
568 break;
569
570 case ast_while:
571 printf("while ( ");
572 if (condition)
573 condition->print();
574 printf(") ");
575 body->print();
576 break;
577
578 case ast_do_while:
579 printf("do ");
580 body->print();
581 printf("while ( ");
582 if (condition)
583 condition->print();
584 printf("); ");
585 break;
586 }
587 }
588
589
590 ast_iteration_statement::ast_iteration_statement(int mode,
591 ast_node *init,
592 ast_node *condition,
593 ast_expression *rest_expression,
594 ast_node *body)
595 {
596 this->mode = ast_iteration_modes(mode);
597 this->init_statement = init;
598 this->condition = condition;
599 this->rest_expression = rest_expression;
600 this->body = body;
601 }
602
603
604 void
605 ast_struct_specifier::print(void) const
606 {
607 printf("struct %s { ", name);
608 foreach_list_const(n, &this->declarations) {
609 ast_node *ast = exec_node_data(ast_node, n, link);
610 ast->print();
611 }
612 printf("} ");
613 }
614
615
616 ast_struct_specifier::ast_struct_specifier(char *identifier,
617 ast_node *declarator_list)
618 {
619 name = identifier;
620 this->declarations.push_degenerate_list_at_head(&declarator_list->link);
621 }