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