msvcirt: Add implementation of streambuf::sputbackc.
[wine.git] / dlls / d3dcompiler_43 / hlsl.y
blobc5f66d6a1be9db13c20a92003f4076224455b9f5
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 static const char * const 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 * const 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 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);
267 if (!count)
268 return NULL;
269 if (count != 1)
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));
274 if (!out_cond)
276 ERR("Out of memory.\n");
277 return NULL;
279 out_cond->node.type = HLSL_IR_IF;
280 operands[0] = cond;
281 operands[1] = operands[2] = NULL;
282 not_cond = new_expr(HLSL_IR_UNOP_LOGIC_NOT, operands, &cond->loc);
283 if (!not_cond)
285 ERR("Out of memory.\n");
286 d3dcompiler_free(out_cond);
287 return NULL;
289 out_cond->condition = &not_cond->node;
290 jump = d3dcompiler_alloc(sizeof(*jump));
291 if (!jump)
293 ERR("Out of memory.\n");
294 d3dcompiler_free(out_cond);
295 d3dcompiler_free(not_cond);
296 return NULL;
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);
307 return NULL;
309 list_init(out_cond->then_instrs);
310 list_add_head(out_cond->then_instrs, &jump->node.entry);
312 return out_cond;
315 enum loop_type
317 LOOP_FOR,
318 LOOP_WHILE,
319 LOOP_DO_WHILE
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));
330 if (!list)
331 goto oom;
332 list_init(list);
334 if (init)
335 list_move_head(list, init);
337 loop = d3dcompiler_alloc(sizeof(*loop));
338 if (!loop)
339 goto oom;
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));
344 if (!loop->body)
345 goto oom;
346 list_init(loop->body);
348 cond_jump = loop_condition(cond);
349 if (!cond_jump)
350 goto oom;
352 if (type != LOOP_DO_WHILE)
353 list_add_tail(loop->body, &cond_jump->node.entry);
355 list_move_tail(loop->body, body);
357 if (iter)
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);
366 return list;
368 oom:
369 ERR("Out of memory.\n");
370 if (loop)
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);
377 free_instr(iter);
378 free_instr_list(body);
379 return NULL;
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);
392 return 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);
404 return count;
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));
412 if (!swizzle)
413 return NULL;
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);
417 swizzle->val = val;
418 swizzle->swizzle = s;
419 return swizzle;
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;
427 BOOL valid;
429 if (value->data_type->type == HLSL_CLASS_MATRIX)
431 /* Matrix swizzle */
432 BOOL m_swizzle;
433 unsigned int inc, x, y;
435 if (len < 3 || swizzle[0] != '_')
436 return NULL;
437 m_swizzle = swizzle[1] == 'm';
438 inc = m_swizzle ? 4 : 3;
440 if (len % inc || len > inc * 4)
441 return NULL;
443 for (i = 0; i < len; i += inc)
445 if (swizzle[i] != '_')
446 return NULL;
447 if (m_swizzle)
449 if (swizzle[i + 1] != 'm')
450 return NULL;
451 x = swizzle[i + 2] - '0';
452 y = swizzle[i + 3] - '0';
454 else
456 x = swizzle[i + 1] - '1';
457 y = swizzle[i + 2] - '1';
460 if (x >= value->data_type->dimx || y >= value->data_type->dimy)
461 return NULL;
462 swiz |= (y << 4 | x) << component * 8;
463 component++;
465 return new_swizzle(swiz, component, value, loc);
468 /* Vector swizzle */
469 if (len > 4)
470 return NULL;
472 for (set = 0; set < 2; ++set)
474 valid = TRUE;
475 component = 0;
476 for (i = 0; i < len; ++i)
478 char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}};
479 unsigned int s = 0;
481 for (s = 0; s < 4; ++s)
483 if (swizzle[i] == c[set][s])
484 break;
486 if (s == 4)
488 valid = FALSE;
489 break;
492 if (s >= value->data_type->dimx)
493 return NULL;
494 swiz |= s << component * 2;
495 component++;
497 if (valid)
498 return new_swizzle(swiz, component, value, loc);
501 return NULL;
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);
518 return;
520 cur_node = list_head(initializer);
521 assert(cur_node);
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)
525 if (!cur_node)
527 d3dcompiler_free(initializer);
528 return;
530 if (components_count_type(field->type) == components_count_type(node->data_type))
532 deref = new_record_deref(&var->node, field);
533 if (!deref)
535 ERR("Out of memory.\n");
536 break;
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);
542 else
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. */
549 while (cur_node)
551 struct list *next = list_next(initializer, cur_node);
552 free_instr(node);
553 cur_node = next;
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)
572 d3dcompiler_free(v);
573 d3dcompiler_free(var_list);
574 return NULL;
576 list_init(statements_list);
578 if (!var_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));
584 if (!var)
586 ERR("Out of memory.\n");
587 d3dcompiler_free(v);
588 continue;
590 var->node.type = HLSL_IR_VAR;
591 if (v->array_size)
592 type = new_array_type(basic_type, v->array_size);
593 else
594 type = basic_type;
595 var->node.data_type = type;
596 var->node.loc = v->loc;
597 var->name = v->name;
598 var->modifiers = modifiers;
599 var->semantic = v->semantic;
600 var->reg_reservation = v->reg_reservation;
601 debug_dump_decl(type, modifiers, v->name, v->loc.line);
603 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
605 var->modifiers |= HLSL_STORAGE_UNIFORM;
606 local = FALSE;
609 if (var->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer)
611 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col,
612 HLSL_LEVEL_ERROR, "const variable without initializer");
613 free_declaration(var);
614 d3dcompiler_free(v);
615 continue;
618 ret = declare_variable(var, local);
619 if (!ret)
621 free_declaration(var);
622 d3dcompiler_free(v);
623 continue;
625 TRACE("Declared variable %s.\n", var->name);
627 if (v->initializer)
629 unsigned int size = initializer_size(v->initializer);
630 struct hlsl_ir_node *node;
632 TRACE("Variable with initializer.\n");
633 if (type->type <= HLSL_CLASS_LAST_NUMERIC
634 && type->dimx * type->dimy != size && size != 1)
636 if (size < type->dimx * type->dimy)
638 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
639 "'%s' initializer does not match", v->name);
640 free_instr_list(v->initializer);
641 d3dcompiler_free(v);
642 continue;
645 if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY)
646 && components_count_type(type) != size)
648 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
649 "'%s' initializer does not match", v->name);
650 free_instr_list(v->initializer);
651 d3dcompiler_free(v);
652 continue;
655 if (type->type == HLSL_CLASS_STRUCT)
657 struct_var_initializer(statements_list, var, v->initializer);
658 d3dcompiler_free(v);
659 continue;
661 if (type->type > HLSL_CLASS_LAST_NUMERIC)
663 FIXME("Initializers for non scalar/struct variables not supported yet.\n");
664 free_instr_list(v->initializer);
665 d3dcompiler_free(v);
666 continue;
668 if (v->array_size > 0)
670 FIXME("Initializing arrays is not supported yet.\n");
671 free_instr_list(v->initializer);
672 d3dcompiler_free(v);
673 continue;
675 if (list_count(v->initializer) > 1)
677 FIXME("Complex initializers are not supported yet.\n");
678 free_instr_list(v->initializer);
679 d3dcompiler_free(v);
680 continue;
682 node = LIST_ENTRY(list_head(v->initializer), struct hlsl_ir_node, entry);
683 assignment = make_assignment(&var->node, ASSIGN_OP_ASSIGN,
684 BWRITERSP_WRITEMASK_ALL, node);
685 list_add_tail(statements_list, &assignment->entry);
686 d3dcompiler_free(v->initializer);
688 d3dcompiler_free(v);
690 d3dcompiler_free(var_list);
691 return statements_list;
694 static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field)
696 struct hlsl_struct_field *f;
698 LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry)
700 if (!strcmp(f->name, field->name))
701 return FALSE;
703 list_add_tail(fields, &field->entry);
704 return TRUE;
707 static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, struct list *fields)
709 struct parse_variable_def *v, *v_next;
710 struct hlsl_struct_field *field;
711 struct list *list;
713 list = d3dcompiler_alloc(sizeof(*list));
714 if (!list)
716 ERR("Out of memory.\n");
717 return NULL;
719 list_init(list);
720 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry)
722 debug_dump_decl(type, 0, v->name, v->loc.line);
723 field = d3dcompiler_alloc(sizeof(*field));
724 if (!field)
726 ERR("Out of memory.\n");
727 d3dcompiler_free(v);
728 return list;
730 field->type = type;
731 field->name = v->name;
732 field->modifiers = modifiers;
733 field->semantic = v->semantic;
734 if (v->initializer)
736 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
737 "struct field with an initializer.\n");
738 free_instr_list(v->initializer);
740 list_add_tail(list, &field->entry);
741 d3dcompiler_free(v);
743 d3dcompiler_free(fields);
744 return list;
747 static struct hlsl_type *new_struct_type(const char *name, DWORD modifiers, struct list *fields)
749 struct hlsl_type *type = d3dcompiler_alloc(sizeof(*type));
751 if (!type)
753 ERR("Out of memory.\n");
754 return NULL;
756 type->type = HLSL_CLASS_STRUCT;
757 type->name = name;
758 type->dimx = type->dimy = 1;
759 type->modifiers = modifiers;
760 type->e.elements = fields;
762 list_add_tail(&hlsl_ctx.types, &type->entry);
764 return type;
767 static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list,
768 struct source_location *loc)
770 BOOL ret;
771 struct hlsl_type *type;
772 struct parse_variable_def *v, *v_next;
774 if (!check_type_modifiers(modifiers, loc))
776 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
777 d3dcompiler_free(v);
778 d3dcompiler_free(list);
779 return FALSE;
782 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
784 if (v->array_size)
785 type = new_array_type(orig_type, v->array_size);
786 else
787 type = clone_hlsl_type(orig_type);
788 if (!type)
790 ERR("Out of memory\n");
791 return FALSE;
793 d3dcompiler_free((void *)type->name);
794 type->name = v->name;
795 type->modifiers |= modifiers;
797 if (type->type != HLSL_CLASS_MATRIX)
798 check_invalid_matrix_modifiers(type->modifiers, &v->loc);
800 ret = add_type_to_scope(hlsl_ctx.cur_scope, type);
801 if (!ret)
803 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
804 "redefinition of custom type '%s'", v->name);
806 d3dcompiler_free(v);
808 d3dcompiler_free(list);
809 return TRUE;
812 static BOOL add_func_parameter(struct list *list, struct parse_parameter *param, const struct source_location *loc)
814 struct hlsl_ir_var *decl = d3dcompiler_alloc(sizeof(*decl));
816 if (!decl)
818 ERR("Out of memory.\n");
819 return FALSE;
821 decl->node.type = HLSL_IR_VAR;
822 decl->node.data_type = param->type;
823 decl->node.loc = *loc;
824 decl->name = param->name;
825 decl->semantic = param->semantic;
826 decl->reg_reservation = param->reg_reservation;
827 decl->modifiers = param->modifiers;
829 if (!add_declaration(hlsl_ctx.cur_scope, decl, FALSE))
831 free_declaration(decl);
832 return FALSE;
834 list_add_tail(list, &decl->node.entry);
835 return TRUE;
838 static struct reg_reservation *parse_reg_reservation(const char *reg_string)
840 struct reg_reservation *reg_res;
841 enum bwritershader_param_register_type type;
842 DWORD regnum = 0;
844 switch (reg_string[0])
846 case 'c':
847 type = BWRITERSPR_CONST;
848 break;
849 case 'i':
850 type = BWRITERSPR_CONSTINT;
851 break;
852 case 'b':
853 type = BWRITERSPR_CONSTBOOL;
854 break;
855 case 's':
856 type = BWRITERSPR_SAMPLER;
857 break;
858 default:
859 FIXME("Unsupported register type.\n");
860 return NULL;
863 if (!sscanf(reg_string + 1, "%u", &regnum))
865 FIXME("Unsupported register reservation syntax.\n");
866 return NULL;
869 reg_res = d3dcompiler_alloc(sizeof(*reg_res));
870 if (!reg_res)
872 ERR("Out of memory.\n");
873 return NULL;
875 reg_res->type = type;
876 reg_res->regnum = regnum;
877 return reg_res;
880 static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tree *funcs, char *name,
881 struct list *params, BOOL exact_signature)
883 struct hlsl_ir_function *func;
884 struct wine_rb_entry *entry;
886 entry = wine_rb_get(funcs, name);
887 if (entry)
889 func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
891 entry = wine_rb_get(&func->overloads, params);
892 if (!entry)
894 if (!exact_signature)
895 FIXME("No exact match, search for a compatible overloaded function (if any).\n");
896 return NULL;
898 return WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
900 return NULL;
905 %locations
906 %error-verbose
907 %expect 1
909 %union
911 struct hlsl_type *type;
912 INT intval;
913 FLOAT floatval;
914 BOOL boolval;
915 char *name;
916 DWORD modifiers;
917 struct hlsl_ir_var *var;
918 struct hlsl_ir_node *instr;
919 struct list *list;
920 struct parse_function function;
921 struct parse_parameter parameter;
922 struct parse_variable_def *variable_def;
923 struct parse_if_body if_body;
924 enum parse_unary_op unary_op;
925 enum parse_assign_op assign_op;
926 struct reg_reservation *reg_reservation;
927 struct parse_colon_attribute colon_attribute;
930 %token KW_BLENDSTATE
931 %token KW_BREAK
932 %token KW_BUFFER
933 %token KW_CBUFFER
934 %token KW_COLUMN_MAJOR
935 %token KW_COMPILE
936 %token KW_CONST
937 %token KW_CONTINUE
938 %token KW_DEPTHSTENCILSTATE
939 %token KW_DEPTHSTENCILVIEW
940 %token KW_DISCARD
941 %token KW_DO
942 %token KW_DOUBLE
943 %token KW_ELSE
944 %token KW_EXTERN
945 %token KW_FALSE
946 %token KW_FOR
947 %token KW_GEOMETRYSHADER
948 %token KW_GROUPSHARED
949 %token KW_IF
950 %token KW_IN
951 %token KW_INLINE
952 %token KW_INOUT
953 %token KW_MATRIX
954 %token KW_NAMESPACE
955 %token KW_NOINTERPOLATION
956 %token KW_OUT
957 %token KW_PASS
958 %token KW_PIXELSHADER
959 %token KW_PRECISE
960 %token KW_RASTERIZERSTATE
961 %token KW_RENDERTARGETVIEW
962 %token KW_RETURN
963 %token KW_REGISTER
964 %token KW_ROW_MAJOR
965 %token KW_SAMPLER
966 %token KW_SAMPLER1D
967 %token KW_SAMPLER2D
968 %token KW_SAMPLER3D
969 %token KW_SAMPLERCUBE
970 %token KW_SAMPLER_STATE
971 %token KW_SAMPLERCOMPARISONSTATE
972 %token KW_SHARED
973 %token KW_STATEBLOCK
974 %token KW_STATEBLOCK_STATE
975 %token KW_STATIC
976 %token KW_STRING
977 %token KW_STRUCT
978 %token KW_SWITCH
979 %token KW_TBUFFER
980 %token KW_TECHNIQUE
981 %token KW_TECHNIQUE10
982 %token KW_TEXTURE
983 %token KW_TEXTURE1D
984 %token KW_TEXTURE1DARRAY
985 %token KW_TEXTURE2D
986 %token KW_TEXTURE2DARRAY
987 %token KW_TEXTURE2DMS
988 %token KW_TEXTURE2DMSARRAY
989 %token KW_TEXTURE3D
990 %token KW_TEXTURE3DARRAY
991 %token KW_TEXTURECUBE
992 %token KW_TRUE
993 %token KW_TYPEDEF
994 %token KW_UNIFORM
995 %token KW_VECTOR
996 %token KW_VERTEXSHADER
997 %token KW_VOID
998 %token KW_VOLATILE
999 %token KW_WHILE
1001 %token OP_INC
1002 %token OP_DEC
1003 %token OP_AND
1004 %token OP_OR
1005 %token OP_EQ
1006 %token OP_LEFTSHIFT
1007 %token OP_LEFTSHIFTASSIGN
1008 %token OP_RIGHTSHIFT
1009 %token OP_RIGHTSHIFTASSIGN
1010 %token OP_ELLIPSIS
1011 %token OP_LE
1012 %token OP_GE
1013 %token OP_NE
1014 %token OP_ADDASSIGN
1015 %token OP_SUBASSIGN
1016 %token OP_MULASSIGN
1017 %token OP_DIVASSIGN
1018 %token OP_MODASSIGN
1019 %token OP_ANDASSIGN
1020 %token OP_ORASSIGN
1021 %token OP_XORASSIGN
1022 %token OP_UNKNOWN1
1023 %token OP_UNKNOWN2
1024 %token OP_UNKNOWN3
1025 %token OP_UNKNOWN4
1027 %token <intval> PRE_LINE
1029 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
1030 %type <name> any_identifier var_identifier
1031 %token <name> STRING
1032 %token <floatval> C_FLOAT
1033 %token <intval> C_INTEGER
1034 %type <boolval> boolean
1035 %type <type> base_type
1036 %type <type> type
1037 %type <list> declaration_statement
1038 %type <list> declaration
1039 %type <list> struct_declaration
1040 %type <type> struct_spec
1041 %type <type> named_struct_spec
1042 %type <type> unnamed_struct_spec
1043 %type <list> type_specs
1044 %type <variable_def> type_spec
1045 %type <list> complex_initializer
1046 %type <list> initializer_expr_list
1047 %type <instr> initializer_expr
1048 %type <modifiers> var_modifiers
1049 %type <list> field
1050 %type <list> parameters
1051 %type <list> param_list
1052 %type <instr> expr
1053 %type <var> variable
1054 %type <intval> array
1055 %type <list> statement
1056 %type <list> statement_list
1057 %type <list> compound_statement
1058 %type <list> jump_statement
1059 %type <list> selection_statement
1060 %type <list> loop_statement
1061 %type <function> func_declaration
1062 %type <function> func_prototype
1063 %type <list> fields_list
1064 %type <parameter> parameter
1065 %type <colon_attribute> colon_attribute
1066 %type <name> semantic
1067 %type <reg_reservation> register_opt
1068 %type <variable_def> variable_def
1069 %type <list> variables_def
1070 %type <list> variables_def_optional
1071 %type <if_body> if_body
1072 %type <instr> primary_expr
1073 %type <instr> postfix_expr
1074 %type <instr> unary_expr
1075 %type <instr> mul_expr
1076 %type <instr> add_expr
1077 %type <instr> shift_expr
1078 %type <instr> relational_expr
1079 %type <instr> equality_expr
1080 %type <instr> bitand_expr
1081 %type <instr> bitxor_expr
1082 %type <instr> bitor_expr
1083 %type <instr> logicand_expr
1084 %type <instr> logicor_expr
1085 %type <instr> conditional_expr
1086 %type <instr> assignment_expr
1087 %type <list> expr_statement
1088 %type <unary_op> unary_op
1089 %type <assign_op> assign_op
1090 %type <modifiers> input_mods
1091 %type <modifiers> input_mod
1094 hlsl_prog: /* empty */
1097 | hlsl_prog func_declaration
1099 const struct hlsl_ir_function_decl *decl;
1101 decl = get_overloaded_func(&hlsl_ctx.functions, $2.name, $2.decl->parameters, TRUE);
1102 if (decl && !decl->func->intrinsic)
1104 if (decl->body && $2.decl->body)
1106 hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
1107 $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
1108 "redefinition of function %s", debugstr_a($2.name));
1109 return 1;
1111 else if (!compare_hlsl_types(decl->node.data_type, $2.decl->node.data_type))
1113 hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
1114 $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
1115 "redefining function %s with a different return type",
1116 debugstr_a($2.name));
1117 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_NOTE,
1118 "%s previously declared here",
1119 debugstr_a($2.name));
1120 return 1;
1124 if ($2.decl->node.data_type->base_type == HLSL_TYPE_VOID && $2.decl->semantic)
1126 hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
1127 $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
1128 "void function with a semantic");
1131 TRACE("Adding function '%s' to the function list.\n", $2.name);
1132 add_function_decl(&hlsl_ctx.functions, $2.name, $2.decl, FALSE);
1134 | hlsl_prog declaration_statement
1136 TRACE("Declaration statement parsed.\n");
1138 | hlsl_prog preproc_directive
1141 | hlsl_prog ';'
1143 TRACE("Skipping stray semicolon.\n");
1146 preproc_directive: PRE_LINE STRING
1148 const char **new_array = NULL;
1150 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
1151 hlsl_ctx.line_no = $1;
1152 if (strcmp($2, hlsl_ctx.source_file))
1153 new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
1154 sizeof(*hlsl_ctx.source_files) * hlsl_ctx.source_files_count + 1);
1156 if (new_array)
1158 hlsl_ctx.source_files = new_array;
1159 hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
1160 hlsl_ctx.source_file = $2;
1162 else
1164 d3dcompiler_free($2);
1168 struct_declaration: struct_spec variables_def_optional ';'
1170 struct source_location loc;
1172 set_location(&loc, &@3);
1173 if (!$2)
1175 if (!$1->name)
1177 hlsl_report_message(loc.file, loc.line, loc.col,
1178 HLSL_LEVEL_ERROR, "anonymous struct declaration with no variables");
1180 check_type_modifiers($1->modifiers, &loc);
1182 $$ = declare_vars($1, 0, $2);
1185 struct_spec: named_struct_spec
1186 | unnamed_struct_spec
1188 named_struct_spec: var_modifiers KW_STRUCT any_identifier '{' fields_list '}'
1190 BOOL ret;
1191 struct source_location loc;
1193 TRACE("Structure %s declaration.\n", debugstr_a($3));
1194 set_location(&loc, &@1);
1195 check_invalid_matrix_modifiers($1, &loc);
1196 $$ = new_struct_type($3, $1, $5);
1198 if (get_variable(hlsl_ctx.cur_scope, $3))
1200 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1201 HLSL_LEVEL_ERROR, "redefinition of '%s'", $3);
1202 return 1;
1205 ret = add_type_to_scope(hlsl_ctx.cur_scope, $$);
1206 if (!ret)
1208 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1209 HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $3);
1210 return 1;
1214 unnamed_struct_spec: var_modifiers KW_STRUCT '{' fields_list '}'
1216 struct source_location loc;
1218 TRACE("Anonymous structure declaration.\n");
1219 set_location(&loc, &@1);
1220 check_invalid_matrix_modifiers($1, &loc);
1221 $$ = new_struct_type(NULL, $1, $4);
1224 any_identifier: VAR_IDENTIFIER
1225 | TYPE_IDENTIFIER
1226 | NEW_IDENTIFIER
1228 fields_list: /* Empty */
1230 $$ = d3dcompiler_alloc(sizeof(*$$));
1231 list_init($$);
1233 | fields_list field
1235 BOOL ret;
1236 struct hlsl_struct_field *field, *next;
1238 $$ = $1;
1239 LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry)
1241 ret = add_struct_field($$, field);
1242 if (ret == FALSE)
1244 hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1245 HLSL_LEVEL_ERROR, "redefinition of '%s'", field->name);
1246 d3dcompiler_free(field);
1249 d3dcompiler_free($2);
1252 field: var_modifiers type variables_def ';'
1254 $$ = gen_struct_fields($2, $1, $3);
1256 | unnamed_struct_spec variables_def ';'
1258 $$ = gen_struct_fields($1, 0, $2);
1261 func_declaration: func_prototype compound_statement
1263 TRACE("Function %s parsed.\n", $1.name);
1264 $$ = $1;
1265 $$.decl->body = $2;
1266 pop_scope(&hlsl_ctx);
1268 | func_prototype ';'
1270 TRACE("Function prototype for %s.\n", $1.name);
1271 $$ = $1;
1272 pop_scope(&hlsl_ctx);
1275 func_prototype: var_modifiers type var_identifier '(' parameters ')' colon_attribute
1277 if (get_variable(hlsl_ctx.globals, $3))
1279 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1280 HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
1281 return 1;
1283 if ($2->base_type == HLSL_TYPE_VOID && $7.semantic)
1285 hlsl_report_message(hlsl_ctx.source_file, @7.first_line, @7.first_column,
1286 HLSL_LEVEL_ERROR, "void function with a semantic");
1289 if ($7.reg_reservation)
1291 FIXME("Unexpected register reservation for a function.\n");
1292 d3dcompiler_free($7.reg_reservation);
1294 $$.decl = new_func_decl($2, $5);
1295 if (!$$.decl)
1297 ERR("Out of memory.\n");
1298 return -1;
1300 $$.name = $3;
1301 $$.decl->semantic = $7.semantic;
1302 set_location(&$$.decl->node.loc, &@3);
1305 compound_statement: '{' '}'
1307 $$ = d3dcompiler_alloc(sizeof(*$$));
1308 list_init($$);
1310 | '{' scope_start statement_list '}'
1312 pop_scope(&hlsl_ctx);
1313 $$ = $3;
1316 scope_start: /* Empty */
1318 push_scope(&hlsl_ctx);
1321 var_identifier: VAR_IDENTIFIER
1322 | NEW_IDENTIFIER
1324 colon_attribute: /* Empty */
1326 $$.semantic = NULL;
1327 $$.reg_reservation = NULL;
1329 | semantic
1331 $$.semantic = $1;
1332 $$.reg_reservation = NULL;
1334 | register_opt
1336 $$.semantic = NULL;
1337 $$.reg_reservation = $1;
1340 semantic: ':' any_identifier
1342 $$ = $2;
1345 /* FIXME: Writemasks */
1346 register_opt: ':' KW_REGISTER '(' any_identifier ')'
1348 $$ = parse_reg_reservation($4);
1349 d3dcompiler_free($4);
1351 | ':' KW_REGISTER '(' any_identifier ',' any_identifier ')'
1353 FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a($4));
1354 d3dcompiler_free($4);
1356 $$ = parse_reg_reservation($6);
1357 d3dcompiler_free($6);
1360 parameters: scope_start
1362 $$ = d3dcompiler_alloc(sizeof(*$$));
1363 list_init($$);
1365 | scope_start param_list
1367 $$ = $2;
1370 param_list: parameter
1372 struct source_location loc;
1374 $$ = d3dcompiler_alloc(sizeof(*$$));
1375 list_init($$);
1376 set_location(&loc, &@1);
1377 if (!add_func_parameter($$, &$1, &loc))
1379 ERR("Error adding function parameter %s.\n", $1.name);
1380 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1381 return -1;
1384 | param_list ',' parameter
1386 struct source_location loc;
1388 $$ = $1;
1389 set_location(&loc, &@3);
1390 if (!add_func_parameter($$, &$3, &loc))
1392 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1393 "duplicate parameter %s", $3.name);
1394 return 1;
1398 parameter: input_mods var_modifiers type any_identifier colon_attribute
1400 $$.modifiers = $1 ? $1 : HLSL_MODIFIER_IN;
1401 $$.modifiers |= $2;
1402 $$.type = $3;
1403 $$.name = $4;
1404 $$.semantic = $5.semantic;
1405 $$.reg_reservation = $5.reg_reservation;
1408 input_mods: /* Empty */
1410 $$ = 0;
1412 | input_mods input_mod
1414 if ($1 & $2)
1416 hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1417 HLSL_LEVEL_ERROR, "duplicate input-output modifiers");
1418 return 1;
1420 $$ = $1 | $2;
1423 input_mod: KW_IN
1425 $$ = HLSL_MODIFIER_IN;
1427 | KW_OUT
1429 $$ = HLSL_MODIFIER_OUT;
1431 | KW_INOUT
1433 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
1436 type: base_type
1438 $$ = $1;
1440 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
1442 if ($3->type != HLSL_CLASS_SCALAR)
1444 hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
1445 hlsl_ctx.line_no);
1446 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1447 return 1;
1449 if ($5 < 1 || $5 > 4)
1451 hlsl_message("Line %u: vector size must be between 1 and 4.\n",
1452 hlsl_ctx.line_no);
1453 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1454 return 1;
1457 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
1459 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
1461 if ($3->type != HLSL_CLASS_SCALAR)
1463 hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
1464 hlsl_ctx.line_no);
1465 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1466 return 1;
1468 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
1470 hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
1471 hlsl_ctx.line_no);
1472 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1473 return 1;
1476 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
1479 base_type: KW_VOID
1481 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
1483 | KW_SAMPLER
1485 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1486 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
1488 | KW_SAMPLER1D
1490 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1491 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
1493 | KW_SAMPLER2D
1495 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1496 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
1498 | KW_SAMPLER3D
1500 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1501 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
1503 | KW_SAMPLERCUBE
1505 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1506 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
1508 | TYPE_IDENTIFIER
1510 struct hlsl_type *type;
1512 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
1513 $$ = type;
1514 d3dcompiler_free($1);
1516 | KW_STRUCT TYPE_IDENTIFIER
1518 struct hlsl_type *type;
1520 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
1521 if (type->type != HLSL_CLASS_STRUCT)
1523 hlsl_message("Line %u: redefining %s as a structure.\n",
1524 hlsl_ctx.line_no, $2);
1525 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1527 else
1529 $$ = type;
1531 d3dcompiler_free($2);
1534 declaration_statement: declaration
1535 | struct_declaration
1536 | typedef
1538 $$ = d3dcompiler_alloc(sizeof(*$$));
1539 if (!$$)
1541 ERR("Out of memory\n");
1542 return -1;
1544 list_init($$);
1547 typedef: KW_TYPEDEF var_modifiers type type_specs ';'
1549 struct source_location loc;
1551 set_location(&loc, &@1);
1552 if (!add_typedef($2, $3, $4, &loc))
1553 return 1;
1555 | KW_TYPEDEF struct_spec type_specs ';'
1557 struct source_location loc;
1559 set_location(&loc, &@1);
1560 if (!add_typedef(0, $2, $3, &loc))
1561 return 1;
1564 type_specs: type_spec
1566 $$ = d3dcompiler_alloc(sizeof(*$$));
1567 list_init($$);
1568 list_add_head($$, &$1->entry);
1570 | type_specs ',' type_spec
1572 $$ = $1;
1573 list_add_tail($$, &$3->entry);
1576 type_spec: any_identifier array
1578 $$ = d3dcompiler_alloc(sizeof(*$$));
1579 set_location(&$$->loc, &@1);
1580 $$->name = $1;
1581 $$->array_size = $2;
1584 declaration: var_modifiers type variables_def ';'
1586 $$ = declare_vars($2, $1, $3);
1589 variables_def_optional: /* Empty */
1591 $$ = NULL;
1593 | variables_def
1595 $$ = $1;
1598 variables_def: variable_def
1600 $$ = d3dcompiler_alloc(sizeof(*$$));
1601 list_init($$);
1602 list_add_head($$, &$1->entry);
1604 | variables_def ',' variable_def
1606 $$ = $1;
1607 list_add_tail($$, &$3->entry);
1610 variable_def: any_identifier array colon_attribute
1612 $$ = d3dcompiler_alloc(sizeof(*$$));
1613 set_location(&$$->loc, &@1);
1614 $$->name = $1;
1615 $$->array_size = $2;
1616 $$->semantic = $3.semantic;
1617 $$->reg_reservation = $3.reg_reservation;
1619 | any_identifier array colon_attribute '=' complex_initializer
1621 TRACE("Declaration with initializer.\n");
1622 $$ = d3dcompiler_alloc(sizeof(*$$));
1623 set_location(&$$->loc, &@1);
1624 $$->name = $1;
1625 $$->array_size = $2;
1626 $$->semantic = $3.semantic;
1627 $$->reg_reservation = $3.reg_reservation;
1628 $$->initializer = $5;
1631 array: /* Empty */
1633 $$ = 0;
1635 | '[' expr ']'
1637 FIXME("Array.\n");
1638 $$ = 0;
1639 free_instr($2);
1642 var_modifiers: /* Empty */
1644 $$ = 0;
1646 | KW_EXTERN var_modifiers
1648 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
1650 | KW_NOINTERPOLATION var_modifiers
1652 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
1654 | KW_PRECISE var_modifiers
1656 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
1658 | KW_SHARED var_modifiers
1660 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
1662 | KW_GROUPSHARED var_modifiers
1664 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
1666 | KW_STATIC var_modifiers
1668 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
1670 | KW_UNIFORM var_modifiers
1672 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
1674 | KW_VOLATILE var_modifiers
1676 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
1678 | KW_CONST var_modifiers
1680 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
1682 | KW_ROW_MAJOR var_modifiers
1684 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
1686 | KW_COLUMN_MAJOR var_modifiers
1688 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
1691 complex_initializer: initializer_expr
1693 $$ = d3dcompiler_alloc(sizeof(*$$));
1694 list_init($$);
1695 list_add_head($$, &$1->entry);
1697 | '{' initializer_expr_list '}'
1699 $$ = $2;
1701 | '{' initializer_expr_list ',' '}'
1703 $$ = $2;
1706 initializer_expr: assignment_expr
1708 $$ = $1;
1711 initializer_expr_list: initializer_expr
1713 $$ = d3dcompiler_alloc(sizeof(*$$));
1714 list_init($$);
1715 list_add_head($$, &$1->entry);
1717 | initializer_expr_list ',' initializer_expr
1719 $$ = $1;
1720 list_add_tail($$, &$3->entry);
1723 boolean: KW_TRUE
1725 $$ = TRUE;
1727 | KW_FALSE
1729 $$ = FALSE;
1732 statement_list: statement
1734 $$ = $1;
1736 | statement_list statement
1738 $$ = $1;
1739 list_move_tail($$, $2);
1740 d3dcompiler_free($2);
1743 statement: declaration_statement
1744 | expr_statement
1745 | compound_statement
1746 | jump_statement
1747 | selection_statement
1748 | loop_statement
1750 /* FIXME: add rule for return with no value */
1751 jump_statement: KW_RETURN expr ';'
1753 struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump));
1754 if (!jump)
1756 ERR("Out of memory\n");
1757 return -1;
1759 jump->node.type = HLSL_IR_JUMP;
1760 set_location(&jump->node.loc, &@1);
1761 jump->type = HLSL_IR_JUMP_RETURN;
1762 jump->node.data_type = $2->data_type;
1763 jump->return_value = $2;
1765 FIXME("Check for valued return on void function.\n");
1766 FIXME("Implicit conversion to the return type if needed, "
1767 "error out if conversion not possible.\n");
1769 $$ = d3dcompiler_alloc(sizeof(*$$));
1770 list_init($$);
1771 list_add_tail($$, &jump->node.entry);
1774 selection_statement: KW_IF '(' expr ')' if_body
1776 struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
1777 if (!instr)
1779 ERR("Out of memory\n");
1780 return -1;
1782 instr->node.type = HLSL_IR_IF;
1783 set_location(&instr->node.loc, &@1);
1784 instr->condition = $3;
1785 instr->then_instrs = $5.then_instrs;
1786 instr->else_instrs = $5.else_instrs;
1787 if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1)
1789 hlsl_report_message(instr->node.loc.file, instr->node.loc.line,
1790 instr->node.loc.col, HLSL_LEVEL_ERROR,
1791 "if condition requires a scalar");
1793 $$ = d3dcompiler_alloc(sizeof(*$$));
1794 list_init($$);
1795 list_add_head($$, &instr->node.entry);
1798 if_body: statement
1800 $$.then_instrs = $1;
1801 $$.else_instrs = NULL;
1803 | statement KW_ELSE statement
1805 $$.then_instrs = $1;
1806 $$.else_instrs = $3;
1809 loop_statement: KW_WHILE '(' expr ')' statement
1811 struct source_location loc;
1812 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1814 if (!cond)
1816 ERR("Out of memory.\n");
1817 return -1;
1819 list_init(cond);
1820 list_add_head(cond, &$3->entry);
1821 set_location(&loc, &@1);
1822 $$ = create_loop(LOOP_WHILE, NULL, cond, NULL, $5, &loc);
1824 | KW_DO statement KW_WHILE '(' expr ')' ';'
1826 struct source_location loc;
1827 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1829 if (!cond)
1831 ERR("Out of memory.\n");
1832 return -1;
1834 list_init(cond);
1835 list_add_head(cond, &$5->entry);
1836 set_location(&loc, &@1);
1837 $$ = create_loop(LOOP_DO_WHILE, NULL, cond, NULL, $2, &loc);
1839 | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
1841 struct source_location loc;
1843 set_location(&loc, &@1);
1844 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1845 pop_scope(&hlsl_ctx);
1847 | KW_FOR '(' scope_start declaration expr_statement expr ')' statement
1849 struct source_location loc;
1851 set_location(&loc, &@1);
1852 if (!$4)
1853 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_WARNING,
1854 "no expressions in for loop initializer");
1855 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1856 pop_scope(&hlsl_ctx);
1859 expr_statement: ';'
1861 $$ = d3dcompiler_alloc(sizeof(*$$));
1862 list_init($$);
1864 | expr ';'
1866 $$ = d3dcompiler_alloc(sizeof(*$$));
1867 list_init($$);
1868 if ($1)
1869 list_add_head($$, &$1->entry);
1872 primary_expr: C_FLOAT
1874 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1875 if (!c)
1877 ERR("Out of memory.\n");
1878 return -1;
1880 c->node.type = HLSL_IR_CONSTANT;
1881 set_location(&c->node.loc, &yylloc);
1882 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("float"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
1883 c->v.value.f[0] = $1;
1884 $$ = &c->node;
1886 | C_INTEGER
1888 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1889 if (!c)
1891 ERR("Out of memory.\n");
1892 return -1;
1894 c->node.type = HLSL_IR_CONSTANT;
1895 set_location(&c->node.loc, &yylloc);
1896 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("int"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
1897 c->v.value.i[0] = $1;
1898 $$ = &c->node;
1900 | boolean
1902 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1903 if (!c)
1905 ERR("Out of memory.\n");
1906 return -1;
1908 c->node.type = HLSL_IR_CONSTANT;
1909 set_location(&c->node.loc, &yylloc);
1910 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("bool"), HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
1911 c->v.value.b[0] = $1;
1912 $$ = &c->node;
1914 | variable
1916 struct hlsl_ir_deref *deref = new_var_deref($1);
1917 if (deref)
1919 $$ = &deref->node;
1920 set_location(&$$->loc, &@1);
1922 else
1923 $$ = NULL;
1925 | '(' expr ')'
1927 $$ = $2;
1930 variable: VAR_IDENTIFIER
1932 struct hlsl_ir_var *var;
1933 var = get_variable(hlsl_ctx.cur_scope, $1);
1934 if (!var)
1936 hlsl_message("Line %d: variable '%s' not declared\n",
1937 hlsl_ctx.line_no, $1);
1938 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1939 return 1;
1941 $$ = var;
1944 postfix_expr: primary_expr
1946 $$ = $1;
1948 | postfix_expr OP_INC
1950 struct hlsl_ir_node *operands[3];
1951 struct source_location loc;
1953 set_location(&loc, &@2);
1954 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1956 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1957 "modifying a const expression");
1958 return 1;
1960 operands[0] = $1;
1961 operands[1] = operands[2] = NULL;
1962 $$ = &new_expr(HLSL_IR_UNOP_POSTINC, operands, &loc)->node;
1963 /* Post increment/decrement expressions are considered const */
1964 $$->data_type = clone_hlsl_type($$->data_type);
1965 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1967 | postfix_expr OP_DEC
1969 struct hlsl_ir_node *operands[3];
1970 struct source_location loc;
1972 set_location(&loc, &@2);
1973 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1975 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1976 "modifying a const expression");
1977 return 1;
1979 operands[0] = $1;
1980 operands[1] = operands[2] = NULL;
1981 $$ = &new_expr(HLSL_IR_UNOP_POSTDEC, operands, &loc)->node;
1982 /* Post increment/decrement expressions are considered const */
1983 $$->data_type = clone_hlsl_type($$->data_type);
1984 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1986 | postfix_expr '.' any_identifier
1988 struct source_location loc;
1990 set_location(&loc, &@2);
1991 if ($1->data_type->type == HLSL_CLASS_STRUCT)
1993 struct hlsl_type *type = $1->data_type;
1994 struct hlsl_struct_field *field;
1996 $$ = NULL;
1997 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
1999 if (!strcmp($3, field->name))
2001 struct hlsl_ir_deref *deref = new_record_deref($1, field);
2003 if (!deref)
2005 ERR("Out of memory\n");
2006 return -1;
2008 deref->node.loc = loc;
2009 $$ = &deref->node;
2010 break;
2013 if (!$$)
2015 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2016 "invalid subscript %s", debugstr_a($3));
2017 return 1;
2020 else if ($1->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
2022 struct hlsl_ir_swizzle *swizzle;
2024 swizzle = get_swizzle($1, $3, &loc);
2025 if (!swizzle)
2027 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2028 "invalid swizzle %s", debugstr_a($3));
2029 return 1;
2031 $$ = &swizzle->node;
2033 else
2035 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2036 "invalid subscript %s", debugstr_a($3));
2037 return 1;
2040 | postfix_expr '[' expr ']'
2042 /* This may be an array dereference or a vector/matrix
2043 * subcomponent access.
2044 * We store it as an array dereference in any case. */
2045 struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
2046 struct hlsl_type *expr_type = $1->data_type;
2047 struct source_location loc;
2049 TRACE("Array dereference from type %s\n", debug_hlsl_type(expr_type));
2050 if (!deref)
2052 ERR("Out of memory\n");
2053 return -1;
2055 deref->node.type = HLSL_IR_DEREF;
2056 set_location(&loc, &@2);
2057 deref->node.loc = loc;
2058 if (expr_type->type == HLSL_CLASS_ARRAY)
2060 deref->node.data_type = expr_type->e.array.type;
2062 else if (expr_type->type == HLSL_CLASS_MATRIX)
2064 deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, expr_type->base_type, expr_type->dimx, 1);
2066 else if (expr_type->type == HLSL_CLASS_VECTOR)
2068 deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_SCALAR, expr_type->base_type, 1, 1);
2070 else
2072 if (expr_type->type == HLSL_CLASS_SCALAR)
2073 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2074 "array-indexed expression is scalar");
2075 else
2076 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2077 "expression is not array-indexable");
2078 d3dcompiler_free(deref);
2079 free_instr($1);
2080 free_instr($3);
2081 return 1;
2083 if ($3->data_type->type != HLSL_CLASS_SCALAR)
2085 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2086 "array index is not scalar");
2087 d3dcompiler_free(deref);
2088 free_instr($1);
2089 free_instr($3);
2090 return 1;
2092 deref->type = HLSL_IR_DEREF_ARRAY;
2093 deref->v.array.array = $1;
2094 deref->v.array.index = $3;
2096 $$ = &deref->node;
2098 /* "var_modifiers" doesn't make sense in this case, but it's needed
2099 in the grammar to avoid shift/reduce conflicts. */
2100 | var_modifiers type '(' initializer_expr_list ')'
2102 struct hlsl_ir_constructor *constructor;
2104 TRACE("%s constructor.\n", debug_hlsl_type($2));
2105 if ($1)
2107 hlsl_message("Line %u: unexpected modifier in a constructor.\n",
2108 hlsl_ctx.line_no);
2109 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2110 return -1;
2112 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
2114 hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
2115 hlsl_ctx.line_no);
2116 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2117 return -1;
2119 if ($2->dimx * $2->dimy != components_count_expr_list($4))
2121 hlsl_message("Line %u: wrong number of components in constructor.\n",
2122 hlsl_ctx.line_no);
2123 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2124 return -1;
2127 constructor = d3dcompiler_alloc(sizeof(*constructor));
2128 constructor->node.type = HLSL_IR_CONSTRUCTOR;
2129 set_location(&constructor->node.loc, &@3);
2130 constructor->node.data_type = $2;
2131 constructor->arguments = $4;
2133 $$ = &constructor->node;
2136 unary_expr: postfix_expr
2138 $$ = $1;
2140 | OP_INC unary_expr
2142 struct hlsl_ir_node *operands[3];
2143 struct source_location loc;
2145 set_location(&loc, &@1);
2146 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2148 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2149 "modifying a const expression");
2150 return 1;
2152 operands[0] = $2;
2153 operands[1] = operands[2] = NULL;
2154 $$ = &new_expr(HLSL_IR_UNOP_PREINC, operands, &loc)->node;
2156 | OP_DEC unary_expr
2158 struct hlsl_ir_node *operands[3];
2159 struct source_location loc;
2161 set_location(&loc, &@1);
2162 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2164 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2165 "modifying a const expression");
2166 return 1;
2168 operands[0] = $2;
2169 operands[1] = operands[2] = NULL;
2170 $$ = &new_expr(HLSL_IR_UNOP_PREDEC, operands, &loc)->node;
2172 | unary_op unary_expr
2174 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
2175 HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
2176 struct hlsl_ir_node *operands[3];
2177 struct source_location loc;
2179 if ($1 == UNARY_OP_PLUS)
2181 $$ = $2;
2183 else
2185 operands[0] = $2;
2186 operands[1] = operands[2] = NULL;
2187 set_location(&loc, &@1);
2188 $$ = &new_expr(ops[$1], operands, &loc)->node;
2191 /* var_modifiers just to avoid shift/reduce conflicts */
2192 | '(' var_modifiers type array ')' unary_expr
2194 struct hlsl_ir_expr *expr;
2195 struct hlsl_type *src_type = $6->data_type;
2196 struct hlsl_type *dst_type;
2197 struct source_location loc;
2199 set_location(&loc, &@3);
2200 if ($2)
2202 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2203 "unexpected modifier in a cast");
2204 return 1;
2207 if ($4)
2208 dst_type = new_array_type($3, $4);
2209 else
2210 dst_type = $3;
2212 if (!compatible_data_types(src_type, dst_type))
2214 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2215 "can't cast from %s to %s",
2216 debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
2217 return 1;
2220 expr = new_cast($6, dst_type, &loc);
2221 $$ = expr ? &expr->node : NULL;
2224 unary_op: '+'
2226 $$ = UNARY_OP_PLUS;
2228 | '-'
2230 $$ = UNARY_OP_MINUS;
2232 | '!'
2234 $$ = UNARY_OP_LOGICNOT;
2236 | '~'
2238 $$ = UNARY_OP_BITNOT;
2241 mul_expr: unary_expr
2243 $$ = $1;
2245 | mul_expr '*' unary_expr
2247 struct source_location loc;
2249 set_location(&loc, &@2);
2250 $$ = &hlsl_mul($1, $3, &loc)->node;
2252 | mul_expr '/' unary_expr
2254 struct source_location loc;
2256 set_location(&loc, &@2);
2257 $$ = &hlsl_div($1, $3, &loc)->node;
2259 | mul_expr '%' unary_expr
2261 struct source_location loc;
2263 set_location(&loc, &@2);
2264 $$ = &hlsl_mod($1, $3, &loc)->node;
2267 add_expr: mul_expr
2269 $$ = $1;
2271 | add_expr '+' mul_expr
2273 struct source_location loc;
2275 set_location(&loc, &@2);
2276 $$ = &hlsl_add($1, $3, &loc)->node;
2278 | add_expr '-' mul_expr
2280 struct source_location loc;
2282 set_location(&loc, &@2);
2283 $$ = &hlsl_sub($1, $3, &loc)->node;
2286 shift_expr: add_expr
2288 $$ = $1;
2290 | shift_expr OP_LEFTSHIFT add_expr
2292 FIXME("Left shift\n");
2294 | shift_expr OP_RIGHTSHIFT add_expr
2296 FIXME("Right shift\n");
2299 relational_expr: shift_expr
2301 $$ = $1;
2303 | relational_expr '<' shift_expr
2305 struct source_location loc;
2307 set_location(&loc, &@2);
2308 $$ = &hlsl_lt($1, $3, &loc)->node;
2310 | relational_expr '>' shift_expr
2312 struct source_location loc;
2314 set_location(&loc, &@2);
2315 $$ = &hlsl_gt($1, $3, &loc)->node;
2317 | relational_expr OP_LE shift_expr
2319 struct source_location loc;
2321 set_location(&loc, &@2);
2322 $$ = &hlsl_le($1, $3, &loc)->node;
2324 | relational_expr OP_GE shift_expr
2326 struct source_location loc;
2328 set_location(&loc, &@2);
2329 $$ = &hlsl_ge($1, $3, &loc)->node;
2332 equality_expr: relational_expr
2334 $$ = $1;
2336 | equality_expr OP_EQ relational_expr
2338 struct source_location loc;
2340 set_location(&loc, &@2);
2341 $$ = &hlsl_eq($1, $3, &loc)->node;
2343 | equality_expr OP_NE relational_expr
2345 struct source_location loc;
2347 set_location(&loc, &@2);
2348 $$ = &hlsl_ne($1, $3, &loc)->node;
2351 bitand_expr: equality_expr
2353 $$ = $1;
2355 | bitand_expr '&' equality_expr
2357 FIXME("bitwise AND\n");
2360 bitxor_expr: bitand_expr
2362 $$ = $1;
2364 | bitxor_expr '^' bitand_expr
2366 FIXME("bitwise XOR\n");
2369 bitor_expr: bitxor_expr
2371 $$ = $1;
2373 | bitor_expr '|' bitxor_expr
2375 FIXME("bitwise OR\n");
2378 logicand_expr: bitor_expr
2380 $$ = $1;
2382 | logicand_expr OP_AND bitor_expr
2384 FIXME("logic AND\n");
2387 logicor_expr: logicand_expr
2389 $$ = $1;
2391 | logicor_expr OP_OR logicand_expr
2393 FIXME("logic OR\n");
2396 conditional_expr: logicor_expr
2398 $$ = $1;
2400 | logicor_expr '?' expr ':' assignment_expr
2402 FIXME("ternary operator\n");
2405 assignment_expr: conditional_expr
2407 $$ = $1;
2409 | unary_expr assign_op assignment_expr
2411 struct source_location loc;
2413 set_location(&loc, &@2);
2414 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
2416 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2417 "l-value is const");
2418 return 1;
2420 $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
2421 if (!$$)
2422 return 1;
2423 $$->loc = loc;
2426 assign_op: '='
2428 $$ = ASSIGN_OP_ASSIGN;
2430 | OP_ADDASSIGN
2432 $$ = ASSIGN_OP_ADD;
2434 | OP_SUBASSIGN
2436 $$ = ASSIGN_OP_SUB;
2438 | OP_MULASSIGN
2440 $$ = ASSIGN_OP_MUL;
2442 | OP_DIVASSIGN
2444 $$ = ASSIGN_OP_DIV;
2446 | OP_MODASSIGN
2448 $$ = ASSIGN_OP_MOD;
2450 | OP_LEFTSHIFTASSIGN
2452 $$ = ASSIGN_OP_LSHIFT;
2454 | OP_RIGHTSHIFTASSIGN
2456 $$ = ASSIGN_OP_RSHIFT;
2458 | OP_ANDASSIGN
2460 $$ = ASSIGN_OP_AND;
2462 | OP_ORASSIGN
2464 $$ = ASSIGN_OP_OR;
2466 | OP_XORASSIGN
2468 $$ = ASSIGN_OP_XOR;
2471 expr: assignment_expr
2473 $$ = $1;
2475 | expr ',' assignment_expr
2477 FIXME("Comma expression\n");
2482 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
2484 loc->file = hlsl_ctx.source_file;
2485 loc->line = l->first_line;
2486 loc->col = l->first_column;
2489 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
2491 if (modifiers & mod)
2493 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2494 "modifier '%s' already specified", debug_modifiers(mod));
2495 return modifiers;
2497 if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
2498 && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
2500 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2501 "more than one matrix majority keyword");
2502 return modifiers;
2504 return modifiers | mod;
2507 static void dump_function_decl(struct wine_rb_entry *entry, void *context)
2509 struct hlsl_ir_function_decl *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
2510 if (func->body)
2511 debug_dump_ir_function_decl(func);
2514 static void dump_function(struct wine_rb_entry *entry, void *context)
2516 struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
2517 wine_rb_for_each_entry(&func->overloads, dump_function_decl, NULL);
2520 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
2521 const char *entrypoint, char **messages)
2523 struct hlsl_scope *scope, *next_scope;
2524 struct hlsl_type *hlsl_type, *next_type;
2525 struct hlsl_ir_var *var, *next_var;
2526 unsigned int i;
2528 hlsl_ctx.status = PARSE_SUCCESS;
2529 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
2530 hlsl_ctx.line_no = hlsl_ctx.column = 1;
2531 hlsl_ctx.source_file = d3dcompiler_strdup("");
2532 hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
2533 if (hlsl_ctx.source_files)
2534 hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
2535 hlsl_ctx.source_files_count = 1;
2536 hlsl_ctx.cur_scope = NULL;
2537 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
2538 list_init(&hlsl_ctx.scopes);
2539 list_init(&hlsl_ctx.types);
2540 init_functions_tree(&hlsl_ctx.functions);
2542 push_scope(&hlsl_ctx);
2543 hlsl_ctx.globals = hlsl_ctx.cur_scope;
2544 declare_predefined_types(hlsl_ctx.globals);
2546 hlsl_parse();
2548 if (TRACE_ON(hlsl_parser))
2550 TRACE("IR dump.\n");
2551 wine_rb_for_each_entry(&hlsl_ctx.functions, dump_function, NULL);
2554 TRACE("Compilation status = %d\n", hlsl_ctx.status);
2555 if (messages)
2557 if (hlsl_ctx.messages.size)
2558 *messages = hlsl_ctx.messages.string;
2559 else
2560 *messages = NULL;
2562 else
2564 if (hlsl_ctx.messages.capacity)
2565 d3dcompiler_free(hlsl_ctx.messages.string);
2568 for (i = 0; i < hlsl_ctx.source_files_count; ++i)
2569 d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
2570 d3dcompiler_free(hlsl_ctx.source_files);
2572 TRACE("Freeing functions IR.\n");
2573 wine_rb_destroy(&hlsl_ctx.functions, free_function_rb, NULL);
2575 TRACE("Freeing variables.\n");
2576 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
2578 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
2580 free_declaration(var);
2582 wine_rb_destroy(&scope->types, NULL, NULL);
2583 d3dcompiler_free(scope);
2586 TRACE("Freeing types.\n");
2587 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
2589 free_hlsl_type(hlsl_type);
2592 return NULL;