shell32/tests: Add PathResolve tests.
[wine.git] / dlls / d3dcompiler_43 / hlsl.y
blobd81d6afa9cce95c9d46ce7f718afb83b207b237a
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 "wine/debug.h"
24 #include <stdio.h>
26 #include "d3dcompiler_private.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser);
30 int hlsl_lex(void);
32 struct hlsl_parse_ctx hlsl_ctx;
34 struct YYLTYPE;
35 static void set_location(struct source_location *loc, const struct YYLTYPE *l);
37 void WINAPIV hlsl_message(const char *fmt, ...)
39 __ms_va_list args;
41 __ms_va_start(args, fmt);
42 compilation_message(&hlsl_ctx.messages, fmt, args);
43 __ms_va_end(args);
46 static const char *hlsl_get_error_level_name(enum hlsl_error_level level)
48 static const char * const names[] =
50 "error",
51 "warning",
52 "note",
54 return names[level];
57 void WINAPIV hlsl_report_message(const char *filename, DWORD line, DWORD column,
58 enum hlsl_error_level level, const char *fmt, ...)
60 __ms_va_list args;
61 char *string = NULL;
62 int rc, size = 0;
64 while (1)
66 __ms_va_start(args, fmt);
67 rc = vsnprintf(string, size, fmt, args);
68 __ms_va_end(args);
70 if (rc >= 0 && rc < size)
71 break;
73 if (rc >= size)
74 size = rc + 1;
75 else
76 size = size ? size * 2 : 32;
78 if (!string)
79 string = d3dcompiler_alloc(size);
80 else
81 string = d3dcompiler_realloc(string, size);
82 if (!string)
84 ERR("Error reallocating memory for a string.\n");
85 return;
89 hlsl_message("%s:%u:%u: %s: %s\n", filename, line, column, hlsl_get_error_level_name(level), string);
90 d3dcompiler_free(string);
92 if (level == HLSL_LEVEL_ERROR)
93 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
94 else if (level == HLSL_LEVEL_WARNING)
95 set_parse_status(&hlsl_ctx.status, PARSE_WARN);
98 static void hlsl_error(const char *s)
100 hlsl_report_message(hlsl_ctx.source_file, hlsl_ctx.line_no, hlsl_ctx.column, HLSL_LEVEL_ERROR, "%s", s);
103 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
105 TRACE("Line %u: ", line_no);
106 if (modifiers)
107 TRACE("%s ", debug_modifiers(modifiers));
108 TRACE("%s %s;\n", debug_hlsl_type(type), declname);
111 static void check_invalid_matrix_modifiers(DWORD modifiers, struct source_location *loc)
113 if (modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
115 hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
116 "'row_major' or 'column_major' modifiers are only allowed for matrices");
120 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
122 BOOL ret;
124 TRACE("Declaring variable %s.\n", decl->name);
125 if (decl->data_type->type == HLSL_CLASS_MATRIX)
127 if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)))
129 decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR
130 ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR;
133 else
134 check_invalid_matrix_modifiers(decl->modifiers, &decl->loc);
136 if (local)
138 DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
139 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
140 if (invalid)
142 hlsl_report_message(decl->loc.file, decl->loc.line, decl->loc.col, HLSL_LEVEL_ERROR,
143 "modifier '%s' invalid for local variables", debug_modifiers(invalid));
145 if (decl->semantic)
147 hlsl_report_message(decl->loc.file, decl->loc.line, decl->loc.col, HLSL_LEVEL_ERROR,
148 "semantics are not allowed on local variables");
149 return FALSE;
152 else
154 if (find_function(decl->name))
156 hlsl_report_message(decl->loc.file, decl->loc.line, decl->loc.col, HLSL_LEVEL_ERROR,
157 "redefinition of '%s'", decl->name);
158 return FALSE;
161 ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
162 if (!ret)
164 struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
166 hlsl_report_message(decl->loc.file, decl->loc.line, decl->loc.col, HLSL_LEVEL_ERROR,
167 "\"%s\" already declared", decl->name);
168 hlsl_report_message(old->loc.file, old->loc.line, old->loc.col, HLSL_LEVEL_NOTE,
169 "\"%s\" was previously declared here", old->name);
170 return FALSE;
172 return TRUE;
175 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc);
177 static BOOL check_type_modifiers(DWORD modifiers, struct source_location *loc)
179 if (modifiers & ~HLSL_TYPE_MODIFIERS_MASK)
181 hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
182 "modifier not allowed on typedefs");
183 return FALSE;
185 return TRUE;
188 static BOOL add_type_to_scope(struct hlsl_scope *scope, struct hlsl_type *def)
190 if (get_type(scope, def->name, FALSE))
191 return FALSE;
193 wine_rb_put(&scope->types, def->name, &def->scope_entry);
194 return TRUE;
197 static void declare_predefined_types(struct hlsl_scope *scope)
199 struct hlsl_type *type;
200 unsigned int x, y, bt;
201 static const char * const names[] =
203 "float",
204 "half",
205 "double",
206 "int",
207 "uint",
208 "bool",
210 char name[10];
212 for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt)
214 for (y = 1; y <= 4; ++y)
216 for (x = 1; x <= 4; ++x)
218 sprintf(name, "%s%ux%u", names[bt], x, y);
219 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_MATRIX, bt, x, y);
220 add_type_to_scope(scope, type);
222 if (y == 1)
224 sprintf(name, "%s%u", names[bt], x);
225 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_VECTOR, bt, x, y);
226 add_type_to_scope(scope, type);
228 if (x == 1)
230 sprintf(name, "%s", names[bt]);
231 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_SCALAR, bt, x, y);
232 add_type_to_scope(scope, type);
239 /* DX8 effects predefined types */
240 type = new_hlsl_type(d3dcompiler_strdup("DWORD"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
241 add_type_to_scope(scope, type);
242 type = new_hlsl_type(d3dcompiler_strdup("FLOAT"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
243 add_type_to_scope(scope, type);
244 type = new_hlsl_type(d3dcompiler_strdup("VECTOR"), HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1);
245 add_type_to_scope(scope, type);
246 type = new_hlsl_type(d3dcompiler_strdup("MATRIX"), HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4);
247 add_type_to_scope(scope, type);
248 type = new_hlsl_type(d3dcompiler_strdup("STRING"), HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1);
249 add_type_to_scope(scope, type);
250 type = new_hlsl_type(d3dcompiler_strdup("TEXTURE"), HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1);
251 add_type_to_scope(scope, type);
252 type = new_hlsl_type(d3dcompiler_strdup("PIXELSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1);
253 add_type_to_scope(scope, type);
254 type = new_hlsl_type(d3dcompiler_strdup("VERTEXSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1);
255 add_type_to_scope(scope, type);
258 static struct hlsl_ir_if *loop_condition(struct list *cond_list)
260 struct hlsl_ir_node *cond, *not_cond;
261 struct hlsl_ir_if *out_cond;
262 struct hlsl_ir_jump *jump;
263 unsigned int count = list_count(cond_list);
265 if (!count)
266 return NULL;
267 if (count != 1)
268 ERR("Got multiple expressions in a for condition.\n");
270 cond = LIST_ENTRY(list_head(cond_list), struct hlsl_ir_node, entry);
271 out_cond = d3dcompiler_alloc(sizeof(*out_cond));
272 if (!out_cond)
274 ERR("Out of memory.\n");
275 return NULL;
277 out_cond->node.type = HLSL_IR_IF;
278 if (!(not_cond = new_unary_expr(HLSL_IR_UNOP_LOGIC_NOT, cond, cond->loc)))
280 ERR("Out of memory.\n");
281 d3dcompiler_free(out_cond);
282 return NULL;
284 out_cond->condition = not_cond;
285 jump = d3dcompiler_alloc(sizeof(*jump));
286 if (!jump)
288 ERR("Out of memory.\n");
289 d3dcompiler_free(out_cond);
290 d3dcompiler_free(not_cond);
291 return NULL;
293 jump->node.type = HLSL_IR_JUMP;
294 jump->type = HLSL_IR_JUMP_BREAK;
295 out_cond->then_instrs = d3dcompiler_alloc(sizeof(*out_cond->then_instrs));
296 if (!out_cond->then_instrs)
298 ERR("Out of memory.\n");
299 d3dcompiler_free(out_cond);
300 d3dcompiler_free(not_cond);
301 d3dcompiler_free(jump);
302 return NULL;
304 list_init(out_cond->then_instrs);
305 list_add_head(out_cond->then_instrs, &jump->node.entry);
307 return out_cond;
310 enum loop_type
312 LOOP_FOR,
313 LOOP_WHILE,
314 LOOP_DO_WHILE
317 static struct list *create_loop(enum loop_type type, struct list *init, struct list *cond,
318 struct hlsl_ir_node *iter, struct list *body, struct source_location *loc)
320 struct list *list = NULL;
321 struct hlsl_ir_loop *loop = NULL;
322 struct hlsl_ir_if *cond_jump = NULL;
324 list = d3dcompiler_alloc(sizeof(*list));
325 if (!list)
326 goto oom;
327 list_init(list);
329 if (init)
330 list_move_head(list, init);
332 loop = d3dcompiler_alloc(sizeof(*loop));
333 if (!loop)
334 goto oom;
335 loop->node.type = HLSL_IR_LOOP;
336 loop->node.loc = *loc;
337 list_add_tail(list, &loop->node.entry);
338 loop->body = d3dcompiler_alloc(sizeof(*loop->body));
339 if (!loop->body)
340 goto oom;
341 list_init(loop->body);
343 cond_jump = loop_condition(cond);
344 if (!cond_jump)
345 goto oom;
347 if (type != LOOP_DO_WHILE)
348 list_add_tail(loop->body, &cond_jump->node.entry);
350 list_move_tail(loop->body, body);
352 if (iter)
353 list_add_tail(loop->body, &iter->entry);
355 if (type == LOOP_DO_WHILE)
356 list_add_tail(loop->body, &cond_jump->node.entry);
358 d3dcompiler_free(init);
359 d3dcompiler_free(cond);
360 d3dcompiler_free(body);
361 return list;
363 oom:
364 ERR("Out of memory.\n");
365 if (loop)
366 d3dcompiler_free(loop->body);
367 d3dcompiler_free(loop);
368 d3dcompiler_free(cond_jump);
369 d3dcompiler_free(list);
370 free_instr_list(init);
371 free_instr_list(cond);
372 free_instr(iter);
373 free_instr_list(body);
374 return NULL;
377 static unsigned int initializer_size(const struct parse_initializer *initializer)
379 unsigned int count = 0, i;
381 for (i = 0; i < initializer->args_count; ++i)
383 count += components_count_type(initializer->args[i]->data_type);
385 TRACE("Initializer size = %u.\n", count);
386 return count;
389 static void free_parse_initializer(struct parse_initializer *initializer)
391 unsigned int i;
392 for (i = 0; i < initializer->args_count; ++i)
393 free_instr(initializer->args[i]);
394 d3dcompiler_free(initializer->args);
397 static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components,
398 struct hlsl_ir_node *val, struct source_location *loc)
400 struct hlsl_ir_swizzle *swizzle = d3dcompiler_alloc(sizeof(*swizzle));
402 if (!swizzle)
403 return NULL;
404 swizzle->node.type = HLSL_IR_SWIZZLE;
405 swizzle->node.loc = *loc;
406 swizzle->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1);
407 swizzle->val = val;
408 swizzle->swizzle = s;
409 return swizzle;
412 static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const char *swizzle,
413 struct source_location *loc)
415 unsigned int len = strlen(swizzle), component = 0;
416 unsigned int i, set, swiz = 0;
417 BOOL valid;
419 if (value->data_type->type == HLSL_CLASS_MATRIX)
421 /* Matrix swizzle */
422 BOOL m_swizzle;
423 unsigned int inc, x, y;
425 if (len < 3 || swizzle[0] != '_')
426 return NULL;
427 m_swizzle = swizzle[1] == 'm';
428 inc = m_swizzle ? 4 : 3;
430 if (len % inc || len > inc * 4)
431 return NULL;
433 for (i = 0; i < len; i += inc)
435 if (swizzle[i] != '_')
436 return NULL;
437 if (m_swizzle)
439 if (swizzle[i + 1] != 'm')
440 return NULL;
441 x = swizzle[i + 2] - '0';
442 y = swizzle[i + 3] - '0';
444 else
446 x = swizzle[i + 1] - '1';
447 y = swizzle[i + 2] - '1';
450 if (x >= value->data_type->dimx || y >= value->data_type->dimy)
451 return NULL;
452 swiz |= (y << 4 | x) << component * 8;
453 component++;
455 return new_swizzle(swiz, component, value, loc);
458 /* Vector swizzle */
459 if (len > 4)
460 return NULL;
462 for (set = 0; set < 2; ++set)
464 valid = TRUE;
465 component = 0;
466 for (i = 0; i < len; ++i)
468 char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}};
469 unsigned int s = 0;
471 for (s = 0; s < 4; ++s)
473 if (swizzle[i] == c[set][s])
474 break;
476 if (s == 4)
478 valid = FALSE;
479 break;
482 if (s >= value->data_type->dimx)
483 return NULL;
484 swiz |= s << component * 2;
485 component++;
487 if (valid)
488 return new_swizzle(swiz, component, value, loc);
491 return NULL;
494 static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var,
495 struct parse_initializer *initializer)
497 struct hlsl_type *type = var->data_type;
498 struct hlsl_struct_field *field;
499 struct hlsl_ir_node *assignment;
500 struct hlsl_ir_deref *deref;
501 unsigned int i = 0;
503 if (initializer_size(initializer) != components_count_type(type))
505 hlsl_report_message(var->loc.file, var->loc.line, var->loc.col, HLSL_LEVEL_ERROR,
506 "structure initializer mismatch");
507 free_parse_initializer(initializer);
508 return;
511 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
513 struct hlsl_ir_node *node = initializer->args[i];
515 if (i++ >= initializer->args_count)
517 d3dcompiler_free(initializer->args);
518 return;
520 if (components_count_type(field->type) == components_count_type(node->data_type))
522 deref = new_record_deref(&new_var_deref(var)->node, field);
523 if (!deref)
525 ERR("Out of memory.\n");
526 break;
528 deref->node.loc = node->loc;
529 assignment = make_assignment(&deref->node, ASSIGN_OP_ASSIGN, BWRITERSP_WRITEMASK_ALL, node);
530 list_add_tail(list, &assignment->entry);
532 else
533 FIXME("Initializing with \"mismatched\" fields is not supported yet.\n");
536 /* Free initializer elements in excess. */
537 for (; i < initializer->args_count; ++i)
538 free_instr(initializer->args[i]);
539 d3dcompiler_free(initializer->args);
542 static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list)
544 struct hlsl_type *type;
545 struct parse_variable_def *v, *v_next;
546 struct hlsl_ir_var *var;
547 struct hlsl_ir_node *assignment;
548 BOOL ret, local = TRUE;
549 struct list *statements_list = d3dcompiler_alloc(sizeof(*statements_list));
551 if (!statements_list)
553 ERR("Out of memory.\n");
554 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
555 d3dcompiler_free(v);
556 d3dcompiler_free(var_list);
557 return NULL;
559 list_init(statements_list);
561 if (!var_list)
562 return statements_list;
564 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
566 var = d3dcompiler_alloc(sizeof(*var));
567 if (!var)
569 ERR("Out of memory.\n");
570 d3dcompiler_free(v);
571 continue;
573 if (v->array_size)
574 type = new_array_type(basic_type, v->array_size);
575 else
576 type = basic_type;
577 var->data_type = type;
578 var->loc = v->loc;
579 var->name = v->name;
580 var->modifiers = modifiers;
581 var->semantic = v->semantic;
582 var->reg_reservation = v->reg_reservation;
583 debug_dump_decl(type, modifiers, v->name, v->loc.line);
585 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
587 var->modifiers |= HLSL_STORAGE_UNIFORM;
588 local = FALSE;
591 if (var->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer.args_count)
593 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col,
594 HLSL_LEVEL_ERROR, "const variable without initializer");
595 free_declaration(var);
596 d3dcompiler_free(v);
597 continue;
600 ret = declare_variable(var, local);
601 if (!ret)
603 free_declaration(var);
604 d3dcompiler_free(v);
605 continue;
607 TRACE("Declared variable %s.\n", var->name);
609 if (v->initializer.args_count)
611 unsigned int size = initializer_size(&v->initializer);
613 TRACE("Variable with initializer.\n");
614 if (type->type <= HLSL_CLASS_LAST_NUMERIC
615 && type->dimx * type->dimy != size && size != 1)
617 if (size < type->dimx * type->dimy)
619 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
620 "'%s' initializer does not match", v->name);
621 free_parse_initializer(&v->initializer);
622 d3dcompiler_free(v);
623 continue;
626 if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY)
627 && components_count_type(type) != size)
629 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
630 "'%s' initializer does not match", v->name);
631 free_parse_initializer(&v->initializer);
632 d3dcompiler_free(v);
633 continue;
636 if (type->type == HLSL_CLASS_STRUCT)
638 struct_var_initializer(statements_list, var, &v->initializer);
639 d3dcompiler_free(v);
640 continue;
642 if (type->type > HLSL_CLASS_LAST_NUMERIC)
644 FIXME("Initializers for non scalar/struct variables not supported yet.\n");
645 free_parse_initializer(&v->initializer);
646 d3dcompiler_free(v);
647 continue;
649 if (v->array_size > 0)
651 FIXME("Initializing arrays is not supported yet.\n");
652 free_parse_initializer(&v->initializer);
653 d3dcompiler_free(v);
654 continue;
656 if (v->initializer.args_count > 1)
658 FIXME("Complex initializers are not supported yet.\n");
659 free_parse_initializer(&v->initializer);
660 d3dcompiler_free(v);
661 continue;
664 assignment = make_assignment(&new_var_deref(var)->node, ASSIGN_OP_ASSIGN,
665 BWRITERSP_WRITEMASK_ALL, v->initializer.args[0]);
666 d3dcompiler_free(v->initializer.args);
667 list_add_tail(statements_list, &assignment->entry);
669 d3dcompiler_free(v);
671 d3dcompiler_free(var_list);
672 return statements_list;
675 static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field)
677 struct hlsl_struct_field *f;
679 LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry)
681 if (!strcmp(f->name, field->name))
682 return FALSE;
684 list_add_tail(fields, &field->entry);
685 return TRUE;
688 static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, struct list *fields)
690 struct parse_variable_def *v, *v_next;
691 struct hlsl_struct_field *field;
692 struct list *list;
694 list = d3dcompiler_alloc(sizeof(*list));
695 if (!list)
697 ERR("Out of memory.\n");
698 return NULL;
700 list_init(list);
701 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry)
703 debug_dump_decl(type, 0, v->name, v->loc.line);
704 field = d3dcompiler_alloc(sizeof(*field));
705 if (!field)
707 ERR("Out of memory.\n");
708 d3dcompiler_free(v);
709 return list;
711 field->type = type;
712 field->name = v->name;
713 field->modifiers = modifiers;
714 field->semantic = v->semantic;
715 if (v->initializer.args_count)
717 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
718 "struct field with an initializer.\n");
719 free_parse_initializer(&v->initializer);
721 list_add_tail(list, &field->entry);
722 d3dcompiler_free(v);
724 d3dcompiler_free(fields);
725 return list;
728 static struct hlsl_type *new_struct_type(const char *name, DWORD modifiers, struct list *fields)
730 struct hlsl_type *type = d3dcompiler_alloc(sizeof(*type));
732 if (!type)
734 ERR("Out of memory.\n");
735 return NULL;
737 type->type = HLSL_CLASS_STRUCT;
738 type->name = name;
739 type->dimx = type->dimy = 1;
740 type->modifiers = modifiers;
741 type->e.elements = fields;
743 list_add_tail(&hlsl_ctx.types, &type->entry);
745 return type;
748 static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list,
749 struct source_location *loc)
751 BOOL ret;
752 struct hlsl_type *type;
753 struct parse_variable_def *v, *v_next;
755 if (!check_type_modifiers(modifiers, loc))
757 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
758 d3dcompiler_free(v);
759 d3dcompiler_free(list);
760 return FALSE;
763 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
765 if (v->array_size)
766 type = new_array_type(orig_type, v->array_size);
767 else
768 type = clone_hlsl_type(orig_type);
769 if (!type)
771 ERR("Out of memory\n");
772 return FALSE;
774 d3dcompiler_free((void *)type->name);
775 type->name = v->name;
776 type->modifiers |= modifiers;
778 if (type->type != HLSL_CLASS_MATRIX)
779 check_invalid_matrix_modifiers(type->modifiers, &v->loc);
781 ret = add_type_to_scope(hlsl_ctx.cur_scope, type);
782 if (!ret)
784 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
785 "redefinition of custom type '%s'", v->name);
787 d3dcompiler_free(v);
789 d3dcompiler_free(list);
790 return TRUE;
793 static BOOL add_func_parameter(struct list *list, struct parse_parameter *param, const struct source_location *loc)
795 struct hlsl_ir_var *decl = d3dcompiler_alloc(sizeof(*decl));
797 if (!decl)
799 ERR("Out of memory.\n");
800 return FALSE;
802 decl->data_type = param->type;
803 decl->loc = *loc;
804 decl->name = param->name;
805 decl->semantic = param->semantic;
806 decl->reg_reservation = param->reg_reservation;
807 decl->modifiers = param->modifiers;
809 if (!add_declaration(hlsl_ctx.cur_scope, decl, FALSE))
811 free_declaration(decl);
812 return FALSE;
814 list_add_tail(list, &decl->param_entry);
815 return TRUE;
818 static struct reg_reservation *parse_reg_reservation(const char *reg_string)
820 struct reg_reservation *reg_res;
821 enum bwritershader_param_register_type type;
822 DWORD regnum = 0;
824 switch (reg_string[0])
826 case 'c':
827 type = BWRITERSPR_CONST;
828 break;
829 case 'i':
830 type = BWRITERSPR_CONSTINT;
831 break;
832 case 'b':
833 type = BWRITERSPR_CONSTBOOL;
834 break;
835 case 's':
836 type = BWRITERSPR_SAMPLER;
837 break;
838 default:
839 FIXME("Unsupported register type.\n");
840 return NULL;
843 if (!sscanf(reg_string + 1, "%u", &regnum))
845 FIXME("Unsupported register reservation syntax.\n");
846 return NULL;
849 reg_res = d3dcompiler_alloc(sizeof(*reg_res));
850 if (!reg_res)
852 ERR("Out of memory.\n");
853 return NULL;
855 reg_res->type = type;
856 reg_res->regnum = regnum;
857 return reg_res;
860 static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tree *funcs, char *name,
861 struct list *params, BOOL exact_signature)
863 struct hlsl_ir_function *func;
864 struct wine_rb_entry *entry;
866 entry = wine_rb_get(funcs, name);
867 if (entry)
869 func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
871 entry = wine_rb_get(&func->overloads, params);
872 if (!entry)
874 if (!exact_signature)
875 FIXME("No exact match, search for a compatible overloaded function (if any).\n");
876 return NULL;
878 return WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
880 return NULL;
885 %locations
886 %define parse.error verbose
887 %expect 1
889 %union
891 struct hlsl_type *type;
892 INT intval;
893 FLOAT floatval;
894 BOOL boolval;
895 char *name;
896 DWORD modifiers;
897 struct hlsl_ir_node *instr;
898 struct list *list;
899 struct parse_function function;
900 struct parse_parameter parameter;
901 struct parse_initializer initializer;
902 struct parse_variable_def *variable_def;
903 struct parse_if_body if_body;
904 enum parse_unary_op unary_op;
905 enum parse_assign_op assign_op;
906 struct reg_reservation *reg_reservation;
907 struct parse_colon_attribute colon_attribute;
910 %token KW_BLENDSTATE
911 %token KW_BREAK
912 %token KW_BUFFER
913 %token KW_CBUFFER
914 %token KW_COLUMN_MAJOR
915 %token KW_COMPILE
916 %token KW_CONST
917 %token KW_CONTINUE
918 %token KW_DEPTHSTENCILSTATE
919 %token KW_DEPTHSTENCILVIEW
920 %token KW_DISCARD
921 %token KW_DO
922 %token KW_DOUBLE
923 %token KW_ELSE
924 %token KW_EXTERN
925 %token KW_FALSE
926 %token KW_FOR
927 %token KW_GEOMETRYSHADER
928 %token KW_GROUPSHARED
929 %token KW_IF
930 %token KW_IN
931 %token KW_INLINE
932 %token KW_INOUT
933 %token KW_MATRIX
934 %token KW_NAMESPACE
935 %token KW_NOINTERPOLATION
936 %token KW_OUT
937 %token KW_PASS
938 %token KW_PIXELSHADER
939 %token KW_PRECISE
940 %token KW_RASTERIZERSTATE
941 %token KW_RENDERTARGETVIEW
942 %token KW_RETURN
943 %token KW_REGISTER
944 %token KW_ROW_MAJOR
945 %token KW_SAMPLER
946 %token KW_SAMPLER1D
947 %token KW_SAMPLER2D
948 %token KW_SAMPLER3D
949 %token KW_SAMPLERCUBE
950 %token KW_SAMPLER_STATE
951 %token KW_SAMPLERCOMPARISONSTATE
952 %token KW_SHARED
953 %token KW_STATEBLOCK
954 %token KW_STATEBLOCK_STATE
955 %token KW_STATIC
956 %token KW_STRING
957 %token KW_STRUCT
958 %token KW_SWITCH
959 %token KW_TBUFFER
960 %token KW_TECHNIQUE
961 %token KW_TECHNIQUE10
962 %token KW_TEXTURE
963 %token KW_TEXTURE1D
964 %token KW_TEXTURE1DARRAY
965 %token KW_TEXTURE2D
966 %token KW_TEXTURE2DARRAY
967 %token KW_TEXTURE2DMS
968 %token KW_TEXTURE2DMSARRAY
969 %token KW_TEXTURE3D
970 %token KW_TEXTURE3DARRAY
971 %token KW_TEXTURECUBE
972 %token KW_TRUE
973 %token KW_TYPEDEF
974 %token KW_UNIFORM
975 %token KW_VECTOR
976 %token KW_VERTEXSHADER
977 %token KW_VOID
978 %token KW_VOLATILE
979 %token KW_WHILE
981 %token OP_INC
982 %token OP_DEC
983 %token OP_AND
984 %token OP_OR
985 %token OP_EQ
986 %token OP_LEFTSHIFT
987 %token OP_LEFTSHIFTASSIGN
988 %token OP_RIGHTSHIFT
989 %token OP_RIGHTSHIFTASSIGN
990 %token OP_ELLIPSIS
991 %token OP_LE
992 %token OP_GE
993 %token OP_NE
994 %token OP_ADDASSIGN
995 %token OP_SUBASSIGN
996 %token OP_MULASSIGN
997 %token OP_DIVASSIGN
998 %token OP_MODASSIGN
999 %token OP_ANDASSIGN
1000 %token OP_ORASSIGN
1001 %token OP_XORASSIGN
1002 %token OP_UNKNOWN1
1003 %token OP_UNKNOWN2
1004 %token OP_UNKNOWN3
1005 %token OP_UNKNOWN4
1007 %token <intval> PRE_LINE
1009 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
1010 %type <name> any_identifier var_identifier
1011 %token <name> STRING
1012 %token <floatval> C_FLOAT
1013 %token <intval> C_INTEGER
1014 %type <boolval> boolean
1015 %type <type> base_type
1016 %type <type> type
1017 %type <list> declaration_statement
1018 %type <list> declaration
1019 %type <list> struct_declaration
1020 %type <type> struct_spec
1021 %type <type> named_struct_spec
1022 %type <type> unnamed_struct_spec
1023 %type <list> type_specs
1024 %type <variable_def> type_spec
1025 %type <initializer> complex_initializer
1026 %type <initializer> initializer_expr_list
1027 %type <instr> initializer_expr
1028 %type <modifiers> var_modifiers
1029 %type <list> field
1030 %type <list> parameters
1031 %type <list> param_list
1032 %type <instr> expr
1033 %type <intval> array
1034 %type <list> statement
1035 %type <list> statement_list
1036 %type <list> compound_statement
1037 %type <list> jump_statement
1038 %type <list> selection_statement
1039 %type <list> loop_statement
1040 %type <function> func_declaration
1041 %type <function> func_prototype
1042 %type <list> fields_list
1043 %type <parameter> parameter
1044 %type <colon_attribute> colon_attribute
1045 %type <name> semantic
1046 %type <reg_reservation> register_opt
1047 %type <variable_def> variable_def
1048 %type <list> variables_def
1049 %type <list> variables_def_optional
1050 %type <if_body> if_body
1051 %type <instr> primary_expr
1052 %type <instr> postfix_expr
1053 %type <instr> unary_expr
1054 %type <instr> mul_expr
1055 %type <instr> add_expr
1056 %type <instr> shift_expr
1057 %type <instr> relational_expr
1058 %type <instr> equality_expr
1059 %type <instr> bitand_expr
1060 %type <instr> bitxor_expr
1061 %type <instr> bitor_expr
1062 %type <instr> logicand_expr
1063 %type <instr> logicor_expr
1064 %type <instr> conditional_expr
1065 %type <instr> assignment_expr
1066 %type <list> expr_statement
1067 %type <unary_op> unary_op
1068 %type <assign_op> assign_op
1069 %type <modifiers> input_mods
1070 %type <modifiers> input_mod
1073 hlsl_prog: /* empty */
1076 | hlsl_prog func_declaration
1078 const struct hlsl_ir_function_decl *decl;
1080 decl = get_overloaded_func(&hlsl_ctx.functions, $2.name, $2.decl->parameters, TRUE);
1081 if (decl && !decl->func->intrinsic)
1083 if (decl->body && $2.decl->body)
1085 hlsl_report_message($2.decl->loc.file, $2.decl->loc.line,
1086 $2.decl->loc.col, HLSL_LEVEL_ERROR,
1087 "redefinition of function %s", debugstr_a($2.name));
1088 YYABORT;
1090 else if (!compare_hlsl_types(decl->return_type, $2.decl->return_type))
1092 hlsl_report_message($2.decl->loc.file, $2.decl->loc.line,
1093 $2.decl->loc.col, HLSL_LEVEL_ERROR,
1094 "redefining function %s with a different return type",
1095 debugstr_a($2.name));
1096 hlsl_report_message(decl->loc.file, decl->loc.line, decl->loc.col, HLSL_LEVEL_NOTE,
1097 "%s previously declared here",
1098 debugstr_a($2.name));
1099 YYABORT;
1103 if ($2.decl->return_type->base_type == HLSL_TYPE_VOID && $2.decl->semantic)
1105 hlsl_report_message($2.decl->loc.file, $2.decl->loc.line,
1106 $2.decl->loc.col, HLSL_LEVEL_ERROR,
1107 "void function with a semantic");
1110 TRACE("Adding function '%s' to the function list.\n", $2.name);
1111 add_function_decl(&hlsl_ctx.functions, $2.name, $2.decl, FALSE);
1113 | hlsl_prog declaration_statement
1115 TRACE("Declaration statement parsed.\n");
1117 | hlsl_prog preproc_directive
1120 | hlsl_prog ';'
1122 TRACE("Skipping stray semicolon.\n");
1125 preproc_directive: PRE_LINE STRING
1127 const char **new_array = NULL;
1129 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
1130 hlsl_ctx.line_no = $1;
1131 if (strcmp($2, hlsl_ctx.source_file))
1132 new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
1133 sizeof(*hlsl_ctx.source_files) * (hlsl_ctx.source_files_count + 1));
1135 if (new_array)
1137 hlsl_ctx.source_files = new_array;
1138 hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
1139 hlsl_ctx.source_file = $2;
1141 else
1143 d3dcompiler_free($2);
1147 struct_declaration: struct_spec variables_def_optional ';'
1149 struct source_location loc;
1151 set_location(&loc, &@3);
1152 if (!$2)
1154 if (!$1->name)
1156 hlsl_report_message(loc.file, loc.line, loc.col,
1157 HLSL_LEVEL_ERROR, "anonymous struct declaration with no variables");
1159 check_type_modifiers($1->modifiers, &loc);
1161 $$ = declare_vars($1, 0, $2);
1164 struct_spec: named_struct_spec
1165 | unnamed_struct_spec
1167 named_struct_spec: var_modifiers KW_STRUCT any_identifier '{' fields_list '}'
1169 BOOL ret;
1170 struct source_location loc;
1172 TRACE("Structure %s declaration.\n", debugstr_a($3));
1173 set_location(&loc, &@1);
1174 check_invalid_matrix_modifiers($1, &loc);
1175 $$ = new_struct_type($3, $1, $5);
1177 if (get_variable(hlsl_ctx.cur_scope, $3))
1179 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1180 HLSL_LEVEL_ERROR, "redefinition of '%s'", $3);
1181 YYABORT;
1184 ret = add_type_to_scope(hlsl_ctx.cur_scope, $$);
1185 if (!ret)
1187 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1188 HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $3);
1189 YYABORT;
1193 unnamed_struct_spec: var_modifiers KW_STRUCT '{' fields_list '}'
1195 struct source_location loc;
1197 TRACE("Anonymous structure declaration.\n");
1198 set_location(&loc, &@1);
1199 check_invalid_matrix_modifiers($1, &loc);
1200 $$ = new_struct_type(NULL, $1, $4);
1203 any_identifier: VAR_IDENTIFIER
1204 | TYPE_IDENTIFIER
1205 | NEW_IDENTIFIER
1207 fields_list: /* Empty */
1209 $$ = d3dcompiler_alloc(sizeof(*$$));
1210 list_init($$);
1212 | fields_list field
1214 BOOL ret;
1215 struct hlsl_struct_field *field, *next;
1217 $$ = $1;
1218 LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry)
1220 ret = add_struct_field($$, field);
1221 if (ret == FALSE)
1223 hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1224 HLSL_LEVEL_ERROR, "redefinition of '%s'", field->name);
1225 d3dcompiler_free(field);
1228 d3dcompiler_free($2);
1231 field: var_modifiers type variables_def ';'
1233 $$ = gen_struct_fields($2, $1, $3);
1235 | unnamed_struct_spec variables_def ';'
1237 $$ = gen_struct_fields($1, 0, $2);
1240 func_declaration: func_prototype compound_statement
1242 TRACE("Function %s parsed.\n", $1.name);
1243 $$ = $1;
1244 $$.decl->body = $2;
1245 pop_scope(&hlsl_ctx);
1247 | func_prototype ';'
1249 TRACE("Function prototype for %s.\n", $1.name);
1250 $$ = $1;
1251 pop_scope(&hlsl_ctx);
1254 func_prototype: var_modifiers type var_identifier '(' parameters ')' colon_attribute
1256 if (get_variable(hlsl_ctx.globals, $3))
1258 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1259 HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
1260 YYABORT;
1262 if ($2->base_type == HLSL_TYPE_VOID && $7.semantic)
1264 hlsl_report_message(hlsl_ctx.source_file, @7.first_line, @7.first_column,
1265 HLSL_LEVEL_ERROR, "void function with a semantic");
1268 if ($7.reg_reservation)
1270 FIXME("Unexpected register reservation for a function.\n");
1271 d3dcompiler_free($7.reg_reservation);
1273 $$.decl = new_func_decl($2, $5);
1274 if (!$$.decl)
1276 ERR("Out of memory.\n");
1277 YYABORT;
1279 $$.name = $3;
1280 $$.decl->semantic = $7.semantic;
1281 set_location(&$$.decl->loc, &@3);
1284 compound_statement: '{' '}'
1286 $$ = d3dcompiler_alloc(sizeof(*$$));
1287 list_init($$);
1289 | '{' scope_start statement_list '}'
1291 pop_scope(&hlsl_ctx);
1292 $$ = $3;
1295 scope_start: /* Empty */
1297 push_scope(&hlsl_ctx);
1300 var_identifier: VAR_IDENTIFIER
1301 | NEW_IDENTIFIER
1303 colon_attribute: /* Empty */
1305 $$.semantic = NULL;
1306 $$.reg_reservation = NULL;
1308 | semantic
1310 $$.semantic = $1;
1311 $$.reg_reservation = NULL;
1313 | register_opt
1315 $$.semantic = NULL;
1316 $$.reg_reservation = $1;
1319 semantic: ':' any_identifier
1321 $$ = $2;
1324 /* FIXME: Writemasks */
1325 register_opt: ':' KW_REGISTER '(' any_identifier ')'
1327 $$ = parse_reg_reservation($4);
1328 d3dcompiler_free($4);
1330 | ':' KW_REGISTER '(' any_identifier ',' any_identifier ')'
1332 FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a($4));
1333 d3dcompiler_free($4);
1335 $$ = parse_reg_reservation($6);
1336 d3dcompiler_free($6);
1339 parameters: scope_start
1341 $$ = d3dcompiler_alloc(sizeof(*$$));
1342 list_init($$);
1344 | scope_start param_list
1346 $$ = $2;
1349 param_list: parameter
1351 struct source_location loc;
1353 $$ = d3dcompiler_alloc(sizeof(*$$));
1354 list_init($$);
1355 set_location(&loc, &@1);
1356 if (!add_func_parameter($$, &$1, &loc))
1358 ERR("Error adding function parameter %s.\n", $1.name);
1359 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1360 YYABORT;
1363 | param_list ',' parameter
1365 struct source_location loc;
1367 $$ = $1;
1368 set_location(&loc, &@3);
1369 if (!add_func_parameter($$, &$3, &loc))
1371 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1372 "duplicate parameter %s", $3.name);
1373 YYABORT;
1377 parameter: input_mods var_modifiers type any_identifier colon_attribute
1379 $$.modifiers = $1 ? $1 : HLSL_MODIFIER_IN;
1380 $$.modifiers |= $2;
1381 $$.type = $3;
1382 $$.name = $4;
1383 $$.semantic = $5.semantic;
1384 $$.reg_reservation = $5.reg_reservation;
1387 input_mods: /* Empty */
1389 $$ = 0;
1391 | input_mods input_mod
1393 if ($1 & $2)
1395 hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1396 HLSL_LEVEL_ERROR, "duplicate input-output modifiers");
1397 YYABORT;
1399 $$ = $1 | $2;
1402 input_mod: KW_IN
1404 $$ = HLSL_MODIFIER_IN;
1406 | KW_OUT
1408 $$ = HLSL_MODIFIER_OUT;
1410 | KW_INOUT
1412 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
1415 type: base_type
1417 $$ = $1;
1419 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
1421 if ($3->type != HLSL_CLASS_SCALAR)
1423 hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
1424 hlsl_ctx.line_no);
1425 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1426 YYABORT;
1428 if ($5 < 1 || $5 > 4)
1430 hlsl_message("Line %u: vector size must be between 1 and 4.\n",
1431 hlsl_ctx.line_no);
1432 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1433 YYABORT;
1436 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
1438 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
1440 if ($3->type != HLSL_CLASS_SCALAR)
1442 hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
1443 hlsl_ctx.line_no);
1444 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1445 YYABORT;
1447 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
1449 hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
1450 hlsl_ctx.line_no);
1451 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1452 YYABORT;
1455 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
1458 base_type: KW_VOID
1460 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
1462 | KW_SAMPLER
1464 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1465 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
1467 | KW_SAMPLER1D
1469 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1470 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
1472 | KW_SAMPLER2D
1474 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1475 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
1477 | KW_SAMPLER3D
1479 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1480 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
1482 | KW_SAMPLERCUBE
1484 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1485 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
1487 | TYPE_IDENTIFIER
1489 struct hlsl_type *type;
1491 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
1492 $$ = type;
1493 d3dcompiler_free($1);
1495 | KW_STRUCT TYPE_IDENTIFIER
1497 struct hlsl_type *type;
1499 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
1500 if (type->type != HLSL_CLASS_STRUCT)
1502 hlsl_message("Line %u: redefining %s as a structure.\n",
1503 hlsl_ctx.line_no, $2);
1504 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1506 else
1508 $$ = type;
1510 d3dcompiler_free($2);
1513 declaration_statement: declaration
1514 | struct_declaration
1515 | typedef
1517 $$ = d3dcompiler_alloc(sizeof(*$$));
1518 if (!$$)
1520 ERR("Out of memory\n");
1521 YYABORT;
1523 list_init($$);
1526 typedef: KW_TYPEDEF var_modifiers type type_specs ';'
1528 struct source_location loc;
1530 set_location(&loc, &@1);
1531 if (!add_typedef($2, $3, $4, &loc))
1532 YYABORT;
1534 | KW_TYPEDEF struct_spec type_specs ';'
1536 struct source_location loc;
1538 set_location(&loc, &@1);
1539 if (!add_typedef(0, $2, $3, &loc))
1540 YYABORT;
1543 type_specs: type_spec
1545 $$ = d3dcompiler_alloc(sizeof(*$$));
1546 list_init($$);
1547 list_add_head($$, &$1->entry);
1549 | type_specs ',' type_spec
1551 $$ = $1;
1552 list_add_tail($$, &$3->entry);
1555 type_spec: any_identifier array
1557 $$ = d3dcompiler_alloc(sizeof(*$$));
1558 set_location(&$$->loc, &@1);
1559 $$->name = $1;
1560 $$->array_size = $2;
1563 declaration: var_modifiers type variables_def ';'
1565 $$ = declare_vars($2, $1, $3);
1568 variables_def_optional: /* Empty */
1570 $$ = NULL;
1572 | variables_def
1574 $$ = $1;
1577 variables_def: variable_def
1579 $$ = d3dcompiler_alloc(sizeof(*$$));
1580 list_init($$);
1581 list_add_head($$, &$1->entry);
1583 | variables_def ',' variable_def
1585 $$ = $1;
1586 list_add_tail($$, &$3->entry);
1589 variable_def: any_identifier array colon_attribute
1591 $$ = d3dcompiler_alloc(sizeof(*$$));
1592 set_location(&$$->loc, &@1);
1593 $$->name = $1;
1594 $$->array_size = $2;
1595 $$->semantic = $3.semantic;
1596 $$->reg_reservation = $3.reg_reservation;
1598 | any_identifier array colon_attribute '=' complex_initializer
1600 TRACE("Declaration with initializer.\n");
1601 $$ = d3dcompiler_alloc(sizeof(*$$));
1602 set_location(&$$->loc, &@1);
1603 $$->name = $1;
1604 $$->array_size = $2;
1605 $$->semantic = $3.semantic;
1606 $$->reg_reservation = $3.reg_reservation;
1607 $$->initializer = $5;
1610 array: /* Empty */
1612 $$ = 0;
1614 | '[' expr ']'
1616 FIXME("Array.\n");
1617 $$ = 0;
1618 free_instr($2);
1621 var_modifiers: /* Empty */
1623 $$ = 0;
1625 | KW_EXTERN var_modifiers
1627 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
1629 | KW_NOINTERPOLATION var_modifiers
1631 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
1633 | KW_PRECISE var_modifiers
1635 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
1637 | KW_SHARED var_modifiers
1639 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
1641 | KW_GROUPSHARED var_modifiers
1643 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
1645 | KW_STATIC var_modifiers
1647 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
1649 | KW_UNIFORM var_modifiers
1651 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
1653 | KW_VOLATILE var_modifiers
1655 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
1657 | KW_CONST var_modifiers
1659 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
1661 | KW_ROW_MAJOR var_modifiers
1663 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
1665 | KW_COLUMN_MAJOR var_modifiers
1667 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
1670 complex_initializer: initializer_expr
1672 $$.args_count = 1;
1673 if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args))))
1674 YYABORT;
1675 $$.args[0] = $1;
1677 | '{' initializer_expr_list '}'
1679 $$ = $2;
1681 | '{' initializer_expr_list ',' '}'
1683 $$ = $2;
1686 initializer_expr: assignment_expr
1688 $$ = $1;
1691 initializer_expr_list: initializer_expr
1693 $$.args_count = 1;
1694 if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args))))
1695 YYABORT;
1696 $$.args[0] = $1;
1698 | initializer_expr_list ',' initializer_expr
1700 $$ = $1;
1701 if (!($$.args = d3dcompiler_realloc($$.args, ($$.args_count + 1) * sizeof(*$$.args))))
1702 YYABORT;
1703 $$.args[$$.args_count++] = $3;
1706 boolean: KW_TRUE
1708 $$ = TRUE;
1710 | KW_FALSE
1712 $$ = FALSE;
1715 statement_list: statement
1717 $$ = $1;
1719 | statement_list statement
1721 $$ = $1;
1722 list_move_tail($$, $2);
1723 d3dcompiler_free($2);
1726 statement: declaration_statement
1727 | expr_statement
1728 | compound_statement
1729 | jump_statement
1730 | selection_statement
1731 | loop_statement
1733 /* FIXME: add rule for return with no value */
1734 jump_statement: KW_RETURN expr ';'
1736 struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump));
1737 if (!jump)
1739 ERR("Out of memory\n");
1740 YYABORT;
1742 jump->node.type = HLSL_IR_JUMP;
1743 set_location(&jump->node.loc, &@1);
1744 jump->type = HLSL_IR_JUMP_RETURN;
1745 jump->node.data_type = $2->data_type;
1746 jump->return_value = $2;
1748 FIXME("Check for valued return on void function.\n");
1749 FIXME("Implicit conversion to the return type if needed, "
1750 "error out if conversion not possible.\n");
1752 $$ = d3dcompiler_alloc(sizeof(*$$));
1753 list_init($$);
1754 list_add_tail($$, &jump->node.entry);
1757 selection_statement: KW_IF '(' expr ')' if_body
1759 struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
1760 if (!instr)
1762 ERR("Out of memory\n");
1763 YYABORT;
1765 instr->node.type = HLSL_IR_IF;
1766 set_location(&instr->node.loc, &@1);
1767 instr->condition = $3;
1768 instr->then_instrs = $5.then_instrs;
1769 instr->else_instrs = $5.else_instrs;
1770 if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1)
1772 hlsl_report_message(instr->node.loc.file, instr->node.loc.line,
1773 instr->node.loc.col, HLSL_LEVEL_ERROR,
1774 "if condition requires a scalar");
1776 $$ = d3dcompiler_alloc(sizeof(*$$));
1777 list_init($$);
1778 list_add_head($$, &instr->node.entry);
1781 if_body: statement
1783 $$.then_instrs = $1;
1784 $$.else_instrs = NULL;
1786 | statement KW_ELSE statement
1788 $$.then_instrs = $1;
1789 $$.else_instrs = $3;
1792 loop_statement: KW_WHILE '(' expr ')' statement
1794 struct source_location loc;
1795 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1797 if (!cond)
1799 ERR("Out of memory.\n");
1800 YYABORT;
1802 list_init(cond);
1803 list_add_head(cond, &$3->entry);
1804 set_location(&loc, &@1);
1805 $$ = create_loop(LOOP_WHILE, NULL, cond, NULL, $5, &loc);
1807 | KW_DO statement KW_WHILE '(' expr ')' ';'
1809 struct source_location loc;
1810 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1812 if (!cond)
1814 ERR("Out of memory.\n");
1815 YYABORT;
1817 list_init(cond);
1818 list_add_head(cond, &$5->entry);
1819 set_location(&loc, &@1);
1820 $$ = create_loop(LOOP_DO_WHILE, NULL, cond, NULL, $2, &loc);
1822 | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
1824 struct source_location loc;
1826 set_location(&loc, &@1);
1827 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1828 pop_scope(&hlsl_ctx);
1830 | KW_FOR '(' scope_start declaration expr_statement expr ')' statement
1832 struct source_location loc;
1834 set_location(&loc, &@1);
1835 if (!$4)
1836 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_WARNING,
1837 "no expressions in for loop initializer");
1838 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1839 pop_scope(&hlsl_ctx);
1842 expr_statement: ';'
1844 $$ = d3dcompiler_alloc(sizeof(*$$));
1845 list_init($$);
1847 | expr ';'
1849 $$ = d3dcompiler_alloc(sizeof(*$$));
1850 list_init($$);
1851 if ($1)
1852 list_add_head($$, &$1->entry);
1855 primary_expr: C_FLOAT
1857 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1858 if (!c)
1860 ERR("Out of memory.\n");
1861 YYABORT;
1863 c->node.type = HLSL_IR_CONSTANT;
1864 set_location(&c->node.loc, &yylloc);
1865 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("float"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
1866 c->v.value.f[0] = $1;
1867 $$ = &c->node;
1869 | C_INTEGER
1871 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1872 if (!c)
1874 ERR("Out of memory.\n");
1875 YYABORT;
1877 c->node.type = HLSL_IR_CONSTANT;
1878 set_location(&c->node.loc, &yylloc);
1879 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("int"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
1880 c->v.value.i[0] = $1;
1881 $$ = &c->node;
1883 | boolean
1885 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1886 if (!c)
1888 ERR("Out of memory.\n");
1889 YYABORT;
1891 c->node.type = HLSL_IR_CONSTANT;
1892 set_location(&c->node.loc, &yylloc);
1893 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("bool"), HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
1894 c->v.value.b[0] = $1;
1895 $$ = &c->node;
1897 | VAR_IDENTIFIER
1899 struct hlsl_ir_deref *deref;
1900 struct hlsl_ir_var *var;
1902 if (!(var = get_variable(hlsl_ctx.cur_scope, $1)))
1904 hlsl_message("Line %d: variable '%s' not declared\n",
1905 hlsl_ctx.line_no, $1);
1906 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1907 YYABORT;
1909 if ((deref = new_var_deref(var)))
1911 $$ = &deref->node;
1912 set_location(&$$->loc, &@1);
1914 else
1915 $$ = NULL;
1917 | '(' expr ')'
1919 $$ = $2;
1922 postfix_expr: primary_expr
1924 $$ = $1;
1926 | postfix_expr OP_INC
1928 struct source_location loc;
1930 set_location(&loc, &@2);
1931 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1933 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1934 "modifying a const expression");
1935 YYABORT;
1937 $$ = new_unary_expr(HLSL_IR_UNOP_POSTINC, $1, loc);
1938 /* Post increment/decrement expressions are considered const */
1939 $$->data_type = clone_hlsl_type($$->data_type);
1940 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1942 | postfix_expr OP_DEC
1944 struct source_location loc;
1946 set_location(&loc, &@2);
1947 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1949 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1950 "modifying a const expression");
1951 YYABORT;
1953 $$ = new_unary_expr(HLSL_IR_UNOP_POSTDEC, $1, loc);
1954 /* Post increment/decrement expressions are considered const */
1955 $$->data_type = clone_hlsl_type($$->data_type);
1956 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1958 | postfix_expr '.' any_identifier
1960 struct source_location loc;
1962 set_location(&loc, &@2);
1963 if ($1->data_type->type == HLSL_CLASS_STRUCT)
1965 struct hlsl_type *type = $1->data_type;
1966 struct hlsl_struct_field *field;
1968 $$ = NULL;
1969 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
1971 if (!strcmp($3, field->name))
1973 struct hlsl_ir_deref *deref = new_record_deref($1, field);
1975 if (!deref)
1977 ERR("Out of memory\n");
1978 YYABORT;
1980 deref->node.loc = loc;
1981 $$ = &deref->node;
1982 break;
1985 if (!$$)
1987 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1988 "invalid subscript %s", debugstr_a($3));
1989 YYABORT;
1992 else if ($1->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
1994 struct hlsl_ir_swizzle *swizzle;
1996 swizzle = get_swizzle($1, $3, &loc);
1997 if (!swizzle)
1999 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2000 "invalid swizzle %s", debugstr_a($3));
2001 YYABORT;
2003 $$ = &swizzle->node;
2005 else
2007 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2008 "invalid subscript %s", debugstr_a($3));
2009 YYABORT;
2012 | postfix_expr '[' expr ']'
2014 /* This may be an array dereference or a vector/matrix
2015 * subcomponent access.
2016 * We store it as an array dereference in any case. */
2017 struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
2018 struct hlsl_type *expr_type = $1->data_type;
2019 struct source_location loc;
2021 TRACE("Array dereference from type %s\n", debug_hlsl_type(expr_type));
2022 if (!deref)
2024 ERR("Out of memory\n");
2025 YYABORT;
2027 deref->node.type = HLSL_IR_DEREF;
2028 set_location(&loc, &@2);
2029 deref->node.loc = loc;
2030 if (expr_type->type == HLSL_CLASS_ARRAY)
2032 deref->node.data_type = expr_type->e.array.type;
2034 else if (expr_type->type == HLSL_CLASS_MATRIX)
2036 deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, expr_type->base_type, expr_type->dimx, 1);
2038 else if (expr_type->type == HLSL_CLASS_VECTOR)
2040 deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_SCALAR, expr_type->base_type, 1, 1);
2042 else
2044 if (expr_type->type == HLSL_CLASS_SCALAR)
2045 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2046 "array-indexed expression is scalar");
2047 else
2048 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2049 "expression is not array-indexable");
2050 d3dcompiler_free(deref);
2051 free_instr($1);
2052 free_instr($3);
2053 YYABORT;
2055 if ($3->data_type->type != HLSL_CLASS_SCALAR)
2057 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2058 "array index is not scalar");
2059 d3dcompiler_free(deref);
2060 free_instr($1);
2061 free_instr($3);
2062 YYABORT;
2064 deref->type = HLSL_IR_DEREF_ARRAY;
2065 deref->v.array.array = $1;
2066 deref->v.array.index = $3;
2068 $$ = &deref->node;
2070 /* "var_modifiers" doesn't make sense in this case, but it's needed
2071 in the grammar to avoid shift/reduce conflicts. */
2072 | var_modifiers type '(' initializer_expr_list ')'
2074 struct hlsl_ir_constructor *constructor;
2076 TRACE("%s constructor.\n", debug_hlsl_type($2));
2077 if ($1)
2079 hlsl_message("Line %u: unexpected modifier in a constructor.\n",
2080 hlsl_ctx.line_no);
2081 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2082 YYABORT;
2084 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
2086 hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
2087 hlsl_ctx.line_no);
2088 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2089 YYABORT;
2091 if ($2->dimx * $2->dimy != initializer_size(&$4))
2093 hlsl_message("Line %u: wrong number of components in constructor.\n",
2094 hlsl_ctx.line_no);
2095 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2096 YYABORT;
2098 assert($4.args_count <= ARRAY_SIZE(constructor->args));
2100 constructor = d3dcompiler_alloc(sizeof(*constructor));
2101 constructor->node.type = HLSL_IR_CONSTRUCTOR;
2102 set_location(&constructor->node.loc, &@3);
2103 constructor->node.data_type = $2;
2104 constructor->args_count = $4.args_count;
2105 memcpy(constructor->args, $4.args, $4.args_count * sizeof(*$4.args));
2106 d3dcompiler_free($4.args);
2107 $$ = &constructor->node;
2110 unary_expr: postfix_expr
2112 $$ = $1;
2114 | OP_INC unary_expr
2116 struct source_location loc;
2118 set_location(&loc, &@1);
2119 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2121 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2122 "modifying a const expression");
2123 YYABORT;
2125 $$ = new_unary_expr(HLSL_IR_UNOP_PREINC, $2, loc);
2127 | OP_DEC unary_expr
2129 struct source_location loc;
2131 set_location(&loc, &@1);
2132 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2134 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2135 "modifying a const expression");
2136 YYABORT;
2138 $$ = new_unary_expr(HLSL_IR_UNOP_PREDEC, $2, loc);
2140 | unary_op unary_expr
2142 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
2143 HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
2144 struct source_location loc;
2146 if ($1 == UNARY_OP_PLUS)
2148 $$ = $2;
2150 else
2152 set_location(&loc, &@1);
2153 $$ = new_unary_expr(ops[$1], $2, loc);
2156 /* var_modifiers just to avoid shift/reduce conflicts */
2157 | '(' var_modifiers type array ')' unary_expr
2159 struct hlsl_ir_expr *expr;
2160 struct hlsl_type *src_type = $6->data_type;
2161 struct hlsl_type *dst_type;
2162 struct source_location loc;
2164 set_location(&loc, &@3);
2165 if ($2)
2167 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2168 "unexpected modifier in a cast");
2169 YYABORT;
2172 if ($4)
2173 dst_type = new_array_type($3, $4);
2174 else
2175 dst_type = $3;
2177 if (!compatible_data_types(src_type, dst_type))
2179 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2180 "can't cast from %s to %s",
2181 debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
2182 YYABORT;
2185 expr = new_cast($6, dst_type, &loc);
2186 $$ = expr ? &expr->node : NULL;
2189 unary_op: '+'
2191 $$ = UNARY_OP_PLUS;
2193 | '-'
2195 $$ = UNARY_OP_MINUS;
2197 | '!'
2199 $$ = UNARY_OP_LOGICNOT;
2201 | '~'
2203 $$ = UNARY_OP_BITNOT;
2206 mul_expr: unary_expr
2208 $$ = $1;
2210 | mul_expr '*' unary_expr
2212 struct source_location loc;
2214 set_location(&loc, &@2);
2215 $$ = new_binary_expr(HLSL_IR_BINOP_MUL, $1, $3, loc);
2217 | mul_expr '/' unary_expr
2219 struct source_location loc;
2221 set_location(&loc, &@2);
2222 $$ = new_binary_expr(HLSL_IR_BINOP_DIV, $1, $3, loc);
2224 | mul_expr '%' unary_expr
2226 struct source_location loc;
2228 set_location(&loc, &@2);
2229 $$ = new_binary_expr(HLSL_IR_BINOP_MOD, $1, $3, loc);
2232 add_expr: mul_expr
2234 $$ = $1;
2236 | add_expr '+' mul_expr
2238 struct source_location loc;
2240 set_location(&loc, &@2);
2241 $$ = new_binary_expr(HLSL_IR_BINOP_ADD, $1, $3, loc);
2243 | add_expr '-' mul_expr
2245 struct source_location loc;
2247 set_location(&loc, &@2);
2248 $$ = new_binary_expr(HLSL_IR_BINOP_SUB, $1, $3, loc);
2251 shift_expr: add_expr
2253 $$ = $1;
2255 | shift_expr OP_LEFTSHIFT add_expr
2257 FIXME("Left shift\n");
2259 | shift_expr OP_RIGHTSHIFT add_expr
2261 FIXME("Right shift\n");
2264 relational_expr: shift_expr
2266 $$ = $1;
2268 | relational_expr '<' shift_expr
2270 struct source_location loc;
2272 set_location(&loc, &@2);
2273 $$ = new_binary_expr(HLSL_IR_BINOP_LESS, $1, $3, loc);
2275 | relational_expr '>' shift_expr
2277 struct source_location loc;
2279 set_location(&loc, &@2);
2280 $$ = new_binary_expr(HLSL_IR_BINOP_GREATER, $1, $3, loc);
2282 | relational_expr OP_LE shift_expr
2284 struct source_location loc;
2286 set_location(&loc, &@2);
2287 $$ = new_binary_expr(HLSL_IR_BINOP_LEQUAL, $1, $3, loc);
2289 | relational_expr OP_GE shift_expr
2291 struct source_location loc;
2293 set_location(&loc, &@2);
2294 $$ = new_binary_expr(HLSL_IR_BINOP_GEQUAL, $1, $3, loc);
2297 equality_expr: relational_expr
2299 $$ = $1;
2301 | equality_expr OP_EQ relational_expr
2303 struct source_location loc;
2305 set_location(&loc, &@2);
2306 $$ = new_binary_expr(HLSL_IR_BINOP_EQUAL, $1, $3, loc);
2308 | equality_expr OP_NE relational_expr
2310 struct source_location loc;
2312 set_location(&loc, &@2);
2313 $$ = new_binary_expr(HLSL_IR_BINOP_NEQUAL, $1, $3, loc);
2316 bitand_expr: equality_expr
2318 $$ = $1;
2320 | bitand_expr '&' equality_expr
2322 FIXME("bitwise AND\n");
2325 bitxor_expr: bitand_expr
2327 $$ = $1;
2329 | bitxor_expr '^' bitand_expr
2331 FIXME("bitwise XOR\n");
2334 bitor_expr: bitxor_expr
2336 $$ = $1;
2338 | bitor_expr '|' bitxor_expr
2340 FIXME("bitwise OR\n");
2343 logicand_expr: bitor_expr
2345 $$ = $1;
2347 | logicand_expr OP_AND bitor_expr
2349 FIXME("logic AND\n");
2352 logicor_expr: logicand_expr
2354 $$ = $1;
2356 | logicor_expr OP_OR logicand_expr
2358 FIXME("logic OR\n");
2361 conditional_expr: logicor_expr
2363 $$ = $1;
2365 | logicor_expr '?' expr ':' assignment_expr
2367 FIXME("ternary operator\n");
2370 assignment_expr: conditional_expr
2372 $$ = $1;
2374 | unary_expr assign_op assignment_expr
2376 struct source_location loc;
2378 set_location(&loc, &@2);
2379 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
2381 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2382 "l-value is const");
2383 YYABORT;
2385 $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
2386 if (!$$)
2387 YYABORT;
2388 $$->loc = loc;
2391 assign_op: '='
2393 $$ = ASSIGN_OP_ASSIGN;
2395 | OP_ADDASSIGN
2397 $$ = ASSIGN_OP_ADD;
2399 | OP_SUBASSIGN
2401 $$ = ASSIGN_OP_SUB;
2403 | OP_MULASSIGN
2405 $$ = ASSIGN_OP_MUL;
2407 | OP_DIVASSIGN
2409 $$ = ASSIGN_OP_DIV;
2411 | OP_MODASSIGN
2413 $$ = ASSIGN_OP_MOD;
2415 | OP_LEFTSHIFTASSIGN
2417 $$ = ASSIGN_OP_LSHIFT;
2419 | OP_RIGHTSHIFTASSIGN
2421 $$ = ASSIGN_OP_RSHIFT;
2423 | OP_ANDASSIGN
2425 $$ = ASSIGN_OP_AND;
2427 | OP_ORASSIGN
2429 $$ = ASSIGN_OP_OR;
2431 | OP_XORASSIGN
2433 $$ = ASSIGN_OP_XOR;
2436 expr: assignment_expr
2438 $$ = $1;
2440 | expr ',' assignment_expr
2442 FIXME("Comma expression\n");
2447 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
2449 loc->file = hlsl_ctx.source_file;
2450 loc->line = l->first_line;
2451 loc->col = l->first_column;
2454 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
2456 if (modifiers & mod)
2458 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2459 "modifier '%s' already specified", debug_modifiers(mod));
2460 return modifiers;
2462 if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
2463 && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
2465 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2466 "more than one matrix majority keyword");
2467 return modifiers;
2469 return modifiers | mod;
2472 static void dump_function_decl(struct wine_rb_entry *entry, void *context)
2474 struct hlsl_ir_function_decl *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
2475 if (func->body)
2476 debug_dump_ir_function_decl(func);
2479 static void dump_function(struct wine_rb_entry *entry, void *context)
2481 struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
2482 wine_rb_for_each_entry(&func->overloads, dump_function_decl, NULL);
2485 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
2486 const char *entrypoint, char **messages)
2488 struct hlsl_scope *scope, *next_scope;
2489 struct hlsl_type *hlsl_type, *next_type;
2490 struct hlsl_ir_var *var, *next_var;
2491 unsigned int i;
2493 hlsl_ctx.status = PARSE_SUCCESS;
2494 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
2495 hlsl_ctx.line_no = hlsl_ctx.column = 1;
2496 hlsl_ctx.source_file = d3dcompiler_strdup("");
2497 hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
2498 if (hlsl_ctx.source_files)
2499 hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
2500 hlsl_ctx.source_files_count = 1;
2501 hlsl_ctx.cur_scope = NULL;
2502 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
2503 list_init(&hlsl_ctx.scopes);
2504 list_init(&hlsl_ctx.types);
2505 init_functions_tree(&hlsl_ctx.functions);
2507 push_scope(&hlsl_ctx);
2508 hlsl_ctx.globals = hlsl_ctx.cur_scope;
2509 declare_predefined_types(hlsl_ctx.globals);
2511 hlsl_parse();
2513 if (TRACE_ON(hlsl_parser))
2515 TRACE("IR dump.\n");
2516 wine_rb_for_each_entry(&hlsl_ctx.functions, dump_function, NULL);
2519 TRACE("Compilation status = %d\n", hlsl_ctx.status);
2520 if (messages)
2522 if (hlsl_ctx.messages.size)
2523 *messages = hlsl_ctx.messages.string;
2524 else
2525 *messages = NULL;
2527 else
2529 if (hlsl_ctx.messages.capacity)
2530 d3dcompiler_free(hlsl_ctx.messages.string);
2533 for (i = 0; i < hlsl_ctx.source_files_count; ++i)
2534 d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
2535 d3dcompiler_free(hlsl_ctx.source_files);
2537 TRACE("Freeing functions IR.\n");
2538 wine_rb_destroy(&hlsl_ctx.functions, free_function_rb, NULL);
2540 TRACE("Freeing variables.\n");
2541 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
2543 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
2545 free_declaration(var);
2547 wine_rb_destroy(&scope->types, NULL, NULL);
2548 d3dcompiler_free(scope);
2551 TRACE("Freeing types.\n");
2552 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
2554 free_hlsl_type(hlsl_type);
2557 return NULL;