From: Antia Puentes <apuen...@igalia.com> From section 3.4 ("Preprocessor") of the GLSL ES 3.00 specification: "#line must have, after macro substitution, one of the following forms: #line line #line line source-string-number where line and source-string-number are constant integral expressions."
From section 4.3.3 ("Constant Expressions") of the same specification: "A constant integral expression is a constant expression that evaluates to a scalar signed or unsigned integer." Fixes 4 dEQP tests: * dEQP-GLES3.functional.shaders.preprocessor.builtin.line_expression_vertex * dEQP-GLES3.functional.shaders.preprocessor.builtin.line_expression_fragment * dEQP-GLES3.functional.shaders.preprocessor.builtin.line_and_file_expression_vertex * dEQP-GLES3.functional.shaders.preprocessor.builtin.line_and_file_expression_fragment --- src/glsl/glcpp/glcpp-parse.y | 91 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 11 deletions(-) diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y index c2f5223..0e96f53 100644 --- a/src/glsl/glcpp/glcpp-parse.y +++ b/src/glsl/glcpp/glcpp-parse.y @@ -180,7 +180,7 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value); * (such as the <HASH> and <DEFINE> start conditions in the lexer). */ %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 %token PASTE -%type <ival> INTEGER operator SPACE integer_constant +%type <ival> INTEGER operator SPACE integer_constant constant_integral_expression %type <expression_value> expression %type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA %type <string_list> identifier_list @@ -229,7 +229,7 @@ expanded_line: glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $2.undefined_macro); _glcpp_parser_skip_stack_change_if (parser, & @1, "elif", $2.value); } -| LINE_EXPANDED integer_constant NEWLINE { +| LINE_EXPANDED constant_integral_expression NEWLINE { parser->has_new_line_number = 1; parser->new_line_number = $2; ralloc_asprintf_rewrite_tail (&parser->output, @@ -237,15 +237,53 @@ expanded_line: "#line %" PRIiMAX "\n", $2); } -| LINE_EXPANDED integer_constant integer_constant NEWLINE { +| LINE_EXPANDED constant_integral_expression SPACE constant_integral_expression NEWLINE { parser->has_new_line_number = 1; parser->new_line_number = $2; parser->has_new_source_number = 1; - parser->new_source_number = $3; + parser->new_source_number = $4; ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#line %" PRIiMAX " %" PRIiMAX "\n", - $2, $3); + $2, $4); + } +; + +constant_integral_expression: + integer_constant { + $$ = $1; + } +| constant_integral_expression '+' constant_integral_expression { + $$ = $1 + $3; + } +| constant_integral_expression '-' constant_integral_expression { + $$ = $1 - $3; + } +| constant_integral_expression '*' constant_integral_expression { + $$ = $1 * $3; + } +| constant_integral_expression '/' constant_integral_expression { + if ($3 == 0) + yyerror (&@1, parser, + "division by 0 in preprocessor directive"); + else + $$ = $1 / $3; + } +| constant_integral_expression '%' constant_integral_expression { + if ($3 == 0) + yyerror (&@1, parser, + "zero modulus in preprocessor directive"); + else + $$ = $1 % $3; + } +| '+' constant_integral_expression %prec UNARY { + $$ = $2; + } +| '-' constant_integral_expression %prec UNARY { + $$ = -$2; + } +| '(' constant_integral_expression ')' { + $$ = $2; } ; @@ -2275,14 +2313,45 @@ glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list) assert (parser->lex_from_list == NULL); /* Copy list, eliminating any space tokens. */ - parser->lex_from_list = _token_list_create (parser); - for (node = list->head; node; node = node->next) { - if (node->token->type == SPACE) - continue; - _token_list_append (parser->lex_from_list, node->token); - } + parser->lex_from_list = _token_list_create (parser); + /* If the list comes from a LINE_EXPANDED, do not remove the + * SPACE tokens that act as parameter separator, i.e., SPACE tokens + * inside parentheses will be removed, consecutive SPACE tokens + * outside parentheses will be reduced to one. + */ + if (list->head->token->type == LINE_EXPANDED) { + int bracket_num = 0; + bool separator = false; + + _token_list_append (parser->lex_from_list, list->head->token); + + for (node = list->head->next; node; node = node->next) { + token_t *token = node->token; + + if (token->type == '(') + bracket_num++; + if (token->type == ')') + bracket_num--; + + if (token->type == SPACE) { + if (bracket_num > 0 || separator) + continue; + separator = true; + } else { + separator = false; + } + + _token_list_append (parser->lex_from_list, token); + } + } else { + for (node = list->head; node; node = node->next) { + if (node->token->type == SPACE) + continue; + _token_list_append (parser->lex_from_list, node->token); + } + } ralloc_free (list); parser->lex_from_node = parser->lex_from_list->head; -- 2.1.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev