Skip to content
Snippets Groups Projects
Commit d2711f9b authored by Timothy Arceri's avatar Timothy Arceri Committed by Marge Bot
Browse files

glsl/glcpp: make sure to expand new token after concatenation

Previously the code was using a hack to change the token type from
INDETIFIER -> OTHER in order to avoid getting in an infinite loop
expanding the tokens. This worked ok until we got to a paste where
the replacement parameters had already had their type changed
to OTHER because the newly created paste token would then
inherit the OTHER type and never get expanded inself.

For example with the follow code:

   #define STEP_ONE() \
	out_Color = vec4(0.0,1.0,0.0,1.0)

   #define GLUE(x,y) x ## _ ## y
   #define EVALUATE(x,y)  GLUE(x,y)
   #define STEP(stepname) EVALUATE(STEP, stepname)()
   #define PERFORM_RAYCASTING_STEP STEP(ONE)

This would get all the way to expanding PERFORM_RAYCASTING_STEP to
STEP_ONE() but because it was created via the paste `x ## _ ## y`
it would never get any further.

To fix this we remove the OTHER hack and instead just track if the
token has already been handled via a bool value `explanding`.

Closes: mesa/mesa#5724



Fixes: 28842c23 ("glcpp: Implement token pasting for non-function-like macros")

Acked-by: default avatarPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Reviewed-by: default avatarIan Romanick <ian.d.romanick@intel.com>
Part-of: <mesa/mesa!14101>
parent 4dc6cd59
No related branches found
No related tags found
No related merge requests found
......@@ -1057,6 +1057,7 @@ _token_create_str(glcpp_parser_t *parser, int type, char *str)
token = linear_alloc_child(parser->linalloc, sizeof(token_t));
token->type = type;
token->value.str = str;
token->expanding = false;
return token;
}
......@@ -1069,6 +1070,7 @@ _token_create_ival(glcpp_parser_t *parser, int type, int ival)
token = linear_alloc_child(parser->linalloc, sizeof(token_t));
token->type = type;
token->value.ival = ival;
token->expanding = false;
return token;
}
......@@ -1958,6 +1960,10 @@ _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node,
struct hash_entry *entry;
macro_t *macro;
/* If token is already being expanded return to avoid an infinite loop */
if (token->expanding)
return NULL;
/* We only expand identifiers */
if (token->type != IDENTIFIER) {
return NULL;
......@@ -1988,14 +1994,15 @@ _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node,
/* Finally, don't expand this macro if we're already actively
* expanding it, (to avoid infinite recursion). */
if (_parser_active_list_contains (parser, identifier)) {
/* We change the token type here from IDENTIFIER to OTHER to prevent any
/* We change the `expanding` bool to true to prevent any
* future expansion of this unexpanded token. */
char *str;
token_list_t *expansion;
token_t *final;
str = linear_strdup(parser->linalloc, token->value.str);
final = _token_create_str(parser, OTHER, str);
final = _token_create_str(parser, token->type, str);
final->expanding = true;
expansion = _token_list_create(parser);
_token_list_append(parser, expansion, final);
return expansion;
......
......@@ -103,6 +103,7 @@ do { \
} while (0)
struct token {
bool expanding;
int type;
YYSTYPE value;
YYLTYPE location;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment