Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/preproc.l | 20 ++++++++++++++++++++ tests/hlsl_d3d12.c | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l index 388b77f6..c5c49251 100644 --- a/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d-shader/preproc.l @@ -471,6 +471,26 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) } continue; } + + if (!strcmp(text, "__LINE__")) + { + const struct preproc_file *file = preproc_get_top_file(ctx); + + /* Not the current line number, but rather the line + * number before invoking any macros. */ + + if (ctx->current_directive) + { + char string[13]; + + sprintf(string, "%d", file->buffer.location.line); + return return_token(T_INTEGER, lval, string); + } + + if (preproc_is_writing(ctx)) + vkd3d_string_buffer_printf(&ctx->buffer, "%d ", file->buffer.location.line); + continue; + } }
if (ctx->current_directive) diff --git a/tests/hlsl_d3d12.c b/tests/hlsl_d3d12.c index 9d8d16d9..03169716 100644 --- a/tests/hlsl_d3d12.c +++ b/tests/hlsl_d3d12.c @@ -350,7 +350,7 @@ static void test_preprocess(void) for (i = 0; i < ARRAY_SIZE(tests); ++i) { vkd3d_test_set_context("Source "%s"", tests[i].source); - todo_if (i == 9 || (i >= 12 && i <= 14)) + todo_if (i == 9) check_preprocess(tests[i].source, NULL, NULL, tests[i].present, tests[i].absent); } vkd3d_test_set_context(NULL);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/preproc.l | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l index c5c49251..80ac7d03 100644 --- a/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d-shader/preproc.l @@ -472,6 +472,29 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) continue; }
+ if (!strcmp(text, "__FILE__")) + { + const struct preproc_file *file = preproc_get_top_file(ctx); + + /* Not the current file name, but rather the file name + * before invoking any macros. */ + + if (ctx->current_directive) + { + char *string; + + if (!(string = vkd3d_malloc(strlen(file->filename) + 3))) + return 0; + sprintf(string, ""%s"", file->filename); + lval->string = string; + return T_STRING; + } + + if (preproc_is_writing(ctx)) + vkd3d_string_buffer_printf(&ctx->buffer, ""%s" ", file->filename); + continue; + } + if (!strcmp(text, "__LINE__")) { const struct preproc_file *file = preproc_get_top_file(ctx);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/preproc.l | 13 +++++++++++++ libs/vkd3d-shader/preproc.y | 1 + tests/hlsl_d3d12.c | 3 +-- 3 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l index 80ac7d03..f7aee198 100644 --- a/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d-shader/preproc.l @@ -129,6 +129,8 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]* return T_IFDEF; if (!strcmp(p, "ifndef")) return T_IFNDEF; + if (!strcmp(p, "pragma")) + return T_PRAGMA; if (!strcmp(p, "undef")) return T_UNDEF;
@@ -352,6 +354,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) case T_IFDEF: case T_IFNDEF: case T_INCLUDE: + case T_PRAGMA: case T_UNDEF: ctx->current_directive = token; break; @@ -387,6 +390,16 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) continue; }
+ if (ctx->current_directive == T_PRAGMA) + { + /* Print all tokens verbatim. */ + if (token == T_PRAGMA) + vkd3d_string_buffer_printf(&ctx->buffer, "#pragma "); + else + vkd3d_string_buffer_printf(&ctx->buffer, "%s", text); + continue; + } + switch (func_state->state) { case STATE_NONE: diff --git a/libs/vkd3d-shader/preproc.y b/libs/vkd3d-shader/preproc.y index 72d6486e..4b276a95 100644 --- a/libs/vkd3d-shader/preproc.y +++ b/libs/vkd3d-shader/preproc.y @@ -326,6 +326,7 @@ static void free_parse_arg_names(struct parse_arg_names *args) %token T_IFDEF "#ifdef" %token T_IFNDEF "#ifndef" %token T_INCLUDE "#include" +%token T_PRAGMA "#pragma" %token T_UNDEF "#undef"
%token T_CONCAT "##" diff --git a/tests/hlsl_d3d12.c b/tests/hlsl_d3d12.c index 03169716..837476d1 100644 --- a/tests/hlsl_d3d12.c +++ b/tests/hlsl_d3d12.c @@ -350,8 +350,7 @@ static void test_preprocess(void) for (i = 0; i < ARRAY_SIZE(tests); ++i) { vkd3d_test_set_context("Source "%s"", tests[i].source); - todo_if (i == 9) - check_preprocess(tests[i].source, NULL, NULL, tests[i].present, tests[i].absent); + check_preprocess(tests[i].source, NULL, NULL, tests[i].present, tests[i].absent); } vkd3d_test_set_context(NULL);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 1 - libs/vkd3d-shader/preproc.l | 12 +++++++++++- libs/vkd3d-shader/preproc.y | 10 ++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 4 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 22151adf..30bea627 100644 --- a/Makefile.am +++ b/Makefile.am @@ -245,7 +245,6 @@ XFAIL_TESTS = \ tests/math.shader_test \ tests/preproc-ifdef.shader_test \ tests/preproc-if-expr.shader_test \ - tests/preproc-invalid.shader_test \ tests/preproc-macro.shader_test \ tests/swizzle-0.shader_test \ tests/swizzle-1.shader_test \ diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l index f7aee198..a2c1e26e 100644 --- a/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d-shader/preproc.l @@ -50,6 +50,7 @@ static void update_location(struct preproc_ctx *ctx); %s C_COMMENT %s CXX_COMMENT
+%s ERROR %s INCLUDE
NEWLINE \r?\n @@ -70,6 +71,8 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]* <C_COMMENT,CXX_COMMENT><<EOF>> {yy_pop_state(yyscanner);} <C_COMMENT,CXX_COMMENT>. {}
+<ERROR>(\{NEWLINE}|[^\n])* {return T_STRING;} + <INITIAL>{IDENTIFIER}/( {return T_IDENTIFIER_PAREN;} <INITIAL>{IDENTIFIER} {return T_IDENTIFIER;}
@@ -109,6 +112,12 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]* for (p = yytext + 1; strchr(" \t", *p); ++p) ;
+ if (!strcmp(p, "error")) + { + BEGIN(ERROR); + return T_ERROR; + } + if (!strcmp(p, "include")) { BEGIN(INCLUDE); @@ -140,7 +149,7 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]* }
<INITIAL,INCLUDE>\{NEWLINE} {} -<INITIAL,INCLUDE>{NEWLINE} { +<INITIAL,INCLUDE,ERROR>{NEWLINE} { BEGIN(INITIAL); return T_NEWLINE; } @@ -350,6 +359,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) case T_ELIF: case T_ELSE: case T_ENDIF: + case T_ERROR: case T_IF: case T_IFDEF: case T_IFNDEF: diff --git a/libs/vkd3d-shader/preproc.y b/libs/vkd3d-shader/preproc.y index 4b276a95..9f650549 100644 --- a/libs/vkd3d-shader/preproc.y +++ b/libs/vkd3d-shader/preproc.y @@ -319,6 +319,7 @@ static void free_parse_arg_names(struct parse_arg_names *args) %token T_NEWLINE
%token T_DEFINE "#define" +%token T_ERROR "#error" %token T_ELIF "#elif" %token T_ELSE "#else" %token T_ENDIF "#endif" @@ -534,6 +535,15 @@ directive preproc_warning(ctx, &@$, VKD3D_SHADER_WARNING_PP_INVALID_DIRECTIVE, "Ignoring #endif without prior #if."); } + | T_ERROR T_NEWLINE + { + preproc_error(ctx, &@$, VKD3D_SHADER_ERROR_PP_ERROR_DIRECTIVE, "Error directive."); + } + | T_ERROR T_STRING T_NEWLINE + { + preproc_error(ctx, &@$, VKD3D_SHADER_ERROR_PP_ERROR_DIRECTIVE, "Error directive: %s", $2); + vkd3d_free($2); + } | T_INCLUDE T_STRING T_NEWLINE { PFN_vkd3d_shader_open_include open_include = ctx->preprocess_info->pfn_open_include; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 157dc5e2..8d9821d5 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -81,6 +81,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_RS_MIXED_DESCRIPTOR_RANGE_TYPES = 3004,
VKD3D_SHADER_ERROR_PP_INVALID_SYNTAX = 4000, + VKD3D_SHADER_ERROR_PP_ERROR_DIRECTIVE = 4001, VKD3D_SHADER_ERROR_PP_INCLUDE_FAILED = 4002,
VKD3D_SHADER_WARNING_PP_ALREADY_DEFINED = 4300,
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@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); + }
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com