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