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;
36 static void set_location(struct source_location *loc, const struct YYLTYPE *l);
38 void hlsl_message(const char *fmt, ...)
43 compilation_message(&hlsl_ctx.messages, fmt, args);
47 static const char *hlsl_get_error_level_name(enum hlsl_error_level level)
58 void hlsl_report_message(const char *filename, DWORD line, DWORD column,
59 enum hlsl_error_level level, const char *fmt, ...)
68 rc = vsnprintf(string, size, fmt, args);
71 if (rc >= 0 && rc < size)
77 size = size ? size * 2 : 32;
80 string = d3dcompiler_alloc(size);
82 string = d3dcompiler_realloc(string, size);
85 ERR("Error reallocating memory for a string.\n");
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);
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)
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;
135 check_invalid_matrix_modifiers(decl->modifiers, &decl->node.loc);
139 DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
140 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
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));
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");
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);
162 ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
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);
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");
189 static BOOL add_type_to_scope(struct hlsl_scope *scope, struct hlsl_type *def)
191 if (get_type(scope, def->name, FALSE))
194 wine_rb_put(&scope->types, def->name, &def->scope_entry);
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[] =
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);
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);
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 struct hlsl_ir_if *loop_condition(struct list *cond_list)
261 struct hlsl_ir_if *out_cond;
262 struct hlsl_ir_expr *not_cond;
263 struct hlsl_ir_node *cond, *operands[3];
264 struct hlsl_ir_jump *jump;
265 unsigned int count = list_count(cond_list);
270 ERR("Got multiple expressions in a for condition.\n");
272 cond = LIST_ENTRY(list_head(cond_list), struct hlsl_ir_node, entry);
273 out_cond = d3dcompiler_alloc(sizeof(*out_cond));
276 ERR("Out of memory.\n");
279 out_cond->node.type = HLSL_IR_IF;
281 operands[1] = operands[2] = NULL;
282 not_cond = new_expr(HLSL_IR_UNOP_LOGIC_NOT, operands, &cond->loc);
285 ERR("Out of memory.\n");
286 d3dcompiler_free(out_cond);
289 out_cond->condition = ¬_cond->node;
290 jump = d3dcompiler_alloc(sizeof(*jump));
293 ERR("Out of memory.\n");
294 d3dcompiler_free(out_cond);
295 d3dcompiler_free(not_cond);
298 jump->node.type = HLSL_IR_JUMP;
299 jump->type = HLSL_IR_JUMP_BREAK;
300 out_cond->then_instrs = d3dcompiler_alloc(sizeof(*out_cond->then_instrs));
301 if (!out_cond->then_instrs)
303 ERR("Out of memory.\n");
304 d3dcompiler_free(out_cond);
305 d3dcompiler_free(not_cond);
306 d3dcompiler_free(jump);
309 list_init(out_cond->then_instrs);
310 list_add_head(out_cond->then_instrs, &jump->node.entry);
322 static struct list *create_loop(enum loop_type type, struct list *init, struct list *cond,
323 struct hlsl_ir_node *iter, struct list *body, struct source_location *loc)
325 struct list *list = NULL;
326 struct hlsl_ir_loop *loop = NULL;
327 struct hlsl_ir_if *cond_jump = NULL;
329 list = d3dcompiler_alloc(sizeof(*list));
335 list_move_head(list, init);
337 loop = d3dcompiler_alloc(sizeof(*loop));
340 loop->node.type = HLSL_IR_LOOP;
341 loop->node.loc = *loc;
342 list_add_tail(list, &loop->node.entry);
343 loop->body = d3dcompiler_alloc(sizeof(*loop->body));
346 list_init(loop->body);
348 cond_jump = loop_condition(cond);
352 if (type != LOOP_DO_WHILE)
353 list_add_tail(loop->body, &cond_jump->node.entry);
355 list_move_tail(loop->body, body);
358 list_add_tail(loop->body, &iter->entry);
360 if (type == LOOP_DO_WHILE)
361 list_add_tail(loop->body, &cond_jump->node.entry);
363 d3dcompiler_free(init);
364 d3dcompiler_free(cond);
365 d3dcompiler_free(body);
369 ERR("Out of memory.\n");
371 d3dcompiler_free(loop->body);
372 d3dcompiler_free(loop);
373 d3dcompiler_free(cond_jump);
374 d3dcompiler_free(list);
375 free_instr_list(init);
376 free_instr_list(cond);
378 free_instr_list(body);
382 static unsigned int initializer_size(struct list *initializer)
384 unsigned int count = 0;
385 struct hlsl_ir_node *node;
387 LIST_FOR_EACH_ENTRY(node, initializer, struct hlsl_ir_node, entry)
389 count += components_count_type(node->data_type);
391 TRACE("Initializer size = %u\n", count);
395 static unsigned int components_count_expr_list(struct list *list)
397 struct hlsl_ir_node *node;
398 unsigned int count = 0;
400 LIST_FOR_EACH_ENTRY(node, list, struct hlsl_ir_node, entry)
402 count += components_count_type(node->data_type);
407 static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components,
408 struct hlsl_ir_node *val, struct source_location *loc)
410 struct hlsl_ir_swizzle *swizzle = d3dcompiler_alloc(sizeof(*swizzle));
414 swizzle->node.type = HLSL_IR_SWIZZLE;
415 swizzle->node.loc = *loc;
416 swizzle->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1);
418 swizzle->swizzle = s;
422 static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const char *swizzle,
423 struct source_location *loc)
425 unsigned int len = strlen(swizzle), component = 0;
426 unsigned int i, set, swiz = 0;
429 if (value->data_type->type == HLSL_CLASS_MATRIX)
433 unsigned int inc, x, y;
435 if (len < 3 || swizzle[0] != '_')
437 m_swizzle = swizzle[1] == 'm';
438 inc = m_swizzle ? 4 : 3;
440 if (len % inc || len > inc * 4)
443 for (i = 0; i < len; i += inc)
445 if (swizzle[i] != '_')
449 if (swizzle[i + 1] != 'm')
451 x = swizzle[i + 2] - '0';
452 y = swizzle[i + 3] - '0';
456 x = swizzle[i + 1] - '1';
457 y = swizzle[i + 2] - '1';
460 if (x >= value->data_type->dimx || y >= value->data_type->dimy)
462 swiz |= (y << 4 | x) << component * 8;
465 return new_swizzle(swiz, component, value, loc);
472 for (set = 0; set < 2; ++set)
476 for (i = 0; i < len; ++i)
478 char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}};
481 for (s = 0; s < 4; ++s)
483 if (swizzle[i] == c[set][s])
492 if (s >= value->data_type->dimx)
494 swiz |= s << component * 2;
498 return new_swizzle(swiz, component, value, loc);
504 static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var, struct list *initializer)
506 struct hlsl_type *type = var->node.data_type;
507 struct hlsl_ir_node *node;
508 struct hlsl_struct_field *field;
509 struct list *cur_node;
510 struct hlsl_ir_node *assignment;
511 struct hlsl_ir_deref *deref;
513 if (initializer_size(initializer) != components_count_type(type))
515 hlsl_report_message(var->node.loc.file, var->node.loc.line, var->node.loc.col, HLSL_LEVEL_ERROR,
516 "structure initializer mismatch");
517 free_instr_list(initializer);
520 cur_node = list_head(initializer);
522 node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
523 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
527 d3dcompiler_free(initializer);
530 if (components_count_type(field->type) == components_count_type(node->data_type))
532 deref = new_record_deref(&var->node, field);
535 ERR("Out of memory.\n");
538 deref->node.loc = node->loc;
539 assignment = make_assignment(&deref->node, ASSIGN_OP_ASSIGN, BWRITERSP_WRITEMASK_ALL, node);
540 list_add_tail(list, &assignment->entry);
543 FIXME("Initializing with \"mismatched\" fields is not supported yet.\n");
544 cur_node = list_next(initializer, cur_node);
545 node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
548 /* Free initializer elements in excess. */
551 struct list *next = list_next(initializer, cur_node);
554 node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
556 d3dcompiler_free(initializer);
559 static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list)
561 struct hlsl_type *type;
562 struct parse_variable_def *v, *v_next;
563 struct hlsl_ir_var *var;
564 struct hlsl_ir_node *assignment;
565 BOOL ret, local = TRUE;
566 struct list *statements_list = d3dcompiler_alloc(sizeof(*statements_list));
568 if (!statements_list)
570 ERR("Out of memory.\n");
571 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
573 d3dcompiler_free(var_list);
576 list_init(statements_list);
579 return statements_list;
581 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
583 var = d3dcompiler_alloc(sizeof(*var));
586 ERR("Out of memory.\n");
590 var->node.type = HLSL_IR_VAR;
592 type = new_array_type(basic_type, v->array_size);
595 var->node.data_type = type;
596 var->node.loc = v->loc;
598 var->modifiers = modifiers;
599 var->semantic = v->semantic;
600 debug_dump_decl(type, modifiers, v->name, v->loc.line);
602 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
604 var->modifiers |= HLSL_STORAGE_UNIFORM;
608 if (var->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer)
610 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col,
611 HLSL_LEVEL_ERROR, "const variable without initializer");
612 free_declaration(var);
617 ret = declare_variable(var, local);
620 free_declaration(var);
624 TRACE("Declared variable %s.\n", var->name);
628 unsigned int size = initializer_size(v->initializer);
629 struct hlsl_ir_node *node;
631 TRACE("Variable with initializer.\n");
632 if (type->type <= HLSL_CLASS_LAST_NUMERIC
633 && type->dimx * type->dimy != size && size != 1)
635 if (size < type->dimx * type->dimy)
637 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
638 "'%s' initializer does not match", v->name);
639 free_instr_list(v->initializer);
644 if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY)
645 && components_count_type(type) != size)
647 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
648 "'%s' initializer does not match", v->name);
649 free_instr_list(v->initializer);
654 if (type->type == HLSL_CLASS_STRUCT)
656 struct_var_initializer(statements_list, var, v->initializer);
660 if (type->type > HLSL_CLASS_LAST_NUMERIC)
662 FIXME("Initializers for non scalar/struct variables not supported yet.\n");
663 free_instr_list(v->initializer);
667 if (v->array_size > 0)
669 FIXME("Initializing arrays is not supported yet.\n");
670 free_instr_list(v->initializer);
674 if (list_count(v->initializer) > 1)
676 FIXME("Complex initializers are not supported yet.\n");
677 free_instr_list(v->initializer);
681 node = LIST_ENTRY(list_head(v->initializer), struct hlsl_ir_node, entry);
682 assignment = make_assignment(&var->node, ASSIGN_OP_ASSIGN,
683 BWRITERSP_WRITEMASK_ALL, node);
684 list_add_tail(statements_list, &assignment->entry);
685 d3dcompiler_free(v->initializer);
689 d3dcompiler_free(var_list);
690 return statements_list;
693 static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field)
695 struct hlsl_struct_field *f;
697 LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry)
699 if (!strcmp(f->name, field->name))
702 list_add_tail(fields, &field->entry);
706 static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, struct list *fields)
708 struct parse_variable_def *v, *v_next;
709 struct hlsl_struct_field *field;
712 list = d3dcompiler_alloc(sizeof(*list));
715 ERR("Out of memory.\n");
719 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry)
721 debug_dump_decl(type, 0, v->name, v->loc.line);
722 field = d3dcompiler_alloc(sizeof(*field));
725 ERR("Out of memory.\n");
730 field->name = v->name;
731 field->modifiers = modifiers;
732 field->semantic = v->semantic;
735 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
736 "struct field with an initializer.\n");
737 free_instr_list(v->initializer);
739 list_add_tail(list, &field->entry);
742 d3dcompiler_free(fields);
746 static struct hlsl_type *new_struct_type(const char *name, DWORD modifiers, struct list *fields)
748 struct hlsl_type *type = d3dcompiler_alloc(sizeof(*type));
752 ERR("Out of memory.\n");
755 type->type = HLSL_CLASS_STRUCT;
757 type->dimx = type->dimy = 1;
758 type->modifiers = modifiers;
759 type->e.elements = fields;
761 list_add_tail(&hlsl_ctx.types, &type->entry);
766 static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list,
767 struct source_location *loc)
770 struct hlsl_type *type;
771 struct parse_variable_def *v, *v_next;
773 if (!check_type_modifiers(modifiers, loc))
775 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
777 d3dcompiler_free(list);
781 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
784 type = new_array_type(orig_type, v->array_size);
786 type = clone_hlsl_type(orig_type);
789 ERR("Out of memory\n");
792 d3dcompiler_free((void *)type->name);
793 type->name = v->name;
794 type->modifiers |= modifiers;
796 if (type->type != HLSL_CLASS_MATRIX)
797 check_invalid_matrix_modifiers(type->modifiers, &v->loc);
799 ret = add_type_to_scope(hlsl_ctx.cur_scope, type);
802 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
803 "redefinition of custom type '%s'", v->name);
807 d3dcompiler_free(list);
811 static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tree *funcs, char *name,
812 struct list *params, BOOL exact_signature)
814 struct hlsl_ir_function *func;
815 struct wine_rb_entry *entry;
817 entry = wine_rb_get(funcs, name);
820 func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
822 entry = wine_rb_get(&func->overloads, params);
825 if (!exact_signature)
826 FIXME("No exact match, search for a compatible overloaded function (if any).\n");
829 return WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
842 struct hlsl_type *type;
848 struct hlsl_ir_var *var;
849 struct hlsl_ir_node *instr;
851 struct parse_function function;
852 struct parse_parameter parameter;
853 struct parse_variable_def *variable_def;
854 struct parse_if_body if_body;
855 enum parse_unary_op unary_op;
856 enum parse_assign_op assign_op;
863 %token KW_COLUMN_MAJOR
867 %token KW_DEPTHSTENCILSTATE
868 %token KW_DEPTHSTENCILVIEW
876 %token KW_GEOMETRYSHADER
877 %token KW_GROUPSHARED
884 %token KW_NOINTERPOLATION
887 %token KW_PIXELSHADER
889 %token KW_RASTERIZERSTATE
890 %token KW_RENDERTARGETVIEW
898 %token KW_SAMPLERCUBE
899 %token KW_SAMPLER_STATE
900 %token KW_SAMPLERCOMPARISONSTATE
903 %token KW_STATEBLOCK_STATE
910 %token KW_TECHNIQUE10
913 %token KW_TEXTURE1DARRAY
915 %token KW_TEXTURE2DARRAY
916 %token KW_TEXTURE2DMS
917 %token KW_TEXTURE2DMSARRAY
919 %token KW_TEXTURE3DARRAY
920 %token KW_TEXTURECUBE
925 %token KW_VERTEXSHADER
936 %token OP_LEFTSHIFTASSIGN
938 %token OP_RIGHTSHIFTASSIGN
956 %token <intval> PRE_LINE
958 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
959 %type <name> any_identifier var_identifier
961 %token <floatval> C_FLOAT
962 %token <intval> C_INTEGER
963 %type <boolval> boolean
964 %type <type> base_type
966 %type <list> declaration_statement
967 %type <list> declaration
968 %type <list> struct_declaration
969 %type <type> struct_spec
970 %type <type> named_struct_spec
971 %type <type> unnamed_struct_spec
972 %type <list> type_specs
973 %type <variable_def> type_spec
974 %type <list> complex_initializer
975 %type <list> initializer_expr_list
976 %type <instr> initializer_expr
977 %type <modifiers> var_modifiers
979 %type <list> parameters
980 %type <list> param_list
984 %type <list> statement
985 %type <list> statement_list
986 %type <list> compound_statement
987 %type <list> jump_statement
988 %type <list> selection_statement
989 %type <list> loop_statement
990 %type <function> func_declaration
991 %type <function> func_prototype
992 %type <list> fields_list
993 %type <parameter> parameter
994 %type <name> semantic
995 %type <variable_def> variable_def
996 %type <list> variables_def
997 %type <list> variables_def_optional
998 %type <if_body> if_body
999 %type <instr> primary_expr
1000 %type <instr> postfix_expr
1001 %type <instr> unary_expr
1002 %type <instr> mul_expr
1003 %type <instr> add_expr
1004 %type <instr> shift_expr
1005 %type <instr> relational_expr
1006 %type <instr> equality_expr
1007 %type <instr> bitand_expr
1008 %type <instr> bitxor_expr
1009 %type <instr> bitor_expr
1010 %type <instr> logicand_expr
1011 %type <instr> logicor_expr
1012 %type <instr> conditional_expr
1013 %type <instr> assignment_expr
1014 %type <list> expr_statement
1015 %type <unary_op> unary_op
1016 %type <assign_op> assign_op
1017 %type <modifiers> input_mods
1018 %type <modifiers> input_mod
1021 hlsl_prog: /* empty */
1024 | hlsl_prog func_declaration
1026 const struct hlsl_ir_function_decl *decl;
1028 decl = get_overloaded_func(&hlsl_ctx.functions, $2.name, $2.decl->parameters, TRUE);
1029 if (decl && !decl->func->intrinsic)
1031 if (decl->body && $2.decl->body)
1033 hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
1034 $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
1035 "redefinition of function %s", debugstr_a($2.name));
1038 else if (!compare_hlsl_types(decl->node.data_type, $2.decl->node.data_type))
1040 hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
1041 $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
1042 "redefining function %s with a different return type",
1043 debugstr_a($2.name));
1044 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_NOTE,
1045 "%s previously declared here",
1046 debugstr_a($2.name));
1051 if ($2.decl->node.data_type->base_type == HLSL_TYPE_VOID && $2.decl->semantic)
1053 hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
1054 $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
1055 "void function with a semantic");
1058 TRACE("Adding function '%s' to the function list.\n", $2.name);
1059 add_function_decl(&hlsl_ctx.functions, $2.name, $2.decl, FALSE);
1061 | hlsl_prog declaration_statement
1063 TRACE("Declaration statement parsed.\n");
1065 | hlsl_prog preproc_directive
1070 TRACE("Skipping stray semicolon.\n");
1073 preproc_directive: PRE_LINE STRING
1075 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
1076 hlsl_ctx.line_no = $1;
1077 if (strcmp($2, hlsl_ctx.source_file))
1079 const char **new_array;
1081 hlsl_ctx.source_file = $2;
1082 new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
1083 sizeof(*hlsl_ctx.source_files) * hlsl_ctx.source_files_count + 1);
1086 hlsl_ctx.source_files = new_array;
1087 hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
1092 struct_declaration: struct_spec variables_def_optional ';'
1094 struct source_location loc;
1096 set_location(&loc, &@3);
1101 hlsl_report_message(loc.file, loc.line, loc.col,
1102 HLSL_LEVEL_ERROR, "anonymous struct declaration with no variables");
1104 check_type_modifiers($1->modifiers, &loc);
1106 $$ = declare_vars($1, 0, $2);
1109 struct_spec: named_struct_spec
1110 | unnamed_struct_spec
1112 named_struct_spec: var_modifiers KW_STRUCT any_identifier '{' fields_list '}'
1115 struct source_location loc;
1117 TRACE("Structure %s declaration.\n", debugstr_a($3));
1118 set_location(&loc, &@1);
1119 check_invalid_matrix_modifiers($1, &loc);
1120 $$ = new_struct_type($3, $1, $5);
1122 if (get_variable(hlsl_ctx.cur_scope, $3))
1124 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1125 HLSL_LEVEL_ERROR, "redefinition of '%s'", $3);
1129 ret = add_type_to_scope(hlsl_ctx.cur_scope, $$);
1132 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1133 HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $3);
1138 unnamed_struct_spec: var_modifiers KW_STRUCT '{' fields_list '}'
1140 struct source_location loc;
1142 TRACE("Anonymous structure declaration.\n");
1143 set_location(&loc, &@1);
1144 check_invalid_matrix_modifiers($1, &loc);
1145 $$ = new_struct_type(NULL, $1, $4);
1148 any_identifier: VAR_IDENTIFIER
1152 fields_list: /* Empty */
1154 $$ = d3dcompiler_alloc(sizeof(*$$));
1160 struct hlsl_struct_field *field, *next;
1163 LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry)
1165 ret = add_struct_field($$, field);
1168 hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1169 HLSL_LEVEL_ERROR, "redefinition of '%s'", field->name);
1170 d3dcompiler_free(field);
1173 d3dcompiler_free($2);
1176 field: var_modifiers type variables_def ';'
1178 $$ = gen_struct_fields($2, $1, $3);
1180 | unnamed_struct_spec variables_def ';'
1182 $$ = gen_struct_fields($1, 0, $2);
1185 func_declaration: func_prototype compound_statement
1187 TRACE("Function %s parsed.\n", $1.name);
1190 pop_scope(&hlsl_ctx);
1192 | func_prototype ';'
1194 TRACE("Function prototype for %s.\n", $1.name);
1196 pop_scope(&hlsl_ctx);
1199 func_prototype: var_modifiers type var_identifier '(' parameters ')' semantic
1201 if (get_variable(hlsl_ctx.globals, $3))
1203 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1204 HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
1207 if ($2->base_type == HLSL_TYPE_VOID && $7)
1209 hlsl_report_message(hlsl_ctx.source_file, @7.first_line, @7.first_column,
1210 HLSL_LEVEL_ERROR, "void function with a semantic");
1213 $$.decl = new_func_decl($2, $5);
1216 ERR("Out of memory.\n");
1220 $$.decl->semantic = $7;
1221 set_location(&$$.decl->node.loc, &@3);
1224 compound_statement: '{' '}'
1226 $$ = d3dcompiler_alloc(sizeof(*$$));
1229 | '{' scope_start statement_list '}'
1231 pop_scope(&hlsl_ctx);
1235 scope_start: /* Empty */
1237 push_scope(&hlsl_ctx);
1240 var_identifier: VAR_IDENTIFIER
1243 semantic: /* Empty */
1247 | ':' any_identifier
1252 parameters: scope_start
1254 $$ = d3dcompiler_alloc(sizeof(*$$));
1257 | scope_start param_list
1262 param_list: parameter
1264 struct source_location loc;
1266 $$ = d3dcompiler_alloc(sizeof(*$$));
1268 set_location(&loc, &@1);
1269 if (!add_func_parameter($$, &$1, &loc))
1271 ERR("Error adding function parameter %s.\n", $1.name);
1272 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1276 | param_list ',' parameter
1278 struct source_location loc;
1281 set_location(&loc, &@3);
1282 if (!add_func_parameter($$, &$3, &loc))
1284 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1285 "duplicate parameter %s", $3.name);
1290 parameter: input_mods var_modifiers type any_identifier semantic
1292 $$.modifiers = $1 ? $1 : HLSL_MODIFIER_IN;
1299 input_mods: /* Empty */
1303 | input_mods input_mod
1307 hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1308 HLSL_LEVEL_ERROR, "duplicate input-output modifiers");
1316 $$ = HLSL_MODIFIER_IN;
1320 $$ = HLSL_MODIFIER_OUT;
1324 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
1331 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
1333 if ($3->type != HLSL_CLASS_SCALAR)
1335 hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
1337 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1340 if ($5 < 1 || $5 > 4)
1342 hlsl_message("Line %u: vector size must be between 1 and 4.\n",
1344 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1348 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
1350 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
1352 if ($3->type != HLSL_CLASS_SCALAR)
1354 hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
1356 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1359 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
1361 hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
1363 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1367 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
1372 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
1376 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1377 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
1381 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1382 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
1386 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1387 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
1391 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1392 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
1396 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1397 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
1401 struct hlsl_type *type;
1403 TRACE("Type %s.\n", $1);
1404 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
1406 d3dcompiler_free($1);
1408 | KW_STRUCT TYPE_IDENTIFIER
1410 struct hlsl_type *type;
1412 TRACE("Struct type %s.\n", $2);
1413 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
1414 if (type->type != HLSL_CLASS_STRUCT)
1416 hlsl_message("Line %u: redefining %s as a structure.\n",
1417 hlsl_ctx.line_no, $2);
1418 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1424 d3dcompiler_free($2);
1427 declaration_statement: declaration
1428 | struct_declaration
1431 $$ = d3dcompiler_alloc(sizeof(*$$));
1434 ERR("Out of memory\n");
1440 typedef: KW_TYPEDEF var_modifiers type type_specs ';'
1442 struct source_location loc;
1444 set_location(&loc, &@1);
1445 if (!add_typedef($2, $3, $4, &loc))
1448 | KW_TYPEDEF struct_spec type_specs ';'
1450 struct source_location loc;
1452 set_location(&loc, &@1);
1453 if (!add_typedef(0, $2, $3, &loc))
1457 type_specs: type_spec
1459 $$ = d3dcompiler_alloc(sizeof(*$$));
1461 list_add_head($$, &$1->entry);
1463 | type_specs ',' type_spec
1466 list_add_tail($$, &$3->entry);
1469 type_spec: any_identifier array
1471 $$ = d3dcompiler_alloc(sizeof(*$$));
1472 set_location(&$$->loc, &@1);
1474 $$->array_size = $2;
1477 declaration: var_modifiers type variables_def ';'
1479 $$ = declare_vars($2, $1, $3);
1482 variables_def_optional: /* Empty */
1491 variables_def: variable_def
1493 $$ = d3dcompiler_alloc(sizeof(*$$));
1495 list_add_head($$, &$1->entry);
1497 | variables_def ',' variable_def
1500 list_add_tail($$, &$3->entry);
1503 variable_def: any_identifier array semantic
1505 $$ = d3dcompiler_alloc(sizeof(*$$));
1506 set_location(&$$->loc, &@1);
1508 $$->array_size = $2;
1511 | any_identifier array semantic '=' complex_initializer
1513 TRACE("Declaration with initializer.\n");
1514 $$ = d3dcompiler_alloc(sizeof(*$$));
1515 set_location(&$$->loc, &@1);
1517 $$->array_size = $2;
1519 $$->initializer = $5;
1533 var_modifiers: /* Empty */
1537 | KW_EXTERN var_modifiers
1539 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
1541 | KW_NOINTERPOLATION var_modifiers
1543 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
1545 | KW_PRECISE var_modifiers
1547 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
1549 | KW_SHARED var_modifiers
1551 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
1553 | KW_GROUPSHARED var_modifiers
1555 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
1557 | KW_STATIC var_modifiers
1559 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
1561 | KW_UNIFORM var_modifiers
1563 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
1565 | KW_VOLATILE var_modifiers
1567 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
1569 | KW_CONST var_modifiers
1571 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
1573 | KW_ROW_MAJOR var_modifiers
1575 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
1577 | KW_COLUMN_MAJOR var_modifiers
1579 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
1582 complex_initializer: initializer_expr
1584 $$ = d3dcompiler_alloc(sizeof(*$$));
1586 list_add_head($$, &$1->entry);
1588 | '{' initializer_expr_list '}'
1592 | '{' initializer_expr_list ',' '}'
1597 initializer_expr: assignment_expr
1602 initializer_expr_list: initializer_expr
1604 $$ = d3dcompiler_alloc(sizeof(*$$));
1606 list_add_head($$, &$1->entry);
1608 | initializer_expr_list ',' initializer_expr
1611 list_add_tail($$, &$3->entry);
1623 statement_list: statement
1627 | statement_list statement
1630 list_move_tail($$, $2);
1631 d3dcompiler_free($2);
1634 statement: declaration_statement
1636 | compound_statement
1638 | selection_statement
1641 /* FIXME: add rule for return with no value */
1642 jump_statement: KW_RETURN expr ';'
1644 struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump));
1647 ERR("Out of memory\n");
1650 jump->node.type = HLSL_IR_JUMP;
1651 set_location(&jump->node.loc, &@1);
1652 jump->type = HLSL_IR_JUMP_RETURN;
1653 jump->node.data_type = $2->data_type;
1654 jump->return_value = $2;
1656 FIXME("Check for valued return on void function.\n");
1657 FIXME("Implicit conversion to the return type if needed, "
1658 "error out if conversion not possible.\n");
1660 $$ = d3dcompiler_alloc(sizeof(*$$));
1662 list_add_tail($$, &jump->node.entry);
1665 selection_statement: KW_IF '(' expr ')' if_body
1667 struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
1670 ERR("Out of memory\n");
1673 instr->node.type = HLSL_IR_IF;
1674 set_location(&instr->node.loc, &@1);
1675 instr->condition = $3;
1676 instr->then_instrs = $5.then_instrs;
1677 instr->else_instrs = $5.else_instrs;
1678 if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1)
1680 hlsl_report_message(instr->node.loc.file, instr->node.loc.line,
1681 instr->node.loc.col, HLSL_LEVEL_ERROR,
1682 "if condition requires a scalar");
1684 $$ = d3dcompiler_alloc(sizeof(*$$));
1686 list_add_head($$, &instr->node.entry);
1691 $$.then_instrs = $1;
1692 $$.else_instrs = NULL;
1694 | statement KW_ELSE statement
1696 $$.then_instrs = $1;
1697 $$.else_instrs = $3;
1700 loop_statement: KW_WHILE '(' expr ')' statement
1702 struct source_location loc;
1703 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1707 ERR("Out of memory.\n");
1711 list_add_head(cond, &$3->entry);
1712 set_location(&loc, &@1);
1713 $$ = create_loop(LOOP_WHILE, NULL, cond, NULL, $5, &loc);
1715 | KW_DO statement KW_WHILE '(' expr ')' ';'
1717 struct source_location loc;
1718 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1722 ERR("Out of memory.\n");
1726 list_add_head(cond, &$5->entry);
1727 set_location(&loc, &@1);
1728 $$ = create_loop(LOOP_DO_WHILE, NULL, cond, NULL, $2, &loc);
1730 | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
1732 struct source_location loc;
1734 set_location(&loc, &@1);
1735 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1736 pop_scope(&hlsl_ctx);
1738 | KW_FOR '(' scope_start declaration expr_statement expr ')' statement
1740 struct source_location loc;
1742 set_location(&loc, &@1);
1744 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_WARNING,
1745 "no expressions in for loop initializer");
1746 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1747 pop_scope(&hlsl_ctx);
1752 $$ = d3dcompiler_alloc(sizeof(*$$));
1757 $$ = d3dcompiler_alloc(sizeof(*$$));
1760 list_add_head($$, &$1->entry);
1763 primary_expr: C_FLOAT
1765 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1768 ERR("Out of memory.\n");
1771 c->node.type = HLSL_IR_CONSTANT;
1772 set_location(&c->node.loc, &yylloc);
1773 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("float"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
1774 c->v.value.f[0] = $1;
1779 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1782 ERR("Out of memory.\n");
1785 c->node.type = HLSL_IR_CONSTANT;
1786 set_location(&c->node.loc, &yylloc);
1787 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("int"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
1788 c->v.value.i[0] = $1;
1793 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1796 ERR("Out of memory.\n");
1799 c->node.type = HLSL_IR_CONSTANT;
1800 set_location(&c->node.loc, &yylloc);
1801 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("bool"), HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
1802 c->v.value.b[0] = $1;
1807 struct hlsl_ir_deref *deref = new_var_deref($1);
1811 set_location(&$$->loc, &@1);
1821 variable: VAR_IDENTIFIER
1823 struct hlsl_ir_var *var;
1824 var = get_variable(hlsl_ctx.cur_scope, $1);
1827 hlsl_message("Line %d: variable '%s' not declared\n",
1828 hlsl_ctx.line_no, $1);
1829 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1835 postfix_expr: primary_expr
1839 | postfix_expr OP_INC
1841 struct hlsl_ir_node *operands[3];
1842 struct source_location loc;
1844 set_location(&loc, &@2);
1845 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1847 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1848 "modifying a const expression");
1852 operands[1] = operands[2] = NULL;
1853 $$ = &new_expr(HLSL_IR_BINOP_POSTINC, operands, &loc)->node;
1854 /* Post increment/decrement expressions are considered const */
1855 $$->data_type = clone_hlsl_type($$->data_type);
1856 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1858 | postfix_expr OP_DEC
1860 struct hlsl_ir_node *operands[3];
1861 struct source_location loc;
1863 set_location(&loc, &@2);
1864 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1866 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1867 "modifying a const expression");
1871 operands[1] = operands[2] = NULL;
1872 $$ = &new_expr(HLSL_IR_BINOP_POSTDEC, operands, &loc)->node;
1873 /* Post increment/decrement expressions are considered const */
1874 $$->data_type = clone_hlsl_type($$->data_type);
1875 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1877 | postfix_expr '.' any_identifier
1879 struct source_location loc;
1881 set_location(&loc, &@2);
1882 if ($1->data_type->type == HLSL_CLASS_STRUCT)
1884 struct hlsl_type *type = $1->data_type;
1885 struct hlsl_struct_field *field;
1888 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
1890 if (!strcmp($3, field->name))
1892 struct hlsl_ir_deref *deref = new_record_deref($1, field);
1896 ERR("Out of memory\n");
1899 deref->node.loc = loc;
1906 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1907 "invalid subscript %s", debugstr_a($3));
1911 else if ($1->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
1913 struct hlsl_ir_swizzle *swizzle;
1915 swizzle = get_swizzle($1, $3, &loc);
1918 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1919 "invalid swizzle %s", debugstr_a($3));
1922 $$ = &swizzle->node;
1926 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1927 "invalid subscript %s", debugstr_a($3));
1931 | postfix_expr '[' expr ']'
1933 /* This may be an array dereference or a vector/matrix
1934 * subcomponent access.
1935 * We store it as an array dereference in any case. */
1936 struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
1937 struct hlsl_type *expr_type = $1->data_type;
1938 struct source_location loc;
1940 TRACE("Array dereference from type %s\n", debug_hlsl_type(expr_type));
1943 ERR("Out of memory\n");
1946 deref->node.type = HLSL_IR_DEREF;
1947 set_location(&loc, &@2);
1948 deref->node.loc = loc;
1949 if (expr_type->type == HLSL_CLASS_ARRAY)
1951 deref->node.data_type = expr_type->e.array.type;
1953 else if (expr_type->type == HLSL_CLASS_MATRIX)
1955 deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, expr_type->base_type, expr_type->dimx, 1);
1957 else if (expr_type->type == HLSL_CLASS_VECTOR)
1959 deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_SCALAR, expr_type->base_type, 1, 1);
1963 if (expr_type->type == HLSL_CLASS_SCALAR)
1964 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1965 "array-indexed expression is scalar");
1967 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1968 "expression is not array-indexable");
1969 d3dcompiler_free(deref);
1974 if ($3->data_type->type != HLSL_CLASS_SCALAR)
1976 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1977 "array index is not scalar");
1978 d3dcompiler_free(deref);
1983 deref->type = HLSL_IR_DEREF_ARRAY;
1984 deref->v.array.array = $1;
1985 deref->v.array.index = $3;
1989 /* "var_modifiers" doesn't make sense in this case, but it's needed
1990 in the grammar to avoid shift/reduce conflicts. */
1991 | var_modifiers type '(' initializer_expr_list ')'
1993 struct hlsl_ir_constructor *constructor;
1995 TRACE("%s constructor.\n", debug_hlsl_type($2));
1998 hlsl_message("Line %u: unexpected modifier in a constructor.\n",
2000 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2003 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
2005 hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
2007 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2010 if ($2->dimx * $2->dimy != components_count_expr_list($4))
2012 hlsl_message("Line %u: wrong number of components in constructor.\n",
2014 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2018 constructor = d3dcompiler_alloc(sizeof(*constructor));
2019 constructor->node.type = HLSL_IR_CONSTRUCTOR;
2020 set_location(&constructor->node.loc, &@3);
2021 constructor->node.data_type = $2;
2022 constructor->arguments = $4;
2024 $$ = &constructor->node;
2027 unary_expr: postfix_expr
2033 struct hlsl_ir_node *operands[3];
2034 struct source_location loc;
2036 set_location(&loc, &@1);
2037 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2039 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2040 "modifying a const expression");
2044 operands[1] = operands[2] = NULL;
2045 $$ = &new_expr(HLSL_IR_BINOP_PREINC, operands, &loc)->node;
2049 struct hlsl_ir_node *operands[3];
2050 struct source_location loc;
2052 set_location(&loc, &@1);
2053 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2055 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2056 "modifying a const expression");
2060 operands[1] = operands[2] = NULL;
2061 $$ = &new_expr(HLSL_IR_BINOP_PREDEC, operands, &loc)->node;
2063 | unary_op unary_expr
2065 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
2066 HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
2067 struct hlsl_ir_node *operands[3];
2068 struct source_location loc;
2070 if ($1 == UNARY_OP_PLUS)
2077 operands[1] = operands[2] = NULL;
2078 set_location(&loc, &@1);
2079 $$ = &new_expr(ops[$1], operands, &loc)->node;
2082 /* var_modifiers just to avoid shift/reduce conflicts */
2083 | '(' var_modifiers type array ')' unary_expr
2085 struct hlsl_ir_expr *expr;
2086 struct hlsl_type *src_type = $6->data_type;
2087 struct hlsl_type *dst_type;
2088 struct source_location loc;
2090 set_location(&loc, &@3);
2093 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2094 "unexpected modifier in a cast");
2099 dst_type = new_array_type($3, $4);
2103 if (!compatible_data_types(src_type, dst_type))
2105 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2106 "can't cast from %s to %s",
2107 debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
2111 expr = new_cast($6, dst_type, &loc);
2112 $$ = expr ? &expr->node : NULL;
2121 $$ = UNARY_OP_MINUS;
2125 $$ = UNARY_OP_LOGICNOT;
2129 $$ = UNARY_OP_BITNOT;
2132 mul_expr: unary_expr
2136 | mul_expr '*' unary_expr
2138 struct source_location loc;
2140 set_location(&loc, &@2);
2141 $$ = &hlsl_mul($1, $3, &loc)->node;
2143 | mul_expr '/' unary_expr
2145 struct source_location loc;
2147 set_location(&loc, &@2);
2148 $$ = &hlsl_div($1, $3, &loc)->node;
2150 | mul_expr '%' unary_expr
2152 struct source_location loc;
2154 set_location(&loc, &@2);
2155 $$ = &hlsl_mod($1, $3, &loc)->node;
2162 | add_expr '+' mul_expr
2164 struct source_location loc;
2166 set_location(&loc, &@2);
2167 $$ = &hlsl_add($1, $3, &loc)->node;
2169 | add_expr '-' mul_expr
2171 struct source_location loc;
2173 set_location(&loc, &@2);
2174 $$ = &hlsl_sub($1, $3, &loc)->node;
2177 shift_expr: add_expr
2181 | shift_expr OP_LEFTSHIFT add_expr
2183 FIXME("Left shift\n");
2185 | shift_expr OP_RIGHTSHIFT add_expr
2187 FIXME("Right shift\n");
2190 relational_expr: shift_expr
2194 | relational_expr '<' shift_expr
2196 struct source_location loc;
2198 set_location(&loc, &@2);
2199 $$ = &hlsl_lt($1, $3, &loc)->node;
2201 | relational_expr '>' shift_expr
2203 struct source_location loc;
2205 set_location(&loc, &@2);
2206 $$ = &hlsl_gt($1, $3, &loc)->node;
2208 | relational_expr OP_LE shift_expr
2210 struct source_location loc;
2212 set_location(&loc, &@2);
2213 $$ = &hlsl_le($1, $3, &loc)->node;
2215 | relational_expr OP_GE shift_expr
2217 struct source_location loc;
2219 set_location(&loc, &@2);
2220 $$ = &hlsl_ge($1, $3, &loc)->node;
2223 equality_expr: relational_expr
2227 | equality_expr OP_EQ relational_expr
2229 struct source_location loc;
2231 set_location(&loc, &@2);
2232 $$ = &hlsl_eq($1, $3, &loc)->node;
2234 | equality_expr OP_NE relational_expr
2236 struct source_location loc;
2238 set_location(&loc, &@2);
2239 $$ = &hlsl_ne($1, $3, &loc)->node;
2242 bitand_expr: equality_expr
2246 | bitand_expr '&' equality_expr
2248 FIXME("bitwise AND\n");
2251 bitxor_expr: bitand_expr
2255 | bitxor_expr '^' bitand_expr
2257 FIXME("bitwise XOR\n");
2260 bitor_expr: bitxor_expr
2264 | bitor_expr '|' bitxor_expr
2266 FIXME("bitwise OR\n");
2269 logicand_expr: bitor_expr
2273 | logicand_expr OP_AND bitor_expr
2275 FIXME("logic AND\n");
2278 logicor_expr: logicand_expr
2282 | logicor_expr OP_OR logicand_expr
2284 FIXME("logic OR\n");
2287 conditional_expr: logicor_expr
2291 | logicor_expr '?' expr ':' assignment_expr
2293 FIXME("ternary operator\n");
2296 assignment_expr: conditional_expr
2300 | unary_expr assign_op assignment_expr
2302 struct source_location loc;
2304 set_location(&loc, &@2);
2305 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
2307 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2308 "l-value is const");
2311 $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
2319 $$ = ASSIGN_OP_ASSIGN;
2341 | OP_LEFTSHIFTASSIGN
2343 $$ = ASSIGN_OP_LSHIFT;
2345 | OP_RIGHTSHIFTASSIGN
2347 $$ = ASSIGN_OP_RSHIFT;
2362 expr: assignment_expr
2366 | expr ',' assignment_expr
2368 FIXME("Comma expression\n");
2373 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
2375 loc->file = hlsl_ctx.source_file;
2376 loc->line = l->first_line;
2377 loc->col = l->first_column;
2380 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
2382 if (modifiers & mod)
2384 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2385 "modifier '%s' already specified", debug_modifiers(mod));
2388 if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
2389 && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
2391 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2392 "more than one matrix majority keyword");
2395 return modifiers | mod;
2398 static void dump_function_decl(struct wine_rb_entry *entry, void *context)
2400 struct hlsl_ir_function_decl *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
2402 debug_dump_ir_function_decl(func);
2405 static void dump_function(struct wine_rb_entry *entry, void *context)
2407 struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
2408 wine_rb_for_each_entry(&func->overloads, dump_function_decl, NULL);
2411 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
2412 const char *entrypoint, char **messages)
2414 struct hlsl_scope *scope, *next_scope;
2415 struct hlsl_type *hlsl_type, *next_type;
2416 struct hlsl_ir_var *var, *next_var;
2419 hlsl_ctx.status = PARSE_SUCCESS;
2420 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
2421 hlsl_ctx.line_no = hlsl_ctx.column = 1;
2422 hlsl_ctx.source_file = d3dcompiler_strdup("");
2423 hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
2424 if (hlsl_ctx.source_files)
2425 hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
2426 hlsl_ctx.source_files_count = 1;
2427 hlsl_ctx.cur_scope = NULL;
2428 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
2429 list_init(&hlsl_ctx.scopes);
2430 list_init(&hlsl_ctx.types);
2431 init_functions_tree(&hlsl_ctx.functions);
2433 push_scope(&hlsl_ctx);
2434 hlsl_ctx.globals = hlsl_ctx.cur_scope;
2435 declare_predefined_types(hlsl_ctx.globals);
2439 if (TRACE_ON(hlsl_parser))
2441 TRACE("IR dump.\n");
2442 wine_rb_for_each_entry(&hlsl_ctx.functions, dump_function, NULL);
2445 TRACE("Compilation status = %d\n", hlsl_ctx.status);
2448 if (hlsl_ctx.messages.size)
2449 *messages = hlsl_ctx.messages.string;
2455 if (hlsl_ctx.messages.capacity)
2456 d3dcompiler_free(hlsl_ctx.messages.string);
2459 for (i = 0; i < hlsl_ctx.source_files_count; ++i)
2460 d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
2461 d3dcompiler_free(hlsl_ctx.source_files);
2463 TRACE("Freeing functions IR.\n");
2464 wine_rb_destroy(&hlsl_ctx.functions, free_function_rb, NULL);
2466 TRACE("Freeing variables.\n");
2467 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
2469 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
2471 free_declaration(var);
2473 wine_rb_destroy(&scope->types, NULL, NULL);
2474 d3dcompiler_free(scope);
2477 TRACE("Freeing types.\n");
2478 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
2480 free_hlsl_type(hlsl_type);