vkd3d-shader/preproc: Store argument values per expansion, not per macro.

This commit is contained in:
Elizabeth Figura
2024-09-20 15:41:35 -05:00
committed by Henri Verbeet
parent e7c4867359
commit aa79bfa681
Notes: Henri Verbeet 2024-10-07 17:53:30 +02:00
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1147
4 changed files with 38 additions and 35 deletions

View File

@@ -29,11 +29,11 @@
#define YY_DECL static int preproc_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner)
static struct preproc_macro *preproc_get_top_macro(struct preproc_ctx *ctx)
static struct preproc_expansion *preproc_get_top_expansion(struct preproc_ctx *ctx)
{
if (!ctx->expansion_count)
return NULL;
return ctx->expansion_stack[ctx->expansion_count - 1].macro;
return &ctx->expansion_stack[ctx->expansion_count - 1];
}
static void update_location(struct preproc_ctx *ctx);
@@ -132,14 +132,14 @@ INT_SUFFIX [uUlL]{0,2}
if (!ctx->last_was_newline)
{
struct preproc_macro *macro;
struct preproc_expansion *exp;
/* Stringification is only done for function-like macro bodies.
* Anywhere else, we need to parse it as two separate tokens.
* We could use a state for this, but yyless() is easier and cheap.
*/
if ((macro = preproc_get_top_macro(ctx)) && macro->arg_count)
if ((exp = preproc_get_top_expansion(ctx)) && exp->macro && exp->macro->arg_count)
return T_HASHSTRING;
yyless(1);
@@ -258,6 +258,12 @@ static void preproc_pop_buffer(struct preproc_ctx *ctx)
yy_delete_buffer(exp->buffer.lexer_buffer, ctx->scanner);
if (exp->macro)
{
for (unsigned int i = 0; i < exp->macro->arg_count; ++i)
vkd3d_string_buffer_cleanup(&exp->arg_values[i].text);
free(exp->arg_values);
}
--ctx->expansion_count;
TRACE("Expansion stack size is now %zu.\n", ctx->expansion_count);
}
@@ -310,15 +316,15 @@ static int return_token(int token, YYSTYPE *lval, const char *text)
static const struct preproc_text *find_arg_expansion(struct preproc_ctx *ctx, const char *s)
{
struct preproc_macro *macro;
struct preproc_expansion *exp;
unsigned int i;
if ((macro = preproc_get_top_macro(ctx)))
if ((exp = preproc_get_top_expansion(ctx)) && exp->macro)
{
for (i = 0; i < macro->arg_count; ++i)
for (i = 0; i < exp->macro->arg_count; ++i)
{
if (!strcmp(s, macro->arg_names[i]))
return &macro->arg_values[i];
if (!strcmp(s, exp->macro->arg_names[i]))
return &exp->arg_values[i];
}
}
return NULL;
@@ -330,7 +336,7 @@ static void preproc_text_add(struct preproc_text *text, const char *string)
}
static bool preproc_push_expansion(struct preproc_ctx *ctx,
const struct preproc_text *text, struct preproc_macro *macro)
const struct preproc_text *text, struct preproc_macro *macro, struct preproc_text *arg_values)
{
struct preproc_expansion *exp;
@@ -342,6 +348,7 @@ static bool preproc_push_expansion(struct preproc_ctx *ctx,
exp->buffer.lexer_buffer = yy_scan_bytes(text->text.buffer, text->text.content_size, ctx->scanner);
exp->buffer.location = text->location;
exp->macro = macro;
exp->arg_values = arg_values;
TRACE("Expansion stack size is now %zu.\n", ctx->expansion_count);
return true;
}
@@ -542,7 +549,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
if ((expansion = find_arg_expansion(ctx, text)))
{
preproc_push_expansion(ctx, expansion, NULL);
preproc_push_expansion(ctx, expansion, NULL, NULL);
continue;
}
@@ -550,7 +557,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
{
if (!macro->arg_count)
{
preproc_push_expansion(ctx, &macro->body, macro);
preproc_push_expansion(ctx, &macro->body, macro, NULL);
}
else
{
@@ -616,16 +623,19 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
case STATE_IDENTIFIER:
if (token == '(')
{
struct preproc_text *first_arg = &func_state->macro->arg_values[0];
unsigned int i;
struct preproc_text *arg_values;
if (!(arg_values = calloc(func_state->macro->arg_count, sizeof(*arg_values))))
return 0;
for (unsigned int i = 0; i < func_state->macro->arg_count; ++i)
vkd3d_string_buffer_init(&arg_values[i].text);
arg_values[0].location = *lloc;
func_state->arg_count = 0;
func_state->paren_depth = 1;
func_state->state = STATE_ARGS;
for (i = 0; i < func_state->macro->arg_count; ++i)
func_state->macro->arg_values[i].text.content_size = 0;
first_arg->location = *lloc;
func_state->arg_values = arg_values;
}
else
{
@@ -649,7 +659,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
VKD3D_ASSERT(func_state->macro->arg_count);
if (func_state->arg_count < func_state->macro->arg_count)
current_arg = &func_state->macro->arg_values[func_state->arg_count];
current_arg = &func_state->arg_values[func_state->arg_count];
switch (token)
{
@@ -664,7 +674,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
if ((expansion = find_arg_expansion(ctx, text)))
{
preproc_push_expansion(ctx, expansion, NULL);
preproc_push_expansion(ctx, expansion, NULL, NULL);
continue;
}
@@ -700,7 +710,8 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
{
if (++func_state->arg_count == func_state->macro->arg_count)
{
preproc_push_expansion(ctx, &func_state->macro->body, func_state->macro);
preproc_push_expansion(ctx, &func_state->macro->body,
func_state->macro, func_state->arg_values);
}
else
{