[Mesa-dev] [PATCH 3/5] glcpp: Allow arithmetic integer expressions in #line
Eduardo Lima Mitev
elima at igalia.com
Wed Mar 11 02:01:26 PDT 2015
From: Antia Puentes <apuentes at 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
More information about the mesa-dev
mailing list