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