On 03/11/2015 02:01 AM, Eduardo Lima Mitev wrote: > 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."
FFS. I can't believe they have a test for this. For what it's worth, this makes the grammar non-LALR. Not too long ago it came up for a vote to remove this since it does not work on *ANY* desktop OpenGL implementation. While there was a majority vote to remove it, it was not a large enough majority (by a single vote). It is also a deviation from C / C++ preprocessors. Carl spent some time on this, and he couldn't find a way to make it work without adding significant bison warnings or have it fail for some cases. Does this patch work for: #line 3 +3 #line 3 (+3) #line 3 +3 3 #line 3 +3 (+3) #line 3 +3 3 +3 It seems like there were a couple other cases, but I can't remember what they were. Perhaps Carl remembers. > 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; > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev