1c095cb66f9fc616bff8019755b9d1c07ee392fb
[mesa.git] / src / compiler / glsl / glcpp / glcpp-parse.y
1 %{
2 /*
3 * Copyright © 2010 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <inttypes.h>
30
31 #include "glcpp.h"
32 #include "main/mtypes.h"
33
34 static void
35 yyerror(YYLTYPE *locp, glcpp_parser_t *parser, const char *error);
36
37 static void
38 _define_object_macro(glcpp_parser_t *parser,
39 YYLTYPE *loc,
40 const char *macro,
41 token_list_t *replacements);
42
43 static void
44 _define_function_macro(glcpp_parser_t *parser,
45 YYLTYPE *loc,
46 const char *macro,
47 string_list_t *parameters,
48 token_list_t *replacements);
49
50 static string_list_t *
51 _string_list_create(glcpp_parser_t *parser);
52
53 static void
54 _string_list_append_item(glcpp_parser_t *parser, string_list_t *list,
55 const char *str);
56
57 static int
58 _string_list_contains(string_list_t *list, const char *member, int *index);
59
60 static const char *
61 _string_list_has_duplicate(string_list_t *list);
62
63 static int
64 _string_list_length(string_list_t *list);
65
66 static int
67 _string_list_equal(string_list_t *a, string_list_t *b);
68
69 static argument_list_t *
70 _argument_list_create(glcpp_parser_t *parser);
71
72 static void
73 _argument_list_append(glcpp_parser_t *parser, argument_list_t *list,
74 token_list_t *argument);
75
76 static int
77 _argument_list_length(argument_list_t *list);
78
79 static token_list_t *
80 _argument_list_member_at(argument_list_t *list, int index);
81
82 static token_t *
83 _token_create_str(glcpp_parser_t *parser, int type, char *str);
84
85 static token_t *
86 _token_create_ival(glcpp_parser_t *parser, int type, int ival);
87
88 static token_list_t *
89 _token_list_create(glcpp_parser_t *parser);
90
91 static void
92 _token_list_append(glcpp_parser_t *parser, token_list_t *list, token_t *token);
93
94 static void
95 _token_list_append_list(token_list_t *list, token_list_t *tail);
96
97 static int
98 _token_list_equal_ignoring_space(token_list_t *a, token_list_t *b);
99
100 static void
101 _parser_active_list_push(glcpp_parser_t *parser, const char *identifier,
102 token_node_t *marker);
103
104 static void
105 _parser_active_list_pop(glcpp_parser_t *parser);
106
107 static int
108 _parser_active_list_contains(glcpp_parser_t *parser, const char *identifier);
109
110 typedef enum {
111 EXPANSION_MODE_IGNORE_DEFINED,
112 EXPANSION_MODE_EVALUATE_DEFINED
113 } expansion_mode_t;
114
115 /* Expand list, and begin lexing from the result (after first
116 * prefixing a token of type 'head_token_type').
117 */
118 static void
119 _glcpp_parser_expand_and_lex_from(glcpp_parser_t *parser, int head_token_type,
120 token_list_t *list, expansion_mode_t mode);
121
122 /* Perform macro expansion in-place on the given list. */
123 static void
124 _glcpp_parser_expand_token_list(glcpp_parser_t *parser, token_list_t *list,
125 expansion_mode_t mode);
126
127 static void
128 _glcpp_parser_print_expanded_token_list(glcpp_parser_t *parser,
129 token_list_t *list);
130
131 static void
132 _glcpp_parser_skip_stack_push_if(glcpp_parser_t *parser, YYLTYPE *loc,
133 int condition);
134
135 static void
136 _glcpp_parser_skip_stack_change_if(glcpp_parser_t *parser, YYLTYPE *loc,
137 const char *type, int condition);
138
139 static void
140 _glcpp_parser_skip_stack_pop(glcpp_parser_t *parser, YYLTYPE *loc);
141
142 static void
143 _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
144 const char *ident, bool explicitly_set);
145
146 static int
147 glcpp_parser_lex(YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser);
148
149 static void
150 glcpp_parser_lex_from(glcpp_parser_t *parser, token_list_t *list);
151
152 static void
153 add_builtin_define(glcpp_parser_t *parser, const char *name, int value);
154
155 %}
156
157 %pure-parser
158 %error-verbose
159
160 %locations
161 %initial-action {
162 @$.first_line = 1;
163 @$.first_column = 1;
164 @$.last_line = 1;
165 @$.last_column = 1;
166 @$.source = 0;
167 }
168
169 %parse-param {glcpp_parser_t *parser}
170 %lex-param {glcpp_parser_t *parser}
171
172 %expect 0
173
174 /* We use HASH_TOKEN, DEFINE_TOKEN and VERSION_TOKEN (as opposed to
175 * HASH, DEFINE, and VERSION) to avoid conflicts with other symbols,
176 * (such as the <HASH> and <DEFINE> start conditions in the lexer). */
177 %token DEFINED ELIF_EXPANDED HASH_TOKEN DEFINE_TOKEN FUNC_IDENTIFIER OBJ_IDENTIFIER ELIF ELSE ENDIF ERROR_TOKEN IF IFDEF IFNDEF LINE PRAGMA UNDEF VERSION_TOKEN GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE PLUS_PLUS MINUS_MINUS
178 %token PASTE
179 %type <ival> INTEGER operator SPACE integer_constant version_constant
180 %type <expression_value> expression
181 %type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA
182 %type <string_list> identifier_list
183 %type <token> preprocessing_token
184 %type <token_list> pp_tokens replacement_list text_line
185 %left OR
186 %left AND
187 %left '|'
188 %left '^'
189 %left '&'
190 %left EQUAL NOT_EQUAL
191 %left '<' '>' LESS_OR_EQUAL GREATER_OR_EQUAL
192 %left LEFT_SHIFT RIGHT_SHIFT
193 %left '+' '-'
194 %left '*' '/' '%'
195 %right UNARY
196
197 %debug
198
199 %%
200
201 input:
202 /* empty */
203 | input line
204 ;
205
206 line:
207 control_line
208 | SPACE control_line
209 | text_line {
210 _glcpp_parser_print_expanded_token_list (parser, $1);
211 _mesa_string_buffer_append_char(parser->output, '\n');
212 }
213 | expanded_line
214 ;
215
216 expanded_line:
217 IF_EXPANDED expression NEWLINE {
218 if (parser->is_gles && $2.undefined_macro)
219 glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $2.undefined_macro);
220 _glcpp_parser_skip_stack_push_if (parser, & @1, $2.value);
221 }
222 | ELIF_EXPANDED expression NEWLINE {
223 if (parser->is_gles && $2.undefined_macro)
224 glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $2.undefined_macro);
225 _glcpp_parser_skip_stack_change_if (parser, & @1, "elif", $2.value);
226 }
227 | LINE_EXPANDED integer_constant NEWLINE {
228 parser->has_new_line_number = 1;
229 parser->new_line_number = $2;
230 _mesa_string_buffer_printf(parser->output, "#line %" PRIiMAX "\n", $2);
231 }
232 | LINE_EXPANDED integer_constant integer_constant NEWLINE {
233 parser->has_new_line_number = 1;
234 parser->new_line_number = $2;
235 parser->has_new_source_number = 1;
236 parser->new_source_number = $3;
237 _mesa_string_buffer_printf(parser->output,
238 "#line %" PRIiMAX " %" PRIiMAX "\n",
239 $2, $3);
240 }
241 ;
242
243 define:
244 OBJ_IDENTIFIER replacement_list NEWLINE {
245 _define_object_macro (parser, & @1, $1, $2);
246 }
247 | FUNC_IDENTIFIER '(' ')' replacement_list NEWLINE {
248 _define_function_macro (parser, & @1, $1, NULL, $4);
249 }
250 | FUNC_IDENTIFIER '(' identifier_list ')' replacement_list NEWLINE {
251 _define_function_macro (parser, & @1, $1, $3, $5);
252 }
253 ;
254
255 control_line:
256 control_line_success {
257 _mesa_string_buffer_append_char(parser->output, '\n');
258 }
259 | control_line_error
260 | HASH_TOKEN LINE pp_tokens NEWLINE {
261
262 if (parser->skip_stack == NULL ||
263 parser->skip_stack->type == SKIP_NO_SKIP)
264 {
265 _glcpp_parser_expand_and_lex_from (parser,
266 LINE_EXPANDED, $3,
267 EXPANSION_MODE_IGNORE_DEFINED);
268 }
269 }
270 ;
271
272 control_line_success:
273 HASH_TOKEN DEFINE_TOKEN define
274 | HASH_TOKEN UNDEF IDENTIFIER NEWLINE {
275 struct hash_entry *entry;
276
277 /* Section 3.4 (Preprocessor) of the GLSL ES 3.00 spec says:
278 *
279 * It is an error to undefine or to redefine a built-in
280 * (pre-defined) macro name.
281 *
282 * The GLSL ES 1.00 spec does not contain this text, but
283 * dEQP's preprocess test in GLES2 checks for it.
284 *
285 * Section 3.3 (Preprocessor) revision 7, of the GLSL 4.50
286 * spec says:
287 *
288 * By convention, all macro names containing two consecutive
289 * underscores ( __ ) are reserved for use by underlying
290 * software layers. Defining or undefining such a name
291 * in a shader does not itself result in an error, but may
292 * result in unintended behaviors that stem from having
293 * multiple definitions of the same name. All macro names
294 * prefixed with "GL_" (...) are also reseved, and defining
295 * such a name results in a compile-time error.
296 *
297 * The code below implements the same checks as GLSLang.
298 */
299 if (strncmp("GL_", $3, 3) == 0)
300 glcpp_error(& @1, parser, "Built-in (pre-defined)"
301 " names beginning with GL_ cannot be undefined.");
302 else if (strstr($3, "__") != NULL) {
303 if (parser->is_gles
304 && parser->version >= 300
305 && (strcmp("__LINE__", $3) == 0
306 || strcmp("__FILE__", $3) == 0
307 || strcmp("__VERSION__", $3) == 0)) {
308 glcpp_error(& @1, parser, "Built-in (pre-defined)"
309 " names cannot be undefined.");
310 } else if (parser->is_gles && parser->version <= 300) {
311 glcpp_error(& @1, parser,
312 " names containing consecutive underscores"
313 " are reserved.");
314 } else {
315 glcpp_warning(& @1, parser,
316 " names containing consecutive underscores"
317 " are reserved.");
318 }
319 }
320
321 entry = _mesa_hash_table_search (parser->defines, $3);
322 if (entry) {
323 _mesa_hash_table_remove (parser->defines, entry);
324 }
325 }
326 | HASH_TOKEN IF pp_tokens NEWLINE {
327 /* Be careful to only evaluate the 'if' expression if
328 * we are not skipping. When we are skipping, we
329 * simply push a new 0-valued 'if' onto the skip
330 * stack.
331 *
332 * This avoids generating diagnostics for invalid
333 * expressions that are being skipped. */
334 if (parser->skip_stack == NULL ||
335 parser->skip_stack->type == SKIP_NO_SKIP)
336 {
337 _glcpp_parser_expand_and_lex_from (parser,
338 IF_EXPANDED, $3,
339 EXPANSION_MODE_EVALUATE_DEFINED);
340 }
341 else
342 {
343 _glcpp_parser_skip_stack_push_if (parser, & @1, 0);
344 parser->skip_stack->type = SKIP_TO_ENDIF;
345 }
346 }
347 | HASH_TOKEN IF NEWLINE {
348 /* #if without an expression is only an error if we
349 * are not skipping */
350 if (parser->skip_stack == NULL ||
351 parser->skip_stack->type == SKIP_NO_SKIP)
352 {
353 glcpp_error(& @1, parser, "#if with no expression");
354 }
355 _glcpp_parser_skip_stack_push_if (parser, & @1, 0);
356 }
357 | HASH_TOKEN IFDEF IDENTIFIER junk NEWLINE {
358 struct hash_entry *entry =
359 _mesa_hash_table_search(parser->defines, $3);
360 macro_t *macro = entry ? entry->data : NULL;
361 _glcpp_parser_skip_stack_push_if (parser, & @1, macro != NULL);
362 }
363 | HASH_TOKEN IFNDEF IDENTIFIER junk NEWLINE {
364 struct hash_entry *entry =
365 _mesa_hash_table_search(parser->defines, $3);
366 macro_t *macro = entry ? entry->data : NULL;
367 _glcpp_parser_skip_stack_push_if (parser, & @3, macro == NULL);
368 }
369 | HASH_TOKEN ELIF pp_tokens NEWLINE {
370 /* Be careful to only evaluate the 'elif' expression
371 * if we are not skipping. When we are skipping, we
372 * simply change to a 0-valued 'elif' on the skip
373 * stack.
374 *
375 * This avoids generating diagnostics for invalid
376 * expressions that are being skipped. */
377 if (parser->skip_stack &&
378 parser->skip_stack->type == SKIP_TO_ELSE)
379 {
380 _glcpp_parser_expand_and_lex_from (parser,
381 ELIF_EXPANDED, $3,
382 EXPANSION_MODE_EVALUATE_DEFINED);
383 }
384 else if (parser->skip_stack &&
385 parser->skip_stack->has_else)
386 {
387 glcpp_error(& @1, parser, "#elif after #else");
388 }
389 else
390 {
391 _glcpp_parser_skip_stack_change_if (parser, & @1,
392 "elif", 0);
393 }
394 }
395 | HASH_TOKEN ELIF NEWLINE {
396 /* #elif without an expression is an error unless we
397 * are skipping. */
398 if (parser->skip_stack &&
399 parser->skip_stack->type == SKIP_TO_ELSE)
400 {
401 glcpp_error(& @1, parser, "#elif with no expression");
402 }
403 else if (parser->skip_stack &&
404 parser->skip_stack->has_else)
405 {
406 glcpp_error(& @1, parser, "#elif after #else");
407 }
408 else
409 {
410 _glcpp_parser_skip_stack_change_if (parser, & @1,
411 "elif", 0);
412 glcpp_warning(& @1, parser, "ignoring illegal #elif without expression");
413 }
414 }
415 | HASH_TOKEN ELSE { parser->lexing_directive = 1; } NEWLINE {
416 if (parser->skip_stack &&
417 parser->skip_stack->has_else)
418 {
419 glcpp_error(& @1, parser, "multiple #else");
420 }
421 else
422 {
423 _glcpp_parser_skip_stack_change_if (parser, & @1, "else", 1);
424 if (parser->skip_stack)
425 parser->skip_stack->has_else = true;
426 }
427 }
428 | HASH_TOKEN ENDIF {
429 _glcpp_parser_skip_stack_pop (parser, & @1);
430 } NEWLINE
431 | HASH_TOKEN VERSION_TOKEN version_constant NEWLINE {
432 if (parser->version_set) {
433 glcpp_error(& @1, parser, "#version must appear on the first line");
434 }
435 _glcpp_parser_handle_version_declaration(parser, $3, NULL, true);
436 }
437 | HASH_TOKEN VERSION_TOKEN version_constant IDENTIFIER NEWLINE {
438 if (parser->version_set) {
439 glcpp_error(& @1, parser, "#version must appear on the first line");
440 }
441 _glcpp_parser_handle_version_declaration(parser, $3, $4, true);
442 }
443 | HASH_TOKEN NEWLINE {
444 glcpp_parser_resolve_implicit_version(parser);
445 }
446 | HASH_TOKEN PRAGMA NEWLINE {
447 _mesa_string_buffer_printf(parser->output, "#%s", $2);
448 }
449 ;
450
451 control_line_error:
452 HASH_TOKEN ERROR_TOKEN NEWLINE {
453 glcpp_error(& @1, parser, "#%s", $2);
454 }
455 | HASH_TOKEN DEFINE_TOKEN NEWLINE {
456 glcpp_error (& @1, parser, "#define without macro name");
457 }
458 | HASH_TOKEN GARBAGE pp_tokens NEWLINE {
459 glcpp_error (& @1, parser, "Illegal non-directive after #");
460 }
461 ;
462
463 integer_constant:
464 INTEGER_STRING {
465 /* let strtoll detect the base */
466 $$ = strtoll ($1, NULL, 0);
467 }
468 | INTEGER {
469 $$ = $1;
470 }
471
472 version_constant:
473 INTEGER_STRING {
474 /* Both octal and hexadecimal constants begin with 0. */
475 if ($1[0] == '0' && $1[1] != '\0') {
476 glcpp_error(&@1, parser, "invalid #version \"%s\" (not a decimal constant)", $1);
477 $$ = 0;
478 } else {
479 $$ = strtoll($1, NULL, 10);
480 }
481 }
482
483 expression:
484 integer_constant {
485 $$.value = $1;
486 $$.undefined_macro = NULL;
487 }
488 | IDENTIFIER {
489 $$.value = 0;
490 if (parser->is_gles)
491 $$.undefined_macro = linear_strdup(parser->linalloc, $1);
492 else
493 $$.undefined_macro = NULL;
494 }
495 | expression OR expression {
496 $$.value = $1.value || $3.value;
497
498 /* Short-circuit: Only flag undefined from right side
499 * if left side evaluates to false.
500 */
501 if ($1.undefined_macro)
502 $$.undefined_macro = $1.undefined_macro;
503 else if (! $1.value)
504 $$.undefined_macro = $3.undefined_macro;
505 }
506 | expression AND expression {
507 $$.value = $1.value && $3.value;
508
509 /* Short-circuit: Only flag undefined from right-side
510 * if left side evaluates to true.
511 */
512 if ($1.undefined_macro)
513 $$.undefined_macro = $1.undefined_macro;
514 else if ($1.value)
515 $$.undefined_macro = $3.undefined_macro;
516 }
517 | expression '|' expression {
518 $$.value = $1.value | $3.value;
519 if ($1.undefined_macro)
520 $$.undefined_macro = $1.undefined_macro;
521 else
522 $$.undefined_macro = $3.undefined_macro;
523 }
524 | expression '^' expression {
525 $$.value = $1.value ^ $3.value;
526 if ($1.undefined_macro)
527 $$.undefined_macro = $1.undefined_macro;
528 else
529 $$.undefined_macro = $3.undefined_macro;
530 }
531 | expression '&' expression {
532 $$.value = $1.value & $3.value;
533 if ($1.undefined_macro)
534 $$.undefined_macro = $1.undefined_macro;
535 else
536 $$.undefined_macro = $3.undefined_macro;
537 }
538 | expression NOT_EQUAL expression {
539 $$.value = $1.value != $3.value;
540 if ($1.undefined_macro)
541 $$.undefined_macro = $1.undefined_macro;
542 else
543 $$.undefined_macro = $3.undefined_macro;
544 }
545 | expression EQUAL expression {
546 $$.value = $1.value == $3.value;
547 if ($1.undefined_macro)
548 $$.undefined_macro = $1.undefined_macro;
549 else
550 $$.undefined_macro = $3.undefined_macro;
551 }
552 | expression GREATER_OR_EQUAL expression {
553 $$.value = $1.value >= $3.value;
554 if ($1.undefined_macro)
555 $$.undefined_macro = $1.undefined_macro;
556 else
557 $$.undefined_macro = $3.undefined_macro;
558 }
559 | expression LESS_OR_EQUAL expression {
560 $$.value = $1.value <= $3.value;
561 if ($1.undefined_macro)
562 $$.undefined_macro = $1.undefined_macro;
563 else
564 $$.undefined_macro = $3.undefined_macro;
565 }
566 | expression '>' expression {
567 $$.value = $1.value > $3.value;
568 if ($1.undefined_macro)
569 $$.undefined_macro = $1.undefined_macro;
570 else
571 $$.undefined_macro = $3.undefined_macro;
572 }
573 | expression '<' expression {
574 $$.value = $1.value < $3.value;
575 if ($1.undefined_macro)
576 $$.undefined_macro = $1.undefined_macro;
577 else
578 $$.undefined_macro = $3.undefined_macro;
579 }
580 | expression RIGHT_SHIFT expression {
581 $$.value = $1.value >> $3.value;
582 if ($1.undefined_macro)
583 $$.undefined_macro = $1.undefined_macro;
584 else
585 $$.undefined_macro = $3.undefined_macro;
586 }
587 | expression LEFT_SHIFT expression {
588 $$.value = $1.value << $3.value;
589 if ($1.undefined_macro)
590 $$.undefined_macro = $1.undefined_macro;
591 else
592 $$.undefined_macro = $3.undefined_macro;
593 }
594 | expression '-' expression {
595 $$.value = $1.value - $3.value;
596 if ($1.undefined_macro)
597 $$.undefined_macro = $1.undefined_macro;
598 else
599 $$.undefined_macro = $3.undefined_macro;
600 }
601 | expression '+' expression {
602 $$.value = $1.value + $3.value;
603 if ($1.undefined_macro)
604 $$.undefined_macro = $1.undefined_macro;
605 else
606 $$.undefined_macro = $3.undefined_macro;
607 }
608 | expression '%' expression {
609 if ($3.value == 0) {
610 yyerror (& @1, parser,
611 "zero modulus in preprocessor directive");
612 } else {
613 $$.value = $1.value % $3.value;
614 }
615 if ($1.undefined_macro)
616 $$.undefined_macro = $1.undefined_macro;
617 else
618 $$.undefined_macro = $3.undefined_macro;
619 }
620 | expression '/' expression {
621 if ($3.value == 0) {
622 yyerror (& @1, parser,
623 "division by 0 in preprocessor directive");
624 } else {
625 $$.value = $1.value / $3.value;
626 }
627 if ($1.undefined_macro)
628 $$.undefined_macro = $1.undefined_macro;
629 else
630 $$.undefined_macro = $3.undefined_macro;
631 }
632 | expression '*' expression {
633 $$.value = $1.value * $3.value;
634 if ($1.undefined_macro)
635 $$.undefined_macro = $1.undefined_macro;
636 else
637 $$.undefined_macro = $3.undefined_macro;
638 }
639 | '!' expression %prec UNARY {
640 $$.value = ! $2.value;
641 $$.undefined_macro = $2.undefined_macro;
642 }
643 | '~' expression %prec UNARY {
644 $$.value = ~ $2.value;
645 $$.undefined_macro = $2.undefined_macro;
646 }
647 | '-' expression %prec UNARY {
648 $$.value = - $2.value;
649 $$.undefined_macro = $2.undefined_macro;
650 }
651 | '+' expression %prec UNARY {
652 $$.value = + $2.value;
653 $$.undefined_macro = $2.undefined_macro;
654 }
655 | '(' expression ')' {
656 $$ = $2;
657 }
658 ;
659
660 identifier_list:
661 IDENTIFIER {
662 $$ = _string_list_create (parser);
663 _string_list_append_item (parser, $$, $1);
664 }
665 | identifier_list ',' IDENTIFIER {
666 $$ = $1;
667 _string_list_append_item (parser, $$, $3);
668 }
669 ;
670
671 text_line:
672 NEWLINE { $$ = NULL; }
673 | pp_tokens NEWLINE
674 ;
675
676 replacement_list:
677 /* empty */ { $$ = NULL; }
678 | pp_tokens
679 ;
680
681 junk:
682 /* empty */
683 | pp_tokens {
684 glcpp_error(&@1, parser, "extra tokens at end of directive");
685 }
686 ;
687
688 pp_tokens:
689 preprocessing_token {
690 parser->space_tokens = 1;
691 $$ = _token_list_create (parser);
692 _token_list_append (parser, $$, $1);
693 }
694 | pp_tokens preprocessing_token {
695 $$ = $1;
696 _token_list_append (parser, $$, $2);
697 }
698 ;
699
700 preprocessing_token:
701 IDENTIFIER {
702 $$ = _token_create_str (parser, IDENTIFIER, $1);
703 $$->location = yylloc;
704 }
705 | INTEGER_STRING {
706 $$ = _token_create_str (parser, INTEGER_STRING, $1);
707 $$->location = yylloc;
708 }
709 | operator {
710 $$ = _token_create_ival (parser, $1, $1);
711 $$->location = yylloc;
712 }
713 | DEFINED {
714 $$ = _token_create_ival (parser, DEFINED, DEFINED);
715 $$->location = yylloc;
716 }
717 | OTHER {
718 $$ = _token_create_str (parser, OTHER, $1);
719 $$->location = yylloc;
720 }
721 | SPACE {
722 $$ = _token_create_ival (parser, SPACE, SPACE);
723 $$->location = yylloc;
724 }
725 ;
726
727 operator:
728 '[' { $$ = '['; }
729 | ']' { $$ = ']'; }
730 | '(' { $$ = '('; }
731 | ')' { $$ = ')'; }
732 | '{' { $$ = '{'; }
733 | '}' { $$ = '}'; }
734 | '.' { $$ = '.'; }
735 | '&' { $$ = '&'; }
736 | '*' { $$ = '*'; }
737 | '+' { $$ = '+'; }
738 | '-' { $$ = '-'; }
739 | '~' { $$ = '~'; }
740 | '!' { $$ = '!'; }
741 | '/' { $$ = '/'; }
742 | '%' { $$ = '%'; }
743 | LEFT_SHIFT { $$ = LEFT_SHIFT; }
744 | RIGHT_SHIFT { $$ = RIGHT_SHIFT; }
745 | '<' { $$ = '<'; }
746 | '>' { $$ = '>'; }
747 | LESS_OR_EQUAL { $$ = LESS_OR_EQUAL; }
748 | GREATER_OR_EQUAL { $$ = GREATER_OR_EQUAL; }
749 | EQUAL { $$ = EQUAL; }
750 | NOT_EQUAL { $$ = NOT_EQUAL; }
751 | '^' { $$ = '^'; }
752 | '|' { $$ = '|'; }
753 | AND { $$ = AND; }
754 | OR { $$ = OR; }
755 | ';' { $$ = ';'; }
756 | ',' { $$ = ','; }
757 | '=' { $$ = '='; }
758 | PASTE { $$ = PASTE; }
759 | PLUS_PLUS { $$ = PLUS_PLUS; }
760 | MINUS_MINUS { $$ = MINUS_MINUS; }
761 ;
762
763 %%
764
765 string_list_t *
766 _string_list_create(glcpp_parser_t *parser)
767 {
768 string_list_t *list;
769
770 list = linear_alloc_child(parser->linalloc, sizeof(string_list_t));
771 list->head = NULL;
772 list->tail = NULL;
773
774 return list;
775 }
776
777 void
778 _string_list_append_item(glcpp_parser_t *parser, string_list_t *list,
779 const char *str)
780 {
781 string_node_t *node;
782
783 node = linear_alloc_child(parser->linalloc, sizeof(string_node_t));
784 node->str = linear_strdup(parser->linalloc, str);
785
786 node->next = NULL;
787
788 if (list->head == NULL) {
789 list->head = node;
790 } else {
791 list->tail->next = node;
792 }
793
794 list->tail = node;
795 }
796
797 int
798 _string_list_contains(string_list_t *list, const char *member, int *index)
799 {
800 string_node_t *node;
801 int i;
802
803 if (list == NULL)
804 return 0;
805
806 for (i = 0, node = list->head; node; i++, node = node->next) {
807 if (strcmp (node->str, member) == 0) {
808 if (index)
809 *index = i;
810 return 1;
811 }
812 }
813
814 return 0;
815 }
816
817 /* Return duplicate string in list (if any), NULL otherwise. */
818 const char *
819 _string_list_has_duplicate(string_list_t *list)
820 {
821 string_node_t *node, *dup;
822
823 if (list == NULL)
824 return NULL;
825
826 for (node = list->head; node; node = node->next) {
827 for (dup = node->next; dup; dup = dup->next) {
828 if (strcmp (node->str, dup->str) == 0)
829 return node->str;
830 }
831 }
832
833 return NULL;
834 }
835
836 int
837 _string_list_length(string_list_t *list)
838 {
839 int length = 0;
840 string_node_t *node;
841
842 if (list == NULL)
843 return 0;
844
845 for (node = list->head; node; node = node->next)
846 length++;
847
848 return length;
849 }
850
851 int
852 _string_list_equal(string_list_t *a, string_list_t *b)
853 {
854 string_node_t *node_a, *node_b;
855
856 if (a == NULL && b == NULL)
857 return 1;
858
859 if (a == NULL || b == NULL)
860 return 0;
861
862 for (node_a = a->head, node_b = b->head;
863 node_a && node_b;
864 node_a = node_a->next, node_b = node_b->next)
865 {
866 if (strcmp (node_a->str, node_b->str))
867 return 0;
868 }
869
870 /* Catch the case of lists being different lengths, (which
871 * would cause the loop above to terminate after the shorter
872 * list). */
873 return node_a == node_b;
874 }
875
876 argument_list_t *
877 _argument_list_create(glcpp_parser_t *parser)
878 {
879 argument_list_t *list;
880
881 list = linear_alloc_child(parser->linalloc, sizeof(argument_list_t));
882 list->head = NULL;
883 list->tail = NULL;
884
885 return list;
886 }
887
888 void
889 _argument_list_append(glcpp_parser_t *parser,
890 argument_list_t *list, token_list_t *argument)
891 {
892 argument_node_t *node;
893
894 node = linear_alloc_child(parser->linalloc, sizeof(argument_node_t));
895 node->argument = argument;
896
897 node->next = NULL;
898
899 if (list->head == NULL) {
900 list->head = node;
901 } else {
902 list->tail->next = node;
903 }
904
905 list->tail = node;
906 }
907
908 int
909 _argument_list_length(argument_list_t *list)
910 {
911 int length = 0;
912 argument_node_t *node;
913
914 if (list == NULL)
915 return 0;
916
917 for (node = list->head; node; node = node->next)
918 length++;
919
920 return length;
921 }
922
923 token_list_t *
924 _argument_list_member_at(argument_list_t *list, int index)
925 {
926 argument_node_t *node;
927 int i;
928
929 if (list == NULL)
930 return NULL;
931
932 node = list->head;
933 for (i = 0; i < index; i++) {
934 node = node->next;
935 if (node == NULL)
936 break;
937 }
938
939 if (node)
940 return node->argument;
941
942 return NULL;
943 }
944
945 token_t *
946 _token_create_str(glcpp_parser_t *parser, int type, char *str)
947 {
948 token_t *token;
949
950 token = linear_alloc_child(parser->linalloc, sizeof(token_t));
951 token->type = type;
952 token->value.str = str;
953
954 return token;
955 }
956
957 token_t *
958 _token_create_ival(glcpp_parser_t *parser, int type, int ival)
959 {
960 token_t *token;
961
962 token = linear_alloc_child(parser->linalloc, sizeof(token_t));
963 token->type = type;
964 token->value.ival = ival;
965
966 return token;
967 }
968
969 token_list_t *
970 _token_list_create(glcpp_parser_t *parser)
971 {
972 token_list_t *list;
973
974 list = linear_alloc_child(parser->linalloc, sizeof(token_list_t));
975 list->head = NULL;
976 list->tail = NULL;
977 list->non_space_tail = NULL;
978
979 return list;
980 }
981
982 void
983 _token_list_append(glcpp_parser_t *parser, token_list_t *list, token_t *token)
984 {
985 token_node_t *node;
986
987 node = linear_alloc_child(parser->linalloc, sizeof(token_node_t));
988 node->token = token;
989 node->next = NULL;
990
991 if (list->head == NULL) {
992 list->head = node;
993 } else {
994 list->tail->next = node;
995 }
996
997 list->tail = node;
998 if (token->type != SPACE)
999 list->non_space_tail = node;
1000 }
1001
1002 void
1003 _token_list_append_list(token_list_t *list, token_list_t *tail)
1004 {
1005 if (tail == NULL || tail->head == NULL)
1006 return;
1007
1008 if (list->head == NULL) {
1009 list->head = tail->head;
1010 } else {
1011 list->tail->next = tail->head;
1012 }
1013
1014 list->tail = tail->tail;
1015 list->non_space_tail = tail->non_space_tail;
1016 }
1017
1018 static token_list_t *
1019 _token_list_copy(glcpp_parser_t *parser, token_list_t *other)
1020 {
1021 token_list_t *copy;
1022 token_node_t *node;
1023
1024 if (other == NULL)
1025 return NULL;
1026
1027 copy = _token_list_create (parser);
1028 for (node = other->head; node; node = node->next) {
1029 token_t *new_token = linear_alloc_child(parser->linalloc, sizeof(token_t));
1030 *new_token = *node->token;
1031 _token_list_append (parser, copy, new_token);
1032 }
1033
1034 return copy;
1035 }
1036
1037 static void
1038 _token_list_trim_trailing_space(token_list_t *list)
1039 {
1040 if (list->non_space_tail) {
1041 list->non_space_tail->next = NULL;
1042 list->tail = list->non_space_tail;
1043 }
1044 }
1045
1046 static int
1047 _token_list_is_empty_ignoring_space(token_list_t *l)
1048 {
1049 token_node_t *n;
1050
1051 if (l == NULL)
1052 return 1;
1053
1054 n = l->head;
1055 while (n != NULL && n->token->type == SPACE)
1056 n = n->next;
1057
1058 return n == NULL;
1059 }
1060
1061 int
1062 _token_list_equal_ignoring_space(token_list_t *a, token_list_t *b)
1063 {
1064 token_node_t *node_a, *node_b;
1065
1066 if (a == NULL || b == NULL) {
1067 int a_empty = _token_list_is_empty_ignoring_space(a);
1068 int b_empty = _token_list_is_empty_ignoring_space(b);
1069 return a_empty == b_empty;
1070 }
1071
1072 node_a = a->head;
1073 node_b = b->head;
1074
1075 while (1)
1076 {
1077 if (node_a == NULL && node_b == NULL)
1078 break;
1079
1080 /* Ignore trailing whitespace */
1081 if (node_a == NULL && node_b->token->type == SPACE) {
1082 while (node_b && node_b->token->type == SPACE)
1083 node_b = node_b->next;
1084 }
1085
1086 if (node_b == NULL && node_a->token->type == SPACE) {
1087 while (node_a && node_a->token->type == SPACE)
1088 node_a = node_a->next;
1089 }
1090
1091 if (node_a == NULL && node_b == NULL)
1092 break;
1093
1094 if (node_a == NULL || node_b == NULL)
1095 return 0;
1096 /* Make sure whitespace appears in the same places in both.
1097 * It need not be exactly the same amount of whitespace,
1098 * though.
1099 */
1100 if (node_a->token->type == SPACE && node_b->token->type == SPACE) {
1101 while (node_a && node_a->token->type == SPACE)
1102 node_a = node_a->next;
1103 while (node_b && node_b->token->type == SPACE)
1104 node_b = node_b->next;
1105 continue;
1106 }
1107
1108 if (node_a->token->type != node_b->token->type)
1109 return 0;
1110
1111 switch (node_a->token->type) {
1112 case INTEGER:
1113 if (node_a->token->value.ival != node_b->token->value.ival) {
1114 return 0;
1115 }
1116 break;
1117 case IDENTIFIER:
1118 case INTEGER_STRING:
1119 case OTHER:
1120 if (strcmp(node_a->token->value.str, node_b->token->value.str)) {
1121 return 0;
1122 }
1123 break;
1124 }
1125
1126 node_a = node_a->next;
1127 node_b = node_b->next;
1128 }
1129
1130 return 1;
1131 }
1132
1133 static void
1134 _token_print(struct _mesa_string_buffer *out, token_t *token)
1135 {
1136 if (token->type < 256) {
1137 _mesa_string_buffer_append_char(out, token->type);
1138 return;
1139 }
1140
1141 switch (token->type) {
1142 case INTEGER:
1143 _mesa_string_buffer_printf(out, "%" PRIiMAX, token->value.ival);
1144 break;
1145 case IDENTIFIER:
1146 case INTEGER_STRING:
1147 case OTHER:
1148 _mesa_string_buffer_append(out, token->value.str);
1149 break;
1150 case SPACE:
1151 _mesa_string_buffer_append_char(out, ' ');
1152 break;
1153 case LEFT_SHIFT:
1154 _mesa_string_buffer_append(out, "<<");
1155 break;
1156 case RIGHT_SHIFT:
1157 _mesa_string_buffer_append(out, ">>");
1158 break;
1159 case LESS_OR_EQUAL:
1160 _mesa_string_buffer_append(out, "<=");
1161 break;
1162 case GREATER_OR_EQUAL:
1163 _mesa_string_buffer_append(out, ">=");
1164 break;
1165 case EQUAL:
1166 _mesa_string_buffer_append(out, "==");
1167 break;
1168 case NOT_EQUAL:
1169 _mesa_string_buffer_append(out, "!=");
1170 break;
1171 case AND:
1172 _mesa_string_buffer_append(out, "&&");
1173 break;
1174 case OR:
1175 _mesa_string_buffer_append(out, "||");
1176 break;
1177 case PASTE:
1178 _mesa_string_buffer_append(out, "##");
1179 break;
1180 case PLUS_PLUS:
1181 _mesa_string_buffer_append(out, "++");
1182 break;
1183 case MINUS_MINUS:
1184 _mesa_string_buffer_append(out, "--");
1185 break;
1186 case DEFINED:
1187 _mesa_string_buffer_append(out, "defined");
1188 break;
1189 case PLACEHOLDER:
1190 /* Nothing to print. */
1191 break;
1192 default:
1193 assert(!"Error: Don't know how to print token.");
1194
1195 break;
1196 }
1197 }
1198
1199 /* Return a new token formed by pasting 'token' and 'other'. Note that this
1200 * function may return 'token' or 'other' directly rather than allocating
1201 * anything new.
1202 *
1203 * Caution: Only very cursory error-checking is performed to see if
1204 * the final result is a valid single token. */
1205 static token_t *
1206 _token_paste(glcpp_parser_t *parser, token_t *token, token_t *other)
1207 {
1208 token_t *combined = NULL;
1209
1210 /* Pasting a placeholder onto anything makes no change. */
1211 if (other->type == PLACEHOLDER)
1212 return token;
1213
1214 /* When 'token' is a placeholder, just return 'other'. */
1215 if (token->type == PLACEHOLDER)
1216 return other;
1217
1218 /* A very few single-character punctuators can be combined
1219 * with another to form a multi-character punctuator. */
1220 switch (token->type) {
1221 case '<':
1222 if (other->type == '<')
1223 combined = _token_create_ival (parser, LEFT_SHIFT, LEFT_SHIFT);
1224 else if (other->type == '=')
1225 combined = _token_create_ival (parser, LESS_OR_EQUAL, LESS_OR_EQUAL);
1226 break;
1227 case '>':
1228 if (other->type == '>')
1229 combined = _token_create_ival (parser, RIGHT_SHIFT, RIGHT_SHIFT);
1230 else if (other->type == '=')
1231 combined = _token_create_ival (parser, GREATER_OR_EQUAL, GREATER_OR_EQUAL);
1232 break;
1233 case '=':
1234 if (other->type == '=')
1235 combined = _token_create_ival (parser, EQUAL, EQUAL);
1236 break;
1237 case '!':
1238 if (other->type == '=')
1239 combined = _token_create_ival (parser, NOT_EQUAL, NOT_EQUAL);
1240 break;
1241 case '&':
1242 if (other->type == '&')
1243 combined = _token_create_ival (parser, AND, AND);
1244 break;
1245 case '|':
1246 if (other->type == '|')
1247 combined = _token_create_ival (parser, OR, OR);
1248 break;
1249 }
1250
1251 if (combined != NULL) {
1252 /* Inherit the location from the first token */
1253 combined->location = token->location;
1254 return combined;
1255 }
1256
1257 /* Two string-valued (or integer) tokens can usually just be
1258 * mashed together. (We also handle a string followed by an
1259 * integer here as well.)
1260 *
1261 * There are some exceptions here. Notably, if the first token
1262 * is an integer (or a string representing an integer), then
1263 * the second token must also be an integer or must be a
1264 * string representing an integer that begins with a digit.
1265 */
1266 if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING || token->type == INTEGER) &&
1267 (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING || other->type == INTEGER))
1268 {
1269 char *str;
1270 int combined_type;
1271
1272 /* Check that pasting onto an integer doesn't create a
1273 * non-integer, (that is, only digits can be
1274 * pasted. */
1275 if (token->type == INTEGER_STRING || token->type == INTEGER) {
1276 switch (other->type) {
1277 case INTEGER_STRING:
1278 if (other->value.str[0] < '0' || other->value.str[0] > '9')
1279 goto FAIL;
1280 break;
1281 case INTEGER:
1282 if (other->value.ival < 0)
1283 goto FAIL;
1284 break;
1285 default:
1286 goto FAIL;
1287 }
1288 }
1289
1290 if (token->type == INTEGER)
1291 str = linear_asprintf(parser->linalloc, "%" PRIiMAX, token->value.ival);
1292 else
1293 str = linear_strdup(parser->linalloc, token->value.str);
1294
1295 if (other->type == INTEGER)
1296 linear_asprintf_append(parser->linalloc, &str, "%" PRIiMAX, other->value.ival);
1297 else
1298 linear_strcat(parser->linalloc, &str, other->value.str);
1299
1300 /* New token is same type as original token, unless we
1301 * started with an integer, in which case we will be
1302 * creating an integer-string. */
1303 combined_type = token->type;
1304 if (combined_type == INTEGER)
1305 combined_type = INTEGER_STRING;
1306
1307 combined = _token_create_str (parser, combined_type, str);
1308 combined->location = token->location;
1309 return combined;
1310 }
1311
1312 FAIL:
1313 glcpp_error (&token->location, parser, "");
1314 _mesa_string_buffer_append(parser->info_log, "Pasting \"");
1315 _token_print(parser->info_log, token);
1316 _mesa_string_buffer_append(parser->info_log, "\" and \"");
1317 _token_print(parser->info_log, other);
1318 _mesa_string_buffer_append(parser->info_log, "\" does not give a valid preprocessing token.\n");
1319
1320 return token;
1321 }
1322
1323 static void
1324 _token_list_print(glcpp_parser_t *parser, token_list_t *list)
1325 {
1326 token_node_t *node;
1327
1328 if (list == NULL)
1329 return;
1330
1331 for (node = list->head; node; node = node->next)
1332 _token_print(parser->output, node->token);
1333 }
1334
1335 void
1336 yyerror(YYLTYPE *locp, glcpp_parser_t *parser, const char *error)
1337 {
1338 glcpp_error(locp, parser, "%s", error);
1339 }
1340
1341 static void
1342 add_builtin_define(glcpp_parser_t *parser, const char *name, int value)
1343 {
1344 token_t *tok;
1345 token_list_t *list;
1346
1347 tok = _token_create_ival (parser, INTEGER, value);
1348
1349 list = _token_list_create(parser);
1350 _token_list_append(parser, list, tok);
1351 _define_object_macro(parser, NULL, name, list);
1352 }
1353
1354 /* Initial output buffer size, 4096 minus ralloc() overhead. It was selected
1355 * to minimize total amount of allocated memory during shader-db run.
1356 */
1357 #define INITIAL_PP_OUTPUT_BUF_SIZE 4048
1358
1359 glcpp_parser_t *
1360 glcpp_parser_create(const struct gl_extensions *extension_list,
1361 glcpp_extension_iterator extensions, void *state, gl_api api)
1362 {
1363 glcpp_parser_t *parser;
1364
1365 parser = ralloc (NULL, glcpp_parser_t);
1366
1367 glcpp_lex_init_extra (parser, &parser->scanner);
1368 parser->defines = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
1369 _mesa_key_string_equal);
1370 parser->linalloc = linear_alloc_parent(parser, 0);
1371 parser->active = NULL;
1372 parser->lexing_directive = 0;
1373 parser->lexing_version_directive = 0;
1374 parser->space_tokens = 1;
1375 parser->last_token_was_newline = 0;
1376 parser->last_token_was_space = 0;
1377 parser->first_non_space_token_this_line = 1;
1378 parser->newline_as_space = 0;
1379 parser->in_control_line = 0;
1380 parser->paren_count = 0;
1381 parser->commented_newlines = 0;
1382
1383 parser->skip_stack = NULL;
1384 parser->skipping = 0;
1385
1386 parser->lex_from_list = NULL;
1387 parser->lex_from_node = NULL;
1388
1389 parser->output = _mesa_string_buffer_create(parser,
1390 INITIAL_PP_OUTPUT_BUF_SIZE);
1391 parser->info_log = _mesa_string_buffer_create(parser,
1392 INITIAL_PP_OUTPUT_BUF_SIZE);
1393 parser->error = 0;
1394
1395 parser->extensions = extensions;
1396 parser->extension_list = extension_list;
1397 parser->state = state;
1398 parser->api = api;
1399 parser->version = 0;
1400 parser->version_set = false;
1401
1402 parser->has_new_line_number = 0;
1403 parser->new_line_number = 1;
1404 parser->has_new_source_number = 0;
1405 parser->new_source_number = 0;
1406
1407 parser->is_gles = false;
1408
1409 return parser;
1410 }
1411
1412 void
1413 glcpp_parser_destroy(glcpp_parser_t *parser)
1414 {
1415 glcpp_lex_destroy (parser->scanner);
1416 _mesa_hash_table_destroy(parser->defines, NULL);
1417 ralloc_free (parser);
1418 }
1419
1420 typedef enum function_status
1421 {
1422 FUNCTION_STATUS_SUCCESS,
1423 FUNCTION_NOT_A_FUNCTION,
1424 FUNCTION_UNBALANCED_PARENTHESES
1425 } function_status_t;
1426
1427 /* Find a set of function-like macro arguments by looking for a
1428 * balanced set of parentheses.
1429 *
1430 * When called, 'node' should be the opening-parenthesis token, (or
1431 * perhaps preceeding SPACE tokens). Upon successful return *last will
1432 * be the last consumed node, (corresponding to the closing right
1433 * parenthesis).
1434 *
1435 * Return values:
1436 *
1437 * FUNCTION_STATUS_SUCCESS:
1438 *
1439 * Successfully parsed a set of function arguments.
1440 *
1441 * FUNCTION_NOT_A_FUNCTION:
1442 *
1443 * Macro name not followed by a '('. This is not an error, but
1444 * simply that the macro name should be treated as a non-macro.
1445 *
1446 * FUNCTION_UNBALANCED_PARENTHESES
1447 *
1448 * Macro name is not followed by a balanced set of parentheses.
1449 */
1450 static function_status_t
1451 _arguments_parse(glcpp_parser_t *parser,
1452 argument_list_t *arguments, token_node_t *node,
1453 token_node_t **last)
1454 {
1455 token_list_t *argument;
1456 int paren_count;
1457
1458 node = node->next;
1459
1460 /* Ignore whitespace before first parenthesis. */
1461 while (node && node->token->type == SPACE)
1462 node = node->next;
1463
1464 if (node == NULL || node->token->type != '(')
1465 return FUNCTION_NOT_A_FUNCTION;
1466
1467 node = node->next;
1468
1469 argument = _token_list_create (parser);
1470 _argument_list_append (parser, arguments, argument);
1471
1472 for (paren_count = 1; node; node = node->next) {
1473 if (node->token->type == '(') {
1474 paren_count++;
1475 } else if (node->token->type == ')') {
1476 paren_count--;
1477 if (paren_count == 0)
1478 break;
1479 }
1480
1481 if (node->token->type == ',' && paren_count == 1) {
1482 _token_list_trim_trailing_space (argument);
1483 argument = _token_list_create (parser);
1484 _argument_list_append (parser, arguments, argument);
1485 } else {
1486 if (argument->head == NULL) {
1487 /* Don't treat initial whitespace as part of the argument. */
1488 if (node->token->type == SPACE)
1489 continue;
1490 }
1491 _token_list_append(parser, argument, node->token);
1492 }
1493 }
1494
1495 if (paren_count)
1496 return FUNCTION_UNBALANCED_PARENTHESES;
1497
1498 *last = node;
1499
1500 return FUNCTION_STATUS_SUCCESS;
1501 }
1502
1503 static token_list_t *
1504 _token_list_create_with_one_ival(glcpp_parser_t *parser, int type, int ival)
1505 {
1506 token_list_t *list;
1507 token_t *node;
1508
1509 list = _token_list_create(parser);
1510 node = _token_create_ival(parser, type, ival);
1511 _token_list_append(parser, list, node);
1512
1513 return list;
1514 }
1515
1516 static token_list_t *
1517 _token_list_create_with_one_space(glcpp_parser_t *parser)
1518 {
1519 return _token_list_create_with_one_ival(parser, SPACE, SPACE);
1520 }
1521
1522 static token_list_t *
1523 _token_list_create_with_one_integer(glcpp_parser_t *parser, int ival)
1524 {
1525 return _token_list_create_with_one_ival(parser, INTEGER, ival);
1526 }
1527
1528 /* Evaluate a DEFINED token node (based on subsequent tokens in the list).
1529 *
1530 * Note: This function must only be called when "node" is a DEFINED token,
1531 * (and will abort with an assertion failure otherwise).
1532 *
1533 * If "node" is followed, (ignoring any SPACE tokens), by an IDENTIFIER token
1534 * (optionally preceded and followed by '(' and ')' tokens) then the following
1535 * occurs:
1536 *
1537 * If the identifier is a defined macro, this function returns 1.
1538 *
1539 * If the identifier is not a defined macro, this function returns 0.
1540 *
1541 * In either case, *last will be updated to the last node in the list
1542 * consumed by the evaluation, (either the token of the identifier or the
1543 * token of the closing parenthesis).
1544 *
1545 * In all other cases, (such as "node is the final node of the list", or
1546 * "missing closing parenthesis", etc.), this function generates a
1547 * preprocessor error, returns -1 and *last will not be set.
1548 */
1549 static int
1550 _glcpp_parser_evaluate_defined(glcpp_parser_t *parser, token_node_t *node,
1551 token_node_t **last)
1552 {
1553 token_node_t *argument, *defined = node;
1554
1555 assert(node->token->type == DEFINED);
1556
1557 node = node->next;
1558
1559 /* Ignore whitespace after DEFINED token. */
1560 while (node && node->token->type == SPACE)
1561 node = node->next;
1562
1563 if (node == NULL)
1564 goto FAIL;
1565
1566 if (node->token->type == IDENTIFIER || node->token->type == OTHER) {
1567 argument = node;
1568 } else if (node->token->type == '(') {
1569 node = node->next;
1570
1571 /* Ignore whitespace after '(' token. */
1572 while (node && node->token->type == SPACE)
1573 node = node->next;
1574
1575 if (node == NULL || (node->token->type != IDENTIFIER &&
1576 node->token->type != OTHER)) {
1577 goto FAIL;
1578 }
1579
1580 argument = node;
1581
1582 node = node->next;
1583
1584 /* Ignore whitespace after identifier, before ')' token. */
1585 while (node && node->token->type == SPACE)
1586 node = node->next;
1587
1588 if (node == NULL || node->token->type != ')')
1589 goto FAIL;
1590 } else {
1591 goto FAIL;
1592 }
1593
1594 *last = node;
1595
1596 return _mesa_hash_table_search(parser->defines,
1597 argument->token->value.str) ? 1 : 0;
1598
1599 FAIL:
1600 glcpp_error (&defined->token->location, parser,
1601 "\"defined\" not followed by an identifier");
1602 return -1;
1603 }
1604
1605 /* Evaluate all DEFINED nodes in a given list, modifying the list in place.
1606 */
1607 static void
1608 _glcpp_parser_evaluate_defined_in_list(glcpp_parser_t *parser,
1609 token_list_t *list)
1610 {
1611 token_node_t *node, *node_prev, *replacement, *last = NULL;
1612 int value;
1613
1614 if (list == NULL)
1615 return;
1616
1617 node_prev = NULL;
1618 node = list->head;
1619
1620 while (node) {
1621
1622 if (node->token->type != DEFINED)
1623 goto NEXT;
1624
1625 value = _glcpp_parser_evaluate_defined (parser, node, &last);
1626 if (value == -1)
1627 goto NEXT;
1628
1629 replacement = linear_alloc_child(parser->linalloc, sizeof(token_node_t));
1630 replacement->token = _token_create_ival (parser, INTEGER, value);
1631
1632 /* Splice replacement node into list, replacing from "node"
1633 * through "last". */
1634 if (node_prev)
1635 node_prev->next = replacement;
1636 else
1637 list->head = replacement;
1638 replacement->next = last->next;
1639 if (last == list->tail)
1640 list->tail = replacement;
1641
1642 node = replacement;
1643
1644 NEXT:
1645 node_prev = node;
1646 node = node->next;
1647 }
1648 }
1649
1650 /* Perform macro expansion on 'list', placing the resulting tokens
1651 * into a new list which is initialized with a first token of type
1652 * 'head_token_type'. Then begin lexing from the resulting list,
1653 * (return to the current lexing source when this list is exhausted).
1654 *
1655 * See the documentation of _glcpp_parser_expand_token_list for a description
1656 * of the "mode" parameter.
1657 */
1658 static void
1659 _glcpp_parser_expand_and_lex_from(glcpp_parser_t *parser, int head_token_type,
1660 token_list_t *list, expansion_mode_t mode)
1661 {
1662 token_list_t *expanded;
1663 token_t *token;
1664
1665 expanded = _token_list_create (parser);
1666 token = _token_create_ival (parser, head_token_type, head_token_type);
1667 _token_list_append (parser, expanded, token);
1668 _glcpp_parser_expand_token_list (parser, list, mode);
1669 _token_list_append_list (expanded, list);
1670 glcpp_parser_lex_from (parser, expanded);
1671 }
1672
1673 static void
1674 _glcpp_parser_apply_pastes(glcpp_parser_t *parser, token_list_t *list)
1675 {
1676 token_node_t *node;
1677
1678 node = list->head;
1679 while (node) {
1680 token_node_t *next_non_space;
1681
1682 /* Look ahead for a PASTE token, skipping space. */
1683 next_non_space = node->next;
1684 while (next_non_space && next_non_space->token->type == SPACE)
1685 next_non_space = next_non_space->next;
1686
1687 if (next_non_space == NULL)
1688 break;
1689
1690 if (next_non_space->token->type != PASTE) {
1691 node = next_non_space;
1692 continue;
1693 }
1694
1695 /* Now find the next non-space token after the PASTE. */
1696 next_non_space = next_non_space->next;
1697 while (next_non_space && next_non_space->token->type == SPACE)
1698 next_non_space = next_non_space->next;
1699
1700 if (next_non_space == NULL) {
1701 yyerror(&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n");
1702 return;
1703 }
1704
1705 node->token = _token_paste(parser, node->token, next_non_space->token);
1706 node->next = next_non_space->next;
1707 if (next_non_space == list->tail)
1708 list->tail = node;
1709 }
1710
1711 list->non_space_tail = list->tail;
1712 }
1713
1714 /* This is a helper function that's essentially part of the
1715 * implementation of _glcpp_parser_expand_node. It shouldn't be called
1716 * except for by that function.
1717 *
1718 * Returns NULL if node is a simple token with no expansion, (that is,
1719 * although 'node' corresponds to an identifier defined as a
1720 * function-like macro, it is not followed with a parenthesized
1721 * argument list).
1722 *
1723 * Compute the complete expansion of node (which is a function-like
1724 * macro) and subsequent nodes which are arguments.
1725 *
1726 * Returns the token list that results from the expansion and sets
1727 * *last to the last node in the list that was consumed by the
1728 * expansion. Specifically, *last will be set as follows: as the
1729 * token of the closing right parenthesis.
1730 *
1731 * See the documentation of _glcpp_parser_expand_token_list for a description
1732 * of the "mode" parameter.
1733 */
1734 static token_list_t *
1735 _glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node,
1736 token_node_t **last, expansion_mode_t mode)
1737 {
1738 struct hash_entry *entry;
1739 macro_t *macro;
1740 const char *identifier;
1741 argument_list_t *arguments;
1742 function_status_t status;
1743 token_list_t *substituted;
1744 int parameter_index;
1745
1746 identifier = node->token->value.str;
1747
1748 entry = _mesa_hash_table_search(parser->defines, identifier);
1749 macro = entry ? entry->data : NULL;
1750
1751 assert(macro->is_function);
1752
1753 arguments = _argument_list_create(parser);
1754 status = _arguments_parse(parser, arguments, node, last);
1755
1756 switch (status) {
1757 case FUNCTION_STATUS_SUCCESS:
1758 break;
1759 case FUNCTION_NOT_A_FUNCTION:
1760 return NULL;
1761 case FUNCTION_UNBALANCED_PARENTHESES:
1762 glcpp_error(&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier);
1763 return NULL;
1764 }
1765
1766 /* Replace a macro defined as empty with a SPACE token. */
1767 if (macro->replacements == NULL) {
1768 return _token_list_create_with_one_space(parser);
1769 }
1770
1771 if (!((_argument_list_length (arguments) ==
1772 _string_list_length (macro->parameters)) ||
1773 (_string_list_length (macro->parameters) == 0 &&
1774 _argument_list_length (arguments) == 1 &&
1775 arguments->head->argument->head == NULL))) {
1776 glcpp_error(&node->token->location, parser,
1777 "Error: macro %s invoked with %d arguments (expected %d)\n",
1778 identifier, _argument_list_length (arguments),
1779 _string_list_length(macro->parameters));
1780 return NULL;
1781 }
1782
1783 /* Perform argument substitution on the replacement list. */
1784 substituted = _token_list_create(parser);
1785
1786 for (node = macro->replacements->head; node; node = node->next) {
1787 if (node->token->type == IDENTIFIER &&
1788 _string_list_contains(macro->parameters, node->token->value.str,
1789 &parameter_index)) {
1790 token_list_t *argument;
1791 argument = _argument_list_member_at(arguments, parameter_index);
1792 /* Before substituting, we expand the argument tokens, or append a
1793 * placeholder token for an empty argument. */
1794 if (argument->head) {
1795 token_list_t *expanded_argument;
1796 expanded_argument = _token_list_copy(parser, argument);
1797 _glcpp_parser_expand_token_list(parser, expanded_argument, mode);
1798 _token_list_append_list(substituted, expanded_argument);
1799 } else {
1800 token_t *new_token;
1801
1802 new_token = _token_create_ival(parser, PLACEHOLDER,
1803 PLACEHOLDER);
1804 _token_list_append(parser, substituted, new_token);
1805 }
1806 } else {
1807 _token_list_append(parser, substituted, node->token);
1808 }
1809 }
1810
1811 /* After argument substitution, and before further expansion
1812 * below, implement token pasting. */
1813
1814 _token_list_trim_trailing_space(substituted);
1815
1816 _glcpp_parser_apply_pastes(parser, substituted);
1817
1818 return substituted;
1819 }
1820
1821 /* Compute the complete expansion of node, (and subsequent nodes after
1822 * 'node' in the case that 'node' is a function-like macro and
1823 * subsequent nodes are arguments).
1824 *
1825 * Returns NULL if node is a simple token with no expansion.
1826 *
1827 * Otherwise, returns the token list that results from the expansion
1828 * and sets *last to the last node in the list that was consumed by
1829 * the expansion. Specifically, *last will be set as follows:
1830 *
1831 * As 'node' in the case of object-like macro expansion.
1832 *
1833 * As the token of the closing right parenthesis in the case of
1834 * function-like macro expansion.
1835 *
1836 * See the documentation of _glcpp_parser_expand_token_list for a description
1837 * of the "mode" parameter.
1838 */
1839 static token_list_t *
1840 _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node,
1841 token_node_t **last, expansion_mode_t mode)
1842 {
1843 token_t *token = node->token;
1844 const char *identifier;
1845 struct hash_entry *entry;
1846 macro_t *macro;
1847
1848 /* We only expand identifiers */
1849 if (token->type != IDENTIFIER) {
1850 return NULL;
1851 }
1852
1853 *last = node;
1854 identifier = token->value.str;
1855
1856 /* Special handling for __LINE__ and __FILE__, (not through
1857 * the hash table). */
1858 if (*identifier == '_') {
1859 if (strcmp(identifier, "__LINE__") == 0)
1860 return _token_list_create_with_one_integer(parser,
1861 node->token->location.first_line);
1862
1863 if (strcmp(identifier, "__FILE__") == 0)
1864 return _token_list_create_with_one_integer(parser,
1865 node->token->location.source);
1866 }
1867
1868 /* Look up this identifier in the hash table. */
1869 entry = _mesa_hash_table_search(parser->defines, identifier);
1870 macro = entry ? entry->data : NULL;
1871
1872 /* Not a macro, so no expansion needed. */
1873 if (macro == NULL)
1874 return NULL;
1875
1876 /* Finally, don't expand this macro if we're already actively
1877 * expanding it, (to avoid infinite recursion). */
1878 if (_parser_active_list_contains (parser, identifier)) {
1879 /* We change the token type here from IDENTIFIER to OTHER to prevent any
1880 * future expansion of this unexpanded token. */
1881 char *str;
1882 token_list_t *expansion;
1883 token_t *final;
1884
1885 str = linear_strdup(parser->linalloc, token->value.str);
1886 final = _token_create_str(parser, OTHER, str);
1887 expansion = _token_list_create(parser);
1888 _token_list_append(parser, expansion, final);
1889 return expansion;
1890 }
1891
1892 if (! macro->is_function) {
1893 token_list_t *replacement;
1894
1895 /* Replace a macro defined as empty with a SPACE token. */
1896 if (macro->replacements == NULL)
1897 return _token_list_create_with_one_space(parser);
1898
1899 replacement = _token_list_copy(parser, macro->replacements);
1900 _glcpp_parser_apply_pastes(parser, replacement);
1901 return replacement;
1902 }
1903
1904 return _glcpp_parser_expand_function(parser, node, last, mode);
1905 }
1906
1907 /* Push a new identifier onto the parser's active list.
1908 *
1909 * Here, 'marker' is the token node that appears in the list after the
1910 * expansion of 'identifier'. That is, when the list iterator begins
1911 * examining 'marker', then it is time to pop this node from the
1912 * active stack.
1913 */
1914 static void
1915 _parser_active_list_push(glcpp_parser_t *parser, const char *identifier,
1916 token_node_t *marker)
1917 {
1918 active_list_t *node;
1919
1920 node = linear_alloc_child(parser->linalloc, sizeof(active_list_t));
1921 node->identifier = linear_strdup(parser->linalloc, identifier);
1922 node->marker = marker;
1923 node->next = parser->active;
1924
1925 parser->active = node;
1926 }
1927
1928 static void
1929 _parser_active_list_pop(glcpp_parser_t *parser)
1930 {
1931 active_list_t *node = parser->active;
1932
1933 if (node == NULL) {
1934 parser->active = NULL;
1935 return;
1936 }
1937
1938 node = parser->active->next;
1939 parser->active = node;
1940 }
1941
1942 static int
1943 _parser_active_list_contains(glcpp_parser_t *parser, const char *identifier)
1944 {
1945 active_list_t *node;
1946
1947 if (parser->active == NULL)
1948 return 0;
1949
1950 for (node = parser->active; node; node = node->next)
1951 if (strcmp(node->identifier, identifier) == 0)
1952 return 1;
1953
1954 return 0;
1955 }
1956
1957 /* Walk over the token list replacing nodes with their expansion.
1958 * Whenever nodes are expanded the walking will walk over the new
1959 * nodes, continuing to expand as necessary. The results are placed in
1960 * 'list' itself.
1961 *
1962 * The "mode" argument controls the handling of any DEFINED tokens that
1963 * result from expansion as follows:
1964 *
1965 * EXPANSION_MODE_IGNORE_DEFINED: Any resulting DEFINED tokens will be
1966 * left in the final list, unevaluated. This is the correct mode
1967 * for expanding any list in any context other than a
1968 * preprocessor conditional, (#if or #elif).
1969 *
1970 * EXPANSION_MODE_EVALUATE_DEFINED: Any resulting DEFINED tokens will be
1971 * evaluated to 0 or 1 tokens depending on whether the following
1972 * token is the name of a defined macro. If the DEFINED token is
1973 * not followed by an (optionally parenthesized) identifier, then
1974 * an error will be generated. This the correct mode for
1975 * expanding any list in the context of a preprocessor
1976 * conditional, (#if or #elif).
1977 */
1978 static void
1979 _glcpp_parser_expand_token_list(glcpp_parser_t *parser, token_list_t *list,
1980 expansion_mode_t mode)
1981 {
1982 token_node_t *node_prev;
1983 token_node_t *node, *last = NULL;
1984 token_list_t *expansion;
1985 active_list_t *active_initial = parser->active;
1986
1987 if (list == NULL)
1988 return;
1989
1990 _token_list_trim_trailing_space (list);
1991
1992 node_prev = NULL;
1993 node = list->head;
1994
1995 if (mode == EXPANSION_MODE_EVALUATE_DEFINED)
1996 _glcpp_parser_evaluate_defined_in_list (parser, list);
1997
1998 while (node) {
1999
2000 while (parser->active && parser->active->marker == node)
2001 _parser_active_list_pop (parser);
2002
2003 expansion = _glcpp_parser_expand_node (parser, node, &last, mode);
2004 if (expansion) {
2005 token_node_t *n;
2006
2007 if (mode == EXPANSION_MODE_EVALUATE_DEFINED) {
2008 _glcpp_parser_evaluate_defined_in_list (parser, expansion);
2009 }
2010
2011 for (n = node; n != last->next; n = n->next)
2012 while (parser->active && parser->active->marker == n) {
2013 _parser_active_list_pop (parser);
2014 }
2015
2016 _parser_active_list_push(parser, node->token->value.str, last->next);
2017
2018 /* Splice expansion into list, supporting a simple deletion if the
2019 * expansion is empty.
2020 */
2021 if (expansion->head) {
2022 if (node_prev)
2023 node_prev->next = expansion->head;
2024 else
2025 list->head = expansion->head;
2026 expansion->tail->next = last->next;
2027 if (last == list->tail)
2028 list->tail = expansion->tail;
2029 } else {
2030 if (node_prev)
2031 node_prev->next = last->next;
2032 else
2033 list->head = last->next;
2034 if (last == list->tail)
2035 list->tail = NULL;
2036 }
2037 } else {
2038 node_prev = node;
2039 }
2040 node = node_prev ? node_prev->next : list->head;
2041 }
2042
2043 /* Remove any lingering effects of this invocation on the
2044 * active list. That is, pop until the list looks like it did
2045 * at the beginning of this function. */
2046 while (parser->active && parser->active != active_initial)
2047 _parser_active_list_pop (parser);
2048
2049 list->non_space_tail = list->tail;
2050 }
2051
2052 void
2053 _glcpp_parser_print_expanded_token_list(glcpp_parser_t *parser,
2054 token_list_t *list)
2055 {
2056 if (list == NULL)
2057 return;
2058
2059 _glcpp_parser_expand_token_list (parser, list, EXPANSION_MODE_IGNORE_DEFINED);
2060
2061 _token_list_trim_trailing_space (list);
2062
2063 _token_list_print (parser, list);
2064 }
2065
2066 static void
2067 _check_for_reserved_macro_name(glcpp_parser_t *parser, YYLTYPE *loc,
2068 const char *identifier)
2069 {
2070 /* Section 3.3 (Preprocessor) of the GLSL 1.30 spec (and later) and
2071 * the GLSL ES spec (all versions) say:
2072 *
2073 * "All macro names containing two consecutive underscores ( __ )
2074 * are reserved for future use as predefined macro names. All
2075 * macro names prefixed with "GL_" ("GL" followed by a single
2076 * underscore) are also reserved."
2077 *
2078 * The intention is that names containing __ are reserved for internal
2079 * use by the implementation, and names prefixed with GL_ are reserved
2080 * for use by Khronos. Since every extension adds a name prefixed
2081 * with GL_ (i.e., the name of the extension), that should be an
2082 * error. Names simply containing __ are dangerous to use, but should
2083 * be allowed.
2084 *
2085 * A future version of the GLSL specification will clarify this.
2086 */
2087 if (strstr(identifier, "__")) {
2088 glcpp_warning(loc, parser, "Macro names containing \"__\" are reserved "
2089 "for use by the implementation.\n");
2090 }
2091 if (strncmp(identifier, "GL_", 3) == 0) {
2092 glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n");
2093 }
2094 if (strcmp(identifier, "defined") == 0) {
2095 glcpp_error (loc, parser, "\"defined\" cannot be used as a macro name");
2096 }
2097 }
2098
2099 static int
2100 _macro_equal(macro_t *a, macro_t *b)
2101 {
2102 if (a->is_function != b->is_function)
2103 return 0;
2104
2105 if (a->is_function) {
2106 if (! _string_list_equal (a->parameters, b->parameters))
2107 return 0;
2108 }
2109
2110 return _token_list_equal_ignoring_space(a->replacements, b->replacements);
2111 }
2112
2113 void
2114 _define_object_macro(glcpp_parser_t *parser, YYLTYPE *loc,
2115 const char *identifier, token_list_t *replacements)
2116 {
2117 macro_t *macro, *previous;
2118 struct hash_entry *entry;
2119
2120 /* We define pre-defined macros before we've started parsing the actual
2121 * file. So if there's no location defined yet, that's what were doing and
2122 * we don't want to generate an error for using the reserved names. */
2123 if (loc != NULL)
2124 _check_for_reserved_macro_name(parser, loc, identifier);
2125
2126 macro = linear_alloc_child(parser->linalloc, sizeof(macro_t));
2127
2128 macro->is_function = 0;
2129 macro->parameters = NULL;
2130 macro->identifier = linear_strdup(parser->linalloc, identifier);
2131 macro->replacements = replacements;
2132
2133 entry = _mesa_hash_table_search(parser->defines, identifier);
2134 previous = entry ? entry->data : NULL;
2135 if (previous) {
2136 if (_macro_equal (macro, previous)) {
2137 return;
2138 }
2139 glcpp_error (loc, parser, "Redefinition of macro %s\n", identifier);
2140 }
2141
2142 _mesa_hash_table_insert (parser->defines, identifier, macro);
2143 }
2144
2145 void
2146 _define_function_macro(glcpp_parser_t *parser, YYLTYPE *loc,
2147 const char *identifier, string_list_t *parameters,
2148 token_list_t *replacements)
2149 {
2150 macro_t *macro, *previous;
2151 struct hash_entry *entry;
2152 const char *dup;
2153
2154 _check_for_reserved_macro_name(parser, loc, identifier);
2155
2156 /* Check for any duplicate parameter names. */
2157 if ((dup = _string_list_has_duplicate (parameters)) != NULL) {
2158 glcpp_error (loc, parser, "Duplicate macro parameter \"%s\"", dup);
2159 }
2160
2161 macro = linear_alloc_child(parser->linalloc, sizeof(macro_t));
2162
2163 macro->is_function = 1;
2164 macro->parameters = parameters;
2165 macro->identifier = linear_strdup(parser->linalloc, identifier);
2166 macro->replacements = replacements;
2167
2168 entry = _mesa_hash_table_search(parser->defines, identifier);
2169 previous = entry ? entry->data : NULL;
2170 if (previous) {
2171 if (_macro_equal (macro, previous)) {
2172 return;
2173 }
2174 glcpp_error (loc, parser, "Redefinition of macro %s\n", identifier);
2175 }
2176
2177 _mesa_hash_table_insert(parser->defines, identifier, macro);
2178 }
2179
2180 static int
2181 glcpp_parser_lex(YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser)
2182 {
2183 token_node_t *node;
2184 int ret;
2185
2186 if (parser->lex_from_list == NULL) {
2187 ret = glcpp_lex(yylval, yylloc, parser->scanner);
2188
2189 /* XXX: This ugly block of code exists for the sole
2190 * purpose of converting a NEWLINE token into a SPACE
2191 * token, but only in the case where we have seen a
2192 * function-like macro name, but have not yet seen its
2193 * closing parenthesis.
2194 *
2195 * There's perhaps a more compact way to do this with
2196 * mid-rule actions in the grammar.
2197 *
2198 * I'm definitely not pleased with the complexity of
2199 * this code here.
2200 */
2201 if (parser->newline_as_space) {
2202 if (ret == '(') {
2203 parser->paren_count++;
2204 } else if (ret == ')') {
2205 parser->paren_count--;
2206 if (parser->paren_count == 0)
2207 parser->newline_as_space = 0;
2208 } else if (ret == NEWLINE) {
2209 ret = SPACE;
2210 } else if (ret != SPACE) {
2211 if (parser->paren_count == 0)
2212 parser->newline_as_space = 0;
2213 }
2214 } else if (parser->in_control_line) {
2215 if (ret == NEWLINE)
2216 parser->in_control_line = 0;
2217 }
2218 else if (ret == DEFINE_TOKEN || ret == UNDEF || ret == IF ||
2219 ret == IFDEF || ret == IFNDEF || ret == ELIF || ret == ELSE ||
2220 ret == ENDIF || ret == HASH_TOKEN) {
2221 parser->in_control_line = 1;
2222 } else if (ret == IDENTIFIER) {
2223 struct hash_entry *entry = _mesa_hash_table_search(parser->defines,
2224 yylval->str);
2225 macro_t *macro = entry ? entry->data : NULL;
2226 if (macro && macro->is_function) {
2227 parser->newline_as_space = 1;
2228 parser->paren_count = 0;
2229 }
2230 }
2231
2232 return ret;
2233 }
2234
2235 node = parser->lex_from_node;
2236
2237 if (node == NULL) {
2238 parser->lex_from_list = NULL;
2239 return NEWLINE;
2240 }
2241
2242 *yylval = node->token->value;
2243 ret = node->token->type;
2244
2245 parser->lex_from_node = node->next;
2246
2247 return ret;
2248 }
2249
2250 static void
2251 glcpp_parser_lex_from(glcpp_parser_t *parser, token_list_t *list)
2252 {
2253 token_node_t *node;
2254
2255 assert (parser->lex_from_list == NULL);
2256
2257 /* Copy list, eliminating any space tokens. */
2258 parser->lex_from_list = _token_list_create (parser);
2259
2260 for (node = list->head; node; node = node->next) {
2261 if (node->token->type == SPACE)
2262 continue;
2263 _token_list_append (parser, parser->lex_from_list, node->token);
2264 }
2265
2266 parser->lex_from_node = parser->lex_from_list->head;
2267
2268 /* It's possible the list consisted of nothing but whitespace. */
2269 if (parser->lex_from_node == NULL) {
2270 parser->lex_from_list = NULL;
2271 }
2272 }
2273
2274 static void
2275 _glcpp_parser_skip_stack_push_if(glcpp_parser_t *parser, YYLTYPE *loc,
2276 int condition)
2277 {
2278 skip_type_t current = SKIP_NO_SKIP;
2279 skip_node_t *node;
2280
2281 if (parser->skip_stack)
2282 current = parser->skip_stack->type;
2283
2284 node = linear_alloc_child(parser->linalloc, sizeof(skip_node_t));
2285 node->loc = *loc;
2286
2287 if (current == SKIP_NO_SKIP) {
2288 if (condition)
2289 node->type = SKIP_NO_SKIP;
2290 else
2291 node->type = SKIP_TO_ELSE;
2292 } else {
2293 node->type = SKIP_TO_ENDIF;
2294 }
2295
2296 node->has_else = false;
2297 node->next = parser->skip_stack;
2298 parser->skip_stack = node;
2299 }
2300
2301 static void
2302 _glcpp_parser_skip_stack_change_if(glcpp_parser_t *parser, YYLTYPE *loc,
2303 const char *type, int condition)
2304 {
2305 if (parser->skip_stack == NULL) {
2306 glcpp_error (loc, parser, "#%s without #if\n", type);
2307 return;
2308 }
2309
2310 if (parser->skip_stack->type == SKIP_TO_ELSE) {
2311 if (condition)
2312 parser->skip_stack->type = SKIP_NO_SKIP;
2313 } else {
2314 parser->skip_stack->type = SKIP_TO_ENDIF;
2315 }
2316 }
2317
2318 static void
2319 _glcpp_parser_skip_stack_pop(glcpp_parser_t *parser, YYLTYPE *loc)
2320 {
2321 skip_node_t *node;
2322
2323 if (parser->skip_stack == NULL) {
2324 glcpp_error (loc, parser, "#endif without #if\n");
2325 return;
2326 }
2327
2328 node = parser->skip_stack;
2329 parser->skip_stack = node->next;
2330 }
2331
2332 static void
2333 _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
2334 const char *identifier,
2335 bool explicitly_set)
2336 {
2337 if (parser->version_set)
2338 return;
2339
2340 parser->version = version;
2341 parser->version_set = true;
2342
2343 add_builtin_define (parser, "__VERSION__", version);
2344
2345 parser->is_gles = (version == 100) ||
2346 (identifier && (strcmp(identifier, "es") == 0));
2347 bool is_compat = version >= 150 && identifier &&
2348 strcmp(identifier, "compatibility") == 0;
2349
2350 /* Add pre-defined macros. */
2351 if (parser->is_gles)
2352 add_builtin_define(parser, "GL_ES", 1);
2353 else if (is_compat)
2354 add_builtin_define(parser, "GL_compatibility_profile", 1);
2355 else if (version >= 150)
2356 add_builtin_define(parser, "GL_core_profile", 1);
2357
2358 /* Currently, all ES2/ES3 implementations support highp in the
2359 * fragment shader, so we always define this macro in ES2/ES3.
2360 * If we ever get a driver that doesn't support highp, we'll
2361 * need to add a flag to the gl_context and check that here.
2362 */
2363 if (version >= 130 || parser->is_gles)
2364 add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1);
2365
2366 /* Add all the extension macros available in this context */
2367 if (parser->extensions)
2368 parser->extensions(parser->state, add_builtin_define, parser,
2369 version, parser->is_gles);
2370
2371 if (parser->extension_list) {
2372 /* If MESA_shader_integer_functions is supported, then the building
2373 * blocks required for the 64x64 => 64 multiply exist. Add defines for
2374 * those functions so that they can be tested.
2375 */
2376 if (parser->extension_list->MESA_shader_integer_functions) {
2377 add_builtin_define(parser, "__have_builtin_builtin_sign64", 1);
2378 add_builtin_define(parser, "__have_builtin_builtin_umul64", 1);
2379 add_builtin_define(parser, "__have_builtin_builtin_udiv64", 1);
2380 add_builtin_define(parser, "__have_builtin_builtin_umod64", 1);
2381 add_builtin_define(parser, "__have_builtin_builtin_idiv64", 1);
2382 add_builtin_define(parser, "__have_builtin_builtin_imod64", 1);
2383 }
2384 }
2385
2386 if (explicitly_set) {
2387 _mesa_string_buffer_printf(parser->output,
2388 "#version %" PRIiMAX "%s%s", version,
2389 identifier ? " " : "",
2390 identifier ? identifier : "");
2391 }
2392 }
2393
2394 /* GLSL version if no version is explicitly specified. */
2395 #define IMPLICIT_GLSL_VERSION 110
2396
2397 /* GLSL ES version if no version is explicitly specified. */
2398 #define IMPLICIT_GLSL_ES_VERSION 100
2399
2400 void
2401 glcpp_parser_resolve_implicit_version(glcpp_parser_t *parser)
2402 {
2403 int language_version = parser->api == API_OPENGLES2 ?
2404 IMPLICIT_GLSL_ES_VERSION : IMPLICIT_GLSL_VERSION;
2405
2406 _glcpp_parser_handle_version_declaration(parser, language_version,
2407 NULL, false);
2408 }