wbemprox: Add support for enumerating class methods.
[wine/multimedia.git] / dlls / d3dcompiler_43 / hlsl.y
blobc67ab541bb8b6110946d1f4ee99c11bdc99213a8
1 /*
2 * HLSL parser
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
22 #include "config.h"
23 #include "wine/debug.h"
25 #include <stdio.h>
27 #include "d3dcompiler_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser);
31 int hlsl_lex(void);
33 struct hlsl_parse_ctx hlsl_ctx;
35 struct YYLTYPE;
36 static void set_location(struct source_location *loc, const struct YYLTYPE *l);
38 void hlsl_message(const char *fmt, ...)
40 va_list args;
42 va_start(args, fmt);
43 compilation_message(&hlsl_ctx.messages, fmt, args);
44 va_end(args);
47 static const char *hlsl_get_error_level_name(enum hlsl_error_level level)
49 const char *names[] =
51 "error",
52 "warning",
53 "note",
55 return names[level];
58 void hlsl_report_message(const char *filename, DWORD line, DWORD column,
59 enum hlsl_error_level level, const char *fmt, ...)
61 va_list args;
62 char *string = NULL;
63 int rc, size = 0;
65 while (1)
67 va_start(args, fmt);
68 rc = vsnprintf(string, size, fmt, args);
69 va_end(args);
71 if (rc >= 0 && rc < size)
72 break;
74 if (rc >= size)
75 size = rc + 1;
76 else
77 size = size ? size * 2 : 32;
79 if (!string)
80 string = d3dcompiler_alloc(size);
81 else
82 string = d3dcompiler_realloc(string, size);
83 if (!string)
85 ERR("Error reallocating memory for a string.\n");
86 return;
90 hlsl_message("%s:%u:%u: %s: %s\n", filename, line, column, hlsl_get_error_level_name(level), string);
91 d3dcompiler_free(string);
93 if (level == HLSL_LEVEL_ERROR)
94 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
95 else if (level == HLSL_LEVEL_WARNING)
96 set_parse_status(&hlsl_ctx.status, PARSE_WARN);
99 static void hlsl_error(const char *s)
101 hlsl_report_message(hlsl_ctx.source_file, hlsl_ctx.line_no, hlsl_ctx.column, HLSL_LEVEL_ERROR, "%s", s);
104 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
106 TRACE("Line %u: ", line_no);
107 if (modifiers)
108 TRACE("%s ", debug_modifiers(modifiers));
109 TRACE("%s %s;\n", debug_hlsl_type(type), declname);
112 static void check_invalid_matrix_modifiers(DWORD modifiers, struct source_location *loc)
114 if (modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
116 hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
117 "'row_major' or 'column_major' modifiers are only allowed for matrices");
121 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
123 BOOL ret;
125 TRACE("Declaring variable %s.\n", decl->name);
126 if (decl->node.data_type->type == HLSL_CLASS_MATRIX)
128 if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)))
130 decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR
131 ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR;
134 else
135 check_invalid_matrix_modifiers(decl->modifiers, &decl->node.loc);
137 if (local)
139 DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
140 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
141 if (invalid)
143 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
144 "modifier '%s' invalid for local variables", debug_modifiers(invalid));
146 if (decl->semantic)
148 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
149 "semantics are not allowed on local variables");
150 return FALSE;
153 else
155 if (find_function(decl->name))
157 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
158 "redefinition of '%s'", decl->name);
159 return FALSE;
162 ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
163 if (!ret)
165 struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
167 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
168 "\"%s\" already declared", decl->name);
169 hlsl_report_message(old->node.loc.file, old->node.loc.line, old->node.loc.col, HLSL_LEVEL_NOTE,
170 "\"%s\" was previously declared here", old->name);
171 return FALSE;
173 return TRUE;
176 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc);
178 static unsigned int components_count_expr_list(struct list *list)
180 struct hlsl_ir_node *node;
181 unsigned int count = 0;
183 LIST_FOR_EACH_ENTRY(node, list, struct hlsl_ir_node, entry)
185 count += components_count_type(node->data_type);
187 return count;
192 %locations
193 %error-verbose
195 %union
197 struct hlsl_type *type;
198 INT intval;
199 FLOAT floatval;
200 BOOL boolval;
201 char *name;
202 DWORD modifiers;
203 struct hlsl_ir_var *var;
204 struct hlsl_ir_node *instr;
205 struct list *list;
206 struct hlsl_ir_function_decl *function;
207 struct parse_parameter parameter;
208 struct parse_variable_def *variable_def;
209 enum parse_unary_op unary_op;
210 enum parse_assign_op assign_op;
213 %token KW_BLENDSTATE
214 %token KW_BREAK
215 %token KW_BUFFER
216 %token KW_CBUFFER
217 %token KW_COLUMN_MAJOR
218 %token KW_COMPILE
219 %token KW_CONST
220 %token KW_CONTINUE
221 %token KW_DEPTHSTENCILSTATE
222 %token KW_DEPTHSTENCILVIEW
223 %token KW_DISCARD
224 %token KW_DO
225 %token KW_DOUBLE
226 %token KW_ELSE
227 %token KW_EXTERN
228 %token KW_FALSE
229 %token KW_FOR
230 %token KW_GEOMETRYSHADER
231 %token KW_GROUPSHARED
232 %token KW_IF
233 %token KW_IN
234 %token KW_INLINE
235 %token KW_INOUT
236 %token KW_MATRIX
237 %token KW_NAMESPACE
238 %token KW_NOINTERPOLATION
239 %token KW_OUT
240 %token KW_PASS
241 %token KW_PIXELSHADER
242 %token KW_PRECISE
243 %token KW_RASTERIZERSTATE
244 %token KW_RENDERTARGETVIEW
245 %token KW_RETURN
246 %token KW_REGISTER
247 %token KW_ROW_MAJOR
248 %token KW_SAMPLER
249 %token KW_SAMPLER1D
250 %token KW_SAMPLER2D
251 %token KW_SAMPLER3D
252 %token KW_SAMPLERCUBE
253 %token KW_SAMPLER_STATE
254 %token KW_SAMPLERCOMPARISONSTATE
255 %token KW_SHARED
256 %token KW_STATEBLOCK
257 %token KW_STATEBLOCK_STATE
258 %token KW_STATIC
259 %token KW_STRING
260 %token KW_STRUCT
261 %token KW_SWITCH
262 %token KW_TBUFFER
263 %token KW_TECHNIQUE
264 %token KW_TECHNIQUE10
265 %token KW_TEXTURE
266 %token KW_TEXTURE1D
267 %token KW_TEXTURE1DARRAY
268 %token KW_TEXTURE2D
269 %token KW_TEXTURE2DARRAY
270 %token KW_TEXTURE2DMS
271 %token KW_TEXTURE2DMSARRAY
272 %token KW_TEXTURE3D
273 %token KW_TEXTURE3DARRAY
274 %token KW_TEXTURECUBE
275 %token KW_TRUE
276 %token KW_TYPEDEF
277 %token KW_UNIFORM
278 %token KW_VECTOR
279 %token KW_VERTEXSHADER
280 %token KW_VOID
281 %token KW_VOLATILE
282 %token KW_WHILE
284 %token OP_INC
285 %token OP_DEC
286 %token OP_AND
287 %token OP_OR
288 %token OP_EQ
289 %token OP_LEFTSHIFT
290 %token OP_LEFTSHIFTASSIGN
291 %token OP_RIGHTSHIFT
292 %token OP_RIGHTSHIFTASSIGN
293 %token OP_ELLIPSIS
294 %token OP_LE
295 %token OP_GE
296 %token OP_NE
297 %token OP_ADDASSIGN
298 %token OP_SUBASSIGN
299 %token OP_MULASSIGN
300 %token OP_DIVASSIGN
301 %token OP_MODASSIGN
302 %token OP_ANDASSIGN
303 %token OP_ORASSIGN
304 %token OP_XORASSIGN
305 %token OP_UNKNOWN1
306 %token OP_UNKNOWN2
307 %token OP_UNKNOWN3
308 %token OP_UNKNOWN4
310 %token <intval> PRE_LINE
312 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
313 %type <name> any_identifier var_identifier
314 %token <name> STRING
315 %token <floatval> C_FLOAT
316 %token <intval> C_INTEGER
317 %type <boolval> boolean
318 %type <type> base_type
319 %type <type> type
320 %type <list> declaration_statement
321 %type <list> complex_initializer
322 %type <list> initializer_expr_list
323 %type <instr> initializer_expr
324 %type <modifiers> var_modifiers
325 %type <list> parameters
326 %type <list> param_list
327 %type <instr> expr
328 %type <var> variable
329 %type <intval> array
330 %type <list> statement
331 %type <list> statement_list
332 %type <list> compound_statement
333 %type <function> func_declaration
334 %type <function> func_prototype
335 %type <parameter> parameter
336 %type <name> semantic
337 %type <variable_def> variable_def
338 %type <list> variables_def
339 %type <instr> primary_expr
340 %type <instr> postfix_expr
341 %type <instr> unary_expr
342 %type <instr> mul_expr
343 %type <instr> add_expr
344 %type <instr> shift_expr
345 %type <instr> relational_expr
346 %type <instr> equality_expr
347 %type <instr> bitand_expr
348 %type <instr> bitxor_expr
349 %type <instr> bitor_expr
350 %type <instr> logicand_expr
351 %type <instr> logicor_expr
352 %type <instr> conditional_expr
353 %type <instr> assignment_expr
354 %type <list> expr_statement
355 %type <unary_op> unary_op
356 %type <assign_op> assign_op
357 %type <modifiers> input_mod
360 hlsl_prog: /* empty */
363 | hlsl_prog func_declaration
365 FIXME("Check that the function doesn't conflict with an already declared one.\n");
366 list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
368 | hlsl_prog declaration_statement
370 TRACE("Declaration statement parsed.\n");
372 | hlsl_prog preproc_directive
376 preproc_directive: PRE_LINE STRING
378 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
379 hlsl_ctx.line_no = $1;
380 if (strcmp($2, hlsl_ctx.source_file))
382 const char **new_array;
384 hlsl_ctx.source_file = $2;
385 new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
386 sizeof(*hlsl_ctx.source_files) * hlsl_ctx.source_files_count + 1);
387 if (new_array)
389 hlsl_ctx.source_files = new_array;
390 hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
395 any_identifier: VAR_IDENTIFIER
396 | TYPE_IDENTIFIER
397 | NEW_IDENTIFIER
399 func_declaration: func_prototype compound_statement
401 TRACE("Function %s parsed.\n", $1->name);
402 $$ = $1;
403 $$->body = $2;
404 pop_scope(&hlsl_ctx);
406 | func_prototype ';'
408 TRACE("Function prototype for %s.\n", $1->name);
409 $$ = $1;
410 pop_scope(&hlsl_ctx);
413 func_prototype: var_modifiers type var_identifier '(' parameters ')' semantic
415 if (get_variable(hlsl_ctx.globals, $3))
417 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
418 HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
419 return 1;
421 if ($2->base_type == HLSL_TYPE_VOID && $7)
423 hlsl_report_message(hlsl_ctx.source_file, @7.first_line, @7.first_column,
424 HLSL_LEVEL_ERROR, "void function with a semantic");
427 $$ = new_func_decl($3, $2, $5);
428 if (!$$)
430 ERR("Out of memory.\n");
431 return -1;
433 $$->semantic = $7;
436 compound_statement: '{' '}'
438 $$ = d3dcompiler_alloc(sizeof(*$$));
439 list_init($$);
441 | '{' scope_start statement_list '}'
443 pop_scope(&hlsl_ctx);
444 $$ = $3;
447 scope_start: /* Empty */
449 push_scope(&hlsl_ctx);
452 var_identifier: VAR_IDENTIFIER
453 | NEW_IDENTIFIER
455 semantic: /* Empty */
457 $$ = NULL;
459 | ':' any_identifier
461 $$ = $2;
464 parameters: scope_start
466 $$ = d3dcompiler_alloc(sizeof(*$$));
467 list_init($$);
469 | scope_start param_list
471 $$ = $2;
474 param_list: parameter
476 struct source_location loc;
478 $$ = d3dcompiler_alloc(sizeof(*$$));
479 list_init($$);
480 set_location(&loc, &@1);
481 if (!add_func_parameter($$, &$1, &loc))
483 ERR("Error adding function parameter %s.\n", $1.name);
484 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
485 return -1;
488 | param_list ',' parameter
490 struct source_location loc;
492 $$ = $1;
493 set_location(&loc, &@3);
494 if (!add_func_parameter($$, &$3, &loc))
496 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
497 "duplicate parameter %s", $3.name);
498 return 1;
502 parameter: input_mod var_modifiers type any_identifier semantic
504 $$.modifiers = $1;
505 $$.modifiers |= $2;
506 $$.type = $3;
507 $$.name = $4;
508 $$.semantic = $5;
511 input_mod: /* Empty */
513 $$ = HLSL_MODIFIER_IN;
515 | KW_IN
517 $$ = HLSL_MODIFIER_IN;
519 | KW_OUT
521 $$ = HLSL_MODIFIER_OUT;
523 | KW_INOUT
525 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
528 type: base_type
530 $$ = $1;
532 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
534 if ($3->type != HLSL_CLASS_SCALAR)
536 hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
537 hlsl_ctx.line_no);
538 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
539 return 1;
541 if ($5 < 1 || $5 > 4)
543 hlsl_message("Line %u: vector size must be between 1 and 4.\n",
544 hlsl_ctx.line_no);
545 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
546 return 1;
549 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
551 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
553 if ($3->type != HLSL_CLASS_SCALAR)
555 hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
556 hlsl_ctx.line_no);
557 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
558 return 1;
560 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
562 hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
563 hlsl_ctx.line_no);
564 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
565 return 1;
568 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
571 base_type: KW_VOID
573 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
575 | KW_SAMPLER
577 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
578 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
580 | KW_SAMPLER1D
582 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
583 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
585 | KW_SAMPLER2D
587 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
588 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
590 | KW_SAMPLER3D
592 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
593 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
595 | KW_SAMPLERCUBE
597 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
598 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
600 | TYPE_IDENTIFIER
602 struct hlsl_type *type;
604 TRACE("Type %s.\n", $1);
605 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
606 $$ = type;
607 d3dcompiler_free($1);
609 | KW_STRUCT TYPE_IDENTIFIER
611 struct hlsl_type *type;
613 TRACE("Struct type %s.\n", $2);
614 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
615 if (type->type != HLSL_CLASS_STRUCT)
617 hlsl_message("Line %u: redefining %s as a structure.\n",
618 hlsl_ctx.line_no, $2);
619 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
621 else
623 $$ = type;
625 d3dcompiler_free($2);
628 declaration_statement: declaration
630 $$ = d3dcompiler_alloc(sizeof(*$$));
631 list_init($$);
634 declaration: var_modifiers type variables_def ';'
636 struct parse_variable_def *v, *v_next;
637 struct hlsl_ir_var *var;
638 BOOL ret, local = TRUE;
640 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
642 debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
643 var = d3dcompiler_alloc(sizeof(*var));
644 var->node.type = HLSL_IR_VAR;
645 if (v->array_size)
646 var->node.data_type = new_array_type($2, v->array_size);
647 else
648 var->node.data_type = $2;
649 var->node.loc = v->loc;
650 var->name = v->name;
651 var->modifiers = $1;
652 var->semantic = v->semantic;
654 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
656 var->modifiers |= HLSL_STORAGE_UNIFORM;
657 local = FALSE;
660 if (var->modifiers & HLSL_MODIFIER_CONST && !v->initializer)
662 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col,
663 HLSL_LEVEL_ERROR, "const variable without initializer");
664 free_declaration(var);
665 d3dcompiler_free(v);
666 continue;
669 ret = declare_variable(var, local);
670 if (!ret)
671 free_declaration(var);
672 else
673 TRACE("Declared variable %s.\n", var->name);
675 if (v->initializer)
677 FIXME("Variable with an initializer.\n");
678 free_instr_list(v->initializer);
681 d3dcompiler_free(v);
683 d3dcompiler_free($3);
686 variables_def: variable_def
688 $$ = d3dcompiler_alloc(sizeof(*$$));
689 list_init($$);
690 list_add_head($$, &$1->entry);
692 | variables_def ',' variable_def
694 $$ = $1;
695 list_add_tail($$, &$3->entry);
698 variable_def: any_identifier array semantic
700 $$ = d3dcompiler_alloc(sizeof(*$$));
701 set_location(&$$->loc, &@1);
702 $$->name = $1;
703 $$->array_size = $2;
704 $$->semantic = $3;
706 | any_identifier array semantic '=' complex_initializer
708 TRACE("Declaration with initializer.\n");
709 $$ = d3dcompiler_alloc(sizeof(*$$));
710 set_location(&$$->loc, &@1);
711 $$->name = $1;
712 $$->array_size = $2;
713 $$->semantic = $3;
714 $$->initializer = $5;
717 array: /* Empty */
719 $$ = 0;
721 | '[' expr ']'
723 FIXME("Array.\n");
724 $$ = 0;
725 free_instr($2);
728 var_modifiers: /* Empty */
730 $$ = 0;
732 | KW_EXTERN var_modifiers
734 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
736 | KW_NOINTERPOLATION var_modifiers
738 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
740 | KW_PRECISE var_modifiers
742 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
744 | KW_SHARED var_modifiers
746 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
748 | KW_GROUPSHARED var_modifiers
750 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
752 | KW_STATIC var_modifiers
754 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
756 | KW_UNIFORM var_modifiers
758 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
760 | KW_VOLATILE var_modifiers
762 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
764 | KW_CONST var_modifiers
766 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
768 | KW_ROW_MAJOR var_modifiers
770 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
772 | KW_COLUMN_MAJOR var_modifiers
774 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
777 complex_initializer: initializer_expr
779 $$ = d3dcompiler_alloc(sizeof(*$$));
780 list_init($$);
781 list_add_head($$, &$1->entry);
783 | '{' initializer_expr_list '}'
785 $$ = $2;
788 initializer_expr: assignment_expr
790 $$ = $1;
793 initializer_expr_list: initializer_expr
795 $$ = d3dcompiler_alloc(sizeof(*$$));
796 list_init($$);
797 list_add_head($$, &$1->entry);
799 | initializer_expr_list ',' initializer_expr
801 $$ = $1;
802 list_add_tail($$, &$3->entry);
805 boolean: KW_TRUE
807 $$ = TRUE;
809 | KW_FALSE
811 $$ = FALSE;
814 statement_list: statement
816 $$ = $1;
818 | statement_list statement
820 $$ = $1;
821 list_move_tail($$, $2);
822 d3dcompiler_free($2);
825 statement: declaration_statement
827 $$ = $1;
829 | expr_statement
831 $$ = $1;
833 | compound_statement
835 $$ = $1;
838 expr_statement: ';'
840 $$ = d3dcompiler_alloc(sizeof(*$$));
841 list_init($$);
843 | expr ';'
845 $$ = d3dcompiler_alloc(sizeof(*$$));
846 list_init($$);
847 if ($1)
848 list_add_head($$, &$1->entry);
851 primary_expr: C_FLOAT
853 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
854 if (!c)
856 ERR("Out of memory.\n");
857 return -1;
859 c->node.type = HLSL_IR_CONSTANT;
860 set_location(&c->node.loc, &yylloc);
861 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
862 c->v.value.f[0] = $1;
863 $$ = &c->node;
865 | C_INTEGER
867 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
868 if (!c)
870 ERR("Out of memory.\n");
871 return -1;
873 c->node.type = HLSL_IR_CONSTANT;
874 set_location(&c->node.loc, &yylloc);
875 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
876 c->v.value.i[0] = $1;
877 $$ = &c->node;
879 | boolean
881 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
882 if (!c)
884 ERR("Out of memory.\n");
885 return -1;
887 c->node.type = HLSL_IR_CONSTANT;
888 set_location(&c->node.loc, &yylloc);
889 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
890 c->v.value.b[0] = $1;
891 $$ = &c->node;
893 | variable
895 struct hlsl_ir_deref *deref = new_var_deref($1);
896 if (deref)
898 $$ = &deref->node;
899 set_location(&$$->loc, &@1);
901 else
902 $$ = NULL;
904 | '(' expr ')'
906 $$ = $2;
909 variable: VAR_IDENTIFIER
911 struct hlsl_ir_var *var;
912 var = get_variable(hlsl_ctx.cur_scope, $1);
913 if (!var)
915 hlsl_message("Line %d: variable '%s' not declared\n",
916 hlsl_ctx.line_no, $1);
917 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
918 return 1;
920 $$ = var;
923 postfix_expr: primary_expr
925 $$ = $1;
927 | postfix_expr OP_INC
929 struct hlsl_ir_node *operands[3];
930 struct source_location loc;
932 operands[0] = $1;
933 operands[1] = operands[2] = NULL;
934 set_location(&loc, &@2);
935 $$ = &new_expr(HLSL_IR_BINOP_POSTINC, operands, &loc)->node;
937 | postfix_expr OP_DEC
939 struct hlsl_ir_node *operands[3];
940 struct source_location loc;
942 operands[0] = $1;
943 operands[1] = operands[2] = NULL;
944 set_location(&loc, &@2);
945 $$ = &new_expr(HLSL_IR_BINOP_POSTDEC, operands, &loc)->node;
947 /* "var_modifiers" doesn't make sense in this case, but it's needed
948 in the grammar to avoid shift/reduce conflicts. */
949 | var_modifiers type '(' initializer_expr_list ')'
951 struct hlsl_ir_constructor *constructor;
953 TRACE("%s constructor.\n", debug_hlsl_type($2));
954 if ($1)
956 hlsl_message("Line %u: unexpected modifier in a constructor.\n",
957 hlsl_ctx.line_no);
958 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
959 return -1;
961 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
963 hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
964 hlsl_ctx.line_no);
965 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
966 return -1;
968 if ($2->dimx * $2->dimy != components_count_expr_list($4))
970 hlsl_message("Line %u: wrong number of components in constructor.\n",
971 hlsl_ctx.line_no);
972 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
973 return -1;
976 constructor = d3dcompiler_alloc(sizeof(*constructor));
977 constructor->node.type = HLSL_IR_CONSTRUCTOR;
978 set_location(&constructor->node.loc, &@3);
979 constructor->node.data_type = $2;
980 constructor->arguments = $4;
982 $$ = &constructor->node;
985 unary_expr: postfix_expr
987 $$ = $1;
989 | OP_INC unary_expr
991 struct hlsl_ir_node *operands[3];
992 struct source_location loc;
994 operands[0] = $2;
995 operands[1] = operands[2] = NULL;
996 set_location(&loc, &@1);
997 $$ = &new_expr(HLSL_IR_BINOP_PREINC, operands, &loc)->node;
999 | OP_DEC unary_expr
1001 struct hlsl_ir_node *operands[3];
1002 struct source_location loc;
1004 operands[0] = $2;
1005 operands[1] = operands[2] = NULL;
1006 set_location(&loc, &@1);
1007 $$ = &new_expr(HLSL_IR_BINOP_PREDEC, operands, &loc)->node;
1009 | unary_op unary_expr
1011 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
1012 HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
1013 struct hlsl_ir_node *operands[3];
1014 struct source_location loc;
1016 if ($1 == UNARY_OP_PLUS)
1018 $$ = $2;
1020 else
1022 operands[0] = $2;
1023 operands[1] = operands[2] = NULL;
1024 set_location(&loc, &@1);
1025 $$ = &new_expr(ops[$1], operands, &loc)->node;
1029 unary_op: '+'
1031 $$ = UNARY_OP_PLUS;
1033 | '-'
1035 $$ = UNARY_OP_MINUS;
1037 | '!'
1039 $$ = UNARY_OP_LOGICNOT;
1041 | '~'
1043 $$ = UNARY_OP_BITNOT;
1046 mul_expr: unary_expr
1048 $$ = $1;
1050 | mul_expr '*' unary_expr
1052 struct source_location loc;
1054 set_location(&loc, &@2);
1055 $$ = &hlsl_mul($1, $3, &loc)->node;
1057 | mul_expr '/' unary_expr
1059 struct source_location loc;
1061 set_location(&loc, &@2);
1062 $$ = &hlsl_div($1, $3, &loc)->node;
1064 | mul_expr '%' unary_expr
1066 struct source_location loc;
1068 set_location(&loc, &@2);
1069 $$ = &hlsl_mod($1, $3, &loc)->node;
1072 add_expr: mul_expr
1074 $$ = $1;
1076 | add_expr '+' mul_expr
1078 struct source_location loc;
1080 set_location(&loc, &@2);
1081 $$ = &hlsl_add($1, $3, &loc)->node;
1083 | add_expr '-' mul_expr
1085 struct source_location loc;
1087 set_location(&loc, &@2);
1088 $$ = &hlsl_sub($1, $3, &loc)->node;
1091 shift_expr: add_expr
1093 $$ = $1;
1095 | shift_expr OP_LEFTSHIFT add_expr
1097 FIXME("Left shift\n");
1099 | shift_expr OP_RIGHTSHIFT add_expr
1101 FIXME("Right shift\n");
1104 relational_expr: shift_expr
1106 $$ = $1;
1108 | relational_expr '<' shift_expr
1110 struct source_location loc;
1112 set_location(&loc, &@2);
1113 $$ = &hlsl_lt($1, $3, &loc)->node;
1115 | relational_expr '>' shift_expr
1117 struct source_location loc;
1119 set_location(&loc, &@2);
1120 $$ = &hlsl_gt($1, $3, &loc)->node;
1122 | relational_expr OP_LE shift_expr
1124 struct source_location loc;
1126 set_location(&loc, &@2);
1127 $$ = &hlsl_le($1, $3, &loc)->node;
1129 | relational_expr OP_GE shift_expr
1131 struct source_location loc;
1133 set_location(&loc, &@2);
1134 $$ = &hlsl_ge($1, $3, &loc)->node;
1137 equality_expr: relational_expr
1139 $$ = $1;
1141 | equality_expr OP_EQ relational_expr
1143 struct source_location loc;
1145 set_location(&loc, &@2);
1146 $$ = &hlsl_eq($1, $3, &loc)->node;
1148 | equality_expr OP_NE relational_expr
1150 struct source_location loc;
1152 set_location(&loc, &@2);
1153 $$ = &hlsl_ne($1, $3, &loc)->node;
1156 bitand_expr: equality_expr
1158 $$ = $1;
1160 | bitand_expr '&' equality_expr
1162 FIXME("bitwise AND\n");
1165 bitxor_expr: bitand_expr
1167 $$ = $1;
1169 | bitxor_expr '^' bitand_expr
1171 FIXME("bitwise XOR\n");
1174 bitor_expr: bitxor_expr
1176 $$ = $1;
1178 | bitor_expr '|' bitxor_expr
1180 FIXME("bitwise OR\n");
1183 logicand_expr: bitor_expr
1185 $$ = $1;
1187 | logicand_expr OP_AND bitor_expr
1189 FIXME("logic AND\n");
1192 logicor_expr: logicand_expr
1194 $$ = $1;
1196 | logicor_expr OP_OR logicand_expr
1198 FIXME("logic OR\n");
1201 conditional_expr: logicor_expr
1203 $$ = $1;
1205 | logicor_expr '?' expr ':' assignment_expr
1207 FIXME("ternary operator\n");
1210 assignment_expr: conditional_expr
1212 $$ = $1;
1214 | unary_expr assign_op assignment_expr
1216 $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
1217 if (!$$)
1218 return 1;
1219 set_location(&$$->loc, &@2);
1222 assign_op: '='
1224 $$ = ASSIGN_OP_ASSIGN;
1226 | OP_ADDASSIGN
1228 $$ = ASSIGN_OP_ADD;
1230 | OP_SUBASSIGN
1232 $$ = ASSIGN_OP_SUB;
1234 | OP_MULASSIGN
1236 $$ = ASSIGN_OP_MUL;
1238 | OP_DIVASSIGN
1240 $$ = ASSIGN_OP_DIV;
1242 | OP_MODASSIGN
1244 $$ = ASSIGN_OP_MOD;
1246 | OP_LEFTSHIFTASSIGN
1248 $$ = ASSIGN_OP_LSHIFT;
1250 | OP_RIGHTSHIFTASSIGN
1252 $$ = ASSIGN_OP_RSHIFT;
1254 | OP_ANDASSIGN
1256 $$ = ASSIGN_OP_AND;
1258 | OP_ORASSIGN
1260 $$ = ASSIGN_OP_OR;
1262 | OP_XORASSIGN
1264 $$ = ASSIGN_OP_XOR;
1267 expr: assignment_expr
1269 $$ = $1;
1271 | expr ',' assignment_expr
1273 FIXME("Comma expression\n");
1278 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
1280 loc->file = hlsl_ctx.source_file;
1281 loc->line = l->first_line;
1282 loc->col = l->first_column;
1285 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
1287 if (modifiers & mod)
1289 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
1290 "modifier '%s' already specified", debug_modifiers(mod));
1291 return modifiers;
1293 if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
1294 && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
1296 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
1297 "more than one matrix majority keyword");
1298 return modifiers;
1300 return modifiers | mod;
1303 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
1304 const char *entrypoint, char **messages)
1306 struct hlsl_ir_function_decl *function;
1307 struct hlsl_scope *scope, *next_scope;
1308 struct hlsl_type *hlsl_type, *next_type;
1309 struct hlsl_ir_var *var, *next_var;
1310 unsigned int i;
1312 hlsl_ctx.status = PARSE_SUCCESS;
1313 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
1314 hlsl_ctx.line_no = hlsl_ctx.column = 1;
1315 hlsl_ctx.source_file = d3dcompiler_strdup("");
1316 hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
1317 if (hlsl_ctx.source_files)
1318 hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
1319 hlsl_ctx.source_files_count = 1;
1320 hlsl_ctx.cur_scope = NULL;
1321 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
1322 list_init(&hlsl_ctx.scopes);
1323 list_init(&hlsl_ctx.types);
1324 list_init(&hlsl_ctx.functions);
1326 push_scope(&hlsl_ctx);
1327 hlsl_ctx.globals = hlsl_ctx.cur_scope;
1329 hlsl_parse();
1331 if (TRACE_ON(hlsl_parser))
1333 struct hlsl_ir_function_decl *func;
1335 TRACE("IR dump.\n");
1336 LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1338 if (func->body)
1339 debug_dump_ir_function(func);
1343 TRACE("Compilation status = %d\n", hlsl_ctx.status);
1344 if (messages)
1346 if (hlsl_ctx.messages.size)
1347 *messages = hlsl_ctx.messages.string;
1348 else
1349 *messages = NULL;
1351 else
1353 if (hlsl_ctx.messages.capacity)
1354 d3dcompiler_free(hlsl_ctx.messages.string);
1357 for (i = 0; i < hlsl_ctx.source_files_count; ++i)
1358 d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
1359 d3dcompiler_free(hlsl_ctx.source_files);
1361 TRACE("Freeing functions IR.\n");
1362 LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1363 free_function(function);
1365 TRACE("Freeing variables.\n");
1366 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
1368 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
1370 free_declaration(var);
1372 d3dcompiler_free(scope);
1375 TRACE("Freeing types.\n");
1376 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
1378 free_hlsl_type(hlsl_type);
1381 return NULL;