4 * Copyright 2008 Stefan Dösinger
5 * Copyright 2012 Matteo Bruni for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/debug.h"
27 #include "d3dcompiler_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser);
33 struct hlsl_parse_ctx hlsl_ctx;
35 void hlsl_message(const char *fmt, ...)
40 compilation_message(&hlsl_ctx.messages, fmt, args);
44 static void hlsl_error(const char *s)
46 hlsl_message("Line %u: %s\n", hlsl_ctx.line_no, s);
47 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
50 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
52 TRACE("Line %u: ", line_no);
53 TRACE("%s %s;\n", debug_hlsl_type(type), declname);
56 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
60 TRACE("Declaring variable %s.\n", decl->name);
61 ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
64 struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
66 hlsl_message("Line %u: \"%s\" already declared.\n", hlsl_ctx.line_no, decl->name);
67 hlsl_message("Line %u: \"%s\" was previously declared here.\n", old->node.line, decl->name);
68 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
80 struct hlsl_type *type;
86 struct parse_variable_def *variable_def;
93 %token KW_COLUMN_MAJOR
97 %token KW_DEPTHSTENCILSTATE
98 %token KW_DEPTHSTENCILVIEW
106 %token KW_GEOMETRYSHADER
107 %token KW_GROUPSHARED
114 %token KW_NOINTERPOLATION
117 %token KW_PIXELSHADER
119 %token KW_RASTERIZERSTATE
120 %token KW_RENDERTARGETVIEW
128 %token KW_SAMPLERCUBE
129 %token KW_SAMPLER_STATE
130 %token KW_SAMPLERCOMPARISONSTATE
133 %token KW_STATEBLOCK_STATE
140 %token KW_TECHNIQUE10
143 %token KW_TEXTURE1DARRAY
145 %token KW_TEXTURE2DARRAY
146 %token KW_TEXTURE2DMS
147 %token KW_TEXTURE2DMSARRAY
149 %token KW_TEXTURE3DARRAY
150 %token KW_TEXTURECUBE
155 %token KW_VERTEXSHADER
166 %token OP_LEFTSHIFTASSIGN
168 %token OP_RIGHTSHIFTASSIGN
188 %token <intval> PRE_LINE
190 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
191 %type <name> any_identifier
193 %token <floatval> C_FLOAT
194 %token <intval> C_INTEGER
195 %type <type> base_type
197 %type <modifiers> var_modifiers
199 %type <name> semantic
200 %type <variable_def> variable_def
201 %type <list> variables_def
204 hlsl_prog: /* empty */
207 | hlsl_prog declaration_statement
209 TRACE("Declaration statement parsed.\n");
211 | hlsl_prog preproc_directive
215 preproc_directive: PRE_LINE STRING
217 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
218 hlsl_ctx.line_no = $1 - 1;
219 d3dcompiler_free(hlsl_ctx.source_file);
220 hlsl_ctx.source_file = $2;
223 any_identifier: VAR_IDENTIFIER
227 semantic: /* Empty */
243 $$ = new_hlsl_type("void", HLSL_TYPE_VOID, 1, 1);
247 struct hlsl_type *type;
249 TRACE("Type %s.\n", $1);
250 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
252 d3dcompiler_free($1);
254 | KW_STRUCT TYPE_IDENTIFIER
256 struct hlsl_type *type;
258 TRACE("Struct type %s.\n", $2);
259 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
260 if (type->base_type != HLSL_TYPE_STRUCT)
262 hlsl_message("Line %u: Redefining %s as a structure.\n",
263 hlsl_ctx.line_no, $2);
264 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
270 d3dcompiler_free($2);
273 declaration_statement: declaration
277 declaration: var_modifiers type variables_def ';'
279 struct parse_variable_def *v, *v_next;
280 struct hlsl_ir_var *var;
281 BOOL ret, local = TRUE;
283 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
285 debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
286 var = d3dcompiler_alloc(sizeof(*var));
287 var->node.type = HLSL_IR_VAR;
289 var->node.data_type = new_array_type($2, v->array_size);
291 var->node.data_type = $2;
294 var->semantic = v->semantic;
295 var->node.line = hlsl_ctx.line_no;
298 FIXME("Variable with an initializer.\n");
301 ret = declare_variable(var, local);
303 free_declaration(var);
305 TRACE("Declared variable %s.\n", var->name);
308 d3dcompiler_free($3);
311 variables_def: variable_def
313 $$ = d3dcompiler_alloc(sizeof(*$$));
315 list_add_head($$, &$1->entry);
317 | variables_def ',' variable_def
320 list_add_tail($$, &$3->entry);
323 /* FIXME: Local variables can't have semantics. */
324 variable_def: any_identifier array semantic
326 $$ = d3dcompiler_alloc(sizeof(*$$));
337 var_modifiers: /* Empty */
344 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const char *entrypoint, char **messages)
346 struct hlsl_scope *scope, *next_scope;
347 struct hlsl_type *hlsl_type, *next_type;
348 struct hlsl_ir_var *var, *next_var;
350 hlsl_ctx.line_no = 1;
351 hlsl_ctx.source_file = d3dcompiler_strdup("");
352 hlsl_ctx.cur_scope = NULL;
353 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
354 list_init(&hlsl_ctx.scopes);
355 list_init(&hlsl_ctx.types);
356 list_init(&hlsl_ctx.functions);
358 push_scope(&hlsl_ctx);
359 hlsl_ctx.globals = hlsl_ctx.cur_scope;
363 d3dcompiler_free(hlsl_ctx.source_file);
365 TRACE("Freeing variables.\n");
366 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
368 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
370 free_declaration(var);
372 d3dcompiler_free(scope);
375 TRACE("Freeing types.\n");
376 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
378 free_hlsl_type(hlsl_type);