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 35const char * 36_mesa_lookup_shader_include(struct gl_context *ctx, char *path, 37 bool error_check); 38 39size_t 40_mesa_get_shader_include_cursor(struct gl_shared_state *shared); 41 42void 43_mesa_set_shader_include_cursor(struct gl_shared_state *shared, size_t cursor); 44 45static void 46yyerror(YYLTYPE *locp, glcpp_parser_t *parser, const char *error); 47 48static void 49_define_object_macro(glcpp_parser_t *parser, 50 YYLTYPE *loc, 51 const char *macro, 52 token_list_t *replacements); 53 54static 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 61static string_list_t * 62_string_list_create(glcpp_parser_t *parser); 63 64static void 65_string_list_append_item(glcpp_parser_t *parser, string_list_t *list, 66 const char *str); 67 68static int 69_string_list_contains(string_list_t *list, const char *member, int *index); 70 71static const char * 72_string_list_has_duplicate(string_list_t *list); 73 74static int 75_string_list_length(string_list_t *list); 76 77static int 78_string_list_equal(string_list_t *a, string_list_t *b); 79 80static argument_list_t * 81_argument_list_create(glcpp_parser_t *parser); 82 83static void 84_argument_list_append(glcpp_parser_t *parser, argument_list_t *list, 85 token_list_t *argument); 86 87static int 88_argument_list_length(argument_list_t *list); 89 90static token_list_t * 91_argument_list_member_at(argument_list_t *list, int index); 92 93static token_t * 94_token_create_str(glcpp_parser_t *parser, int type, char *str); 95 96static token_t * 97_token_create_ival(glcpp_parser_t *parser, int type, int ival); 98 99static token_list_t * 100_token_list_create(glcpp_parser_t *parser); 101 102static void 103_token_list_append(glcpp_parser_t *parser, token_list_t *list, token_t *token); 104 105static void 106_token_list_append_list(token_list_t *list, token_list_t *tail); 107 108static int 109_token_list_equal_ignoring_space(token_list_t *a, token_list_t *b); 110 111static void 112_parser_active_list_push(glcpp_parser_t *parser, const char *identifier, 113 token_node_t *marker); 114 115static void 116_parser_active_list_pop(glcpp_parser_t *parser); 117 118static int 119_parser_active_list_contains(glcpp_parser_t *parser, const char *identifier); 120 121typedef 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 */ 129static 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. */ 134static void 135_glcpp_parser_expand_token_list(glcpp_parser_t *parser, token_list_t *list, 136 expansion_mode_t mode); 137 138static void 139_glcpp_parser_print_expanded_token_list(glcpp_parser_t *parser, 140 token_list_t *list); 141 142static void 143_glcpp_parser_skip_stack_push_if(glcpp_parser_t *parser, YYLTYPE *loc, 144 int condition); 145 146static void 147_glcpp_parser_skip_stack_change_if(glcpp_parser_t *parser, YYLTYPE *loc, 148 const char *type, int condition); 149 150static void 151_glcpp_parser_skip_stack_pop(glcpp_parser_t *parser, YYLTYPE *loc); 152 153static void 154_glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version, 155 const char *ident, bool explicitly_set); 156 157static int 158glcpp_parser_lex(YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser); 159 160static void 161glcpp_parser_lex_from(glcpp_parser_t *parser, token_list_t *list); 162 163struct define_include { 164 glcpp_parser_t *parser; 165 YYLTYPE *loc; 166}; 167 168static void 169glcpp_parser_copy_defines(const void *key, void *data, void *closure); 170 171static void 172add_builtin_define(glcpp_parser_t *parser, const char *name, int value); 173 174%} 175 176%pure-parser 177%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 220input: 221 /* empty */ 222| input line 223; 224 225line: 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 235expanded_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 269define: 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 281control_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 298control_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 551control_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 563integer_constant: 564 INTEGER_STRING { 565 /* let strtoll detect the base */ 566 $$ = strtoll ($1, NULL, 0); 567 } 568| INTEGER { 569 $$ = $1; 570 } 571 572version_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 583expression: 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 760identifier_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 771text_line: 772 NEWLINE { $$ = NULL; } 773| pp_tokens NEWLINE 774; 775 776replacement_list: 777 /* empty */ { $$ = NULL; } 778| pp_tokens 779; 780 781junk: 782 /* empty */ 783| pp_tokens { 784 if (parser->gl_ctx->Const.AllowExtraPPTokens) 785 glcpp_warning(&@1, parser, "extra tokens at end of directive"); 786 else 787 glcpp_error(&@1, parser, "extra tokens at end of directive"); 788 } 789; 790 791pp_tokens: 792 preprocessing_token { 793 parser->space_tokens = 1; 794 $$ = _token_list_create (parser); 795 _token_list_append (parser, $$, $1); 796 } 797| pp_tokens preprocessing_token { 798 $$ = $1; 799 _token_list_append (parser, $$, $2); 800 } 801; 802 803preprocessing_token: 804 IDENTIFIER { 805 $$ = _token_create_str (parser, IDENTIFIER, $1); 806 $$->location = yylloc; 807 } 808| INTEGER_STRING { 809 $$ = _token_create_str (parser, INTEGER_STRING, $1); 810 $$->location = yylloc; 811 } 812| PATH { 813 $$ = _token_create_str (parser, PATH, $1); 814 $$->location = yylloc; 815 } 816| operator { 817 $$ = _token_create_ival (parser, $1, $1); 818 $$->location = yylloc; 819 } 820| DEFINED { 821 $$ = _token_create_ival (parser, DEFINED, DEFINED); 822 $$->location = yylloc; 823 } 824| OTHER { 825 $$ = _token_create_str (parser, OTHER, $1); 826 $$->location = yylloc; 827 } 828| SPACE { 829 $$ = _token_create_ival (parser, SPACE, SPACE); 830 $$->location = yylloc; 831 } 832; 833 834operator: 835 '[' { $$ = '['; } 836| ']' { $$ = ']'; } 837| '(' { $$ = '('; } 838| ')' { $$ = ')'; } 839| '{' { $$ = '{'; } 840| '}' { $$ = '}'; } 841| '.' { $$ = '.'; } 842| '&' { $$ = '&'; } 843| '*' { $$ = '*'; } 844| '+' { $$ = '+'; } 845| '-' { $$ = '-'; } 846| '~' { $$ = '~'; } 847| '!' { $$ = '!'; } 848| '/' { $$ = '/'; } 849| '%' { $$ = '%'; } 850| LEFT_SHIFT { $$ = LEFT_SHIFT; } 851| RIGHT_SHIFT { $$ = RIGHT_SHIFT; } 852| '<' { $$ = '<'; } 853| '>' { $$ = '>'; } 854| LESS_OR_EQUAL { $$ = LESS_OR_EQUAL; } 855| GREATER_OR_EQUAL { $$ = GREATER_OR_EQUAL; } 856| EQUAL { $$ = EQUAL; } 857| NOT_EQUAL { $$ = NOT_EQUAL; } 858| '^' { $$ = '^'; } 859| '|' { $$ = '|'; } 860| AND { $$ = AND; } 861| OR { $$ = OR; } 862| ';' { $$ = ';'; } 863| ',' { $$ = ','; } 864| '=' { $$ = '='; } 865| PASTE { $$ = PASTE; } 866| PLUS_PLUS { $$ = PLUS_PLUS; } 867| MINUS_MINUS { $$ = MINUS_MINUS; } 868; 869 870%% 871 872string_list_t * 873_string_list_create(glcpp_parser_t *parser) 874{ 875 string_list_t *list; 876 877 list = linear_alloc_child(parser->linalloc, sizeof(string_list_t)); 878 list->head = NULL; 879 list->tail = NULL; 880 881 return list; 882} 883 884void 885_string_list_append_item(glcpp_parser_t *parser, string_list_t *list, 886 const char *str) 887{ 888 string_node_t *node; 889 890 node = linear_alloc_child(parser->linalloc, sizeof(string_node_t)); 891 node->str = linear_strdup(parser->linalloc, str); 892 893 node->next = NULL; 894 895 if (list->head == NULL) { 896 list->head = node; 897 } else { 898 list->tail->next = node; 899 } 900 901 list->tail = node; 902} 903 904int 905_string_list_contains(string_list_t *list, const char *member, int *index) 906{ 907 string_node_t *node; 908 int i; 909 910 if (list == NULL) 911 return 0; 912 913 for (i = 0, node = list->head; node; i++, node = node->next) { 914 if (strcmp (node->str, member) == 0) { 915 if (index) 916 *index = i; 917 return 1; 918 } 919 } 920 921 return 0; 922} 923 924/* Return duplicate string in list (if any), NULL otherwise. */ 925const char * 926_string_list_has_duplicate(string_list_t *list) 927{ 928 string_node_t *node, *dup; 929 930 if (list == NULL) 931 return NULL; 932 933 for (node = list->head; node; node = node->next) { 934 for (dup = node->next; dup; dup = dup->next) { 935 if (strcmp (node->str, dup->str) == 0) 936 return node->str; 937 } 938 } 939 940 return NULL; 941} 942 943int 944_string_list_length(string_list_t *list) 945{ 946 int length = 0; 947 string_node_t *node; 948 949 if (list == NULL) 950 return 0; 951 952 for (node = list->head; node; node = node->next) 953 length++; 954 955 return length; 956} 957 958int 959_string_list_equal(string_list_t *a, string_list_t *b) 960{ 961 string_node_t *node_a, *node_b; 962 963 if (a == NULL && b == NULL) 964 return 1; 965 966 if (a == NULL || b == NULL) 967 return 0; 968 969 for (node_a = a->head, node_b = b->head; 970 node_a && node_b; 971 node_a = node_a->next, node_b = node_b->next) 972 { 973 if (strcmp (node_a->str, node_b->str)) 974 return 0; 975 } 976 977 /* Catch the case of lists being different lengths, (which 978 * would cause the loop above to terminate after the shorter 979 * list). */ 980 return node_a == node_b; 981} 982 983argument_list_t * 984_argument_list_create(glcpp_parser_t *parser) 985{ 986 argument_list_t *list; 987 988 list = linear_alloc_child(parser->linalloc, sizeof(argument_list_t)); 989 list->head = NULL; 990 list->tail = NULL; 991 992 return list; 993} 994 995void 996_argument_list_append(glcpp_parser_t *parser, 997 argument_list_t *list, token_list_t *argument) 998{ 999 argument_node_t *node; 1000 1001 node = linear_alloc_child(parser->linalloc, sizeof(argument_node_t)); 1002 node->argument = argument; 1003 1004 node->next = NULL; 1005 1006 if (list->head == NULL) { 1007 list->head = node; 1008 } else { 1009 list->tail->next = node; 1010 } 1011 1012 list->tail = node; 1013} 1014 1015int 1016_argument_list_length(argument_list_t *list) 1017{ 1018 int length = 0; 1019 argument_node_t *node; 1020 1021 if (list == NULL) 1022 return 0; 1023 1024 for (node = list->head; node; node = node->next) 1025 length++; 1026 1027 return length; 1028} 1029 1030token_list_t * 1031_argument_list_member_at(argument_list_t *list, int index) 1032{ 1033 argument_node_t *node; 1034 int i; 1035 1036 if (list == NULL) 1037 return NULL; 1038 1039 node = list->head; 1040 for (i = 0; i < index; i++) { 1041 node = node->next; 1042 if (node == NULL) 1043 break; 1044 } 1045 1046 if (node) 1047 return node->argument; 1048 1049 return NULL; 1050} 1051 1052token_t * 1053_token_create_str(glcpp_parser_t *parser, int type, char *str) 1054{ 1055 token_t *token; 1056 1057 token = linear_alloc_child(parser->linalloc, sizeof(token_t)); 1058 token->type = type; 1059 token->value.str = str; 1060 token->expanding = false; 1061 1062 return token; 1063} 1064 1065token_t * 1066_token_create_ival(glcpp_parser_t *parser, int type, int ival) 1067{ 1068 token_t *token; 1069 1070 token = linear_alloc_child(parser->linalloc, sizeof(token_t)); 1071 token->type = type; 1072 token->value.ival = ival; 1073 token->expanding = false; 1074 1075 return token; 1076} 1077 1078token_list_t * 1079_token_list_create(glcpp_parser_t *parser) 1080{ 1081 token_list_t *list; 1082 1083 list = linear_alloc_child(parser->linalloc, sizeof(token_list_t)); 1084 list->head = NULL; 1085 list->tail = NULL; 1086 list->non_space_tail = NULL; 1087 1088 return list; 1089} 1090 1091void 1092_token_list_append(glcpp_parser_t *parser, token_list_t *list, token_t *token) 1093{ 1094 token_node_t *node; 1095 1096 node = linear_alloc_child(parser->linalloc, sizeof(token_node_t)); 1097 node->token = token; 1098 node->next = NULL; 1099 1100 if (list->head == NULL) { 1101 list->head = node; 1102 } else { 1103 list->tail->next = node; 1104 } 1105 1106 list->tail = node; 1107 if (token->type != SPACE) 1108 list->non_space_tail = node; 1109} 1110 1111void 1112_token_list_append_list(token_list_t *list, token_list_t *tail) 1113{ 1114 if (tail == NULL || tail->head == NULL) 1115 return; 1116 1117 if (list->head == NULL) { 1118 list->head = tail->head; 1119 } else { 1120 list->tail->next = tail->head; 1121 } 1122 1123 list->tail = tail->tail; 1124 list->non_space_tail = tail->non_space_tail; 1125} 1126 1127static token_list_t * 1128_token_list_copy(glcpp_parser_t *parser, token_list_t *other) 1129{ 1130 token_list_t *copy; 1131 token_node_t *node; 1132 1133 if (other == NULL) 1134 return NULL; 1135 1136 copy = _token_list_create (parser); 1137 for (node = other->head; node; node = node->next) { 1138 token_t *new_token = linear_alloc_child(parser->linalloc, sizeof(token_t)); 1139 *new_token = *node->token; 1140 _token_list_append (parser, copy, new_token); 1141 } 1142 1143 return copy; 1144} 1145 1146static void 1147_token_list_trim_trailing_space(token_list_t *list) 1148{ 1149 if (list->non_space_tail) { 1150 list->non_space_tail->next = NULL; 1151 list->tail = list->non_space_tail; 1152 } 1153} 1154 1155static int 1156_token_list_is_empty_ignoring_space(token_list_t *l) 1157{ 1158 token_node_t *n; 1159 1160 if (l == NULL) 1161 return 1; 1162 1163 n = l->head; 1164 while (n != NULL && n->token->type == SPACE) 1165 n = n->next; 1166 1167 return n == NULL; 1168} 1169 1170int 1171_token_list_equal_ignoring_space(token_list_t *a, token_list_t *b) 1172{ 1173 token_node_t *node_a, *node_b; 1174 1175 if (a == NULL || b == NULL) { 1176 int a_empty = _token_list_is_empty_ignoring_space(a); 1177 int b_empty = _token_list_is_empty_ignoring_space(b); 1178 return a_empty == b_empty; 1179 } 1180 1181 node_a = a->head; 1182 node_b = b->head; 1183 1184 while (1) 1185 { 1186 if (node_a == NULL && node_b == NULL) 1187 break; 1188 1189 /* Ignore trailing whitespace */ 1190 if (node_a == NULL && node_b->token->type == SPACE) { 1191 while (node_b && node_b->token->type == SPACE) 1192 node_b = node_b->next; 1193 } 1194 1195 if (node_a == NULL && node_b == NULL) 1196 break; 1197 1198 if (node_b == NULL && node_a->token->type == SPACE) { 1199 while (node_a && node_a->token->type == SPACE) 1200 node_a = node_a->next; 1201 } 1202 1203 if (node_a == NULL && node_b == NULL) 1204 break; 1205 1206 if (node_a == NULL || node_b == NULL) 1207 return 0; 1208 /* Make sure whitespace appears in the same places in both. 1209 * It need not be exactly the same amount of whitespace, 1210 * though. 1211 */ 1212 if (node_a->token->type == SPACE && node_b->token->type == SPACE) { 1213 while (node_a && node_a->token->type == SPACE) 1214 node_a = node_a->next; 1215 while (node_b && node_b->token->type == SPACE) 1216 node_b = node_b->next; 1217 continue; 1218 } 1219 1220 if (node_a->token->type != node_b->token->type) 1221 return 0; 1222 1223 switch (node_a->token->type) { 1224 case INTEGER: 1225 if (node_a->token->value.ival != node_b->token->value.ival) { 1226 return 0; 1227 } 1228 break; 1229 case IDENTIFIER: 1230 case INTEGER_STRING: 1231 case OTHER: 1232 if (strcmp(node_a->token->value.str, node_b->token->value.str)) { 1233 return 0; 1234 } 1235 break; 1236 } 1237 1238 node_a = node_a->next; 1239 node_b = node_b->next; 1240 } 1241 1242 return 1; 1243} 1244 1245static void 1246_token_print(struct _mesa_string_buffer *out, token_t *token) 1247{ 1248 if (token->type < 256) { 1249 _mesa_string_buffer_append_char(out, token->type); 1250 return; 1251 } 1252 1253 switch (token->type) { 1254 case INTEGER: 1255 _mesa_string_buffer_printf(out, "%" PRIiMAX, token->value.ival); 1256 break; 1257 case IDENTIFIER: 1258 case INTEGER_STRING: 1259 case PATH: 1260 case OTHER: 1261 _mesa_string_buffer_append(out, token->value.str); 1262 break; 1263 case SPACE: 1264 _mesa_string_buffer_append_char(out, ' '); 1265 break; 1266 case LEFT_SHIFT: 1267 _mesa_string_buffer_append(out, "<<"); 1268 break; 1269 case RIGHT_SHIFT: 1270 _mesa_string_buffer_append(out, ">>"); 1271 break; 1272 case LESS_OR_EQUAL: 1273 _mesa_string_buffer_append(out, "<="); 1274 break; 1275 case GREATER_OR_EQUAL: 1276 _mesa_string_buffer_append(out, ">="); 1277 break; 1278 case EQUAL: 1279 _mesa_string_buffer_append(out, "=="); 1280 break; 1281 case NOT_EQUAL: 1282 _mesa_string_buffer_append(out, "!="); 1283 break; 1284 case AND: 1285 _mesa_string_buffer_append(out, "&&"); 1286 break; 1287 case OR: 1288 _mesa_string_buffer_append(out, "||"); 1289 break; 1290 case PASTE: 1291 _mesa_string_buffer_append(out, "##"); 1292 break; 1293 case PLUS_PLUS: 1294 _mesa_string_buffer_append(out, "++"); 1295 break; 1296 case MINUS_MINUS: 1297 _mesa_string_buffer_append(out, "--"); 1298 break; 1299 case DEFINED: 1300 _mesa_string_buffer_append(out, "defined"); 1301 break; 1302 case PLACEHOLDER: 1303 /* Nothing to print. */ 1304 break; 1305 default: 1306 assert(!"Error: Don't know how to print token."); 1307 1308 break; 1309 } 1310} 1311 1312/* Return a new token formed by pasting 'token' and 'other'. Note that this 1313 * function may return 'token' or 'other' directly rather than allocating 1314 * anything new. 1315 * 1316 * Caution: Only very cursory error-checking is performed to see if 1317 * the final result is a valid single token. */ 1318static token_t * 1319_token_paste(glcpp_parser_t *parser, token_t *token, token_t *other) 1320{ 1321 token_t *combined = NULL; 1322 1323 /* Pasting a placeholder onto anything makes no change. */ 1324 if (other->type == PLACEHOLDER) 1325 return token; 1326 1327 /* When 'token' is a placeholder, just return 'other'. */ 1328 if (token->type == PLACEHOLDER) 1329 return other; 1330 1331 /* A very few single-character punctuators can be combined 1332 * with another to form a multi-character punctuator. */ 1333 switch (token->type) { 1334 case '<': 1335 if (other->type == '<') 1336 combined = _token_create_ival (parser, LEFT_SHIFT, LEFT_SHIFT); 1337 else if (other->type == '=') 1338 combined = _token_create_ival (parser, LESS_OR_EQUAL, LESS_OR_EQUAL); 1339 break; 1340 case '>': 1341 if (other->type == '>') 1342 combined = _token_create_ival (parser, RIGHT_SHIFT, RIGHT_SHIFT); 1343 else if (other->type == '=') 1344 combined = _token_create_ival (parser, GREATER_OR_EQUAL, GREATER_OR_EQUAL); 1345 break; 1346 case '=': 1347 if (other->type == '=') 1348 combined = _token_create_ival (parser, EQUAL, EQUAL); 1349 break; 1350 case '!': 1351 if (other->type == '=') 1352 combined = _token_create_ival (parser, NOT_EQUAL, NOT_EQUAL); 1353 break; 1354 case '&': 1355 if (other->type == '&') 1356 combined = _token_create_ival (parser, AND, AND); 1357 break; 1358 case '|': 1359 if (other->type == '|') 1360 combined = _token_create_ival (parser, OR, OR); 1361 break; 1362 } 1363 1364 if (combined != NULL) { 1365 /* Inherit the location from the first token */ 1366 combined->location = token->location; 1367 return combined; 1368 } 1369 1370 /* Two string-valued (or integer) tokens can usually just be 1371 * mashed together. (We also handle a string followed by an 1372 * integer here as well.) 1373 * 1374 * There are some exceptions here. Notably, if the first token 1375 * is an integer (or a string representing an integer), then 1376 * the second token must also be an integer or must be a 1377 * string representing an integer that begins with a digit. 1378 */ 1379 if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING || token->type == INTEGER) && 1380 (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING || other->type == INTEGER)) 1381 { 1382 char *str; 1383 int combined_type; 1384 1385 /* Check that pasting onto an integer doesn't create a 1386 * non-integer, (that is, only digits can be 1387 * pasted. */ 1388 if (token->type == INTEGER_STRING || token->type == INTEGER) { 1389 switch (other->type) { 1390 case INTEGER_STRING: 1391 if (other->value.str[0] < '0' || other->value.str[0] > '9') 1392 goto FAIL; 1393 break; 1394 case INTEGER: 1395 if (other->value.ival < 0) 1396 goto FAIL; 1397 break; 1398 default: 1399 goto FAIL; 1400 } 1401 } 1402 1403 if (token->type == INTEGER) 1404 str = linear_asprintf(parser->linalloc, "%" PRIiMAX, token->value.ival); 1405 else 1406 str = linear_strdup(parser->linalloc, token->value.str); 1407 1408 if (other->type == INTEGER) 1409 linear_asprintf_append(parser->linalloc, &str, "%" PRIiMAX, other->value.ival); 1410 else 1411 linear_strcat(parser->linalloc, &str, other->value.str); 1412 1413 /* New token is same type as original token, unless we 1414 * started with an integer, in which case we will be 1415 * creating an integer-string. */ 1416 combined_type = token->type; 1417 if (combined_type == INTEGER) 1418 combined_type = INTEGER_STRING; 1419 1420 combined = _token_create_str (parser, combined_type, str); 1421 combined->location = token->location; 1422 return combined; 1423 } 1424 1425 FAIL: 1426 glcpp_error (&token->location, parser, ""); 1427 _mesa_string_buffer_append(parser->info_log, "Pasting \""); 1428 _token_print(parser->info_log, token); 1429 _mesa_string_buffer_append(parser->info_log, "\" and \""); 1430 _token_print(parser->info_log, other); 1431 _mesa_string_buffer_append(parser->info_log, "\" does not give a valid preprocessing token.\n"); 1432 1433 return token; 1434} 1435 1436static void 1437_token_list_print(glcpp_parser_t *parser, token_list_t *list) 1438{ 1439 token_node_t *node; 1440 1441 if (list == NULL) 1442 return; 1443 1444 for (node = list->head; node; node = node->next) 1445 _token_print(parser->output, node->token); 1446} 1447 1448void 1449yyerror(YYLTYPE *locp, glcpp_parser_t *parser, const char *error) 1450{ 1451 glcpp_error(locp, parser, "%s", error); 1452} 1453 1454static void 1455add_builtin_define(glcpp_parser_t *parser, const char *name, int value) 1456{ 1457 token_t *tok; 1458 token_list_t *list; 1459 1460 tok = _token_create_ival (parser, INTEGER, value); 1461 1462 list = _token_list_create(parser); 1463 _token_list_append(parser, list, tok); 1464 _define_object_macro(parser, NULL, name, list); 1465} 1466 1467/* Initial output buffer size, 4096 minus ralloc() overhead. It was selected 1468 * to minimize total amount of allocated memory during shader-db run. 1469 */ 1470#define INITIAL_PP_OUTPUT_BUF_SIZE 4048 1471 1472glcpp_parser_t * 1473glcpp_parser_create(struct gl_context *gl_ctx, 1474 glcpp_extension_iterator extensions, void *state) 1475{ 1476 glcpp_parser_t *parser; 1477 1478 parser = ralloc (NULL, glcpp_parser_t); 1479 1480 glcpp_lex_init_extra (parser, &parser->scanner); 1481 parser->defines = _mesa_hash_table_create(NULL, _mesa_hash_string, 1482 _mesa_key_string_equal); 1483 parser->linalloc = linear_alloc_parent(parser, 0); 1484 parser->active = NULL; 1485 parser->lexing_directive = 0; 1486 parser->lexing_version_directive = 0; 1487 parser->space_tokens = 1; 1488 parser->last_token_was_newline = 0; 1489 parser->last_token_was_space = 0; 1490 parser->first_non_space_token_this_line = 1; 1491 parser->newline_as_space = 0; 1492 parser->in_control_line = 0; 1493 parser->paren_count = 0; 1494 parser->commented_newlines = 0; 1495 1496 parser->skip_stack = NULL; 1497 parser->skipping = 0; 1498 1499 parser->lex_from_list = NULL; 1500 parser->lex_from_node = NULL; 1501 1502 parser->output = _mesa_string_buffer_create(parser, 1503 INITIAL_PP_OUTPUT_BUF_SIZE); 1504 parser->info_log = _mesa_string_buffer_create(parser, 1505 INITIAL_PP_OUTPUT_BUF_SIZE); 1506 parser->error = 0; 1507 1508 parser->gl_ctx = gl_ctx; 1509 parser->extensions = extensions; 1510 parser->extension_list = &gl_ctx->Extensions; 1511 parser->state = state; 1512 parser->api = gl_ctx->API; 1513 parser->version = 0; 1514 parser->version_set = false; 1515 1516 parser->has_new_line_number = 0; 1517 parser->new_line_number = 1; 1518 parser->has_new_source_number = 0; 1519 parser->new_source_number = 0; 1520 1521 parser->is_gles = false; 1522 1523 return parser; 1524} 1525 1526void 1527glcpp_parser_destroy(glcpp_parser_t *parser) 1528{ 1529 glcpp_lex_destroy (parser->scanner); 1530 _mesa_hash_table_destroy(parser->defines, NULL); 1531 ralloc_free (parser); 1532} 1533 1534typedef enum function_status 1535{ 1536 FUNCTION_STATUS_SUCCESS, 1537 FUNCTION_NOT_A_FUNCTION, 1538 FUNCTION_UNBALANCED_PARENTHESES 1539} function_status_t; 1540 1541/* Find a set of function-like macro arguments by looking for a 1542 * balanced set of parentheses. 1543 * 1544 * When called, 'node' should be the opening-parenthesis token, (or 1545 * perhaps preceeding SPACE tokens). Upon successful return *last will 1546 * be the last consumed node, (corresponding to the closing right 1547 * parenthesis). 1548 * 1549 * Return values: 1550 * 1551 * FUNCTION_STATUS_SUCCESS: 1552 * 1553 * Successfully parsed a set of function arguments. 1554 * 1555 * FUNCTION_NOT_A_FUNCTION: 1556 * 1557 * Macro name not followed by a '('. This is not an error, but 1558 * simply that the macro name should be treated as a non-macro. 1559 * 1560 * FUNCTION_UNBALANCED_PARENTHESES 1561 * 1562 * Macro name is not followed by a balanced set of parentheses. 1563 */ 1564static function_status_t 1565_arguments_parse(glcpp_parser_t *parser, 1566 argument_list_t *arguments, token_node_t *node, 1567 token_node_t **last) 1568{ 1569 token_list_t *argument; 1570 int paren_count; 1571 1572 node = node->next; 1573 1574 /* Ignore whitespace before first parenthesis. */ 1575 while (node && node->token->type == SPACE) 1576 node = node->next; 1577 1578 if (node == NULL || node->token->type != '(') 1579 return FUNCTION_NOT_A_FUNCTION; 1580 1581 node = node->next; 1582 1583 argument = _token_list_create (parser); 1584 _argument_list_append (parser, arguments, argument); 1585 1586 for (paren_count = 1; node; node = node->next) { 1587 if (node->token->type == '(') { 1588 paren_count++; 1589 } else if (node->token->type == ')') { 1590 paren_count--; 1591 if (paren_count == 0) 1592 break; 1593 } 1594 1595 if (node->token->type == ',' && paren_count == 1) { 1596 _token_list_trim_trailing_space (argument); 1597 argument = _token_list_create (parser); 1598 _argument_list_append (parser, arguments, argument); 1599 } else { 1600 if (argument->head == NULL) { 1601 /* Don't treat initial whitespace as part of the argument. */ 1602 if (node->token->type == SPACE) 1603 continue; 1604 } 1605 _token_list_append(parser, argument, node->token); 1606 } 1607 } 1608 1609 if (paren_count) 1610 return FUNCTION_UNBALANCED_PARENTHESES; 1611 1612 *last = node; 1613 1614 return FUNCTION_STATUS_SUCCESS; 1615} 1616 1617static token_list_t * 1618_token_list_create_with_one_ival(glcpp_parser_t *parser, int type, int ival) 1619{ 1620 token_list_t *list; 1621 token_t *node; 1622 1623 list = _token_list_create(parser); 1624 node = _token_create_ival(parser, type, ival); 1625 _token_list_append(parser, list, node); 1626 1627 return list; 1628} 1629 1630static token_list_t * 1631_token_list_create_with_one_space(glcpp_parser_t *parser) 1632{ 1633 return _token_list_create_with_one_ival(parser, SPACE, SPACE); 1634} 1635 1636static token_list_t * 1637_token_list_create_with_one_integer(glcpp_parser_t *parser, int ival) 1638{ 1639 return _token_list_create_with_one_ival(parser, INTEGER, ival); 1640} 1641 1642/* Evaluate a DEFINED token node (based on subsequent tokens in the list). 1643 * 1644 * Note: This function must only be called when "node" is a DEFINED token, 1645 * (and will abort with an assertion failure otherwise). 1646 * 1647 * If "node" is followed, (ignoring any SPACE tokens), by an IDENTIFIER token 1648 * (optionally preceded and followed by '(' and ')' tokens) then the following 1649 * occurs: 1650 * 1651 * If the identifier is a defined macro, this function returns 1. 1652 * 1653 * If the identifier is not a defined macro, this function returns 0. 1654 * 1655 * In either case, *last will be updated to the last node in the list 1656 * consumed by the evaluation, (either the token of the identifier or the 1657 * token of the closing parenthesis). 1658 * 1659 * In all other cases, (such as "node is the final node of the list", or 1660 * "missing closing parenthesis", etc.), this function generates a 1661 * preprocessor error, returns -1 and *last will not be set. 1662 */ 1663static int 1664_glcpp_parser_evaluate_defined(glcpp_parser_t *parser, token_node_t *node, 1665 token_node_t **last) 1666{ 1667 token_node_t *argument, *defined = node; 1668 1669 assert(node->token->type == DEFINED); 1670 1671 node = node->next; 1672 1673 /* Ignore whitespace after DEFINED token. */ 1674 while (node && node->token->type == SPACE) 1675 node = node->next; 1676 1677 if (node == NULL) 1678 goto FAIL; 1679 1680 if (node->token->type == IDENTIFIER || node->token->type == OTHER) { 1681 argument = node; 1682 } else if (node->token->type == '(') { 1683 node = node->next; 1684 1685 /* Ignore whitespace after '(' token. */ 1686 while (node && node->token->type == SPACE) 1687 node = node->next; 1688 1689 if (node == NULL || (node->token->type != IDENTIFIER && 1690 node->token->type != OTHER)) { 1691 goto FAIL; 1692 } 1693 1694 argument = node; 1695 1696 node = node->next; 1697 1698 /* Ignore whitespace after identifier, before ')' token. */ 1699 while (node && node->token->type == SPACE) 1700 node = node->next; 1701 1702 if (node == NULL || node->token->type != ')') 1703 goto FAIL; 1704 } else { 1705 goto FAIL; 1706 } 1707 1708 *last = node; 1709 1710 return _mesa_hash_table_search(parser->defines, 1711 argument->token->value.str) ? 1 : 0; 1712 1713FAIL: 1714 glcpp_error (&defined->token->location, parser, 1715 "\"defined\" not followed by an identifier"); 1716 return -1; 1717} 1718 1719/* Evaluate all DEFINED nodes in a given list, modifying the list in place. 1720 */ 1721static void 1722_glcpp_parser_evaluate_defined_in_list(glcpp_parser_t *parser, 1723 token_list_t *list) 1724{ 1725 token_node_t *node, *node_prev, *replacement, *last = NULL; 1726 int value; 1727 1728 if (list == NULL) 1729 return; 1730 1731 node_prev = NULL; 1732 node = list->head; 1733 1734 while (node) { 1735 1736 if (node->token->type != DEFINED) 1737 goto NEXT; 1738 1739 value = _glcpp_parser_evaluate_defined (parser, node, &last); 1740 if (value == -1) 1741 goto NEXT; 1742 1743 replacement = linear_alloc_child(parser->linalloc, sizeof(token_node_t)); 1744 replacement->token = _token_create_ival (parser, INTEGER, value); 1745 1746 /* Splice replacement node into list, replacing from "node" 1747 * through "last". */ 1748 if (node_prev) 1749 node_prev->next = replacement; 1750 else 1751 list->head = replacement; 1752 replacement->next = last->next; 1753 if (last == list->tail) 1754 list->tail = replacement; 1755 1756 node = replacement; 1757 1758 NEXT: 1759 node_prev = node; 1760 node = node->next; 1761 } 1762} 1763 1764/* Perform macro expansion on 'list', placing the resulting tokens 1765 * into a new list which is initialized with a first token of type 1766 * 'head_token_type'. Then begin lexing from the resulting list, 1767 * (return to the current lexing source when this list is exhausted). 1768 * 1769 * See the documentation of _glcpp_parser_expand_token_list for a description 1770 * of the "mode" parameter. 1771 */ 1772static void 1773_glcpp_parser_expand_and_lex_from(glcpp_parser_t *parser, int head_token_type, 1774 token_list_t *list, expansion_mode_t mode) 1775{ 1776 token_list_t *expanded; 1777 token_t *token; 1778 1779 expanded = _token_list_create (parser); 1780 token = _token_create_ival (parser, head_token_type, head_token_type); 1781 _token_list_append (parser, expanded, token); 1782 _glcpp_parser_expand_token_list (parser, list, mode); 1783 _token_list_append_list (expanded, list); 1784 glcpp_parser_lex_from (parser, expanded); 1785} 1786 1787static void 1788_glcpp_parser_apply_pastes(glcpp_parser_t *parser, token_list_t *list) 1789{ 1790 token_node_t *node; 1791 1792 node = list->head; 1793 while (node) { 1794 token_node_t *next_non_space; 1795 1796 /* Look ahead for a PASTE token, skipping space. */ 1797 next_non_space = node->next; 1798 while (next_non_space && next_non_space->token->type == SPACE) 1799 next_non_space = next_non_space->next; 1800 1801 if (next_non_space == NULL) 1802 break; 1803 1804 if (next_non_space->token->type != PASTE) { 1805 node = next_non_space; 1806 continue; 1807 } 1808 1809 /* Now find the next non-space token after the PASTE. */ 1810 next_non_space = next_non_space->next; 1811 while (next_non_space && next_non_space->token->type == SPACE) 1812 next_non_space = next_non_space->next; 1813 1814 if (next_non_space == NULL) { 1815 yyerror(&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n"); 1816 return; 1817 } 1818 1819 node->token = _token_paste(parser, node->token, next_non_space->token); 1820 node->next = next_non_space->next; 1821 if (next_non_space == list->tail) 1822 list->tail = node; 1823 } 1824 1825 list->non_space_tail = list->tail; 1826} 1827 1828/* This is a helper function that's essentially part of the 1829 * implementation of _glcpp_parser_expand_node. It shouldn't be called 1830 * except for by that function. 1831 * 1832 * Returns NULL if node is a simple token with no expansion, (that is, 1833 * although 'node' corresponds to an identifier defined as a 1834 * function-like macro, it is not followed with a parenthesized 1835 * argument list). 1836 * 1837 * Compute the complete expansion of node (which is a function-like 1838 * macro) and subsequent nodes which are arguments. 1839 * 1840 * Returns the token list that results from the expansion and sets 1841 * *last to the last node in the list that was consumed by the 1842 * expansion. Specifically, *last will be set as follows: as the 1843 * token of the closing right parenthesis. 1844 * 1845 * See the documentation of _glcpp_parser_expand_token_list for a description 1846 * of the "mode" parameter. 1847 */ 1848static token_list_t * 1849_glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node, 1850 token_node_t **last, expansion_mode_t mode) 1851{ 1852 struct hash_entry *entry; 1853 macro_t *macro; 1854 const char *identifier; 1855 argument_list_t *arguments; 1856 function_status_t status; 1857 token_list_t *substituted; 1858 int parameter_index; 1859 1860 identifier = node->token->value.str; 1861 1862 entry = _mesa_hash_table_search(parser->defines, identifier); 1863 macro = entry ? entry->data : NULL; 1864 1865 assert(macro->is_function); 1866 1867 arguments = _argument_list_create(parser); 1868 status = _arguments_parse(parser, arguments, node, last); 1869 1870 switch (status) { 1871 case FUNCTION_STATUS_SUCCESS: 1872 break; 1873 case FUNCTION_NOT_A_FUNCTION: 1874 return NULL; 1875 case FUNCTION_UNBALANCED_PARENTHESES: 1876 glcpp_error(&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier); 1877 return NULL; 1878 } 1879 1880 /* Replace a macro defined as empty with a SPACE token. */ 1881 if (macro->replacements == NULL) { 1882 return _token_list_create_with_one_space(parser); 1883 } 1884 1885 if (!((_argument_list_length (arguments) == 1886 _string_list_length (macro->parameters)) || 1887 (_string_list_length (macro->parameters) == 0 && 1888 _argument_list_length (arguments) == 1 && 1889 arguments->head->argument->head == NULL))) { 1890 glcpp_error(&node->token->location, parser, 1891 "Error: macro %s invoked with %d arguments (expected %d)\n", 1892 identifier, _argument_list_length (arguments), 1893 _string_list_length(macro->parameters)); 1894 return NULL; 1895 } 1896 1897 /* Perform argument substitution on the replacement list. */ 1898 substituted = _token_list_create(parser); 1899 1900 for (node = macro->replacements->head; node; node = node->next) { 1901 if (node->token->type == IDENTIFIER && 1902 _string_list_contains(macro->parameters, node->token->value.str, 1903 ¶meter_index)) { 1904 token_list_t *argument; 1905 argument = _argument_list_member_at(arguments, parameter_index); 1906 /* Before substituting, we expand the argument tokens, or append a 1907 * placeholder token for an empty argument. */ 1908 if (argument->head) { 1909 token_list_t *expanded_argument; 1910 expanded_argument = _token_list_copy(parser, argument); 1911 _glcpp_parser_expand_token_list(parser, expanded_argument, mode); 1912 _token_list_append_list(substituted, expanded_argument); 1913 } else { 1914 token_t *new_token; 1915 1916 new_token = _token_create_ival(parser, PLACEHOLDER, 1917 PLACEHOLDER); 1918 _token_list_append(parser, substituted, new_token); 1919 } 1920 } else { 1921 _token_list_append(parser, substituted, node->token); 1922 } 1923 } 1924 1925 /* After argument substitution, and before further expansion 1926 * below, implement token pasting. */ 1927 1928 _token_list_trim_trailing_space(substituted); 1929 1930 _glcpp_parser_apply_pastes(parser, substituted); 1931 1932 return substituted; 1933} 1934 1935/* Compute the complete expansion of node, (and subsequent nodes after 1936 * 'node' in the case that 'node' is a function-like macro and 1937 * subsequent nodes are arguments). 1938 * 1939 * Returns NULL if node is a simple token with no expansion. 1940 * 1941 * Otherwise, returns the token list that results from the expansion 1942 * and sets *last to the last node in the list that was consumed by 1943 * the expansion. Specifically, *last will be set as follows: 1944 * 1945 * As 'node' in the case of object-like macro expansion. 1946 * 1947 * As the token of the closing right parenthesis in the case of 1948 * function-like macro expansion. 1949 * 1950 * See the documentation of _glcpp_parser_expand_token_list for a description 1951 * of the "mode" parameter. 1952 */ 1953static token_list_t * 1954_glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node, 1955 token_node_t **last, expansion_mode_t mode, 1956 int line) 1957{ 1958 token_t *token = node->token; 1959 const char *identifier; 1960 struct hash_entry *entry; 1961 macro_t *macro; 1962 1963 /* If token is already being expanded return to avoid an infinite loop */ 1964 if (token->expanding) 1965 return NULL; 1966 1967 /* We only expand identifiers */ 1968 if (token->type != IDENTIFIER) { 1969 return NULL; 1970 } 1971 1972 *last = node; 1973 identifier = token->value.str; 1974 1975 /* Special handling for __LINE__ and __FILE__, (not through 1976 * the hash table). */ 1977 if (*identifier == '_') { 1978 if (strcmp(identifier, "__LINE__") == 0) 1979 return _token_list_create_with_one_integer(parser, line); 1980 1981 if (strcmp(identifier, "__FILE__") == 0) 1982 return _token_list_create_with_one_integer(parser, 1983 node->token->location.source); 1984 } 1985 1986 /* Look up this identifier in the hash table. */ 1987 entry = _mesa_hash_table_search(parser->defines, identifier); 1988 macro = entry ? entry->data : NULL; 1989 1990 /* Not a macro, so no expansion needed. */ 1991 if (macro == NULL) 1992 return NULL; 1993 1994 /* Finally, don't expand this macro if we're already actively 1995 * expanding it, (to avoid infinite recursion). */ 1996 if (_parser_active_list_contains (parser, identifier)) { 1997 /* We change the `expanding` bool to true to prevent any 1998 * future expansion of this unexpanded token. */ 1999 char *str; 2000 token_list_t *expansion; 2001 token_t *final; 2002 2003 str = linear_strdup(parser->linalloc, token->value.str); 2004 final = _token_create_str(parser, token->type, str); 2005 final->expanding = true; 2006 expansion = _token_list_create(parser); 2007 _token_list_append(parser, expansion, final); 2008 return expansion; 2009 } 2010 2011 if (! macro->is_function) { 2012 token_list_t *replacement; 2013 2014 /* Replace a macro defined as empty with a SPACE token. */ 2015 if (macro->replacements == NULL) 2016 return _token_list_create_with_one_space(parser); 2017 2018 replacement = _token_list_copy(parser, macro->replacements); 2019 _glcpp_parser_apply_pastes(parser, replacement); 2020 return replacement; 2021 } 2022 2023 return _glcpp_parser_expand_function(parser, node, last, mode); 2024} 2025 2026/* Push a new identifier onto the parser's active list. 2027 * 2028 * Here, 'marker' is the token node that appears in the list after the 2029 * expansion of 'identifier'. That is, when the list iterator begins 2030 * examining 'marker', then it is time to pop this node from the 2031 * active stack. 2032 */ 2033static void 2034_parser_active_list_push(glcpp_parser_t *parser, const char *identifier, 2035 token_node_t *marker) 2036{ 2037 active_list_t *node; 2038 2039 node = linear_alloc_child(parser->linalloc, sizeof(active_list_t)); 2040 node->identifier = linear_strdup(parser->linalloc, identifier); 2041 node->marker = marker; 2042 node->next = parser->active; 2043 2044 parser->active = node; 2045} 2046 2047static void 2048_parser_active_list_pop(glcpp_parser_t *parser) 2049{ 2050 active_list_t *node = parser->active; 2051 2052 if (node == NULL) { 2053 parser->active = NULL; 2054 return; 2055 } 2056 2057 node = parser->active->next; 2058 parser->active = node; 2059} 2060 2061static int 2062_parser_active_list_contains(glcpp_parser_t *parser, const char *identifier) 2063{ 2064 active_list_t *node; 2065 2066 if (parser->active == NULL) 2067 return 0; 2068 2069 for (node = parser->active; node; node = node->next) 2070 if (strcmp(node->identifier, identifier) == 0) 2071 return 1; 2072 2073 return 0; 2074} 2075 2076/* Walk over the token list replacing nodes with their expansion. 2077 * Whenever nodes are expanded the walking will walk over the new 2078 * nodes, continuing to expand as necessary. The results are placed in 2079 * 'list' itself. 2080 * 2081 * The "mode" argument controls the handling of any DEFINED tokens that 2082 * result from expansion as follows: 2083 * 2084 * EXPANSION_MODE_IGNORE_DEFINED: Any resulting DEFINED tokens will be 2085 * left in the final list, unevaluated. This is the correct mode 2086 * for expanding any list in any context other than a 2087 * preprocessor conditional, (#if or #elif). 2088 * 2089 * EXPANSION_MODE_EVALUATE_DEFINED: Any resulting DEFINED tokens will be 2090 * evaluated to 0 or 1 tokens depending on whether the following 2091 * token is the name of a defined macro. If the DEFINED token is 2092 * not followed by an (optionally parenthesized) identifier, then 2093 * an error will be generated. This the correct mode for 2094 * expanding any list in the context of a preprocessor 2095 * conditional, (#if or #elif). 2096 */ 2097static void 2098_glcpp_parser_expand_token_list(glcpp_parser_t *parser, token_list_t *list, 2099 expansion_mode_t mode) 2100{ 2101 token_node_t *node_prev; 2102 token_node_t *node, *last = NULL; 2103 token_list_t *expansion; 2104 active_list_t *active_initial = parser->active; 2105 int line; 2106 2107 if (list == NULL) 2108 return; 2109 2110 _token_list_trim_trailing_space (list); 2111 2112 line = list->tail->token->location.last_line; 2113 2114 node_prev = NULL; 2115 node = list->head; 2116 2117 if (mode == EXPANSION_MODE_EVALUATE_DEFINED) 2118 _glcpp_parser_evaluate_defined_in_list (parser, list); 2119 2120 while (node) { 2121 2122 while (parser->active && parser->active->marker == node) 2123 _parser_active_list_pop (parser); 2124 2125 expansion = _glcpp_parser_expand_node (parser, node, &last, mode, line); 2126 if (expansion) { 2127 token_node_t *n; 2128 2129 if (mode == EXPANSION_MODE_EVALUATE_DEFINED) { 2130 _glcpp_parser_evaluate_defined_in_list (parser, expansion); 2131 } 2132 2133 for (n = node; n != last->next; n = n->next) 2134 while (parser->active && parser->active->marker == n) { 2135 _parser_active_list_pop (parser); 2136 } 2137 2138 _parser_active_list_push(parser, node->token->value.str, last->next); 2139 2140 /* Splice expansion into list, supporting a simple deletion if the 2141 * expansion is empty. 2142 */ 2143 if (expansion->head) { 2144 if (node_prev) 2145 node_prev->next = expansion->head; 2146 else 2147 list->head = expansion->head; 2148 expansion->tail->next = last->next; 2149 if (last == list->tail) 2150 list->tail = expansion->tail; 2151 } else { 2152 if (node_prev) 2153 node_prev->next = last->next; 2154 else 2155 list->head = last->next; 2156 if (last == list->tail) 2157 list->tail = NULL; 2158 } 2159 } else { 2160 node_prev = node; 2161 } 2162 node = node_prev ? node_prev->next : list->head; 2163 } 2164 2165 /* Remove any lingering effects of this invocation on the 2166 * active list. That is, pop until the list looks like it did 2167 * at the beginning of this function. */ 2168 while (parser->active && parser->active != active_initial) 2169 _parser_active_list_pop (parser); 2170 2171 list->non_space_tail = list->tail; 2172} 2173 2174void 2175_glcpp_parser_print_expanded_token_list(glcpp_parser_t *parser, 2176 token_list_t *list) 2177{ 2178 if (list == NULL) 2179 return; 2180 2181 _glcpp_parser_expand_token_list (parser, list, EXPANSION_MODE_IGNORE_DEFINED); 2182 2183 _token_list_trim_trailing_space (list); 2184 2185 _token_list_print (parser, list); 2186} 2187 2188static void 2189_check_for_reserved_macro_name(glcpp_parser_t *parser, YYLTYPE *loc, 2190 const char *identifier) 2191{ 2192 /* Section 3.3 (Preprocessor) of the GLSL 1.30 spec (and later) and 2193 * the GLSL ES spec (all versions) say: 2194 * 2195 * "All macro names containing two consecutive underscores ( __ ) 2196 * are reserved for future use as predefined macro names. All 2197 * macro names prefixed with "GL_" ("GL" followed by a single 2198 * underscore) are also reserved." 2199 * 2200 * The intention is that names containing __ are reserved for internal 2201 * use by the implementation, and names prefixed with GL_ are reserved 2202 * for use by Khronos. Since every extension adds a name prefixed 2203 * with GL_ (i.e., the name of the extension), that should be an 2204 * error. Names simply containing __ are dangerous to use, but should 2205 * be allowed. 2206 * 2207 * A future version of the GLSL specification will clarify this. 2208 */ 2209 if (strstr(identifier, "__")) { 2210 glcpp_warning(loc, parser, "Macro names containing \"__\" are reserved " 2211 "for use by the implementation.\n"); 2212 } 2213 if (strncmp(identifier, "GL_", 3) == 0) { 2214 glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n"); 2215 } 2216 if (strcmp(identifier, "defined") == 0) { 2217 glcpp_error (loc, parser, "\"defined\" cannot be used as a macro name"); 2218 } 2219} 2220 2221static int 2222_macro_equal(macro_t *a, macro_t *b) 2223{ 2224 if (a->is_function != b->is_function) 2225 return 0; 2226 2227 if (a->is_function) { 2228 if (! _string_list_equal (a->parameters, b->parameters)) 2229 return 0; 2230 } 2231 2232 return _token_list_equal_ignoring_space(a->replacements, b->replacements); 2233} 2234 2235void 2236_define_object_macro(glcpp_parser_t *parser, YYLTYPE *loc, 2237 const char *identifier, token_list_t *replacements) 2238{ 2239 macro_t *macro, *previous; 2240 struct hash_entry *entry; 2241 2242 /* We define pre-defined macros before we've started parsing the actual 2243 * file. So if there's no location defined yet, that's what were doing and 2244 * we don't want to generate an error for using the reserved names. */ 2245 if (loc != NULL) 2246 _check_for_reserved_macro_name(parser, loc, identifier); 2247 2248 macro = linear_alloc_child(parser->linalloc, sizeof(macro_t)); 2249 2250 macro->is_function = 0; 2251 macro->parameters = NULL; 2252 macro->identifier = linear_strdup(parser->linalloc, identifier); 2253 macro->replacements = replacements; 2254 2255 entry = _mesa_hash_table_search(parser->defines, identifier); 2256 previous = entry ? entry->data : NULL; 2257 if (previous) { 2258 if (_macro_equal (macro, previous)) { 2259 return; 2260 } 2261 glcpp_error (loc, parser, "Redefinition of macro %s\n", identifier); 2262 } 2263 2264 _mesa_hash_table_insert (parser->defines, identifier, macro); 2265} 2266 2267void 2268_define_function_macro(glcpp_parser_t *parser, YYLTYPE *loc, 2269 const char *identifier, string_list_t *parameters, 2270 token_list_t *replacements) 2271{ 2272 macro_t *macro, *previous; 2273 struct hash_entry *entry; 2274 const char *dup; 2275 2276 _check_for_reserved_macro_name(parser, loc, identifier); 2277 2278 /* Check for any duplicate parameter names. */ 2279 if ((dup = _string_list_has_duplicate (parameters)) != NULL) { 2280 glcpp_error (loc, parser, "Duplicate macro parameter \"%s\"", dup); 2281 } 2282 2283 macro = linear_alloc_child(parser->linalloc, sizeof(macro_t)); 2284 2285 macro->is_function = 1; 2286 macro->parameters = parameters; 2287 macro->identifier = linear_strdup(parser->linalloc, identifier); 2288 macro->replacements = replacements; 2289 2290 entry = _mesa_hash_table_search(parser->defines, identifier); 2291 previous = entry ? entry->data : NULL; 2292 if (previous) { 2293 if (_macro_equal (macro, previous)) { 2294 return; 2295 } 2296 glcpp_error (loc, parser, "Redefinition of macro %s\n", identifier); 2297 } 2298 2299 _mesa_hash_table_insert(parser->defines, identifier, macro); 2300} 2301 2302static int 2303glcpp_parser_lex(YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser) 2304{ 2305 token_node_t *node; 2306 int ret; 2307 2308 if (parser->lex_from_list == NULL) { 2309 ret = glcpp_lex(yylval, yylloc, parser->scanner); 2310 2311 /* XXX: This ugly block of code exists for the sole 2312 * purpose of converting a NEWLINE token into a SPACE 2313 * token, but only in the case where we have seen a 2314 * function-like macro name, but have not yet seen its 2315 * closing parenthesis. 2316 * 2317 * There's perhaps a more compact way to do this with 2318 * mid-rule actions in the grammar. 2319 * 2320 * I'm definitely not pleased with the complexity of 2321 * this code here. 2322 */ 2323 if (parser->newline_as_space) { 2324 if (ret == '(') { 2325 parser->paren_count++; 2326 } else if (ret == ')') { 2327 parser->paren_count--; 2328 if (parser->paren_count == 0) 2329 parser->newline_as_space = 0; 2330 } else if (ret == NEWLINE) { 2331 ret = SPACE; 2332 } else if (ret != SPACE) { 2333 if (parser->paren_count == 0) 2334 parser->newline_as_space = 0; 2335 } 2336 } else if (parser->in_control_line) { 2337 if (ret == NEWLINE) 2338 parser->in_control_line = 0; 2339 } 2340 else if (ret == DEFINE_TOKEN || ret == UNDEF || ret == IF || 2341 ret == IFDEF || ret == IFNDEF || ret == ELIF || ret == ELSE || 2342 ret == ENDIF || ret == HASH_TOKEN) { 2343 parser->in_control_line = 1; 2344 } else if (ret == IDENTIFIER) { 2345 struct hash_entry *entry = _mesa_hash_table_search(parser->defines, 2346 yylval->str); 2347 macro_t *macro = entry ? entry->data : NULL; 2348 if (macro && macro->is_function) { 2349 parser->newline_as_space = 1; 2350 parser->paren_count = 0; 2351 } 2352 } 2353 2354 return ret; 2355 } 2356 2357 node = parser->lex_from_node; 2358 2359 if (node == NULL) { 2360 parser->lex_from_list = NULL; 2361 return NEWLINE; 2362 } 2363 2364 *yylval = node->token->value; 2365 ret = node->token->type; 2366 2367 parser->lex_from_node = node->next; 2368 2369 return ret; 2370} 2371 2372static void 2373glcpp_parser_lex_from(glcpp_parser_t *parser, token_list_t *list) 2374{ 2375 token_node_t *node; 2376 2377 assert (parser->lex_from_list == NULL); 2378 2379 /* Copy list, eliminating any space tokens. */ 2380 parser->lex_from_list = _token_list_create (parser); 2381 2382 for (node = list->head; node; node = node->next) { 2383 if (node->token->type == SPACE) 2384 continue; 2385 _token_list_append (parser, parser->lex_from_list, node->token); 2386 } 2387 2388 parser->lex_from_node = parser->lex_from_list->head; 2389 2390 /* It's possible the list consisted of nothing but whitespace. */ 2391 if (parser->lex_from_node == NULL) { 2392 parser->lex_from_list = NULL; 2393 } 2394} 2395 2396static void 2397_glcpp_parser_skip_stack_push_if(glcpp_parser_t *parser, YYLTYPE *loc, 2398 int condition) 2399{ 2400 skip_type_t current = SKIP_NO_SKIP; 2401 skip_node_t *node; 2402 2403 if (parser->skip_stack) 2404 current = parser->skip_stack->type; 2405 2406 node = linear_alloc_child(parser->linalloc, sizeof(skip_node_t)); 2407 node->loc = *loc; 2408 2409 if (current == SKIP_NO_SKIP) { 2410 if (condition) 2411 node->type = SKIP_NO_SKIP; 2412 else 2413 node->type = SKIP_TO_ELSE; 2414 } else { 2415 node->type = SKIP_TO_ENDIF; 2416 } 2417 2418 node->has_else = false; 2419 node->next = parser->skip_stack; 2420 parser->skip_stack = node; 2421} 2422 2423static void 2424_glcpp_parser_skip_stack_change_if(glcpp_parser_t *parser, YYLTYPE *loc, 2425 const char *type, int condition) 2426{ 2427 if (parser->skip_stack == NULL) { 2428 glcpp_error (loc, parser, "#%s without #if\n", type); 2429 return; 2430 } 2431 2432 if (parser->skip_stack->type == SKIP_TO_ELSE) { 2433 if (condition) 2434 parser->skip_stack->type = SKIP_NO_SKIP; 2435 } else { 2436 parser->skip_stack->type = SKIP_TO_ENDIF; 2437 } 2438} 2439 2440static void 2441_glcpp_parser_skip_stack_pop(glcpp_parser_t *parser, YYLTYPE *loc) 2442{ 2443 skip_node_t *node; 2444 2445 if (parser->skip_stack == NULL) { 2446 glcpp_error (loc, parser, "#endif without #if\n"); 2447 return; 2448 } 2449 2450 node = parser->skip_stack; 2451 parser->skip_stack = node->next; 2452} 2453 2454static void 2455_glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version, 2456 const char *identifier, 2457 bool explicitly_set) 2458{ 2459 if (parser->version_set) 2460 return; 2461 2462 parser->version = version; 2463 parser->version_set = true; 2464 2465 add_builtin_define (parser, "__VERSION__", version); 2466 2467 parser->is_gles = (version == 100) || 2468 (identifier && (strcmp(identifier, "es") == 0)); 2469 bool is_compat = version >= 150 && identifier && 2470 strcmp(identifier, "compatibility") == 0; 2471 2472 /* Add pre-defined macros. */ 2473 if (parser->is_gles) 2474 add_builtin_define(parser, "GL_ES", 1); 2475 else if (is_compat) 2476 add_builtin_define(parser, "GL_compatibility_profile", 1); 2477 else if (version >= 150) 2478 add_builtin_define(parser, "GL_core_profile", 1); 2479 2480 /* Currently, all ES2/ES3 implementations support highp in the 2481 * fragment shader, so we always define this macro in ES2/ES3. 2482 * If we ever get a driver that doesn't support highp, we'll 2483 * need to add a flag to the gl_context and check that here. 2484 */ 2485 if (version >= 130 || parser->is_gles) 2486 add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1); 2487 2488 /* Add all the extension macros available in this context */ 2489 if (parser->extensions) 2490 parser->extensions(parser->state, add_builtin_define, parser, 2491 version, parser->is_gles); 2492 2493 if (parser->extension_list) { 2494 /* If MESA_shader_integer_functions is supported, then the building 2495 * blocks required for the 64x64 => 64 multiply exist. Add defines for 2496 * those functions so that they can be tested. 2497 */ 2498 if (parser->extension_list->MESA_shader_integer_functions) { 2499 add_builtin_define(parser, "__have_builtin_builtin_udiv64", 1); 2500 add_builtin_define(parser, "__have_builtin_builtin_umod64", 1); 2501 add_builtin_define(parser, "__have_builtin_builtin_idiv64", 1); 2502 add_builtin_define(parser, "__have_builtin_builtin_imod64", 1); 2503 } 2504 } 2505 2506 if (explicitly_set) { 2507 _mesa_string_buffer_printf(parser->output, 2508 "#version %" PRIiMAX "%s%s", version, 2509 identifier ? " " : "", 2510 identifier ? identifier : ""); 2511 } 2512} 2513 2514/* GLSL version if no version is explicitly specified. */ 2515#define IMPLICIT_GLSL_VERSION 110 2516 2517/* GLSL ES version if no version is explicitly specified. */ 2518#define IMPLICIT_GLSL_ES_VERSION 100 2519 2520void 2521glcpp_parser_resolve_implicit_version(glcpp_parser_t *parser) 2522{ 2523 int language_version = parser->api == API_OPENGLES2 ? 2524 IMPLICIT_GLSL_ES_VERSION : IMPLICIT_GLSL_VERSION; 2525 2526 _glcpp_parser_handle_version_declaration(parser, language_version, 2527 NULL, false); 2528} 2529 2530static void 2531glcpp_parser_copy_defines(const void *key, void *data, void *closure) 2532{ 2533 struct define_include *di = (struct define_include *) closure; 2534 macro_t *macro = (macro_t *) data; 2535 2536 /* If we hit an error on a previous pass, just return */ 2537 if (di->parser->error) 2538 return; 2539 2540 const char *identifier = macro->identifier; 2541 struct hash_entry *entry = _mesa_hash_table_search(di->parser->defines, 2542 identifier); 2543 2544 macro_t *previous = entry ? entry->data : NULL; 2545 if (previous) { 2546 if (_macro_equal(macro, previous)) { 2547 return; 2548 } 2549 glcpp_error(di->loc, di->parser, "Redefinition of macro %s\n", 2550 identifier); 2551 } 2552 2553 _mesa_hash_table_insert(di->parser->defines, identifier, macro); 2554} 2555