vkd3d-shader/preproc: Parse hash marks as two separate tokens when not in stringification contexts.

This commit is contained in:
Zebediah Figura 2023-07-29 18:08:29 -05:00 committed by Alexandre Julliard
parent 9a80ff28e4
commit 9b98489155
Notes: Alexandre Julliard 2023-08-02 21:24:27 +09:00
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/291
2 changed files with 26 additions and 15 deletions

View File

@ -29,6 +29,13 @@
#define YY_DECL static int preproc_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner) #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)
{
if (!ctx->expansion_count)
return NULL;
return ctx->expansion_stack[ctx->expansion_count - 1].macro;
}
static void update_location(struct preproc_ctx *ctx); static void update_location(struct preproc_ctx *ctx);
#define YY_USER_ACTION update_location(yyget_extra(yyscanner)); #define YY_USER_ACTION update_location(yyget_extra(yyscanner));
@ -124,7 +131,20 @@ INT_SUFFIX [uUlL]{0,2}
const char *p; const char *p;
if (!ctx->last_was_newline) if (!ctx->last_was_newline)
return T_HASHSTRING; {
struct preproc_macro *macro;
/* 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)
return T_HASHSTRING;
yyless(1);
return T_TEXT;
}
for (p = yytext + 1; strchr(" \t", *p); ++p) for (p = yytext + 1; strchr(" \t", *p); ++p)
; ;
@ -218,13 +238,6 @@ static bool preproc_is_writing(struct preproc_ctx *ctx)
return file->if_stack[file->if_count - 1].current_true; return file->if_stack[file->if_count - 1].current_true;
} }
static struct preproc_macro *preproc_get_top_macro(struct preproc_ctx *ctx)
{
if (!ctx->expansion_count)
return NULL;
return ctx->expansion_stack[ctx->expansion_count - 1].macro;
}
/* Concatenation is not done for object-like macros, but is done for both /* Concatenation is not done for object-like macros, but is done for both
* function-like macro bodies and their arguments. */ * function-like macro bodies and their arguments. */
static bool should_concat(struct preproc_ctx *ctx) static bool should_concat(struct preproc_ctx *ctx)
@ -440,9 +453,6 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
switch (func_state->state) switch (func_state->state)
{ {
case STATE_NONE: case STATE_NONE:
{
struct preproc_macro *macro;
if (token == T_CONCAT && should_concat(ctx)) if (token == T_CONCAT && should_concat(ctx))
{ {
while (ctx->buffer.content_size while (ctx->buffer.content_size
@ -451,9 +461,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
break; break;
} }
/* Stringification, however, is only done for function-like if (token == T_HASHSTRING)
* macro bodies. */
if (token == T_HASHSTRING && (macro = preproc_get_top_macro(ctx)) && macro->arg_count)
{ {
const struct preproc_text *expansion; const struct preproc_text *expansion;
const char *p = text + 1; const char *p = text + 1;
@ -585,7 +593,6 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
else else
vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text); vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text);
break; break;
}
case STATE_IDENTIFIER: case STATE_IDENTIFIER:
if (token == '(') if (token == '(')

View File

@ -301,3 +301,7 @@ fail
[preproc] [preproc]
#define __LINE__ pass #define __LINE__ pass
__LINE__ __LINE__
[preproc]
#define KEY pass
apple # KEY