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

@ -60,6 +60,7 @@ struct preproc_expansion
{
struct preproc_buffer buffer;
const struct preproc_text *text;
struct preproc_text *arg_values;
/* Back-pointer to the macro, if this expansion a macro body. This is
* necessary so that argument tokens can be correctly replaced. */
struct preproc_macro *macro;
@ -72,7 +73,6 @@ struct preproc_macro
char **arg_names;
size_t arg_count;
struct preproc_text *arg_values;
struct preproc_text body;
};
@ -117,6 +117,7 @@ struct preproc_ctx
STATE_ARGS,
} state;
unsigned int paren_depth;
struct preproc_text *arg_values;
} text_func, directive_func;
int current_directive;

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
{

View File

@ -91,7 +91,6 @@ bool preproc_add_macro(struct preproc_ctx *ctx, const struct vkd3d_shader_locati
size_t arg_count, const struct vkd3d_shader_location *body_loc, struct vkd3d_string_buffer *body)
{
struct preproc_macro *macro;
unsigned int i;
int ret;
if ((macro = preproc_find_macro(ctx, name)))
@ -108,14 +107,6 @@ bool preproc_add_macro(struct preproc_ctx *ctx, const struct vkd3d_shader_locati
macro->name = name;
macro->arg_names = arg_names;
macro->arg_count = arg_count;
macro->arg_values = NULL;
if (arg_count && !(macro->arg_values = vkd3d_calloc(arg_count, sizeof(*macro->arg_values))))
{
vkd3d_free(macro);
return false;
}
for (i = 0; i < arg_count; ++i)
vkd3d_string_buffer_init(&macro->arg_values[i].text);
macro->body.text = *body;
macro->body.location = *body_loc;
ret = rb_put(&ctx->macros, name, &macro->entry);
@ -129,12 +120,8 @@ void preproc_free_macro(struct preproc_macro *macro)
vkd3d_free(macro->name);
for (i = 0; i < macro->arg_count; ++i)
{
vkd3d_string_buffer_cleanup(&macro->arg_values[i].text);
vkd3d_free(macro->arg_names[i]);
}
vkd3d_free(macro->arg_names);
vkd3d_free(macro->arg_values);
vkd3d_string_buffer_cleanup(&macro->body.text);
vkd3d_free(macro);
}

View File

@ -375,3 +375,7 @@ key1
[preproc]
#define key1 ::key2 pass
key1
[preproc]
#define KEY(a, b) a b
KEY(KEY(x, y), pass)