d3dcompiler: Allow casts to arrays.
[wine/multimedia.git] / dlls / d3dcompiler_43 / hlsl.y
blob7bce0544c3247e59f974180869514c24db41172f
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 BOOL check_type_modifiers(DWORD modifiers, struct source_location *loc)
180 if (modifiers & ~HLSL_TYPE_MODIFIERS_MASK)
182 hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
183 "modifier not allowed on typedefs");
184 return FALSE;
186 return TRUE;
189 static BOOL add_type_to_scope(struct hlsl_scope *scope, struct hlsl_type *def)
191 if (get_type(scope, def->name, FALSE))
192 return FALSE;
194 wine_rb_put(&scope->types, def->name, &def->scope_entry);
195 return TRUE;
198 static void declare_predefined_types(struct hlsl_scope *scope)
200 struct hlsl_type *type;
201 unsigned int x, y, bt;
202 static const char *names[] =
204 "float",
205 "half",
206 "double",
207 "int",
208 "uint",
209 "bool",
211 char name[10];
213 for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt)
215 for (y = 1; y <= 4; ++y)
217 for (x = 1; x <= 4; ++x)
219 sprintf(name, "%s%ux%u", names[bt], x, y);
220 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_MATRIX, bt, x, y);
221 add_type_to_scope(scope, type);
223 if (y == 1)
225 sprintf(name, "%s%u", names[bt], x);
226 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_VECTOR, bt, x, y);
227 add_type_to_scope(scope, type);
229 if (x == 1)
231 sprintf(name, "%s", names[bt]);
232 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_SCALAR, bt, x, y);
233 add_type_to_scope(scope, type);
240 /* DX8 effects predefined types */
241 type = new_hlsl_type(d3dcompiler_strdup("DWORD"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
242 add_type_to_scope(scope, type);
243 type = new_hlsl_type(d3dcompiler_strdup("FLOAT"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
244 add_type_to_scope(scope, type);
245 type = new_hlsl_type(d3dcompiler_strdup("VECTOR"), HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1);
246 add_type_to_scope(scope, type);
247 type = new_hlsl_type(d3dcompiler_strdup("MATRIX"), HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4);
248 add_type_to_scope(scope, type);
249 type = new_hlsl_type(d3dcompiler_strdup("STRING"), HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1);
250 add_type_to_scope(scope, type);
251 type = new_hlsl_type(d3dcompiler_strdup("TEXTURE"), HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1);
252 add_type_to_scope(scope, type);
253 type = new_hlsl_type(d3dcompiler_strdup("PIXELSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1);
254 add_type_to_scope(scope, type);
255 type = new_hlsl_type(d3dcompiler_strdup("VERTEXSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1);
256 add_type_to_scope(scope, type);
259 static unsigned int initializer_size(struct list *initializer)
261 unsigned int count = 0;
262 struct hlsl_ir_node *node;
264 LIST_FOR_EACH_ENTRY(node, initializer, struct hlsl_ir_node, entry)
266 count += components_count_type(node->data_type);
268 TRACE("Initializer size = %u\n", count);
269 return count;
272 static unsigned int components_count_expr_list(struct list *list)
274 struct hlsl_ir_node *node;
275 unsigned int count = 0;
277 LIST_FOR_EACH_ENTRY(node, list, struct hlsl_ir_node, entry)
279 count += components_count_type(node->data_type);
281 return count;
284 static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components,
285 struct hlsl_ir_node *val, struct source_location *loc)
287 struct hlsl_ir_swizzle *swizzle = d3dcompiler_alloc(sizeof(*swizzle));
289 if (!swizzle)
290 return NULL;
291 swizzle->node.type = HLSL_IR_SWIZZLE;
292 swizzle->node.loc = *loc;
293 swizzle->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1);
294 swizzle->val = val;
295 swizzle->swizzle = s;
296 return swizzle;
299 static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const char *swizzle,
300 struct source_location *loc)
302 unsigned int len = strlen(swizzle), component = 0;
303 unsigned int i, set, swiz = 0;
304 BOOL valid;
306 if (value->data_type->type == HLSL_CLASS_MATRIX)
308 /* Matrix swizzle */
309 BOOL m_swizzle;
310 unsigned int inc, x, y;
312 if (len < 3 || swizzle[0] != '_')
313 return NULL;
314 m_swizzle = swizzle[1] == 'm';
315 inc = m_swizzle ? 4 : 3;
317 if (len % inc || len > inc * 4)
318 return NULL;
320 for (i = 0; i < len; i += inc)
322 if (swizzle[i] != '_')
323 return NULL;
324 if (m_swizzle)
326 if (swizzle[i + 1] != 'm')
327 return NULL;
328 x = swizzle[i + 2] - '0';
329 y = swizzle[i + 3] - '0';
331 else
333 x = swizzle[i + 1] - '1';
334 y = swizzle[i + 2] - '1';
337 if (x >= value->data_type->dimx || y >= value->data_type->dimy)
338 return NULL;
339 swiz |= (y << 4 | x) << component * 8;
340 component++;
342 return new_swizzle(swiz, component, value, loc);
345 /* Vector swizzle */
346 if (len > 4)
347 return NULL;
349 for (set = 0; set < 2; ++set)
351 valid = TRUE;
352 component = 0;
353 for (i = 0; i < len; ++i)
355 char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}};
356 unsigned int s = 0;
358 for (s = 0; s < 4; ++s)
360 if (swizzle[i] == c[set][s])
361 break;
363 if (s == 4)
365 valid = FALSE;
366 break;
369 if (s >= value->data_type->dimx)
370 return NULL;
371 swiz |= s << component * 2;
372 component++;
374 if (valid)
375 return new_swizzle(swiz, component, value, loc);
378 return NULL;
381 static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list,
382 struct source_location *loc)
384 BOOL ret;
385 struct hlsl_type *type;
386 struct parse_variable_def *v, *v_next;
388 if (!check_type_modifiers(modifiers, loc))
390 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
391 d3dcompiler_free(v);
392 d3dcompiler_free(list);
393 return FALSE;
396 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
398 if (v->array_size)
399 type = new_array_type(orig_type, v->array_size);
400 else
401 type = clone_hlsl_type(orig_type);
402 if (!type)
404 ERR("Out of memory\n");
405 return FALSE;
407 d3dcompiler_free((void *)type->name);
408 type->name = v->name;
409 type->modifiers |= modifiers;
411 if (type->type != HLSL_CLASS_MATRIX)
412 check_invalid_matrix_modifiers(type->modifiers, &v->loc);
414 ret = add_type_to_scope(hlsl_ctx.cur_scope, type);
415 if (!ret)
417 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
418 "redefinition of custom type '%s'", v->name);
420 d3dcompiler_free(v);
422 d3dcompiler_free(list);
423 return TRUE;
428 %locations
429 %error-verbose
430 %expect 1
432 %union
434 struct hlsl_type *type;
435 INT intval;
436 FLOAT floatval;
437 BOOL boolval;
438 char *name;
439 DWORD modifiers;
440 struct hlsl_ir_var *var;
441 struct hlsl_ir_node *instr;
442 struct list *list;
443 struct hlsl_ir_function_decl *function;
444 struct parse_parameter parameter;
445 struct parse_variable_def *variable_def;
446 struct parse_if_body if_body;
447 enum parse_unary_op unary_op;
448 enum parse_assign_op assign_op;
451 %token KW_BLENDSTATE
452 %token KW_BREAK
453 %token KW_BUFFER
454 %token KW_CBUFFER
455 %token KW_COLUMN_MAJOR
456 %token KW_COMPILE
457 %token KW_CONST
458 %token KW_CONTINUE
459 %token KW_DEPTHSTENCILSTATE
460 %token KW_DEPTHSTENCILVIEW
461 %token KW_DISCARD
462 %token KW_DO
463 %token KW_DOUBLE
464 %token KW_ELSE
465 %token KW_EXTERN
466 %token KW_FALSE
467 %token KW_FOR
468 %token KW_GEOMETRYSHADER
469 %token KW_GROUPSHARED
470 %token KW_IF
471 %token KW_IN
472 %token KW_INLINE
473 %token KW_INOUT
474 %token KW_MATRIX
475 %token KW_NAMESPACE
476 %token KW_NOINTERPOLATION
477 %token KW_OUT
478 %token KW_PASS
479 %token KW_PIXELSHADER
480 %token KW_PRECISE
481 %token KW_RASTERIZERSTATE
482 %token KW_RENDERTARGETVIEW
483 %token KW_RETURN
484 %token KW_REGISTER
485 %token KW_ROW_MAJOR
486 %token KW_SAMPLER
487 %token KW_SAMPLER1D
488 %token KW_SAMPLER2D
489 %token KW_SAMPLER3D
490 %token KW_SAMPLERCUBE
491 %token KW_SAMPLER_STATE
492 %token KW_SAMPLERCOMPARISONSTATE
493 %token KW_SHARED
494 %token KW_STATEBLOCK
495 %token KW_STATEBLOCK_STATE
496 %token KW_STATIC
497 %token KW_STRING
498 %token KW_STRUCT
499 %token KW_SWITCH
500 %token KW_TBUFFER
501 %token KW_TECHNIQUE
502 %token KW_TECHNIQUE10
503 %token KW_TEXTURE
504 %token KW_TEXTURE1D
505 %token KW_TEXTURE1DARRAY
506 %token KW_TEXTURE2D
507 %token KW_TEXTURE2DARRAY
508 %token KW_TEXTURE2DMS
509 %token KW_TEXTURE2DMSARRAY
510 %token KW_TEXTURE3D
511 %token KW_TEXTURE3DARRAY
512 %token KW_TEXTURECUBE
513 %token KW_TRUE
514 %token KW_TYPEDEF
515 %token KW_UNIFORM
516 %token KW_VECTOR
517 %token KW_VERTEXSHADER
518 %token KW_VOID
519 %token KW_VOLATILE
520 %token KW_WHILE
522 %token OP_INC
523 %token OP_DEC
524 %token OP_AND
525 %token OP_OR
526 %token OP_EQ
527 %token OP_LEFTSHIFT
528 %token OP_LEFTSHIFTASSIGN
529 %token OP_RIGHTSHIFT
530 %token OP_RIGHTSHIFTASSIGN
531 %token OP_ELLIPSIS
532 %token OP_LE
533 %token OP_GE
534 %token OP_NE
535 %token OP_ADDASSIGN
536 %token OP_SUBASSIGN
537 %token OP_MULASSIGN
538 %token OP_DIVASSIGN
539 %token OP_MODASSIGN
540 %token OP_ANDASSIGN
541 %token OP_ORASSIGN
542 %token OP_XORASSIGN
543 %token OP_UNKNOWN1
544 %token OP_UNKNOWN2
545 %token OP_UNKNOWN3
546 %token OP_UNKNOWN4
548 %token <intval> PRE_LINE
550 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
551 %type <name> any_identifier var_identifier
552 %token <name> STRING
553 %token <floatval> C_FLOAT
554 %token <intval> C_INTEGER
555 %type <boolval> boolean
556 %type <type> base_type
557 %type <type> type
558 %type <list> declaration_statement
559 %type <list> declaration
560 %type <list> type_specs
561 %type <variable_def> type_spec
562 %type <list> complex_initializer
563 %type <list> initializer_expr_list
564 %type <instr> initializer_expr
565 %type <modifiers> var_modifiers
566 %type <list> parameters
567 %type <list> param_list
568 %type <instr> expr
569 %type <var> variable
570 %type <intval> array
571 %type <list> statement
572 %type <list> statement_list
573 %type <list> compound_statement
574 %type <list> jump_statement
575 %type <list> selection_statement
576 %type <function> func_declaration
577 %type <function> func_prototype
578 %type <parameter> parameter
579 %type <name> semantic
580 %type <variable_def> variable_def
581 %type <list> variables_def
582 %type <if_body> if_body
583 %type <instr> primary_expr
584 %type <instr> postfix_expr
585 %type <instr> unary_expr
586 %type <instr> mul_expr
587 %type <instr> add_expr
588 %type <instr> shift_expr
589 %type <instr> relational_expr
590 %type <instr> equality_expr
591 %type <instr> bitand_expr
592 %type <instr> bitxor_expr
593 %type <instr> bitor_expr
594 %type <instr> logicand_expr
595 %type <instr> logicor_expr
596 %type <instr> conditional_expr
597 %type <instr> assignment_expr
598 %type <list> expr_statement
599 %type <unary_op> unary_op
600 %type <assign_op> assign_op
601 %type <modifiers> input_mod
604 hlsl_prog: /* empty */
607 | hlsl_prog func_declaration
609 FIXME("Check that the function doesn't conflict with an already declared one.\n");
610 list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
612 | hlsl_prog declaration_statement
614 TRACE("Declaration statement parsed.\n");
616 | hlsl_prog preproc_directive
620 preproc_directive: PRE_LINE STRING
622 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
623 hlsl_ctx.line_no = $1;
624 if (strcmp($2, hlsl_ctx.source_file))
626 const char **new_array;
628 hlsl_ctx.source_file = $2;
629 new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
630 sizeof(*hlsl_ctx.source_files) * hlsl_ctx.source_files_count + 1);
631 if (new_array)
633 hlsl_ctx.source_files = new_array;
634 hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
639 any_identifier: VAR_IDENTIFIER
640 | TYPE_IDENTIFIER
641 | NEW_IDENTIFIER
643 func_declaration: func_prototype compound_statement
645 TRACE("Function %s parsed.\n", $1->name);
646 $$ = $1;
647 $$->body = $2;
648 pop_scope(&hlsl_ctx);
650 | func_prototype ';'
652 TRACE("Function prototype for %s.\n", $1->name);
653 $$ = $1;
654 pop_scope(&hlsl_ctx);
657 func_prototype: var_modifiers type var_identifier '(' parameters ')' semantic
659 if (get_variable(hlsl_ctx.globals, $3))
661 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
662 HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
663 return 1;
665 if ($2->base_type == HLSL_TYPE_VOID && $7)
667 hlsl_report_message(hlsl_ctx.source_file, @7.first_line, @7.first_column,
668 HLSL_LEVEL_ERROR, "void function with a semantic");
671 $$ = new_func_decl($3, $2, $5);
672 if (!$$)
674 ERR("Out of memory.\n");
675 return -1;
677 $$->semantic = $7;
680 compound_statement: '{' '}'
682 $$ = d3dcompiler_alloc(sizeof(*$$));
683 list_init($$);
685 | '{' scope_start statement_list '}'
687 pop_scope(&hlsl_ctx);
688 $$ = $3;
691 scope_start: /* Empty */
693 push_scope(&hlsl_ctx);
696 var_identifier: VAR_IDENTIFIER
697 | NEW_IDENTIFIER
699 semantic: /* Empty */
701 $$ = NULL;
703 | ':' any_identifier
705 $$ = $2;
708 parameters: scope_start
710 $$ = d3dcompiler_alloc(sizeof(*$$));
711 list_init($$);
713 | scope_start param_list
715 $$ = $2;
718 param_list: parameter
720 struct source_location loc;
722 $$ = d3dcompiler_alloc(sizeof(*$$));
723 list_init($$);
724 set_location(&loc, &@1);
725 if (!add_func_parameter($$, &$1, &loc))
727 ERR("Error adding function parameter %s.\n", $1.name);
728 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
729 return -1;
732 | param_list ',' parameter
734 struct source_location loc;
736 $$ = $1;
737 set_location(&loc, &@3);
738 if (!add_func_parameter($$, &$3, &loc))
740 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
741 "duplicate parameter %s", $3.name);
742 return 1;
746 parameter: input_mod var_modifiers type any_identifier semantic
748 $$.modifiers = $1;
749 $$.modifiers |= $2;
750 $$.type = $3;
751 $$.name = $4;
752 $$.semantic = $5;
755 input_mod: /* Empty */
757 $$ = HLSL_MODIFIER_IN;
759 | KW_IN
761 $$ = HLSL_MODIFIER_IN;
763 | KW_OUT
765 $$ = HLSL_MODIFIER_OUT;
767 | KW_INOUT
769 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
772 type: base_type
774 $$ = $1;
776 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
778 if ($3->type != HLSL_CLASS_SCALAR)
780 hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
781 hlsl_ctx.line_no);
782 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
783 return 1;
785 if ($5 < 1 || $5 > 4)
787 hlsl_message("Line %u: vector size must be between 1 and 4.\n",
788 hlsl_ctx.line_no);
789 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
790 return 1;
793 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
795 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
797 if ($3->type != HLSL_CLASS_SCALAR)
799 hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
800 hlsl_ctx.line_no);
801 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
802 return 1;
804 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
806 hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
807 hlsl_ctx.line_no);
808 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
809 return 1;
812 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
815 base_type: KW_VOID
817 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
819 | KW_SAMPLER
821 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
822 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
824 | KW_SAMPLER1D
826 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
827 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
829 | KW_SAMPLER2D
831 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
832 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
834 | KW_SAMPLER3D
836 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
837 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
839 | KW_SAMPLERCUBE
841 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
842 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
844 | TYPE_IDENTIFIER
846 struct hlsl_type *type;
848 TRACE("Type %s.\n", $1);
849 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
850 $$ = type;
851 d3dcompiler_free($1);
853 | KW_STRUCT TYPE_IDENTIFIER
855 struct hlsl_type *type;
857 TRACE("Struct type %s.\n", $2);
858 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
859 if (type->type != HLSL_CLASS_STRUCT)
861 hlsl_message("Line %u: redefining %s as a structure.\n",
862 hlsl_ctx.line_no, $2);
863 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
865 else
867 $$ = type;
869 d3dcompiler_free($2);
872 declaration_statement: declaration
874 $$ = $1;
876 | typedef
878 $$ = d3dcompiler_alloc(sizeof(*$$));
879 if (!$$)
881 ERR("Out of memory\n");
882 return -1;
884 list_init($$);
887 typedef: KW_TYPEDEF var_modifiers type type_specs ';'
889 struct source_location loc;
891 set_location(&loc, &@1);
892 if (!add_typedef($2, $3, $4, &loc))
893 return 1;
896 type_specs: type_spec
898 $$ = d3dcompiler_alloc(sizeof(*$$));
899 list_init($$);
900 list_add_head($$, &$1->entry);
902 | type_specs ',' type_spec
904 $$ = $1;
905 list_add_tail($$, &$3->entry);
908 type_spec: any_identifier array
910 $$ = d3dcompiler_alloc(sizeof(*$$));
911 set_location(&$$->loc, &@1);
912 $$->name = $1;
913 $$->array_size = $2;
916 declaration: var_modifiers type variables_def ';'
918 struct hlsl_type *type;
919 struct parse_variable_def *v, *v_next;
920 struct hlsl_ir_var *var;
921 struct hlsl_ir_node *assignment;
922 BOOL ret, local = TRUE;
924 $$ = d3dcompiler_alloc(sizeof(*$$));
925 list_init($$);
926 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
928 debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
929 var = d3dcompiler_alloc(sizeof(*var));
930 var->node.type = HLSL_IR_VAR;
931 if (v->array_size)
932 type = new_array_type($2, v->array_size);
933 else
934 type = $2;
935 var->node.data_type = type;
936 var->node.loc = v->loc;
937 var->name = v->name;
938 var->modifiers = $1;
939 var->semantic = v->semantic;
941 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
943 var->modifiers |= HLSL_STORAGE_UNIFORM;
944 local = FALSE;
947 if (var->modifiers & HLSL_MODIFIER_CONST && !v->initializer)
949 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col,
950 HLSL_LEVEL_ERROR, "const variable without initializer");
951 free_declaration(var);
952 d3dcompiler_free(v);
953 continue;
956 ret = declare_variable(var, local);
957 if (!ret)
958 free_declaration(var);
959 else
960 TRACE("Declared variable %s.\n", var->name);
962 if (v->initializer)
964 unsigned int size = initializer_size(v->initializer);
965 struct hlsl_ir_node *node;
967 TRACE("Variable with initializer\n");
968 if (type->type <= HLSL_CLASS_LAST_NUMERIC
969 && type->dimx * type->dimy != size
970 && size != 1)
972 if (size < type->dimx * type->dimy)
974 hlsl_report_message(v->loc.file,
975 v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
976 "'%s' initializer does not match", v->name);
977 free_instr_list(v->initializer);
978 d3dcompiler_free(v);
979 continue;
983 if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY)
984 && components_count_type(type) != size)
986 hlsl_report_message(v->loc.file,
987 v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
988 "'%s' initializer does not match", v->name);
989 free_instr_list(v->initializer);
990 d3dcompiler_free(v);
991 continue;
994 if (type->type > HLSL_CLASS_LAST_NUMERIC)
996 FIXME("Initializers for non scalar/struct variables not supported yet\n");
997 free_instr_list(v->initializer);
998 d3dcompiler_free(v);
999 continue;
1001 if (v->array_size > 0)
1003 FIXME("Initializing arrays is not supported yet\n");
1004 free_instr_list(v->initializer);
1005 d3dcompiler_free(v);
1006 continue;
1009 if (list_count(v->initializer) > 1)
1011 FIXME("Complex initializers are not supported yet.\n");
1012 free_instr_list(v->initializer);
1013 d3dcompiler_free(v);
1014 continue;
1016 node = LIST_ENTRY(list_head(v->initializer), struct hlsl_ir_node, entry);
1017 assignment = make_assignment(&var->node, ASSIGN_OP_ASSIGN,
1018 BWRITERSP_WRITEMASK_ALL, node);
1019 list_add_tail($$, &assignment->entry);
1021 d3dcompiler_free(v);
1023 d3dcompiler_free($3);
1026 variables_def: variable_def
1028 $$ = d3dcompiler_alloc(sizeof(*$$));
1029 list_init($$);
1030 list_add_head($$, &$1->entry);
1032 | variables_def ',' variable_def
1034 $$ = $1;
1035 list_add_tail($$, &$3->entry);
1038 variable_def: any_identifier array semantic
1040 $$ = d3dcompiler_alloc(sizeof(*$$));
1041 set_location(&$$->loc, &@1);
1042 $$->name = $1;
1043 $$->array_size = $2;
1044 $$->semantic = $3;
1046 | any_identifier array semantic '=' complex_initializer
1048 TRACE("Declaration with initializer.\n");
1049 $$ = d3dcompiler_alloc(sizeof(*$$));
1050 set_location(&$$->loc, &@1);
1051 $$->name = $1;
1052 $$->array_size = $2;
1053 $$->semantic = $3;
1054 $$->initializer = $5;
1057 array: /* Empty */
1059 $$ = 0;
1061 | '[' expr ']'
1063 FIXME("Array.\n");
1064 $$ = 0;
1065 free_instr($2);
1068 var_modifiers: /* Empty */
1070 $$ = 0;
1072 | KW_EXTERN var_modifiers
1074 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
1076 | KW_NOINTERPOLATION var_modifiers
1078 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
1080 | KW_PRECISE var_modifiers
1082 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
1084 | KW_SHARED var_modifiers
1086 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
1088 | KW_GROUPSHARED var_modifiers
1090 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
1092 | KW_STATIC var_modifiers
1094 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
1096 | KW_UNIFORM var_modifiers
1098 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
1100 | KW_VOLATILE var_modifiers
1102 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
1104 | KW_CONST var_modifiers
1106 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
1108 | KW_ROW_MAJOR var_modifiers
1110 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
1112 | KW_COLUMN_MAJOR var_modifiers
1114 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
1117 complex_initializer: initializer_expr
1119 $$ = d3dcompiler_alloc(sizeof(*$$));
1120 list_init($$);
1121 list_add_head($$, &$1->entry);
1123 | '{' initializer_expr_list '}'
1125 $$ = $2;
1128 initializer_expr: assignment_expr
1130 $$ = $1;
1133 initializer_expr_list: initializer_expr
1135 $$ = d3dcompiler_alloc(sizeof(*$$));
1136 list_init($$);
1137 list_add_head($$, &$1->entry);
1139 | initializer_expr_list ',' initializer_expr
1141 $$ = $1;
1142 list_add_tail($$, &$3->entry);
1145 boolean: KW_TRUE
1147 $$ = TRUE;
1149 | KW_FALSE
1151 $$ = FALSE;
1154 statement_list: statement
1156 $$ = $1;
1158 | statement_list statement
1160 $$ = $1;
1161 list_move_tail($$, $2);
1162 d3dcompiler_free($2);
1165 statement: declaration_statement
1166 | expr_statement
1167 | compound_statement
1168 | jump_statement
1169 | selection_statement
1171 /* FIXME: add rule for return with no value */
1172 jump_statement: KW_RETURN expr ';'
1174 struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump));
1175 if (!jump)
1177 ERR("Out of memory\n");
1178 return -1;
1180 jump->node.type = HLSL_IR_JUMP;
1181 set_location(&jump->node.loc, &@1);
1182 jump->type = HLSL_IR_JUMP_RETURN;
1183 jump->node.data_type = $2->data_type;
1184 jump->return_value = $2;
1186 FIXME("Check for valued return on void function.\n");
1187 FIXME("Implicit conversion to the return type if needed, "
1188 "error out if conversion not possible.\n");
1190 $$ = d3dcompiler_alloc(sizeof(*$$));
1191 list_init($$);
1192 list_add_tail($$, &jump->node.entry);
1195 selection_statement: KW_IF '(' expr ')' if_body
1197 struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
1198 if (!instr)
1200 ERR("Out of memory\n");
1201 return -1;
1203 instr->node.type = HLSL_IR_IF;
1204 set_location(&instr->node.loc, &@1);
1205 instr->condition = $3;
1206 instr->then_instrs = $5.then_instrs;
1207 instr->else_instrs = $5.else_instrs;
1208 if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1)
1210 hlsl_report_message(instr->node.loc.file, instr->node.loc.line,
1211 instr->node.loc.col, HLSL_LEVEL_ERROR,
1212 "if condition requires a scalar");
1214 $$ = d3dcompiler_alloc(sizeof(*$$));
1215 list_init($$);
1216 list_add_head($$, &instr->node.entry);
1219 if_body: statement
1221 $$.then_instrs = $1;
1222 $$.else_instrs = NULL;
1224 | statement KW_ELSE statement
1226 $$.then_instrs = $1;
1227 $$.else_instrs = $3;
1230 expr_statement: ';'
1232 $$ = d3dcompiler_alloc(sizeof(*$$));
1233 list_init($$);
1235 | expr ';'
1237 $$ = d3dcompiler_alloc(sizeof(*$$));
1238 list_init($$);
1239 if ($1)
1240 list_add_head($$, &$1->entry);
1243 primary_expr: C_FLOAT
1245 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1246 if (!c)
1248 ERR("Out of memory.\n");
1249 return -1;
1251 c->node.type = HLSL_IR_CONSTANT;
1252 set_location(&c->node.loc, &yylloc);
1253 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
1254 c->v.value.f[0] = $1;
1255 $$ = &c->node;
1257 | C_INTEGER
1259 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1260 if (!c)
1262 ERR("Out of memory.\n");
1263 return -1;
1265 c->node.type = HLSL_IR_CONSTANT;
1266 set_location(&c->node.loc, &yylloc);
1267 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
1268 c->v.value.i[0] = $1;
1269 $$ = &c->node;
1271 | boolean
1273 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1274 if (!c)
1276 ERR("Out of memory.\n");
1277 return -1;
1279 c->node.type = HLSL_IR_CONSTANT;
1280 set_location(&c->node.loc, &yylloc);
1281 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
1282 c->v.value.b[0] = $1;
1283 $$ = &c->node;
1285 | variable
1287 struct hlsl_ir_deref *deref = new_var_deref($1);
1288 if (deref)
1290 $$ = &deref->node;
1291 set_location(&$$->loc, &@1);
1293 else
1294 $$ = NULL;
1296 | '(' expr ')'
1298 $$ = $2;
1301 variable: VAR_IDENTIFIER
1303 struct hlsl_ir_var *var;
1304 var = get_variable(hlsl_ctx.cur_scope, $1);
1305 if (!var)
1307 hlsl_message("Line %d: variable '%s' not declared\n",
1308 hlsl_ctx.line_no, $1);
1309 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1310 return 1;
1312 $$ = var;
1315 postfix_expr: primary_expr
1317 $$ = $1;
1319 | postfix_expr OP_INC
1321 struct hlsl_ir_node *operands[3];
1322 struct source_location loc;
1324 set_location(&loc, &@2);
1325 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1327 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1328 "modifying a const expression");
1329 return 1;
1331 operands[0] = $1;
1332 operands[1] = operands[2] = NULL;
1333 $$ = &new_expr(HLSL_IR_BINOP_POSTINC, operands, &loc)->node;
1334 /* Post increment/decrement expressions are considered const */
1335 $$->data_type = clone_hlsl_type($$->data_type);
1336 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1338 | postfix_expr OP_DEC
1340 struct hlsl_ir_node *operands[3];
1341 struct source_location loc;
1343 set_location(&loc, &@2);
1344 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1346 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1347 "modifying a const expression");
1348 return 1;
1350 operands[0] = $1;
1351 operands[1] = operands[2] = NULL;
1352 $$ = &new_expr(HLSL_IR_BINOP_POSTDEC, operands, &loc)->node;
1353 /* Post increment/decrement expressions are considered const */
1354 $$->data_type = clone_hlsl_type($$->data_type);
1355 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1357 | postfix_expr '.' any_identifier
1359 struct source_location loc;
1361 set_location(&loc, &@2);
1362 if ($1->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
1364 struct hlsl_ir_swizzle *swizzle;
1366 swizzle = get_swizzle($1, $3, &loc);
1367 if (!swizzle)
1369 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1370 "invalid swizzle %s", debugstr_a($3));
1371 return 1;
1373 $$ = &swizzle->node;
1375 else
1377 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1378 "invalid subscript %s", debugstr_a($3));
1379 return 1;
1382 /* "var_modifiers" doesn't make sense in this case, but it's needed
1383 in the grammar to avoid shift/reduce conflicts. */
1384 | var_modifiers type '(' initializer_expr_list ')'
1386 struct hlsl_ir_constructor *constructor;
1388 TRACE("%s constructor.\n", debug_hlsl_type($2));
1389 if ($1)
1391 hlsl_message("Line %u: unexpected modifier in a constructor.\n",
1392 hlsl_ctx.line_no);
1393 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1394 return -1;
1396 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
1398 hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
1399 hlsl_ctx.line_no);
1400 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1401 return -1;
1403 if ($2->dimx * $2->dimy != components_count_expr_list($4))
1405 hlsl_message("Line %u: wrong number of components in constructor.\n",
1406 hlsl_ctx.line_no);
1407 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1408 return -1;
1411 constructor = d3dcompiler_alloc(sizeof(*constructor));
1412 constructor->node.type = HLSL_IR_CONSTRUCTOR;
1413 set_location(&constructor->node.loc, &@3);
1414 constructor->node.data_type = $2;
1415 constructor->arguments = $4;
1417 $$ = &constructor->node;
1420 unary_expr: postfix_expr
1422 $$ = $1;
1424 | OP_INC unary_expr
1426 struct hlsl_ir_node *operands[3];
1427 struct source_location loc;
1429 set_location(&loc, &@1);
1430 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
1432 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1433 "modifying a const expression");
1434 return 1;
1436 operands[0] = $2;
1437 operands[1] = operands[2] = NULL;
1438 $$ = &new_expr(HLSL_IR_BINOP_PREINC, operands, &loc)->node;
1440 | OP_DEC unary_expr
1442 struct hlsl_ir_node *operands[3];
1443 struct source_location loc;
1445 set_location(&loc, &@1);
1446 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
1448 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1449 "modifying a const expression");
1450 return 1;
1452 operands[0] = $2;
1453 operands[1] = operands[2] = NULL;
1454 $$ = &new_expr(HLSL_IR_BINOP_PREDEC, operands, &loc)->node;
1456 | unary_op unary_expr
1458 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
1459 HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
1460 struct hlsl_ir_node *operands[3];
1461 struct source_location loc;
1463 if ($1 == UNARY_OP_PLUS)
1465 $$ = $2;
1467 else
1469 operands[0] = $2;
1470 operands[1] = operands[2] = NULL;
1471 set_location(&loc, &@1);
1472 $$ = &new_expr(ops[$1], operands, &loc)->node;
1475 /* var_modifiers just to avoid shift/reduce conflicts */
1476 | '(' var_modifiers type array ')' unary_expr
1478 struct hlsl_ir_expr *expr;
1479 struct hlsl_type *src_type = $6->data_type;
1480 struct hlsl_type *dst_type;
1481 struct source_location loc;
1483 set_location(&loc, &@3);
1484 if ($2)
1486 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1487 "unexpected modifier in a cast");
1488 return 1;
1491 if ($4)
1492 dst_type = new_array_type($3, $4);
1493 else
1494 dst_type = $3;
1496 if (!compatible_data_types(src_type, dst_type))
1498 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1499 "can't cast from %s to %s",
1500 debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
1501 return 1;
1504 expr = new_cast($6, dst_type, &loc);
1505 $$ = expr ? &expr->node : NULL;
1508 unary_op: '+'
1510 $$ = UNARY_OP_PLUS;
1512 | '-'
1514 $$ = UNARY_OP_MINUS;
1516 | '!'
1518 $$ = UNARY_OP_LOGICNOT;
1520 | '~'
1522 $$ = UNARY_OP_BITNOT;
1525 mul_expr: unary_expr
1527 $$ = $1;
1529 | mul_expr '*' unary_expr
1531 struct source_location loc;
1533 set_location(&loc, &@2);
1534 $$ = &hlsl_mul($1, $3, &loc)->node;
1536 | mul_expr '/' unary_expr
1538 struct source_location loc;
1540 set_location(&loc, &@2);
1541 $$ = &hlsl_div($1, $3, &loc)->node;
1543 | mul_expr '%' unary_expr
1545 struct source_location loc;
1547 set_location(&loc, &@2);
1548 $$ = &hlsl_mod($1, $3, &loc)->node;
1551 add_expr: mul_expr
1553 $$ = $1;
1555 | add_expr '+' mul_expr
1557 struct source_location loc;
1559 set_location(&loc, &@2);
1560 $$ = &hlsl_add($1, $3, &loc)->node;
1562 | add_expr '-' mul_expr
1564 struct source_location loc;
1566 set_location(&loc, &@2);
1567 $$ = &hlsl_sub($1, $3, &loc)->node;
1570 shift_expr: add_expr
1572 $$ = $1;
1574 | shift_expr OP_LEFTSHIFT add_expr
1576 FIXME("Left shift\n");
1578 | shift_expr OP_RIGHTSHIFT add_expr
1580 FIXME("Right shift\n");
1583 relational_expr: shift_expr
1585 $$ = $1;
1587 | relational_expr '<' shift_expr
1589 struct source_location loc;
1591 set_location(&loc, &@2);
1592 $$ = &hlsl_lt($1, $3, &loc)->node;
1594 | relational_expr '>' shift_expr
1596 struct source_location loc;
1598 set_location(&loc, &@2);
1599 $$ = &hlsl_gt($1, $3, &loc)->node;
1601 | relational_expr OP_LE shift_expr
1603 struct source_location loc;
1605 set_location(&loc, &@2);
1606 $$ = &hlsl_le($1, $3, &loc)->node;
1608 | relational_expr OP_GE shift_expr
1610 struct source_location loc;
1612 set_location(&loc, &@2);
1613 $$ = &hlsl_ge($1, $3, &loc)->node;
1616 equality_expr: relational_expr
1618 $$ = $1;
1620 | equality_expr OP_EQ relational_expr
1622 struct source_location loc;
1624 set_location(&loc, &@2);
1625 $$ = &hlsl_eq($1, $3, &loc)->node;
1627 | equality_expr OP_NE relational_expr
1629 struct source_location loc;
1631 set_location(&loc, &@2);
1632 $$ = &hlsl_ne($1, $3, &loc)->node;
1635 bitand_expr: equality_expr
1637 $$ = $1;
1639 | bitand_expr '&' equality_expr
1641 FIXME("bitwise AND\n");
1644 bitxor_expr: bitand_expr
1646 $$ = $1;
1648 | bitxor_expr '^' bitand_expr
1650 FIXME("bitwise XOR\n");
1653 bitor_expr: bitxor_expr
1655 $$ = $1;
1657 | bitor_expr '|' bitxor_expr
1659 FIXME("bitwise OR\n");
1662 logicand_expr: bitor_expr
1664 $$ = $1;
1666 | logicand_expr OP_AND bitor_expr
1668 FIXME("logic AND\n");
1671 logicor_expr: logicand_expr
1673 $$ = $1;
1675 | logicor_expr OP_OR logicand_expr
1677 FIXME("logic OR\n");
1680 conditional_expr: logicor_expr
1682 $$ = $1;
1684 | logicor_expr '?' expr ':' assignment_expr
1686 FIXME("ternary operator\n");
1689 assignment_expr: conditional_expr
1691 $$ = $1;
1693 | unary_expr assign_op assignment_expr
1695 struct source_location loc;
1697 set_location(&loc, &@2);
1698 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1700 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1701 "l-value is const");
1702 return 1;
1704 $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
1705 if (!$$)
1706 return 1;
1707 $$->loc = loc;
1710 assign_op: '='
1712 $$ = ASSIGN_OP_ASSIGN;
1714 | OP_ADDASSIGN
1716 $$ = ASSIGN_OP_ADD;
1718 | OP_SUBASSIGN
1720 $$ = ASSIGN_OP_SUB;
1722 | OP_MULASSIGN
1724 $$ = ASSIGN_OP_MUL;
1726 | OP_DIVASSIGN
1728 $$ = ASSIGN_OP_DIV;
1730 | OP_MODASSIGN
1732 $$ = ASSIGN_OP_MOD;
1734 | OP_LEFTSHIFTASSIGN
1736 $$ = ASSIGN_OP_LSHIFT;
1738 | OP_RIGHTSHIFTASSIGN
1740 $$ = ASSIGN_OP_RSHIFT;
1742 | OP_ANDASSIGN
1744 $$ = ASSIGN_OP_AND;
1746 | OP_ORASSIGN
1748 $$ = ASSIGN_OP_OR;
1750 | OP_XORASSIGN
1752 $$ = ASSIGN_OP_XOR;
1755 expr: assignment_expr
1757 $$ = $1;
1759 | expr ',' assignment_expr
1761 FIXME("Comma expression\n");
1766 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
1768 loc->file = hlsl_ctx.source_file;
1769 loc->line = l->first_line;
1770 loc->col = l->first_column;
1773 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
1775 if (modifiers & mod)
1777 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
1778 "modifier '%s' already specified", debug_modifiers(mod));
1779 return modifiers;
1781 if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
1782 && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
1784 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
1785 "more than one matrix majority keyword");
1786 return modifiers;
1788 return modifiers | mod;
1791 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
1792 const char *entrypoint, char **messages)
1794 struct hlsl_ir_function_decl *function;
1795 struct hlsl_scope *scope, *next_scope;
1796 struct hlsl_type *hlsl_type, *next_type;
1797 struct hlsl_ir_var *var, *next_var;
1798 unsigned int i;
1800 hlsl_ctx.status = PARSE_SUCCESS;
1801 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
1802 hlsl_ctx.line_no = hlsl_ctx.column = 1;
1803 hlsl_ctx.source_file = d3dcompiler_strdup("");
1804 hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
1805 if (hlsl_ctx.source_files)
1806 hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
1807 hlsl_ctx.source_files_count = 1;
1808 hlsl_ctx.cur_scope = NULL;
1809 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
1810 list_init(&hlsl_ctx.scopes);
1811 list_init(&hlsl_ctx.types);
1812 list_init(&hlsl_ctx.functions);
1814 push_scope(&hlsl_ctx);
1815 hlsl_ctx.globals = hlsl_ctx.cur_scope;
1816 declare_predefined_types(hlsl_ctx.globals);
1818 hlsl_parse();
1820 if (TRACE_ON(hlsl_parser))
1822 struct hlsl_ir_function_decl *func;
1824 TRACE("IR dump.\n");
1825 LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1827 if (func->body)
1828 debug_dump_ir_function(func);
1832 TRACE("Compilation status = %d\n", hlsl_ctx.status);
1833 if (messages)
1835 if (hlsl_ctx.messages.size)
1836 *messages = hlsl_ctx.messages.string;
1837 else
1838 *messages = NULL;
1840 else
1842 if (hlsl_ctx.messages.capacity)
1843 d3dcompiler_free(hlsl_ctx.messages.string);
1846 for (i = 0; i < hlsl_ctx.source_files_count; ++i)
1847 d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
1848 d3dcompiler_free(hlsl_ctx.source_files);
1850 TRACE("Freeing functions IR.\n");
1851 LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1852 free_function(function);
1854 TRACE("Freeing variables.\n");
1855 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
1857 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
1859 free_declaration(var);
1861 wine_rb_destroy(&scope->types, NULL, NULL);
1862 d3dcompiler_free(scope);
1865 TRACE("Freeing types.\n");
1866 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
1868 free_hlsl_type(hlsl_type);
1871 return NULL;