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);
54 TRACE("%s ", debug_modifiers(modifiers));
55 TRACE("%s %s;\n", debug_hlsl_type(type), declname);
58 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
62 TRACE("Declaring variable %s.\n", decl->name);
63 if (decl->node.data_type->type == HLSL_CLASS_MATRIX)
65 if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)))
67 decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR
68 ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR;
73 DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
74 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
77 hlsl_message("Line %u: modifier '%s' invalid for local variables.\n",
78 hlsl_ctx.line_no, debug_modifiers(invalid));
79 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
82 ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
85 struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
87 hlsl_message("Line %u: \"%s\" already declared.\n", hlsl_ctx.line_no, decl->name);
88 hlsl_message("Line %u: \"%s\" was previously declared here.\n", old->node.line, decl->name);
89 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
95 static DWORD add_modifier(DWORD modifiers, DWORD mod)
99 hlsl_message("Line %u: modifier '%s' already specified.\n",
100 hlsl_ctx.line_no, debug_modifiers(mod));
101 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
104 if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
105 && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
107 hlsl_message("Line %u: more than one matrix majority keyword.\n",
109 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
112 return modifiers | mod;
121 struct hlsl_type *type;
127 struct hlsl_ir_var *var;
128 struct hlsl_ir_node *instr;
130 struct parse_variable_def *variable_def;
137 %token KW_COLUMN_MAJOR
141 %token KW_DEPTHSTENCILSTATE
142 %token KW_DEPTHSTENCILVIEW
150 %token KW_GEOMETRYSHADER
151 %token KW_GROUPSHARED
158 %token KW_NOINTERPOLATION
161 %token KW_PIXELSHADER
163 %token KW_RASTERIZERSTATE
164 %token KW_RENDERTARGETVIEW
172 %token KW_SAMPLERCUBE
173 %token KW_SAMPLER_STATE
174 %token KW_SAMPLERCOMPARISONSTATE
177 %token KW_STATEBLOCK_STATE
184 %token KW_TECHNIQUE10
187 %token KW_TEXTURE1DARRAY
189 %token KW_TEXTURE2DARRAY
190 %token KW_TEXTURE2DMS
191 %token KW_TEXTURE2DMSARRAY
193 %token KW_TEXTURE3DARRAY
194 %token KW_TEXTURECUBE
199 %token KW_VERTEXSHADER
210 %token OP_LEFTSHIFTASSIGN
212 %token OP_RIGHTSHIFTASSIGN
230 %token <intval> PRE_LINE
232 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
233 %type <name> any_identifier
235 %token <floatval> C_FLOAT
236 %token <intval> C_INTEGER
237 %type <boolval> boolean
238 %type <type> base_type
240 %type <list> complex_initializer
241 %type <list> initializer_expr_list
242 %type <instr> initializer_expr
243 %type <modifiers> var_modifiers
247 %type <name> semantic
248 %type <variable_def> variable_def
249 %type <list> variables_def
250 %type <instr> primary_expr
251 %type <instr> postfix_expr
252 %type <instr> unary_expr
253 %type <instr> mul_expr
254 %type <instr> add_expr
255 %type <instr> shift_expr
256 %type <instr> relational_expr
257 %type <instr> equality_expr
258 %type <instr> bitand_expr
259 %type <instr> bitxor_expr
260 %type <instr> bitor_expr
261 %type <instr> logicand_expr
262 %type <instr> logicor_expr
263 %type <instr> conditional_expr
264 %type <instr> assignment_expr
267 hlsl_prog: /* empty */
270 | hlsl_prog declaration_statement
272 TRACE("Declaration statement parsed.\n");
274 | hlsl_prog preproc_directive
278 preproc_directive: PRE_LINE STRING
280 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
281 hlsl_ctx.line_no = $1 - 1;
282 d3dcompiler_free(hlsl_ctx.source_file);
283 hlsl_ctx.source_file = $2;
286 any_identifier: VAR_IDENTIFIER
290 semantic: /* Empty */
303 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
305 if ($3->type != HLSL_CLASS_SCALAR)
307 hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
309 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
312 if ($5 < 1 || $5 > 4)
314 hlsl_message("Line %u: vector size must be between 1 and 4.\n",
316 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
320 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
322 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
324 if ($3->type != HLSL_CLASS_SCALAR)
326 hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
328 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
331 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
333 hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
335 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
339 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
344 $$ = new_hlsl_type("void", HLSL_CLASS_SCALAR, HLSL_TYPE_VOID, 1, 1);
348 $$ = new_hlsl_type("sampler", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
349 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
353 $$ = new_hlsl_type("sampler1D", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
354 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
358 $$ = new_hlsl_type("sampler2D", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
359 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
363 $$ = new_hlsl_type("sampler3D", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
364 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
368 $$ = new_hlsl_type("samplerCUBE", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
369 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
373 struct hlsl_type *type;
375 TRACE("Type %s.\n", $1);
376 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
378 d3dcompiler_free($1);
380 | KW_STRUCT TYPE_IDENTIFIER
382 struct hlsl_type *type;
384 TRACE("Struct type %s.\n", $2);
385 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
386 if (type->type != HLSL_CLASS_STRUCT)
388 hlsl_message("Line %u: redefining %s as a structure.\n",
389 hlsl_ctx.line_no, $2);
390 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
396 d3dcompiler_free($2);
399 declaration_statement: declaration
403 declaration: var_modifiers type variables_def ';'
405 struct parse_variable_def *v, *v_next;
406 struct hlsl_ir_var *var;
407 BOOL ret, local = TRUE;
409 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
411 debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
412 var = d3dcompiler_alloc(sizeof(*var));
413 var->node.type = HLSL_IR_VAR;
415 var->node.data_type = new_array_type($2, v->array_size);
417 var->node.data_type = $2;
420 var->semantic = v->semantic;
421 var->node.line = hlsl_ctx.line_no;
424 FIXME("Variable with an initializer.\n");
425 free_instr_list(v->initializer);
428 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
430 var->modifiers |= HLSL_STORAGE_UNIFORM;
434 ret = declare_variable(var, local);
436 free_declaration(var);
438 TRACE("Declared variable %s.\n", var->name);
441 d3dcompiler_free($3);
444 variables_def: variable_def
446 $$ = d3dcompiler_alloc(sizeof(*$$));
448 list_add_head($$, &$1->entry);
450 | variables_def ',' variable_def
453 list_add_tail($$, &$3->entry);
456 /* FIXME: Local variables can't have semantics. */
457 variable_def: any_identifier array semantic
459 $$ = d3dcompiler_alloc(sizeof(*$$));
464 | any_identifier array semantic '=' complex_initializer
466 TRACE("Declaration with initializer.\n");
467 $$ = d3dcompiler_alloc(sizeof(*$$));
471 $$->initializer = $5;
485 var_modifiers: /* Empty */
489 | KW_EXTERN var_modifiers
491 $$ = add_modifier($2, HLSL_STORAGE_EXTERN);
493 | KW_NOINTERPOLATION var_modifiers
495 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION);
497 | KW_PRECISE var_modifiers
499 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE);
501 | KW_SHARED var_modifiers
503 $$ = add_modifier($2, HLSL_STORAGE_SHARED);
505 | KW_GROUPSHARED var_modifiers
507 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED);
509 | KW_STATIC var_modifiers
511 $$ = add_modifier($2, HLSL_STORAGE_STATIC);
513 | KW_UNIFORM var_modifiers
515 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM);
517 | KW_VOLATILE var_modifiers
519 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE);
521 | KW_CONST var_modifiers
523 $$ = add_modifier($2, HLSL_MODIFIER_CONST);
525 | KW_ROW_MAJOR var_modifiers
527 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR);
529 | KW_COLUMN_MAJOR var_modifiers
531 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR);
534 complex_initializer: initializer_expr
536 $$ = d3dcompiler_alloc(sizeof(*$$));
538 list_add_head($$, &$1->entry);
540 | '{' initializer_expr_list '}'
545 initializer_expr: assignment_expr
550 initializer_expr_list: initializer_expr
552 $$ = d3dcompiler_alloc(sizeof(*$$));
554 list_add_head($$, &$1->entry);
556 | initializer_expr_list ',' initializer_expr
559 list_add_tail($$, &$3->entry);
571 primary_expr: C_FLOAT
573 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
576 ERR("Out of memory.\n");
579 c->node.type = HLSL_IR_CONSTANT;
580 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
581 c->v.value.f[0] = $1;
586 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
589 ERR("Out of memory.\n");
592 c->node.type = HLSL_IR_CONSTANT;
593 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
594 c->v.value.i[0] = $1;
599 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
602 ERR("Out of memory.\n");
605 c->node.type = HLSL_IR_CONSTANT;
606 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
607 c->v.value.b[0] = $1;
612 struct hlsl_ir_deref *deref = new_var_deref($1);
613 $$ = deref ? &deref->node : NULL;
620 variable: VAR_IDENTIFIER
622 struct hlsl_ir_var *var;
623 var = get_variable(hlsl_ctx.cur_scope, $1);
626 hlsl_message("Line %d: variable '%s' not declared\n",
627 hlsl_ctx.line_no, $1);
628 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
634 postfix_expr: primary_expr
639 unary_expr: postfix_expr
659 relational_expr: shift_expr
664 equality_expr: relational_expr
669 bitand_expr: equality_expr
674 bitxor_expr: bitand_expr
679 bitor_expr: bitxor_expr
684 logicand_expr: bitor_expr
689 logicor_expr: logicand_expr
694 conditional_expr: logicor_expr
699 assignment_expr: conditional_expr
704 expr: assignment_expr
708 | expr ',' assignment_expr
710 FIXME("Comma expression\n");
715 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const char *entrypoint, char **messages)
717 struct hlsl_scope *scope, *next_scope;
718 struct hlsl_type *hlsl_type, *next_type;
719 struct hlsl_ir_var *var, *next_var;
721 hlsl_ctx.line_no = 1;
722 hlsl_ctx.source_file = d3dcompiler_strdup("");
723 hlsl_ctx.cur_scope = NULL;
724 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
725 list_init(&hlsl_ctx.scopes);
726 list_init(&hlsl_ctx.types);
727 list_init(&hlsl_ctx.functions);
729 push_scope(&hlsl_ctx);
730 hlsl_ctx.globals = hlsl_ctx.cur_scope;
734 d3dcompiler_free(hlsl_ctx.source_file);
736 TRACE("Freeing variables.\n");
737 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
739 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
741 free_declaration(var);
743 d3dcompiler_free(scope);
746 TRACE("Freeing types.\n");
747 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
749 free_hlsl_type(hlsl_type);