mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 11:38:05 +02:00
Fix bug (and add tests) for a function-like macro defined as itself.
This case worked previously, but broke in the recent rewrite of function- like macro expansion. The recursion was still terminated correctly, but any parenthesized expression after the macro name was still being swallowed even though the identifier was not being expanded as a macro. The fix is to notice earlier that the identifier is an already-expanding macro. We let the lexer know this through the classify_token function so that an already-expanding macro is lexed as an identifier, not a FUNC_MACRO.
This commit is contained in:
parent
a807fb72c4
commit
be0e2e9b2a
3 changed files with 30 additions and 33 deletions
|
|
@ -427,6 +427,22 @@ glcpp_parser_destroy (glcpp_parser_t *parser)
|
|||
talloc_free (parser);
|
||||
}
|
||||
|
||||
static int
|
||||
glcpp_parser_is_expanding (glcpp_parser_t *parser, const char *member)
|
||||
{
|
||||
expansion_node_t *node;
|
||||
|
||||
for (node = parser->expansions; node; node = node->next) {
|
||||
if (node->macro &&
|
||||
strcmp (node->macro->identifier, member) == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
token_class_t
|
||||
glcpp_parser_classify_token (glcpp_parser_t *parser,
|
||||
const char *identifier,
|
||||
|
|
@ -457,6 +473,12 @@ glcpp_parser_classify_token (glcpp_parser_t *parser,
|
|||
if (macro == NULL)
|
||||
return TOKEN_CLASS_IDENTIFIER;
|
||||
|
||||
/* Don't consider this a macro if we are already actively
|
||||
* expanding this macro. */
|
||||
if (glcpp_parser_is_expanding (parser, identifier))
|
||||
return TOKEN_CLASS_IDENTIFIER;
|
||||
|
||||
/* Definitely a macro. Just need to check if it's function-like. */
|
||||
if (macro->is_function)
|
||||
return TOKEN_CLASS_FUNC_MACRO;
|
||||
else
|
||||
|
|
@ -580,37 +602,6 @@ glcpp_parser_pop_expansion (glcpp_parser_t *parser)
|
|||
talloc_free (node);
|
||||
}
|
||||
|
||||
int
|
||||
glcpp_parser_is_expanding (glcpp_parser_t *parser, const char *member)
|
||||
{
|
||||
expansion_node_t *node;
|
||||
|
||||
for (node = parser->expansions; node; node = node->next) {
|
||||
if (node->macro &&
|
||||
strcmp (node->macro->identifier, member) == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_expand_macro (glcpp_parser_t *parser,
|
||||
const char *token,
|
||||
macro_t *macro,
|
||||
argument_list_t *arguments)
|
||||
{
|
||||
/* Don't recurse if we're already actively expanding this token. */
|
||||
if (glcpp_parser_is_expanding (parser, token)) {
|
||||
printf ("%s", token);
|
||||
return;
|
||||
}
|
||||
|
||||
glcpp_parser_push_expansion_macro (parser, macro, arguments);
|
||||
}
|
||||
|
||||
void
|
||||
_expand_object_macro (glcpp_parser_t *parser, const char *identifier)
|
||||
{
|
||||
|
|
@ -618,8 +609,9 @@ _expand_object_macro (glcpp_parser_t *parser, const char *identifier)
|
|||
|
||||
macro = hash_table_find (parser->defines, identifier);
|
||||
assert (! macro->is_function);
|
||||
assert (! glcpp_parser_is_expanding (parser, identifier));
|
||||
|
||||
_expand_macro (parser, identifier, macro, NULL);
|
||||
glcpp_parser_push_expansion_macro (parser, macro, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -631,6 +623,7 @@ _expand_function_macro (glcpp_parser_t *parser,
|
|||
|
||||
macro = hash_table_find (parser->defines, identifier);
|
||||
assert (macro->is_function);
|
||||
assert (! glcpp_parser_is_expanding (parser, identifier));
|
||||
|
||||
if (_argument_list_length (arguments) !=
|
||||
_string_list_length (macro->parameters))
|
||||
|
|
@ -643,5 +636,5 @@ _expand_function_macro (glcpp_parser_t *parser,
|
|||
return;
|
||||
}
|
||||
|
||||
_expand_macro (parser, identifier, macro, arguments);
|
||||
glcpp_parser_push_expansion_macro (parser, macro, arguments);
|
||||
}
|
||||
|
|
|
|||
2
tests/032-define-func-self-recurse.c
Normal file
2
tests/032-define-func-self-recurse.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define foo(a) foo(2 * (a))
|
||||
foo(3)
|
||||
2
tests/033-define-func-self-compose.c
Normal file
2
tests/033-define-func-self-compose.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define foo(a) foo(2 * (a))
|
||||
foo(foo(3))
|
||||
Loading…
Add table
Reference in a new issue