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