[Mesa-dev] [PATCH] glcpp: Expand macro before expanding __LINE__ in its replacement
Zhaowei Yuan
zhaowei.yuan at samsung.com
Fri Aug 17 02:18:16 UTC 2018
From: zhaowei yuan <zhaowei.yuan at samsung.com>
If a macro which contains __LINE__ in its replacement, we should expand the
macro itself firstly and then expanding __LINE__, otherwise __LINE__ will
be expanded as an wrong line number.
This patch fixes following CTS test case:
dEQP-GLES2.functional.shaders.preprocessor.predefined_macros.line_2_vertex
dEQP-GLES2.functional.shaders.preprocessor.predefined_macros.line_2_fragment
dEQP-GLES3.functional.shaders.preprocessor.predefined_macros.line_2_vertex
dEQP-GLES3.functional.shaders.preprocessor.predefined_macros.line_2_fragment
Signed-off-by: zhaowei yuan <zhaowei.yuan at samsung.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106590
Signed-off-by: zhaowei yuan <zhaowei.yuan at samsung.com>
---
src/compiler/glsl/glcpp/glcpp-lex.l | 1 +
src/compiler/glsl/glcpp/glcpp-parse.y | 55 ++++++++++++++++++++++++++++++-----
src/compiler/glsl/glcpp/glcpp.h | 4 ++-
src/compiler/glsl/glcpp/pp.c | 3 +-
4 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/src/compiler/glsl/glcpp/glcpp-lex.l b/src/compiler/glsl/glcpp/glcpp-lex.l
index 9cfcc12..86b82c2 100644
--- a/src/compiler/glsl/glcpp/glcpp-lex.l
+++ b/src/compiler/glsl/glcpp/glcpp-lex.l
@@ -50,6 +50,7 @@ void glcpp_set_column (int column_no , yyscan_t yyscanner);
yylloc->first_line = yylloc->last_line = yylineno; \
yycolumn += yyleng; \
yylloc->last_column = yycolumn + 1; \
+ yylloc->position = (yytext - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf); \
parser->has_new_line_number = 0; \
parser->has_new_source_number = 0; \
} while(0);
diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y
index 4be5cfa..27a1873 100644
--- a/src/compiler/glsl/glcpp/glcpp-parse.y
+++ b/src/compiler/glsl/glcpp/glcpp-parse.y
@@ -1016,7 +1016,7 @@ _token_list_append_list(token_list_t *list, token_list_t *tail)
}
static token_list_t *
-_token_list_copy(glcpp_parser_t *parser, token_list_t *other)
+_token_list_copy(glcpp_parser_t *parser, token_list_t *other, token_node_t *macro_node)
{
token_list_t *copy;
token_node_t *node;
@@ -1028,6 +1028,12 @@ _token_list_copy(glcpp_parser_t *parser, token_list_t *other)
for (node = other->head; node; node = node->next) {
token_t *new_token = linear_alloc_child(parser->linalloc, sizeof(token_t));
*new_token = *node->token;
+
+ if (macro_node) {
+ new_token->location.first_line = macro_node->token->location.first_line;
+ new_token->location.last_line = macro_node->token->location.last_line;
+ }
+
_token_list_append (parser, copy, new_token);
}
@@ -1344,7 +1350,7 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value)
glcpp_parser_t *
glcpp_parser_create(const struct gl_extensions *extension_list,
- glcpp_extension_iterator extensions, void *state, gl_api api)
+ glcpp_extension_iterator extensions, void *state, gl_api api, const char *input)
{
glcpp_parser_t *parser;
@@ -1372,6 +1378,11 @@ glcpp_parser_create(const struct gl_extensions *extension_list,
parser->lex_from_list = NULL;
parser->lex_from_node = NULL;
+ parser->input = _mesa_string_buffer_create(parser, strlen(input) + 1);
+ strcpy(parser->input->buf, input);
+ parser->input->buf[strlen(input)] = '\0';
+ parser->input->length = strlen(input);
+
parser->output = _mesa_string_buffer_create(parser,
INITIAL_PP_OUTPUT_BUF_SIZE);
parser->info_log = _mesa_string_buffer_create(parser,
@@ -1436,7 +1447,7 @@ typedef enum function_status
static function_status_t
_arguments_parse(glcpp_parser_t *parser,
argument_list_t *arguments, token_node_t *node,
- token_node_t **last)
+ token_node_t **last, int *end_position)
{
token_list_t *argument;
int paren_count;
@@ -1460,8 +1471,10 @@ _arguments_parse(glcpp_parser_t *parser,
paren_count++;
} else if (node->token->type == ')') {
paren_count--;
- if (paren_count == 0)
+ if (paren_count == 0) {
+ *end_position = node->token->location.position;
break;
+ }
}
if (node->token->type == ',' && paren_count == 1) {
@@ -1697,6 +1710,28 @@ _glcpp_parser_apply_pastes(glcpp_parser_t *parser, token_list_t *list)
list->non_space_tail = list->tail;
}
+static int
+_glcpp_parser_get_line(glcpp_parser_t *parser, int offset)
+{
+ int line = 1;
+ int i;
+
+ for (i = 0; parser->input->buf[i] && i <= offset; i++) {
+ if (parser->input->buf[i] == '\n' || parser->input->buf[i] == '\r')
+ line++;
+ }
+
+ return line;
+}
+
+static void
+_glcpp_sync_location(glcpp_parser_t *parser, token_t *token, token_t *macro_token)
+{
+ token->location.source = macro_token->location.source;
+ token->location.first_line = _glcpp_parser_get_line(parser, token->location.position);
+ token->location.last_line = token->location.first_line;
+}
+
/* This is a helper function that's essentially part of the
* implementation of _glcpp_parser_expand_node. It shouldn't be called
* except for by that function.
@@ -1727,7 +1762,9 @@ _glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node,
argument_list_t *arguments;
function_status_t status;
token_list_t *substituted;
+ token_node_t *macro_node = node;
int parameter_index;
+ int end_position;
identifier = node->token->value.str;
@@ -1737,7 +1774,7 @@ _glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node,
assert(macro->is_function);
arguments = _argument_list_create(parser);
- status = _arguments_parse(parser, arguments, node, last);
+ status = _arguments_parse(parser, arguments, node, last, &end_position);
switch (status) {
case FUNCTION_STATUS_SUCCESS:
@@ -1779,7 +1816,8 @@ _glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node,
* placeholder token for an empty argument. */
if (argument->head) {
token_list_t *expanded_argument;
- expanded_argument = _token_list_copy(parser, argument);
+ expanded_argument = _token_list_copy(parser, argument, NULL);
+ _glcpp_sync_location(parser, expanded_argument->head->token, macro_node->token);
_glcpp_parser_expand_token_list(parser, expanded_argument, mode);
_token_list_append_list(substituted, expanded_argument);
} else {
@@ -1790,6 +1828,8 @@ _glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node,
_token_list_append(parser, substituted, new_token);
}
} else {
+ node->token->location.position = end_position;
+ _glcpp_sync_location(parser, node->token, macro_node->token);
_token_list_append(parser, substituted, node->token);
}
}
@@ -1830,6 +1870,7 @@ _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node,
const char *identifier;
struct hash_entry *entry;
macro_t *macro;
+ token_node_t *macro_node = node;
/* We only expand identifiers */
if (token->type != IDENTIFIER) {
@@ -1882,7 +1923,7 @@ _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node,
if (macro->replacements == NULL)
return _token_list_create_with_one_space(parser);
- replacement = _token_list_copy(parser, macro->replacements);
+ replacement = _token_list_copy(parser, macro->replacements, macro_node);
_glcpp_parser_apply_pastes(parser, replacement);
return replacement;
}
diff --git a/src/compiler/glsl/glcpp/glcpp.h b/src/compiler/glsl/glcpp/glcpp.h
index c7e382e..eed6923 100644
--- a/src/compiler/glsl/glcpp/glcpp.h
+++ b/src/compiler/glsl/glcpp/glcpp.h
@@ -78,6 +78,7 @@ typedef struct YYLTYPE {
int first_column;
int last_line;
int last_column;
+ int position;
unsigned source;
} YYLTYPE;
# define YYLTYPE_IS_DECLARED 1
@@ -204,6 +205,7 @@ struct glcpp_parser {
token_list_t *lex_from_list;
token_node_t *lex_from_node;
struct _mesa_string_buffer *output;
+ struct _mesa_string_buffer *input;
struct _mesa_string_buffer *info_log;
int error;
glcpp_extension_iterator extensions;
@@ -229,7 +231,7 @@ struct glcpp_parser {
glcpp_parser_t *
glcpp_parser_create(const struct gl_extensions *extension_list,
- glcpp_extension_iterator extensions, void *state, gl_api api);
+ glcpp_extension_iterator extensions, void *state, gl_api api, const char *input);
int
glcpp_parser_parse (glcpp_parser_t *parser);
diff --git a/src/compiler/glsl/glcpp/pp.c b/src/compiler/glsl/glcpp/pp.c
index 32dee11..1ac733f 100644
--- a/src/compiler/glsl/glcpp/pp.c
+++ b/src/compiler/glsl/glcpp/pp.c
@@ -228,7 +228,7 @@ glcpp_preprocess(void *ralloc_ctx, const char **shader, char **info_log,
{
int errors;
glcpp_parser_t *parser =
- glcpp_parser_create(&gl_ctx->Extensions, extensions, state, gl_ctx->API);
+ glcpp_parser_create(&gl_ctx->Extensions, extensions, state, gl_ctx->API, *shader);
if (! gl_ctx->Const.DisableGLSLLineContinuations)
*shader = remove_line_continuations(parser, *shader);
@@ -247,6 +247,7 @@ glcpp_preprocess(void *ralloc_ctx, const char **shader, char **info_log,
/* Crimp the buffer first, to conserve memory */
_mesa_string_buffer_crimp_to_fit(parser->output);
+ ralloc_steal(ralloc_ctx, parser->input->buf);
ralloc_steal(ralloc_ctx, parser->output->buf);
*shader = parser->output->buf;
--
1.9.1
More information about the mesa-dev
mailing list