3 * Copyright © 2010 Intel Corporation
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:
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
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.
32 #include "main/core.h" /* for struct gl_extensions */
33 #include "main/mtypes.h" /* for gl_api enum */
36 yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error);
39 _define_object_macro (glcpp_parser_t *parser,
42 token_list_t *replacements);
45 _define_function_macro (glcpp_parser_t *parser,
48 string_list_t *parameters,
49 token_list_t *replacements);
51 static string_list_t *
52 _string_list_create (void *ctx);
55 _string_list_append_item (string_list_t *list, const char *str);
58 _string_list_contains (string_list_t *list, const char *member, int *index);
61 _string_list_has_duplicate (string_list_t *list);
64 _string_list_length (string_list_t *list);
67 _string_list_equal (string_list_t *a, string_list_t *b);
69 static argument_list_t *
70 _argument_list_create (void *ctx);
73 _argument_list_append (argument_list_t *list, token_list_t *argument);
76 _argument_list_length (argument_list_t *list);
79 _argument_list_member_at (argument_list_t *list, int index);
81 /* Note: This function ralloc_steal()s the str pointer. */
83 _token_create_str (void *ctx, int type, char *str);
86 _token_create_ival (void *ctx, int type, int ival);
89 _token_list_create (void *ctx);
92 _token_list_append (token_list_t *list, token_t *token);
95 _token_list_append_list (token_list_t *list, token_list_t *tail);
98 _token_list_equal_ignoring_space (token_list_t *a, token_list_t *b);
101 _parser_active_list_push (glcpp_parser_t *parser,
102 const char *identifier,
103 token_node_t *marker);
106 _parser_active_list_pop (glcpp_parser_t *parser);
109 _parser_active_list_contains (glcpp_parser_t *parser, const char *identifier);
112 EXPANSION_MODE_IGNORE_DEFINED,
113 EXPANSION_MODE_EVALUATE_DEFINED
116 /* Expand list, and begin lexing from the result (after first
117 * prefixing a token of type 'head_token_type').
120 _glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser,
123 expansion_mode_t mode);
125 /* Perform macro expansion in-place on the given list. */
127 _glcpp_parser_expand_token_list (glcpp_parser_t *parser,
129 expansion_mode_t mode);
132 _glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
136 _glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc,
140 _glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc,
141 const char *type, int condition);
144 _glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc);
147 _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
148 const char *ident, bool explicitly_set);
151 glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser);
154 glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list);
157 add_builtin_define(glcpp_parser_t *parser, const char *name, int value);
173 %parse-param {glcpp_parser_t *parser}
174 %lex-param {glcpp_parser_t *parser}
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
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
194 %left EQUAL NOT_EQUAL
195 %left '<' '>' LESS_OR_EQUAL GREATER_OR_EQUAL
196 %left LEFT_SHIFT RIGHT_SHIFT
214 _glcpp_parser_print_expanded_token_list (parser, $1);
215 ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
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);
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);
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",
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",
253 OBJ_IDENTIFIER replacement_list NEWLINE {
254 _define_object_macro (parser, & @1, $1, $2);
256 | FUNC_IDENTIFIER '(' ')' replacement_list NEWLINE {
257 _define_function_macro (parser, & @1, $1, NULL, $4);
259 | FUNC_IDENTIFIER '(' identifier_list ')' replacement_list NEWLINE {
260 _define_function_macro (parser, & @1, $1, $3, $5);
265 control_line_success {
266 ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
269 | HASH_TOKEN LINE pp_tokens NEWLINE {
271 if (parser->skip_stack == NULL ||
272 parser->skip_stack->type == SKIP_NO_SKIP)
274 _glcpp_parser_expand_and_lex_from (parser,
276 EXPANSION_MODE_IGNORE_DEFINED);
281 control_line_success:
282 HASH_TOKEN DEFINE_TOKEN define
283 | HASH_TOKEN UNDEF IDENTIFIER NEWLINE {
285 if (strcmp("__LINE__", $3) == 0
286 || strcmp("__FILE__", $3) == 0
287 || strcmp("__VERSION__", $3) == 0
288 || strncmp("GL_", $3, 3) == 0)
289 glcpp_error(& @1, parser, "Built-in (pre-defined)"
290 " macro names cannot be undefined.");
292 macro = hash_table_find (parser->defines, $3);
294 hash_table_remove (parser->defines, $3);
299 | HASH_TOKEN IF pp_tokens NEWLINE {
300 /* Be careful to only evaluate the 'if' expression if
301 * we are not skipping. When we are skipping, we
302 * simply push a new 0-valued 'if' onto the skip
305 * This avoids generating diagnostics for invalid
306 * expressions that are being skipped. */
307 if (parser->skip_stack == NULL ||
308 parser->skip_stack->type == SKIP_NO_SKIP)
310 _glcpp_parser_expand_and_lex_from (parser,
312 EXPANSION_MODE_EVALUATE_DEFINED);
316 _glcpp_parser_skip_stack_push_if (parser, & @1, 0);
317 parser->skip_stack->type = SKIP_TO_ENDIF;
320 | HASH_TOKEN IF NEWLINE {
321 /* #if without an expression is only an error if we
322 * are not skipping */
323 if (parser->skip_stack == NULL ||
324 parser->skip_stack->type == SKIP_NO_SKIP)
326 glcpp_error(& @1, parser, "#if with no expression");
328 _glcpp_parser_skip_stack_push_if (parser, & @1, 0);
330 | HASH_TOKEN IFDEF IDENTIFIER junk NEWLINE {
331 macro_t *macro = hash_table_find (parser->defines, $3);
333 _glcpp_parser_skip_stack_push_if (parser, & @1, macro != NULL);
335 | HASH_TOKEN IFNDEF IDENTIFIER junk NEWLINE {
336 macro_t *macro = hash_table_find (parser->defines, $3);
338 _glcpp_parser_skip_stack_push_if (parser, & @3, macro == NULL);
340 | HASH_TOKEN ELIF pp_tokens NEWLINE {
341 /* Be careful to only evaluate the 'elif' expression
342 * if we are not skipping. When we are skipping, we
343 * simply change to a 0-valued 'elif' on the skip
346 * This avoids generating diagnostics for invalid
347 * expressions that are being skipped. */
348 if (parser->skip_stack &&
349 parser->skip_stack->type == SKIP_TO_ELSE)
351 _glcpp_parser_expand_and_lex_from (parser,
353 EXPANSION_MODE_EVALUATE_DEFINED);
355 else if (parser->skip_stack &&
356 parser->skip_stack->has_else)
358 glcpp_error(& @1, parser, "#elif after #else");
362 _glcpp_parser_skip_stack_change_if (parser, & @1,
366 | HASH_TOKEN ELIF NEWLINE {
367 /* #elif without an expression is an error unless we
369 if (parser->skip_stack &&
370 parser->skip_stack->type == SKIP_TO_ELSE)
372 glcpp_error(& @1, parser, "#elif with no expression");
374 else if (parser->skip_stack &&
375 parser->skip_stack->has_else)
377 glcpp_error(& @1, parser, "#elif after #else");
381 _glcpp_parser_skip_stack_change_if (parser, & @1,
383 glcpp_warning(& @1, parser, "ignoring illegal #elif without expression");
386 | HASH_TOKEN ELSE { parser->lexing_directive = 1; } NEWLINE {
387 if (parser->skip_stack &&
388 parser->skip_stack->has_else)
390 glcpp_error(& @1, parser, "multiple #else");
394 _glcpp_parser_skip_stack_change_if (parser, & @1, "else", 1);
395 if (parser->skip_stack)
396 parser->skip_stack->has_else = true;
400 _glcpp_parser_skip_stack_pop (parser, & @1);
402 | HASH_TOKEN VERSION_TOKEN integer_constant NEWLINE {
403 if (parser->version_resolved) {
404 glcpp_error(& @1, parser, "#version must appear on the first line");
406 _glcpp_parser_handle_version_declaration(parser, $3, NULL, true);
408 | HASH_TOKEN VERSION_TOKEN integer_constant IDENTIFIER NEWLINE {
409 if (parser->version_resolved) {
410 glcpp_error(& @1, parser, "#version must appear on the first line");
412 _glcpp_parser_handle_version_declaration(parser, $3, $4, true);
414 | HASH_TOKEN NEWLINE {
415 glcpp_parser_resolve_implicit_version(parser);
417 | HASH_TOKEN PRAGMA NEWLINE {
418 ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#%s", $2);
423 HASH_TOKEN ERROR_TOKEN NEWLINE {
424 glcpp_error(& @1, parser, "#%s", $2);
426 | HASH_TOKEN DEFINE_TOKEN NEWLINE {
427 glcpp_error (& @1, parser, "#define without macro name");
429 | HASH_TOKEN GARBAGE pp_tokens NEWLINE {
430 glcpp_error (& @1, parser, "Illegal non-directive after #");
436 if (strlen ($1) >= 3 && strncmp ($1, "0x", 2) == 0) {
437 $$ = strtoll ($1 + 2, NULL, 16);
438 } else if ($1[0] == '0') {
439 $$ = strtoll ($1, NULL, 8);
441 $$ = strtoll ($1, NULL, 10);
451 $$.undefined_macro = NULL;
456 $$.undefined_macro = ralloc_strdup (parser, $1);
458 $$.undefined_macro = NULL;
460 | expression OR expression {
461 $$.value = $1.value || $3.value;
463 /* Short-circuit: Only flag undefined from right side
464 * if left side evaluates to false.
466 if ($1.undefined_macro)
467 $$.undefined_macro = $1.undefined_macro;
469 $$.undefined_macro = $3.undefined_macro;
471 | expression AND expression {
472 $$.value = $1.value && $3.value;
474 /* Short-circuit: Only flag undefined from right-side
475 * if left side evaluates to true.
477 if ($1.undefined_macro)
478 $$.undefined_macro = $1.undefined_macro;
480 $$.undefined_macro = $3.undefined_macro;
482 | expression '|' expression {
483 $$.value = $1.value | $3.value;
484 if ($1.undefined_macro)
485 $$.undefined_macro = $1.undefined_macro;
487 $$.undefined_macro = $3.undefined_macro;
489 | expression '^' expression {
490 $$.value = $1.value ^ $3.value;
491 if ($1.undefined_macro)
492 $$.undefined_macro = $1.undefined_macro;
494 $$.undefined_macro = $3.undefined_macro;
496 | expression '&' expression {
497 $$.value = $1.value & $3.value;
498 if ($1.undefined_macro)
499 $$.undefined_macro = $1.undefined_macro;
501 $$.undefined_macro = $3.undefined_macro;
503 | expression NOT_EQUAL expression {
504 $$.value = $1.value != $3.value;
505 if ($1.undefined_macro)
506 $$.undefined_macro = $1.undefined_macro;
508 $$.undefined_macro = $3.undefined_macro;
510 | expression EQUAL expression {
511 $$.value = $1.value == $3.value;
512 if ($1.undefined_macro)
513 $$.undefined_macro = $1.undefined_macro;
515 $$.undefined_macro = $3.undefined_macro;
517 | expression GREATER_OR_EQUAL expression {
518 $$.value = $1.value >= $3.value;
519 if ($1.undefined_macro)
520 $$.undefined_macro = $1.undefined_macro;
522 $$.undefined_macro = $3.undefined_macro;
524 | expression LESS_OR_EQUAL expression {
525 $$.value = $1.value <= $3.value;
526 if ($1.undefined_macro)
527 $$.undefined_macro = $1.undefined_macro;
529 $$.undefined_macro = $3.undefined_macro;
531 | expression '>' expression {
532 $$.value = $1.value > $3.value;
533 if ($1.undefined_macro)
534 $$.undefined_macro = $1.undefined_macro;
536 $$.undefined_macro = $3.undefined_macro;
538 | expression '<' expression {
539 $$.value = $1.value < $3.value;
540 if ($1.undefined_macro)
541 $$.undefined_macro = $1.undefined_macro;
543 $$.undefined_macro = $3.undefined_macro;
545 | expression RIGHT_SHIFT expression {
546 $$.value = $1.value >> $3.value;
547 if ($1.undefined_macro)
548 $$.undefined_macro = $1.undefined_macro;
550 $$.undefined_macro = $3.undefined_macro;
552 | expression LEFT_SHIFT expression {
553 $$.value = $1.value << $3.value;
554 if ($1.undefined_macro)
555 $$.undefined_macro = $1.undefined_macro;
557 $$.undefined_macro = $3.undefined_macro;
559 | expression '-' expression {
560 $$.value = $1.value - $3.value;
561 if ($1.undefined_macro)
562 $$.undefined_macro = $1.undefined_macro;
564 $$.undefined_macro = $3.undefined_macro;
566 | expression '+' expression {
567 $$.value = $1.value + $3.value;
568 if ($1.undefined_macro)
569 $$.undefined_macro = $1.undefined_macro;
571 $$.undefined_macro = $3.undefined_macro;
573 | expression '%' expression {
575 yyerror (& @1, parser,
576 "zero modulus in preprocessor directive");
578 $$.value = $1.value % $3.value;
580 if ($1.undefined_macro)
581 $$.undefined_macro = $1.undefined_macro;
583 $$.undefined_macro = $3.undefined_macro;
585 | expression '/' expression {
587 yyerror (& @1, parser,
588 "division by 0 in preprocessor directive");
590 $$.value = $1.value / $3.value;
592 if ($1.undefined_macro)
593 $$.undefined_macro = $1.undefined_macro;
595 $$.undefined_macro = $3.undefined_macro;
597 | expression '*' expression {
598 $$.value = $1.value * $3.value;
599 if ($1.undefined_macro)
600 $$.undefined_macro = $1.undefined_macro;
602 $$.undefined_macro = $3.undefined_macro;
604 | '!' expression %prec UNARY {
605 $$.value = ! $2.value;
606 $$.undefined_macro = $2.undefined_macro;
608 | '~' expression %prec UNARY {
609 $$.value = ~ $2.value;
610 $$.undefined_macro = $2.undefined_macro;
612 | '-' expression %prec UNARY {
613 $$.value = - $2.value;
614 $$.undefined_macro = $2.undefined_macro;
616 | '+' expression %prec UNARY {
617 $$.value = + $2.value;
618 $$.undefined_macro = $2.undefined_macro;
620 | '(' expression ')' {
627 $$ = _string_list_create (parser);
628 _string_list_append_item ($$, $1);
629 ralloc_steal ($$, $1);
631 | identifier_list ',' IDENTIFIER {
633 _string_list_append_item ($$, $3);
634 ralloc_steal ($$, $3);
639 NEWLINE { $$ = NULL; }
644 /* empty */ { $$ = NULL; }
651 glcpp_error(&@1, parser, "extra tokens at end of directive");
656 preprocessing_token {
657 parser->space_tokens = 1;
658 $$ = _token_list_create (parser);
659 _token_list_append ($$, $1);
661 | pp_tokens preprocessing_token {
663 _token_list_append ($$, $2);
669 $$ = _token_create_str (parser, IDENTIFIER, $1);
670 $$->location = yylloc;
673 $$ = _token_create_str (parser, INTEGER_STRING, $1);
674 $$->location = yylloc;
677 $$ = _token_create_ival (parser, $1, $1);
678 $$->location = yylloc;
681 $$ = _token_create_ival (parser, DEFINED, DEFINED);
682 $$->location = yylloc;
685 $$ = _token_create_str (parser, OTHER, $1);
686 $$->location = yylloc;
689 $$ = _token_create_ival (parser, SPACE, SPACE);
690 $$->location = yylloc;
710 | LEFT_SHIFT { $$ = LEFT_SHIFT; }
711 | RIGHT_SHIFT { $$ = RIGHT_SHIFT; }
714 | LESS_OR_EQUAL { $$ = LESS_OR_EQUAL; }
715 | GREATER_OR_EQUAL { $$ = GREATER_OR_EQUAL; }
716 | EQUAL { $$ = EQUAL; }
717 | NOT_EQUAL { $$ = NOT_EQUAL; }
725 | PASTE { $$ = PASTE; }
726 | PLUS_PLUS { $$ = PLUS_PLUS; }
727 | MINUS_MINUS { $$ = MINUS_MINUS; }
733 _string_list_create (void *ctx)
737 list = ralloc (ctx, string_list_t);
745 _string_list_append_item (string_list_t *list, const char *str)
749 node = ralloc (list, string_node_t);
750 node->str = ralloc_strdup (node, str);
754 if (list->head == NULL) {
757 list->tail->next = node;
764 _string_list_contains (string_list_t *list, const char *member, int *index)
772 for (i = 0, node = list->head; node; i++, node = node->next) {
773 if (strcmp (node->str, member) == 0) {
783 /* Return duplicate string in list (if any), NULL otherwise. */
785 _string_list_has_duplicate (string_list_t *list)
787 string_node_t *node, *dup;
792 for (node = list->head; node; node = node->next) {
793 for (dup = node->next; dup; dup = dup->next) {
794 if (strcmp (node->str, dup->str) == 0)
803 _string_list_length (string_list_t *list)
811 for (node = list->head; node; node = node->next)
818 _string_list_equal (string_list_t *a, string_list_t *b)
820 string_node_t *node_a, *node_b;
822 if (a == NULL && b == NULL)
825 if (a == NULL || b == NULL)
828 for (node_a = a->head, node_b = b->head;
830 node_a = node_a->next, node_b = node_b->next)
832 if (strcmp (node_a->str, node_b->str))
836 /* Catch the case of lists being different lengths, (which
837 * would cause the loop above to terminate after the shorter
839 return node_a == node_b;
843 _argument_list_create (void *ctx)
845 argument_list_t *list;
847 list = ralloc (ctx, argument_list_t);
855 _argument_list_append (argument_list_t *list, token_list_t *argument)
857 argument_node_t *node;
859 node = ralloc (list, argument_node_t);
860 node->argument = argument;
864 if (list->head == NULL) {
867 list->tail->next = node;
874 _argument_list_length (argument_list_t *list)
877 argument_node_t *node;
882 for (node = list->head; node; node = node->next)
889 _argument_list_member_at (argument_list_t *list, int index)
891 argument_node_t *node;
898 for (i = 0; i < index; i++) {
905 return node->argument;
910 /* Note: This function ralloc_steal()s the str pointer. */
912 _token_create_str (void *ctx, int type, char *str)
916 token = ralloc (ctx, token_t);
918 token->value.str = str;
920 ralloc_steal (token, str);
926 _token_create_ival (void *ctx, int type, int ival)
930 token = ralloc (ctx, token_t);
932 token->value.ival = ival;
938 _token_list_create (void *ctx)
942 list = ralloc (ctx, token_list_t);
945 list->non_space_tail = NULL;
951 _token_list_append (token_list_t *list, token_t *token)
955 node = ralloc (list, token_node_t);
959 if (list->head == NULL) {
962 list->tail->next = node;
966 if (token->type != SPACE)
967 list->non_space_tail = node;
971 _token_list_append_list (token_list_t *list, token_list_t *tail)
973 if (tail == NULL || tail->head == NULL)
976 if (list->head == NULL) {
977 list->head = tail->head;
979 list->tail->next = tail->head;
982 list->tail = tail->tail;
983 list->non_space_tail = tail->non_space_tail;
986 static token_list_t *
987 _token_list_copy (void *ctx, token_list_t *other)
995 copy = _token_list_create (ctx);
996 for (node = other->head; node; node = node->next) {
997 token_t *new_token = ralloc (copy, token_t);
998 *new_token = *node->token;
999 _token_list_append (copy, new_token);
1006 _token_list_trim_trailing_space (token_list_t *list)
1008 token_node_t *tail, *next;
1010 if (list->non_space_tail) {
1011 tail = list->non_space_tail->next;
1012 list->non_space_tail->next = NULL;
1013 list->tail = list->non_space_tail;
1024 _token_list_is_empty_ignoring_space (token_list_t *l)
1032 while (n != NULL && n->token->type == SPACE)
1039 _token_list_equal_ignoring_space (token_list_t *a, token_list_t *b)
1041 token_node_t *node_a, *node_b;
1043 if (a == NULL || b == NULL) {
1044 int a_empty = _token_list_is_empty_ignoring_space(a);
1045 int b_empty = _token_list_is_empty_ignoring_space(b);
1046 return a_empty == b_empty;
1054 if (node_a == NULL && node_b == NULL)
1057 if (node_a == NULL || node_b == NULL)
1059 /* Make sure whitespace appears in the same places in both.
1060 * It need not be exactly the same amount of whitespace,
1063 if (node_a->token->type == SPACE
1064 && node_b->token->type == SPACE) {
1065 while (node_a && node_a->token->type == SPACE)
1066 node_a = node_a->next;
1067 while (node_b && node_b->token->type == SPACE)
1068 node_b = node_b->next;
1072 if (node_a->token->type != node_b->token->type)
1075 switch (node_a->token->type) {
1077 if (node_a->token->value.ival !=
1078 node_b->token->value.ival)
1084 case INTEGER_STRING:
1086 if (strcmp (node_a->token->value.str,
1087 node_b->token->value.str))
1094 node_a = node_a->next;
1095 node_b = node_b->next;
1102 _token_print (char **out, size_t *len, token_t *token)
1104 if (token->type < 256) {
1105 ralloc_asprintf_rewrite_tail (out, len, "%c", token->type);
1109 switch (token->type) {
1111 ralloc_asprintf_rewrite_tail (out, len, "%" PRIiMAX, token->value.ival);
1114 case INTEGER_STRING:
1116 ralloc_asprintf_rewrite_tail (out, len, "%s", token->value.str);
1119 ralloc_asprintf_rewrite_tail (out, len, " ");
1122 ralloc_asprintf_rewrite_tail (out, len, "<<");
1125 ralloc_asprintf_rewrite_tail (out, len, ">>");
1128 ralloc_asprintf_rewrite_tail (out, len, "<=");
1130 case GREATER_OR_EQUAL:
1131 ralloc_asprintf_rewrite_tail (out, len, ">=");
1134 ralloc_asprintf_rewrite_tail (out, len, "==");
1137 ralloc_asprintf_rewrite_tail (out, len, "!=");
1140 ralloc_asprintf_rewrite_tail (out, len, "&&");
1143 ralloc_asprintf_rewrite_tail (out, len, "||");
1146 ralloc_asprintf_rewrite_tail (out, len, "##");
1149 ralloc_asprintf_rewrite_tail (out, len, "++");
1152 ralloc_asprintf_rewrite_tail (out, len, "--");
1155 ralloc_asprintf_rewrite_tail (out, len, "defined");
1158 /* Nothing to print. */
1161 assert(!"Error: Don't know how to print token.");
1167 /* Return a new token (ralloc()ed off of 'token') formed by pasting
1168 * 'token' and 'other'. Note that this function may return 'token' or
1169 * 'other' directly rather than allocating anything new.
1171 * Caution: Only very cursory error-checking is performed to see if
1172 * the final result is a valid single token. */
1174 _token_paste (glcpp_parser_t *parser, token_t *token, token_t *other)
1176 token_t *combined = NULL;
1178 /* Pasting a placeholder onto anything makes no change. */
1179 if (other->type == PLACEHOLDER)
1182 /* When 'token' is a placeholder, just return 'other'. */
1183 if (token->type == PLACEHOLDER)
1186 /* A very few single-character punctuators can be combined
1187 * with another to form a multi-character punctuator. */
1188 switch (token->type) {
1190 if (other->type == '<')
1191 combined = _token_create_ival (token, LEFT_SHIFT, LEFT_SHIFT);
1192 else if (other->type == '=')
1193 combined = _token_create_ival (token, LESS_OR_EQUAL, LESS_OR_EQUAL);
1196 if (other->type == '>')
1197 combined = _token_create_ival (token, RIGHT_SHIFT, RIGHT_SHIFT);
1198 else if (other->type == '=')
1199 combined = _token_create_ival (token, GREATER_OR_EQUAL, GREATER_OR_EQUAL);
1202 if (other->type == '=')
1203 combined = _token_create_ival (token, EQUAL, EQUAL);
1206 if (other->type == '=')
1207 combined = _token_create_ival (token, NOT_EQUAL, NOT_EQUAL);
1210 if (other->type == '&')
1211 combined = _token_create_ival (token, AND, AND);
1214 if (other->type == '|')
1215 combined = _token_create_ival (token, OR, OR);
1219 if (combined != NULL) {
1220 /* Inherit the location from the first token */
1221 combined->location = token->location;
1225 /* Two string-valued (or integer) tokens can usually just be
1226 * mashed together. (We also handle a string followed by an
1227 * integer here as well.)
1229 * There are some exceptions here. Notably, if the first token
1230 * is an integer (or a string representing an integer), then
1231 * the second token must also be an integer or must be a
1232 * string representing an integer that begins with a digit.
1234 if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING || token->type == INTEGER) &&
1235 (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING || other->type == INTEGER))
1240 /* Check that pasting onto an integer doesn't create a
1241 * non-integer, (that is, only digits can be
1243 if (token->type == INTEGER_STRING || token->type == INTEGER)
1245 switch (other->type) {
1246 case INTEGER_STRING:
1247 if (other->value.str[0] < '0' ||
1248 other->value.str[0] > '9')
1252 if (other->value.ival < 0)
1260 if (token->type == INTEGER)
1261 str = ralloc_asprintf (token, "%" PRIiMAX,
1264 str = ralloc_strdup (token, token->value.str);
1267 if (other->type == INTEGER)
1268 ralloc_asprintf_append (&str, "%" PRIiMAX,
1271 ralloc_strcat (&str, other->value.str);
1273 /* New token is same type as original token, unless we
1274 * started with an integer, in which case we will be
1275 * creating an integer-string. */
1276 combined_type = token->type;
1277 if (combined_type == INTEGER)
1278 combined_type = INTEGER_STRING;
1280 combined = _token_create_str (token, combined_type, str);
1281 combined->location = token->location;
1286 glcpp_error (&token->location, parser, "");
1287 ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "Pasting \"");
1288 _token_print (&parser->info_log, &parser->info_log_length, token);
1289 ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" and \"");
1290 _token_print (&parser->info_log, &parser->info_log_length, other);
1291 ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" does not give a valid preprocessing token.\n");
1297 _token_list_print (glcpp_parser_t *parser, token_list_t *list)
1304 for (node = list->head; node; node = node->next)
1305 _token_print (&parser->output, &parser->output_length, node->token);
1309 yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error)
1311 glcpp_error(locp, parser, "%s", error);
1314 static void add_builtin_define(glcpp_parser_t *parser,
1315 const char *name, int value)
1320 tok = _token_create_ival (parser, INTEGER, value);
1322 list = _token_list_create(parser);
1323 _token_list_append(list, tok);
1324 _define_object_macro(parser, NULL, name, list);
1328 glcpp_parser_create (const struct gl_extensions *extensions, gl_api api)
1330 glcpp_parser_t *parser;
1332 parser = ralloc (NULL, glcpp_parser_t);
1334 glcpp_lex_init_extra (parser, &parser->scanner);
1335 parser->defines = hash_table_ctor (32, hash_table_string_hash,
1336 hash_table_string_compare);
1337 parser->active = NULL;
1338 parser->lexing_directive = 0;
1339 parser->space_tokens = 1;
1340 parser->last_token_was_newline = 0;
1341 parser->last_token_was_space = 0;
1342 parser->first_non_space_token_this_line = 1;
1343 parser->newline_as_space = 0;
1344 parser->in_control_line = 0;
1345 parser->paren_count = 0;
1346 parser->commented_newlines = 0;
1348 parser->skip_stack = NULL;
1349 parser->skipping = 0;
1351 parser->lex_from_list = NULL;
1352 parser->lex_from_node = NULL;
1354 parser->output = ralloc_strdup(parser, "");
1355 parser->output_length = 0;
1356 parser->info_log = ralloc_strdup(parser, "");
1357 parser->info_log_length = 0;
1360 parser->extensions = extensions;
1362 parser->version_resolved = false;
1364 parser->has_new_line_number = 0;
1365 parser->new_line_number = 1;
1366 parser->has_new_source_number = 0;
1367 parser->new_source_number = 0;
1373 glcpp_parser_destroy (glcpp_parser_t *parser)
1375 glcpp_lex_destroy (parser->scanner);
1376 hash_table_dtor (parser->defines);
1377 ralloc_free (parser);
1380 typedef enum function_status
1382 FUNCTION_STATUS_SUCCESS,
1383 FUNCTION_NOT_A_FUNCTION,
1384 FUNCTION_UNBALANCED_PARENTHESES
1385 } function_status_t;
1387 /* Find a set of function-like macro arguments by looking for a
1388 * balanced set of parentheses.
1390 * When called, 'node' should be the opening-parenthesis token, (or
1391 * perhaps preceeding SPACE tokens). Upon successful return *last will
1392 * be the last consumed node, (corresponding to the closing right
1397 * FUNCTION_STATUS_SUCCESS:
1399 * Successfully parsed a set of function arguments.
1401 * FUNCTION_NOT_A_FUNCTION:
1403 * Macro name not followed by a '('. This is not an error, but
1404 * simply that the macro name should be treated as a non-macro.
1406 * FUNCTION_UNBALANCED_PARENTHESES
1408 * Macro name is not followed by a balanced set of parentheses.
1410 static function_status_t
1411 _arguments_parse (argument_list_t *arguments,
1413 token_node_t **last)
1415 token_list_t *argument;
1420 /* Ignore whitespace before first parenthesis. */
1421 while (node && node->token->type == SPACE)
1424 if (node == NULL || node->token->type != '(')
1425 return FUNCTION_NOT_A_FUNCTION;
1429 argument = _token_list_create (arguments);
1430 _argument_list_append (arguments, argument);
1432 for (paren_count = 1; node; node = node->next) {
1433 if (node->token->type == '(')
1437 else if (node->token->type == ')')
1440 if (paren_count == 0)
1444 if (node->token->type == ',' &&
1447 _token_list_trim_trailing_space (argument);
1448 argument = _token_list_create (arguments);
1449 _argument_list_append (arguments, argument);
1452 if (argument->head == NULL) {
1453 /* Don't treat initial whitespace as
1454 * part of the argument. */
1455 if (node->token->type == SPACE)
1458 _token_list_append (argument, node->token);
1463 return FUNCTION_UNBALANCED_PARENTHESES;
1467 return FUNCTION_STATUS_SUCCESS;
1470 static token_list_t *
1471 _token_list_create_with_one_ival (void *ctx, int type, int ival)
1476 list = _token_list_create (ctx);
1477 node = _token_create_ival (list, type, ival);
1478 _token_list_append (list, node);
1483 static token_list_t *
1484 _token_list_create_with_one_space (void *ctx)
1486 return _token_list_create_with_one_ival (ctx, SPACE, SPACE);
1489 static token_list_t *
1490 _token_list_create_with_one_integer (void *ctx, int ival)
1492 return _token_list_create_with_one_ival (ctx, INTEGER, ival);
1495 /* Evaluate a DEFINED token node (based on subsequent tokens in the list).
1497 * Note: This function must only be called when "node" is a DEFINED token,
1498 * (and will abort with an assertion failure otherwise).
1500 * If "node" is followed, (ignoring any SPACE tokens), by an IDENTIFIER token
1501 * (optionally preceded and followed by '(' and ')' tokens) then the following
1504 * If the identifier is a defined macro, this function returns 1.
1506 * If the identifier is not a defined macro, this function returns 0.
1508 * In either case, *last will be updated to the last node in the list
1509 * consumed by the evaluation, (either the token of the identifier or the
1510 * token of the closing parenthesis).
1512 * In all other cases, (such as "node is the final node of the list", or
1513 * "missing closing parenthesis", etc.), this function generates a
1514 * preprocessor error, returns -1 and *last will not be set.
1517 _glcpp_parser_evaluate_defined (glcpp_parser_t *parser,
1519 token_node_t **last)
1521 token_node_t *argument, *defined = node;
1523 assert (node->token->type == DEFINED);
1527 /* Ignore whitespace after DEFINED token. */
1528 while (node && node->token->type == SPACE)
1534 if (node->token->type == IDENTIFIER || node->token->type == OTHER) {
1536 } else if (node->token->type == '(') {
1539 /* Ignore whitespace after '(' token. */
1540 while (node && node->token->type == SPACE)
1543 if (node == NULL || (node->token->type != IDENTIFIER &&
1544 node->token->type != OTHER))
1553 /* Ignore whitespace after identifier, before ')' token. */
1554 while (node && node->token->type == SPACE)
1557 if (node == NULL || node->token->type != ')')
1565 return hash_table_find (parser->defines,
1566 argument->token->value.str) ? 1 : 0;
1569 glcpp_error (&defined->token->location, parser,
1570 "\"defined\" not followed by an identifier");
1574 /* Evaluate all DEFINED nodes in a given list, modifying the list in place.
1577 _glcpp_parser_evaluate_defined_in_list (glcpp_parser_t *parser,
1580 token_node_t *node, *node_prev, *replacement, *last = NULL;
1591 if (node->token->type != DEFINED)
1594 value = _glcpp_parser_evaluate_defined (parser, node, &last);
1598 replacement = ralloc (list, token_node_t);
1599 replacement->token = _token_create_ival (list, INTEGER, value);
1601 /* Splice replacement node into list, replacing from "node"
1602 * through "last". */
1604 node_prev->next = replacement;
1606 list->head = replacement;
1607 replacement->next = last->next;
1608 if (last == list->tail)
1609 list->tail = replacement;
1619 /* Perform macro expansion on 'list', placing the resulting tokens
1620 * into a new list which is initialized with a first token of type
1621 * 'head_token_type'. Then begin lexing from the resulting list,
1622 * (return to the current lexing source when this list is exhausted).
1624 * See the documentation of _glcpp_parser_expand_token_list for a description
1625 * of the "mode" parameter.
1628 _glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser,
1629 int head_token_type,
1631 expansion_mode_t mode)
1633 token_list_t *expanded;
1636 expanded = _token_list_create (parser);
1637 token = _token_create_ival (parser, head_token_type, head_token_type);
1638 _token_list_append (expanded, token);
1639 _glcpp_parser_expand_token_list (parser, list, mode);
1640 _token_list_append_list (expanded, list);
1641 glcpp_parser_lex_from (parser, expanded);
1645 _glcpp_parser_apply_pastes (glcpp_parser_t *parser, token_list_t *list)
1652 token_node_t *next_non_space;
1654 /* Look ahead for a PASTE token, skipping space. */
1655 next_non_space = node->next;
1656 while (next_non_space && next_non_space->token->type == SPACE)
1657 next_non_space = next_non_space->next;
1659 if (next_non_space == NULL)
1662 if (next_non_space->token->type != PASTE) {
1663 node = next_non_space;
1667 /* Now find the next non-space token after the PASTE. */
1668 next_non_space = next_non_space->next;
1669 while (next_non_space && next_non_space->token->type == SPACE)
1670 next_non_space = next_non_space->next;
1672 if (next_non_space == NULL) {
1673 yyerror (&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n");
1677 node->token = _token_paste (parser, node->token, next_non_space->token);
1678 node->next = next_non_space->next;
1679 if (next_non_space == list->tail)
1683 list->non_space_tail = list->tail;
1686 /* This is a helper function that's essentially part of the
1687 * implementation of _glcpp_parser_expand_node. It shouldn't be called
1688 * except for by that function.
1690 * Returns NULL if node is a simple token with no expansion, (that is,
1691 * although 'node' corresponds to an identifier defined as a
1692 * function-like macro, it is not followed with a parenthesized
1695 * Compute the complete expansion of node (which is a function-like
1696 * macro) and subsequent nodes which are arguments.
1698 * Returns the token list that results from the expansion and sets
1699 * *last to the last node in the list that was consumed by the
1700 * expansion. Specifically, *last will be set as follows: as the
1701 * token of the closing right parenthesis.
1703 * See the documentation of _glcpp_parser_expand_token_list for a description
1704 * of the "mode" parameter.
1706 static token_list_t *
1707 _glcpp_parser_expand_function (glcpp_parser_t *parser,
1709 token_node_t **last,
1710 expansion_mode_t mode)
1713 const char *identifier;
1714 argument_list_t *arguments;
1715 function_status_t status;
1716 token_list_t *substituted;
1717 int parameter_index;
1719 identifier = node->token->value.str;
1721 macro = hash_table_find (parser->defines, identifier);
1723 assert (macro->is_function);
1725 arguments = _argument_list_create (parser);
1726 status = _arguments_parse (arguments, node, last);
1729 case FUNCTION_STATUS_SUCCESS:
1731 case FUNCTION_NOT_A_FUNCTION:
1733 case FUNCTION_UNBALANCED_PARENTHESES:
1734 glcpp_error (&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier);
1738 /* Replace a macro defined as empty with a SPACE token. */
1739 if (macro->replacements == NULL) {
1740 ralloc_free (arguments);
1741 return _token_list_create_with_one_space (parser);
1744 if (! ((_argument_list_length (arguments) ==
1745 _string_list_length (macro->parameters)) ||
1746 (_string_list_length (macro->parameters) == 0 &&
1747 _argument_list_length (arguments) == 1 &&
1748 arguments->head->argument->head == NULL)))
1750 glcpp_error (&node->token->location, parser,
1751 "Error: macro %s invoked with %d arguments (expected %d)\n",
1753 _argument_list_length (arguments),
1754 _string_list_length (macro->parameters));
1758 /* Perform argument substitution on the replacement list. */
1759 substituted = _token_list_create (arguments);
1761 for (node = macro->replacements->head; node; node = node->next)
1763 if (node->token->type == IDENTIFIER &&
1764 _string_list_contains (macro->parameters,
1765 node->token->value.str,
1768 token_list_t *argument;
1769 argument = _argument_list_member_at (arguments,
1771 /* Before substituting, we expand the argument
1772 * tokens, or append a placeholder token for
1773 * an empty argument. */
1774 if (argument->head) {
1775 token_list_t *expanded_argument;
1776 expanded_argument = _token_list_copy (parser,
1778 _glcpp_parser_expand_token_list (parser,
1781 _token_list_append_list (substituted,
1786 new_token = _token_create_ival (substituted,
1789 _token_list_append (substituted, new_token);
1792 _token_list_append (substituted, node->token);
1796 /* After argument substitution, and before further expansion
1797 * below, implement token pasting. */
1799 _token_list_trim_trailing_space (substituted);
1801 _glcpp_parser_apply_pastes (parser, substituted);
1806 /* Compute the complete expansion of node, (and subsequent nodes after
1807 * 'node' in the case that 'node' is a function-like macro and
1808 * subsequent nodes are arguments).
1810 * Returns NULL if node is a simple token with no expansion.
1812 * Otherwise, returns the token list that results from the expansion
1813 * and sets *last to the last node in the list that was consumed by
1814 * the expansion. Specifically, *last will be set as follows:
1816 * As 'node' in the case of object-like macro expansion.
1818 * As the token of the closing right parenthesis in the case of
1819 * function-like macro expansion.
1821 * See the documentation of _glcpp_parser_expand_token_list for a description
1822 * of the "mode" parameter.
1824 static token_list_t *
1825 _glcpp_parser_expand_node (glcpp_parser_t *parser,
1827 token_node_t **last,
1828 expansion_mode_t mode)
1830 token_t *token = node->token;
1831 const char *identifier;
1834 /* We only expand identifiers */
1835 if (token->type != IDENTIFIER) {
1840 identifier = token->value.str;
1842 /* Special handling for __LINE__ and __FILE__, (not through
1843 * the hash table). */
1844 if (strcmp(identifier, "__LINE__") == 0)
1845 return _token_list_create_with_one_integer (parser, node->token->location.first_line);
1847 if (strcmp(identifier, "__FILE__") == 0)
1848 return _token_list_create_with_one_integer (parser, node->token->location.source);
1850 /* Look up this identifier in the hash table. */
1851 macro = hash_table_find (parser->defines, identifier);
1853 /* Not a macro, so no expansion needed. */
1857 /* Finally, don't expand this macro if we're already actively
1858 * expanding it, (to avoid infinite recursion). */
1859 if (_parser_active_list_contains (parser, identifier)) {
1860 /* We change the token type here from IDENTIFIER to
1861 * OTHER to prevent any future expansion of this
1862 * unexpanded token. */
1864 token_list_t *expansion;
1867 str = ralloc_strdup (parser, token->value.str);
1868 final = _token_create_str (parser, OTHER, str);
1869 expansion = _token_list_create (parser);
1870 _token_list_append (expansion, final);
1874 if (! macro->is_function)
1876 token_list_t *replacement;
1878 /* Replace a macro defined as empty with a SPACE token. */
1879 if (macro->replacements == NULL)
1880 return _token_list_create_with_one_space (parser);
1882 replacement = _token_list_copy (parser, macro->replacements);
1883 _glcpp_parser_apply_pastes (parser, replacement);
1887 return _glcpp_parser_expand_function (parser, node, last, mode);
1890 /* Push a new identifier onto the parser's active list.
1892 * Here, 'marker' is the token node that appears in the list after the
1893 * expansion of 'identifier'. That is, when the list iterator begins
1894 * examining 'marker', then it is time to pop this node from the
1898 _parser_active_list_push (glcpp_parser_t *parser,
1899 const char *identifier,
1900 token_node_t *marker)
1902 active_list_t *node;
1904 node = ralloc (parser->active, active_list_t);
1905 node->identifier = ralloc_strdup (node, identifier);
1906 node->marker = marker;
1907 node->next = parser->active;
1909 parser->active = node;
1913 _parser_active_list_pop (glcpp_parser_t *parser)
1915 active_list_t *node = parser->active;
1918 parser->active = NULL;
1922 node = parser->active->next;
1923 ralloc_free (parser->active);
1925 parser->active = node;
1929 _parser_active_list_contains (glcpp_parser_t *parser, const char *identifier)
1931 active_list_t *node;
1933 if (parser->active == NULL)
1936 for (node = parser->active; node; node = node->next)
1937 if (strcmp (node->identifier, identifier) == 0)
1943 /* Walk over the token list replacing nodes with their expansion.
1944 * Whenever nodes are expanded the walking will walk over the new
1945 * nodes, continuing to expand as necessary. The results are placed in
1948 * The "mode" argument controls the handling of any DEFINED tokens that
1949 * result from expansion as follows:
1951 * EXPANSION_MODE_IGNORE_DEFINED: Any resulting DEFINED tokens will be
1952 * left in the final list, unevaluated. This is the correct mode
1953 * for expanding any list in any context other than a
1954 * preprocessor conditional, (#if or #elif).
1956 * EXPANSION_MODE_EVALUATE_DEFINED: Any resulting DEFINED tokens will be
1957 * evaluated to 0 or 1 tokens depending on whether the following
1958 * token is the name of a defined macro. If the DEFINED token is
1959 * not followed by an (optionally parenthesized) identifier, then
1960 * an error will be generated. This the correct mode for
1961 * expanding any list in the context of a preprocessor
1962 * conditional, (#if or #elif).
1965 _glcpp_parser_expand_token_list (glcpp_parser_t *parser,
1967 expansion_mode_t mode)
1969 token_node_t *node_prev;
1970 token_node_t *node, *last = NULL;
1971 token_list_t *expansion;
1972 active_list_t *active_initial = parser->active;
1977 _token_list_trim_trailing_space (list);
1982 if (mode == EXPANSION_MODE_EVALUATE_DEFINED)
1983 _glcpp_parser_evaluate_defined_in_list (parser, list);
1987 while (parser->active && parser->active->marker == node)
1988 _parser_active_list_pop (parser);
1990 expansion = _glcpp_parser_expand_node (parser, node, &last, mode);
1994 if (mode == EXPANSION_MODE_EVALUATE_DEFINED) {
1995 _glcpp_parser_evaluate_defined_in_list (parser,
1999 for (n = node; n != last->next; n = n->next)
2000 while (parser->active &&
2001 parser->active->marker == n)
2003 _parser_active_list_pop (parser);
2006 _parser_active_list_push (parser,
2007 node->token->value.str,
2010 /* Splice expansion into list, supporting a
2011 * simple deletion if the expansion is
2013 if (expansion->head) {
2015 node_prev->next = expansion->head;
2017 list->head = expansion->head;
2018 expansion->tail->next = last->next;
2019 if (last == list->tail)
2020 list->tail = expansion->tail;
2023 node_prev->next = last->next;
2025 list->head = last->next;
2026 if (last == list->tail)
2032 node = node_prev ? node_prev->next : list->head;
2035 /* Remove any lingering effects of this invocation on the
2036 * active list. That is, pop until the list looks like it did
2037 * at the beginning of this function. */
2038 while (parser->active && parser->active != active_initial)
2039 _parser_active_list_pop (parser);
2041 list->non_space_tail = list->tail;
2045 _glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
2051 _glcpp_parser_expand_token_list (parser, list, EXPANSION_MODE_IGNORE_DEFINED);
2053 _token_list_trim_trailing_space (list);
2055 _token_list_print (parser, list);
2059 _check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc,
2060 const char *identifier)
2062 /* Section 3.3 (Preprocessor) of the GLSL 1.30 spec (and later) and
2063 * the GLSL ES spec (all versions) say:
2065 * "All macro names containing two consecutive underscores ( __ )
2066 * are reserved for future use as predefined macro names. All
2067 * macro names prefixed with "GL_" ("GL" followed by a single
2068 * underscore) are also reserved."
2070 * The intention is that names containing __ are reserved for internal
2071 * use by the implementation, and names prefixed with GL_ are reserved
2072 * for use by Khronos. Since every extension adds a name prefixed
2073 * with GL_ (i.e., the name of the extension), that should be an
2074 * error. Names simply containing __ are dangerous to use, but should
2077 * A future version of the GLSL specification will clarify this.
2079 if (strstr(identifier, "__")) {
2080 glcpp_warning(loc, parser,
2081 "Macro names containing \"__\" are reserved "
2082 "for use by the implementation.\n");
2084 if (strncmp(identifier, "GL_", 3) == 0) {
2085 glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n");
2087 if (strcmp(identifier, "defined") == 0) {
2088 glcpp_error (loc, parser, "\"defined\" cannot be used as a macro name");
2093 _macro_equal (macro_t *a, macro_t *b)
2095 if (a->is_function != b->is_function)
2098 if (a->is_function) {
2099 if (! _string_list_equal (a->parameters, b->parameters))
2103 return _token_list_equal_ignoring_space (a->replacements,
2108 _define_object_macro (glcpp_parser_t *parser,
2110 const char *identifier,
2111 token_list_t *replacements)
2113 macro_t *macro, *previous;
2115 /* We define pre-defined macros before we've started parsing the
2116 * actual file. So if there's no location defined yet, that's what
2117 * were doing and we don't want to generate an error for using the
2118 * reserved names. */
2120 _check_for_reserved_macro_name(parser, loc, identifier);
2122 macro = ralloc (parser, macro_t);
2124 macro->is_function = 0;
2125 macro->parameters = NULL;
2126 macro->identifier = ralloc_strdup (macro, identifier);
2127 macro->replacements = replacements;
2128 ralloc_steal (macro, replacements);
2130 previous = hash_table_find (parser->defines, identifier);
2132 if (_macro_equal (macro, previous)) {
2133 ralloc_free (macro);
2136 glcpp_error (loc, parser, "Redefinition of macro %s\n",
2140 hash_table_insert (parser->defines, macro, identifier);
2144 _define_function_macro (glcpp_parser_t *parser,
2146 const char *identifier,
2147 string_list_t *parameters,
2148 token_list_t *replacements)
2150 macro_t *macro, *previous;
2153 _check_for_reserved_macro_name(parser, loc, identifier);
2155 /* Check for any duplicate parameter names. */
2156 if ((dup = _string_list_has_duplicate (parameters)) != NULL) {
2157 glcpp_error (loc, parser, "Duplicate macro parameter \"%s\"",
2161 macro = ralloc (parser, macro_t);
2162 ralloc_steal (macro, parameters);
2163 ralloc_steal (macro, replacements);
2165 macro->is_function = 1;
2166 macro->parameters = parameters;
2167 macro->identifier = ralloc_strdup (macro, identifier);
2168 macro->replacements = replacements;
2169 previous = hash_table_find (parser->defines, identifier);
2171 if (_macro_equal (macro, previous)) {
2172 ralloc_free (macro);
2175 glcpp_error (loc, parser, "Redefinition of macro %s\n",
2179 hash_table_insert (parser->defines, macro, identifier);
2183 glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser)
2188 if (parser->lex_from_list == NULL) {
2189 ret = glcpp_lex (yylval, yylloc, parser->scanner);
2191 /* XXX: This ugly block of code exists for the sole
2192 * purpose of converting a NEWLINE token into a SPACE
2193 * token, but only in the case where we have seen a
2194 * function-like macro name, but have not yet seen its
2195 * closing parenthesis.
2197 * There's perhaps a more compact way to do this with
2198 * mid-rule actions in the grammar.
2200 * I'm definitely not pleased with the complexity of
2203 if (parser->newline_as_space)
2206 parser->paren_count++;
2207 } else if (ret == ')') {
2208 parser->paren_count--;
2209 if (parser->paren_count == 0)
2210 parser->newline_as_space = 0;
2211 } else if (ret == NEWLINE) {
2213 } else if (ret != SPACE) {
2214 if (parser->paren_count == 0)
2215 parser->newline_as_space = 0;
2218 else if (parser->in_control_line)
2221 parser->in_control_line = 0;
2223 else if (ret == DEFINE_TOKEN ||
2224 ret == UNDEF || ret == IF ||
2225 ret == IFDEF || ret == IFNDEF ||
2226 ret == ELIF || ret == ELSE ||
2227 ret == ENDIF || ret == HASH_TOKEN)
2229 parser->in_control_line = 1;
2231 else if (ret == IDENTIFIER)
2234 macro = hash_table_find (parser->defines,
2236 if (macro && macro->is_function) {
2237 parser->newline_as_space = 1;
2238 parser->paren_count = 0;
2245 node = parser->lex_from_node;
2248 ralloc_free (parser->lex_from_list);
2249 parser->lex_from_list = NULL;
2253 *yylval = node->token->value;
2254 ret = node->token->type;
2256 parser->lex_from_node = node->next;
2262 glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list)
2266 assert (parser->lex_from_list == NULL);
2268 /* Copy list, eliminating any space tokens. */
2269 parser->lex_from_list = _token_list_create (parser);
2271 for (node = list->head; node; node = node->next) {
2272 if (node->token->type == SPACE)
2274 _token_list_append (parser->lex_from_list, node->token);
2279 parser->lex_from_node = parser->lex_from_list->head;
2281 /* It's possible the list consisted of nothing but whitespace. */
2282 if (parser->lex_from_node == NULL) {
2283 ralloc_free (parser->lex_from_list);
2284 parser->lex_from_list = NULL;
2289 _glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc,
2292 skip_type_t current = SKIP_NO_SKIP;
2295 if (parser->skip_stack)
2296 current = parser->skip_stack->type;
2298 node = ralloc (parser, skip_node_t);
2301 if (current == SKIP_NO_SKIP) {
2303 node->type = SKIP_NO_SKIP;
2305 node->type = SKIP_TO_ELSE;
2307 node->type = SKIP_TO_ENDIF;
2310 node->has_else = false;
2311 node->next = parser->skip_stack;
2312 parser->skip_stack = node;
2316 _glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc,
2317 const char *type, int condition)
2319 if (parser->skip_stack == NULL) {
2320 glcpp_error (loc, parser, "#%s without #if\n", type);
2324 if (parser->skip_stack->type == SKIP_TO_ELSE) {
2326 parser->skip_stack->type = SKIP_NO_SKIP;
2328 parser->skip_stack->type = SKIP_TO_ENDIF;
2333 _glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc)
2337 if (parser->skip_stack == NULL) {
2338 glcpp_error (loc, parser, "#endif without #if\n");
2342 node = parser->skip_stack;
2343 parser->skip_stack = node->next;
2348 _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
2349 const char *es_identifier,
2350 bool explicitly_set)
2352 const struct gl_extensions *extensions = parser->extensions;
2354 if (parser->version_resolved)
2357 parser->version_resolved = true;
2359 add_builtin_define (parser, "__VERSION__", version);
2361 parser->is_gles = (version == 100) ||
2363 (strcmp(es_identifier, "es") == 0));
2365 /* Add pre-defined macros. */
2366 if (parser->is_gles) {
2367 add_builtin_define(parser, "GL_ES", 1);
2368 add_builtin_define(parser, "GL_EXT_separate_shader_objects", 1);
2369 add_builtin_define(parser, "GL_EXT_draw_buffers", 1);
2371 if (extensions != NULL) {
2372 if (extensions->OES_EGL_image_external)
2373 add_builtin_define(parser, "GL_OES_EGL_image_external", 1);
2374 if (extensions->OES_sample_variables) {
2375 add_builtin_define(parser, "GL_OES_sample_variables", 1);
2376 add_builtin_define(parser, "GL_OES_shader_multisample_interpolation", 1);
2378 if (extensions->OES_standard_derivatives)
2379 add_builtin_define(parser, "GL_OES_standard_derivatives", 1);
2380 if (extensions->ARB_texture_multisample)
2381 add_builtin_define(parser, "GL_OES_texture_storage_multisample_2d_array", 1);
2382 if (extensions->ARB_blend_func_extended)
2383 add_builtin_define(parser, "GL_EXT_blend_func_extended", 1);
2385 if (version >= 310) {
2386 if (extensions->ARB_shader_image_load_store)
2387 add_builtin_define(parser, "GL_OES_shader_image_atomic", 1);
2389 if (extensions->OES_geometry_shader) {
2390 add_builtin_define(parser, "GL_OES_geometry_point_size", 1);
2391 add_builtin_define(parser, "GL_OES_geometry_shader", 1);
2393 if (extensions->ARB_gpu_shader5) {
2394 add_builtin_define(parser, "GL_EXT_gpu_shader5", 1);
2395 add_builtin_define(parser, "GL_OES_gpu_shader5", 1);
2397 if (extensions->OES_texture_buffer) {
2398 add_builtin_define(parser, "GL_EXT_texture_buffer", 1);
2399 add_builtin_define(parser, "GL_OES_texture_buffer", 1);
2404 add_builtin_define(parser, "GL_ARB_draw_buffers", 1);
2405 add_builtin_define(parser, "GL_ARB_enhanced_layouts", 1);
2406 add_builtin_define(parser, "GL_ARB_separate_shader_objects", 1);
2407 add_builtin_define(parser, "GL_ARB_texture_rectangle", 1);
2408 add_builtin_define(parser, "GL_AMD_shader_trinary_minmax", 1);
2411 if (extensions != NULL) {
2412 if (extensions->EXT_texture_array)
2413 add_builtin_define(parser, "GL_EXT_texture_array", 1);
2415 if (extensions->ARB_arrays_of_arrays)
2416 add_builtin_define(parser, "GL_ARB_arrays_of_arrays", 1);
2418 if (extensions->ARB_fragment_coord_conventions)
2419 add_builtin_define(parser, "GL_ARB_fragment_coord_conventions",
2422 if (extensions->ARB_fragment_layer_viewport)
2423 add_builtin_define(parser, "GL_ARB_fragment_layer_viewport", 1);
2425 if (extensions->ARB_explicit_attrib_location)
2426 add_builtin_define(parser, "GL_ARB_explicit_attrib_location", 1);
2428 if (extensions->ARB_explicit_uniform_location)
2429 add_builtin_define(parser, "GL_ARB_explicit_uniform_location", 1);
2431 if (extensions->ARB_shader_texture_lod)
2432 add_builtin_define(parser, "GL_ARB_shader_texture_lod", 1);
2434 if (extensions->ARB_draw_instanced)
2435 add_builtin_define(parser, "GL_ARB_draw_instanced", 1);
2437 if (extensions->ARB_conservative_depth) {
2438 add_builtin_define(parser, "GL_AMD_conservative_depth", 1);
2439 add_builtin_define(parser, "GL_ARB_conservative_depth", 1);
2442 if (extensions->ARB_shader_bit_encoding)
2443 add_builtin_define(parser, "GL_ARB_shader_bit_encoding", 1);
2445 if (extensions->ARB_shader_clock)
2446 add_builtin_define(parser, "GL_ARB_shader_clock", 1);
2448 if (extensions->ARB_uniform_buffer_object)
2449 add_builtin_define(parser, "GL_ARB_uniform_buffer_object", 1);
2451 if (extensions->ARB_texture_cube_map_array)
2452 add_builtin_define(parser, "GL_ARB_texture_cube_map_array", 1);
2454 if (extensions->ARB_shading_language_packing)
2455 add_builtin_define(parser, "GL_ARB_shading_language_packing", 1);
2457 if (extensions->ARB_texture_multisample)
2458 add_builtin_define(parser, "GL_ARB_texture_multisample", 1);
2460 if (extensions->ARB_texture_query_levels)
2461 add_builtin_define(parser, "GL_ARB_texture_query_levels", 1);
2463 if (extensions->ARB_texture_query_lod)
2464 add_builtin_define(parser, "GL_ARB_texture_query_lod", 1);
2466 if (extensions->ARB_gpu_shader5)
2467 add_builtin_define(parser, "GL_ARB_gpu_shader5", 1);
2469 if (extensions->ARB_gpu_shader_fp64)
2470 add_builtin_define(parser, "GL_ARB_gpu_shader_fp64", 1);
2472 if (extensions->ARB_vertex_attrib_64bit)
2473 add_builtin_define(parser, "GL_ARB_vertex_attrib_64bit", 1);
2475 if (extensions->AMD_vertex_shader_layer)
2476 add_builtin_define(parser, "GL_AMD_vertex_shader_layer", 1);
2478 if (extensions->AMD_vertex_shader_viewport_index)
2479 add_builtin_define(parser, "GL_AMD_vertex_shader_viewport_index", 1);
2481 if (extensions->ARB_shading_language_420pack)
2482 add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1);
2484 if (extensions->ARB_sample_shading)
2485 add_builtin_define(parser, "GL_ARB_sample_shading", 1);
2487 if (extensions->ARB_texture_gather)
2488 add_builtin_define(parser, "GL_ARB_texture_gather", 1);
2490 if (extensions->ARB_shader_atomic_counters)
2491 add_builtin_define(parser, "GL_ARB_shader_atomic_counters", 1);
2493 if (extensions->ARB_shader_atomic_counter_ops)
2494 add_builtin_define(parser, "GL_ARB_shader_atomic_counter_ops", 1);
2496 if (extensions->ARB_viewport_array)
2497 add_builtin_define(parser, "GL_ARB_viewport_array", 1);
2499 if (extensions->ARB_compute_shader)
2500 add_builtin_define(parser, "GL_ARB_compute_shader", 1);
2502 if (extensions->ARB_shader_image_load_store)
2503 add_builtin_define(parser, "GL_ARB_shader_image_load_store", 1);
2505 if (extensions->ARB_shader_image_size)
2506 add_builtin_define(parser, "GL_ARB_shader_image_size", 1);
2508 if (extensions->ARB_shader_texture_image_samples)
2509 add_builtin_define(parser, "GL_ARB_shader_texture_image_samples", 1);
2511 if (extensions->ARB_derivative_control)
2512 add_builtin_define(parser, "GL_ARB_derivative_control", 1);
2514 if (extensions->ARB_shader_precision)
2515 add_builtin_define(parser, "GL_ARB_shader_precision", 1);
2517 if (extensions->ARB_shader_storage_buffer_object)
2518 add_builtin_define(parser, "GL_ARB_shader_storage_buffer_object", 1);
2520 if (extensions->ARB_tessellation_shader)
2521 add_builtin_define(parser, "GL_ARB_tessellation_shader", 1);
2523 if (extensions->ARB_shader_subroutine)
2524 add_builtin_define(parser, "GL_ARB_shader_subroutine", 1);
2526 if (extensions->ARB_shader_draw_parameters)
2527 add_builtin_define(parser, "GL_ARB_shader_draw_parameters", 1);
2531 if (extensions != NULL) {
2532 if (extensions->EXT_shader_integer_mix)
2533 add_builtin_define(parser, "GL_EXT_shader_integer_mix", 1);
2535 if (extensions->EXT_shader_samples_identical)
2536 add_builtin_define(parser, "GL_EXT_shader_samples_identical", 1);
2540 add_builtin_define(parser, "GL_core_profile", 1);
2542 /* Currently, all ES2/ES3 implementations support highp in the
2543 * fragment shader, so we always define this macro in ES2/ES3.
2544 * If we ever get a driver that doesn't support highp, we'll
2545 * need to add a flag to the gl_context and check that here.
2547 if (version >= 130 || parser->is_gles)
2548 add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1);
2550 if (explicitly_set) {
2551 ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length,
2552 "#version %" PRIiMAX "%s%s", version,
2553 es_identifier ? " " : "",
2554 es_identifier ? es_identifier : "");
2558 /* GLSL version if no version is explicitly specified. */
2559 #define IMPLICIT_GLSL_VERSION 110
2561 /* GLSL ES version if no version is explicitly specified. */
2562 #define IMPLICIT_GLSL_ES_VERSION 100
2565 glcpp_parser_resolve_implicit_version(glcpp_parser_t *parser)
2567 int language_version = parser->api == API_OPENGLES2 ?
2568 IMPLICIT_GLSL_ES_VERSION :
2569 IMPLICIT_GLSL_VERSION;
2571 _glcpp_parser_handle_version_declaration(parser, language_version,