Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com> --- libs/vkd3d-shader/preproc.h | 1 + libs/vkd3d-shader/preproc.l | 16 ++++++++++++++++ libs/vkd3d-shader/preproc.y | 15 +++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/libs/vkd3d-shader/preproc.h b/libs/vkd3d-shader/preproc.h index 0f2d8ba9..eff70f69 100644 --- a/libs/vkd3d-shader/preproc.h +++ b/libs/vkd3d-shader/preproc.h @@ -125,6 +125,7 @@ struct preproc_ctx bool last_was_newline; bool last_was_eof; + bool last_was_defined; bool error; }; diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l index a2c1e26e..95b043ed 100644 --- a/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d-shader/preproc.l @@ -73,6 +73,8 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]* <ERROR>(\\{NEWLINE}|[^\n])* {return T_STRING;} +<INITIAL>defined/\( {return T_DEFINED;} +<INITIAL>defined {return T_DEFINED;} <INITIAL>{IDENTIFIER}/\( {return T_IDENTIFIER_PAREN;} <INITIAL>{IDENTIFIER} {return T_IDENTIFIER;} @@ -377,6 +379,9 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) ctx->last_was_newline = (token == T_NEWLINE); } + if (ctx->current_directive && token == T_DEFINED) + ctx->last_was_defined = true; + func_state = ctx->current_directive ? &ctx->directive_func : &ctx->text_func; TRACE("Parsing token %d%s, line %d, in directive %d, state %#x, string %s.\n", @@ -471,6 +476,17 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) case T_UNDEF: /* Return identifiers verbatim. */ return return_token(token, lval, text); + + case T_IF: + case T_ELIF: + /* Return identifiers verbatim only if they're the + * argument to "defined". */ + if (ctx->last_was_defined) + { + ctx->last_was_defined = false; + return return_token(token, lval, text); + } + break; } /* Otherwise, expand a macro if there is one. */ diff --git a/libs/vkd3d-shader/preproc.y b/libs/vkd3d-shader/preproc.y index 9f650549..f9047c9f 100644 --- a/libs/vkd3d-shader/preproc.y +++ b/libs/vkd3d-shader/preproc.y @@ -331,6 +331,7 @@ static void free_parse_arg_names(struct parse_arg_names *args) %token T_UNDEF "#undef" %token T_CONCAT "##" +%token T_DEFINED "defined" %type <integer> expr %type <string> body_token @@ -429,6 +430,10 @@ body_token_const { $$ = "##"; } + | T_DEFINED + { + $$ = "defined"; + } directive : T_DEFINE T_IDENTIFIER body_text T_NEWLINE @@ -583,3 +588,13 @@ expr $$ = preproc_parse_integer($1); vkd3d_free($1); } + | T_DEFINED T_IDENTIFIER + { + $$ = !!preproc_find_macro(ctx, $2); + vkd3d_free($2); + } + | T_DEFINED '(' T_IDENTIFIER ')' + { + $$ = !!preproc_find_macro(ctx, $3); + vkd3d_free($3); + } -- 2.30.0