d3dcompiler: Cache vector types.
[wine.git] / dlls / d3dcompiler_43 / hlsl.y
blob83aa95b54fc7ca2ad2636133c2d0d507f03d3431
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 <limits.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 struct source_location get_location(const struct YYLTYPE *l);
38 void WINAPIV hlsl_message(const char *fmt, ...)
40 __ms_va_list args;
42 __ms_va_start(args, fmt);
43 compilation_message(&hlsl_ctx.messages, fmt, args);
44 __ms_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 WINAPIV hlsl_report_message(const struct source_location loc,
59 enum hlsl_error_level level, const char *fmt, ...)
61 __ms_va_list args;
62 char *string = NULL;
63 int rc, size = 0;
65 while (1)
67 __ms_va_start(args, fmt);
68 rc = vsnprintf(string, size, fmt, args);
69 __ms_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", loc.file, loc.line, loc.col,
91 hlsl_get_error_level_name(level), string);
92 d3dcompiler_free(string);
94 if (level == HLSL_LEVEL_ERROR)
95 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
96 else if (level == HLSL_LEVEL_WARNING)
97 set_parse_status(&hlsl_ctx.status, PARSE_WARN);
100 static void hlsl_error(const char *s)
102 const struct source_location loc =
104 .file = hlsl_ctx.source_file,
105 .line = hlsl_ctx.line_no,
106 .col = hlsl_ctx.column,
108 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "%s", s);
111 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
113 TRACE("Line %u: ", line_no);
114 if (modifiers)
115 TRACE("%s ", debug_modifiers(modifiers));
116 TRACE("%s %s;\n", debug_hlsl_type(type), declname);
119 static void check_invalid_matrix_modifiers(DWORD modifiers, struct source_location loc)
121 if (modifiers & HLSL_MODIFIERS_MAJORITY_MASK)
123 hlsl_report_message(loc, HLSL_LEVEL_ERROR,
124 "'row_major' or 'column_major' modifiers are only allowed for matrices");
128 static BOOL type_is_single_reg(const struct hlsl_type *type)
130 return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR;
133 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
135 BOOL ret;
137 TRACE("Declaring variable %s.\n", decl->name);
138 if (decl->data_type->type != HLSL_CLASS_MATRIX)
139 check_invalid_matrix_modifiers(decl->modifiers, decl->loc);
141 if (local)
143 DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
144 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
145 if (invalid)
147 hlsl_report_message(decl->loc, HLSL_LEVEL_ERROR,
148 "modifier '%s' invalid for local variables", debug_modifiers(invalid));
150 if (decl->semantic)
152 hlsl_report_message(decl->loc, HLSL_LEVEL_ERROR,
153 "semantics are not allowed on local variables");
154 return FALSE;
157 else
159 if (find_function(decl->name))
161 hlsl_report_message(decl->loc, HLSL_LEVEL_ERROR, "redefinition of '%s'", decl->name);
162 return FALSE;
165 ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
166 if (!ret)
168 struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
170 hlsl_report_message(decl->loc, HLSL_LEVEL_ERROR, "\"%s\" already declared", decl->name);
171 hlsl_report_message(old->loc, HLSL_LEVEL_NOTE, "\"%s\" was previously declared here", old->name);
172 return FALSE;
174 return TRUE;
177 static DWORD add_modifiers(DWORD modifiers, DWORD mod, const struct source_location loc)
179 if (modifiers & mod)
181 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifier '%s' already specified", debug_modifiers(mod));
182 return modifiers;
184 if ((mod & HLSL_MODIFIERS_MAJORITY_MASK) && (modifiers & HLSL_MODIFIERS_MAJORITY_MASK))
186 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "more than one matrix majority keyword");
187 return modifiers;
189 return modifiers | mod;
192 static BOOL add_type_to_scope(struct hlsl_scope *scope, struct hlsl_type *def)
194 if (get_type(scope, def->name, FALSE))
195 return FALSE;
197 wine_rb_put(&scope->types, def->name, &def->scope_entry);
198 return TRUE;
201 static void declare_predefined_types(struct hlsl_scope *scope)
203 struct hlsl_type *type;
204 unsigned int x, y, bt;
205 static const char * const names[] =
207 "float",
208 "half",
209 "double",
210 "int",
211 "uint",
212 "bool",
214 char name[10];
216 static const char *const sampler_names[] =
218 "sampler",
219 "sampler1D",
220 "sampler2D",
221 "sampler3D",
222 "samplerCUBE"
225 for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt)
227 for (y = 1; y <= 4; ++y)
229 for (x = 1; x <= 4; ++x)
231 sprintf(name, "%s%ux%u", names[bt], y, x);
232 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_MATRIX, bt, x, y);
233 add_type_to_scope(scope, type);
235 if (y == 1)
237 sprintf(name, "%s%u", names[bt], x);
238 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_VECTOR, bt, x, y);
239 add_type_to_scope(scope, type);
240 hlsl_ctx.builtin_types.vector[bt][x - 1] = type;
242 if (x == 1)
244 sprintf(name, "%s", names[bt]);
245 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_SCALAR, bt, x, y);
246 add_type_to_scope(scope, type);
247 hlsl_ctx.builtin_types.scalar[bt] = type;
254 for (bt = 0; bt <= HLSL_SAMPLER_DIM_MAX; ++bt)
256 type = new_hlsl_type(d3dcompiler_strdup(sampler_names[bt]), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
257 type->sampler_dim = bt;
258 hlsl_ctx.builtin_types.sampler[bt] = type;
261 hlsl_ctx.builtin_types.Void = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
263 /* DX8 effects predefined types */
264 type = new_hlsl_type(d3dcompiler_strdup("DWORD"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
265 add_type_to_scope(scope, type);
266 type = new_hlsl_type(d3dcompiler_strdup("FLOAT"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
267 add_type_to_scope(scope, type);
268 type = new_hlsl_type(d3dcompiler_strdup("VECTOR"), HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1);
269 add_type_to_scope(scope, type);
270 type = new_hlsl_type(d3dcompiler_strdup("MATRIX"), HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4);
271 add_type_to_scope(scope, type);
272 type = new_hlsl_type(d3dcompiler_strdup("STRING"), HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1);
273 add_type_to_scope(scope, type);
274 type = new_hlsl_type(d3dcompiler_strdup("TEXTURE"), HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1);
275 add_type_to_scope(scope, type);
276 type = new_hlsl_type(d3dcompiler_strdup("PIXELSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1);
277 add_type_to_scope(scope, type);
278 type = new_hlsl_type(d3dcompiler_strdup("VERTEXSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1);
279 add_type_to_scope(scope, type);
282 static BOOL type_is_void(const struct hlsl_type *type)
284 return type->type == HLSL_CLASS_OBJECT && type->base_type == HLSL_TYPE_VOID;
287 static BOOL append_conditional_break(struct list *cond_list)
289 struct hlsl_ir_node *condition, *not;
290 struct hlsl_ir_jump *jump;
291 struct hlsl_ir_if *iff;
293 /* E.g. "for (i = 0; ; ++i)". */
294 if (!list_count(cond_list))
295 return TRUE;
297 condition = node_from_list(cond_list);
298 if (!(not = new_unary_expr(HLSL_IR_UNOP_LOGIC_NOT, condition, condition->loc)))
300 ERR("Out of memory.\n");
301 return FALSE;
303 list_add_tail(cond_list, &not->entry);
305 if (!(iff = d3dcompiler_alloc(sizeof(*iff))))
307 ERR("Out of memory.\n");
308 return FALSE;
310 init_node(&iff->node, HLSL_IR_IF, NULL, condition->loc);
311 iff->condition = not;
312 list_add_tail(cond_list, &iff->node.entry);
314 if (!(iff->then_instrs = d3dcompiler_alloc(sizeof(*iff->then_instrs))))
316 ERR("Out of memory.\n");
317 return FALSE;
319 list_init(iff->then_instrs);
321 if (!(jump = d3dcompiler_alloc(sizeof(*jump))))
323 ERR("Out of memory.\n");
324 return FALSE;
326 init_node(&jump->node, HLSL_IR_JUMP, NULL, condition->loc);
327 jump->type = HLSL_IR_JUMP_BREAK;
328 list_add_head(iff->then_instrs, &jump->node.entry);
329 return TRUE;
332 enum loop_type
334 LOOP_FOR,
335 LOOP_WHILE,
336 LOOP_DO_WHILE
339 static struct list *create_loop(enum loop_type type, struct list *init, struct list *cond,
340 struct list *iter, struct list *body, struct source_location loc)
342 struct list *list = NULL;
343 struct hlsl_ir_loop *loop = NULL;
344 struct hlsl_ir_if *cond_jump = NULL;
346 list = d3dcompiler_alloc(sizeof(*list));
347 if (!list)
348 goto oom;
349 list_init(list);
351 if (init)
352 list_move_head(list, init);
354 loop = d3dcompiler_alloc(sizeof(*loop));
355 if (!loop)
356 goto oom;
357 init_node(&loop->node, HLSL_IR_LOOP, NULL, loc);
358 list_add_tail(list, &loop->node.entry);
359 loop->body = d3dcompiler_alloc(sizeof(*loop->body));
360 if (!loop->body)
361 goto oom;
362 list_init(loop->body);
364 if (!append_conditional_break(cond))
365 goto oom;
367 if (type != LOOP_DO_WHILE)
368 list_move_tail(loop->body, cond);
370 list_move_tail(loop->body, body);
372 if (iter)
373 list_move_tail(loop->body, iter);
375 if (type == LOOP_DO_WHILE)
376 list_move_tail(loop->body, cond);
378 d3dcompiler_free(init);
379 d3dcompiler_free(cond);
380 d3dcompiler_free(body);
381 return list;
383 oom:
384 ERR("Out of memory.\n");
385 if (loop)
386 d3dcompiler_free(loop->body);
387 d3dcompiler_free(loop);
388 d3dcompiler_free(cond_jump);
389 d3dcompiler_free(list);
390 free_instr_list(init);
391 free_instr_list(cond);
392 free_instr_list(iter);
393 free_instr_list(body);
394 return NULL;
397 static unsigned int initializer_size(const struct parse_initializer *initializer)
399 unsigned int count = 0, i;
401 for (i = 0; i < initializer->args_count; ++i)
403 count += components_count_type(initializer->args[i]->data_type);
405 TRACE("Initializer size = %u.\n", count);
406 return count;
409 static void free_parse_initializer(struct parse_initializer *initializer)
411 free_instr_list(initializer->instrs);
412 d3dcompiler_free(initializer->args);
415 static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components,
416 struct hlsl_ir_node *val, struct source_location *loc)
418 struct hlsl_ir_swizzle *swizzle = d3dcompiler_alloc(sizeof(*swizzle));
420 if (!swizzle)
421 return NULL;
422 init_node(&swizzle->node, HLSL_IR_SWIZZLE,
423 new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1), *loc);
424 swizzle->val = val;
425 swizzle->swizzle = s;
426 return swizzle;
429 static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const char *swizzle,
430 struct source_location *loc)
432 unsigned int len = strlen(swizzle), component = 0;
433 unsigned int i, set, swiz = 0;
434 BOOL valid;
436 if (value->data_type->type == HLSL_CLASS_MATRIX)
438 /* Matrix swizzle */
439 BOOL m_swizzle;
440 unsigned int inc, x, y;
442 if (len < 3 || swizzle[0] != '_')
443 return NULL;
444 m_swizzle = swizzle[1] == 'm';
445 inc = m_swizzle ? 4 : 3;
447 if (len % inc || len > inc * 4)
448 return NULL;
450 for (i = 0; i < len; i += inc)
452 if (swizzle[i] != '_')
453 return NULL;
454 if (m_swizzle)
456 if (swizzle[i + 1] != 'm')
457 return NULL;
458 y = swizzle[i + 2] - '0';
459 x = swizzle[i + 3] - '0';
461 else
463 y = swizzle[i + 1] - '1';
464 x = swizzle[i + 2] - '1';
467 if (x >= value->data_type->dimx || y >= value->data_type->dimy)
468 return NULL;
469 swiz |= (y << 4 | x) << component * 8;
470 component++;
472 return new_swizzle(swiz, component, value, loc);
475 /* Vector swizzle */
476 if (len > 4)
477 return NULL;
479 for (set = 0; set < 2; ++set)
481 valid = TRUE;
482 component = 0;
483 for (i = 0; i < len; ++i)
485 char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}};
486 unsigned int s = 0;
488 for (s = 0; s < 4; ++s)
490 if (swizzle[i] == c[set][s])
491 break;
493 if (s == 4)
495 valid = FALSE;
496 break;
499 if (s >= value->data_type->dimx)
500 return NULL;
501 swiz |= s << component * 2;
502 component++;
504 if (valid)
505 return new_swizzle(swiz, component, value, loc);
508 return NULL;
511 static struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type *type,
512 const struct source_location loc)
514 struct hlsl_ir_var *var;
516 if (!(var = d3dcompiler_alloc(sizeof(*var))))
518 hlsl_ctx.status = PARSE_ERR;
519 return NULL;
522 var->name = strdup(name);
523 var->data_type = type;
524 var->loc = loc;
525 list_add_tail(&hlsl_ctx.globals->vars, &var->scope_entry);
526 return var;
529 static struct hlsl_ir_assignment *new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
530 struct hlsl_ir_node *rhs, unsigned int writemask, struct source_location loc)
532 struct hlsl_ir_assignment *assign;
534 if (!writemask && type_is_single_reg(rhs->data_type))
535 writemask = (1 << rhs->data_type->dimx) - 1;
537 if (!(assign = d3dcompiler_alloc(sizeof(*assign))))
538 return NULL;
540 init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, loc);
541 assign->lhs.var = var;
542 assign->lhs.offset = offset;
543 assign->rhs = rhs;
544 assign->writemask = writemask;
545 return assign;
548 static struct hlsl_ir_assignment *make_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs)
550 return new_assignment(lhs, NULL, rhs, 0, rhs->loc);
553 static struct hlsl_ir_jump *new_return(struct hlsl_ir_node *return_value, struct source_location loc)
555 struct hlsl_type *return_type = hlsl_ctx.cur_function->return_type;
556 struct hlsl_ir_jump *jump;
558 if (return_value)
560 struct hlsl_ir_assignment *assignment;
562 if (!(return_value = implicit_conversion(return_value, return_type, &loc)))
563 return NULL;
565 if (!(assignment = make_simple_assignment(hlsl_ctx.cur_function->return_var, return_value)))
566 return NULL;
567 list_add_after(&return_value->entry, &assignment->node.entry);
569 else if (!type_is_void(return_type))
571 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "non-void function must return a value");
572 return NULL;
575 if (!(jump = d3dcompiler_alloc(sizeof(*jump))))
577 ERR("Out of memory\n");
578 return NULL;
580 init_node(&jump->node, HLSL_IR_JUMP, NULL, loc);
581 jump->type = HLSL_IR_JUMP_RETURN;
583 return jump;
586 static struct hlsl_ir_constant *new_uint_constant(unsigned int n, const struct source_location loc)
588 struct hlsl_ir_constant *c;
590 if (!(c = d3dcompiler_alloc(sizeof(*c))))
591 return NULL;
592 init_node(&c->node, HLSL_IR_CONSTANT, hlsl_ctx.builtin_types.scalar[HLSL_TYPE_UINT], loc);
593 c->v.value.u[0] = n;
594 return c;
597 static struct hlsl_ir_load *new_var_load(struct hlsl_ir_var *var, const struct source_location loc)
599 struct hlsl_ir_load *load = d3dcompiler_alloc(sizeof(*load));
601 if (!load)
603 ERR("Out of memory.\n");
604 return NULL;
606 init_node(&load->node, HLSL_IR_LOAD, var->data_type, loc);
607 load->src.var = var;
608 return load;
611 static struct hlsl_ir_load *new_load(struct hlsl_ir_node *var_node, struct hlsl_ir_node *offset,
612 struct hlsl_type *data_type, const struct source_location loc)
614 struct hlsl_ir_node *add = NULL;
615 struct hlsl_ir_load *load;
616 struct hlsl_ir_var *var;
618 if (var_node->type == HLSL_IR_LOAD)
620 const struct hlsl_deref *src = &load_from_node(var_node)->src;
622 var = src->var;
623 if (src->offset)
625 if (!(add = new_binary_expr(HLSL_IR_BINOP_ADD, src->offset, offset, loc)))
626 return NULL;
627 list_add_after(&offset->entry, &add->entry);
628 offset = add;
631 else
633 struct hlsl_ir_assignment *assign;
634 char name[27];
636 sprintf(name, "<deref-%p>", var_node);
637 if (!(var = new_synthetic_var(name, var_node->data_type, var_node->loc)))
638 return NULL;
640 TRACE("Synthesized variable %p for %s node.\n", var, debug_node_type(var_node->type));
642 if (!(assign = make_simple_assignment(var, var_node)))
643 return NULL;
645 list_add_after(&var_node->entry, &assign->node.entry);
648 if (!(load = d3dcompiler_alloc(sizeof(*load))))
649 return NULL;
650 init_node(&load->node, HLSL_IR_LOAD, data_type, loc);
651 load->src.var = var;
652 load->src.offset = offset;
653 list_add_after(&offset->entry, &load->node.entry);
654 return load;
657 static struct hlsl_ir_load *new_record_load(struct hlsl_ir_node *record,
658 const struct hlsl_struct_field *field, const struct source_location loc)
660 struct hlsl_ir_constant *c;
662 if (!(c = new_uint_constant(field->reg_offset * 4, loc)))
663 return NULL;
664 list_add_after(&record->entry, &c->node.entry);
666 return new_load(record, &c->node, field->type, loc);
669 static struct hlsl_ir_load *new_array_load(struct hlsl_ir_node *array,
670 struct hlsl_ir_node *index, const struct source_location loc)
672 const struct hlsl_type *expr_type = array->data_type;
673 struct hlsl_type *data_type;
674 struct hlsl_ir_constant *c;
675 struct hlsl_ir_node *mul;
677 TRACE("Array load from type %s.\n", debug_hlsl_type(expr_type));
679 if (expr_type->type == HLSL_CLASS_ARRAY)
681 data_type = expr_type->e.array.type;
683 else if (expr_type->type == HLSL_CLASS_MATRIX || expr_type->type == HLSL_CLASS_VECTOR)
685 /* This needs to be lowered now, while we still have type information. */
686 FIXME("Index of matrix or vector type.\n");
687 return NULL;
689 else
691 if (expr_type->type == HLSL_CLASS_SCALAR)
692 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "array-indexed expression is scalar");
693 else
694 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "expression is not array-indexable");
695 return NULL;
698 if (!(c = new_uint_constant(data_type->reg_size * 4, loc)))
699 return NULL;
700 list_add_after(&index->entry, &c->node.entry);
701 if (!(mul = new_binary_expr(HLSL_IR_BINOP_MUL, index, &c->node, loc)))
702 return NULL;
703 list_add_after(&c->node.entry, &mul->entry);
704 index = mul;
706 return new_load(array, index, data_type, loc);
709 static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var,
710 struct parse_initializer *initializer)
712 struct hlsl_type *type = var->data_type;
713 struct hlsl_struct_field *field;
714 unsigned int i = 0;
716 if (initializer_size(initializer) != components_count_type(type))
718 hlsl_report_message(var->loc, HLSL_LEVEL_ERROR, "structure initializer mismatch");
719 free_parse_initializer(initializer);
720 return;
723 list_move_tail(list, initializer->instrs);
724 d3dcompiler_free(initializer->instrs);
726 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
728 struct hlsl_ir_node *node = initializer->args[i];
729 struct hlsl_ir_assignment *assign;
730 struct hlsl_ir_constant *c;
732 if (i++ >= initializer->args_count)
733 break;
735 if (components_count_type(field->type) == components_count_type(node->data_type))
737 if (!(c = new_uint_constant(field->reg_offset * 4, node->loc)))
738 break;
739 list_add_tail(list, &c->node.entry);
741 if (!(assign = new_assignment(var, &c->node, node, 0, node->loc)))
742 break;
743 list_add_tail(list, &assign->node.entry);
745 else
746 FIXME("Initializing with \"mismatched\" fields is not supported yet.\n");
749 d3dcompiler_free(initializer->args);
752 static void free_parse_variable_def(struct parse_variable_def *v)
754 free_parse_initializer(&v->initializer);
755 d3dcompiler_free(v->name);
756 d3dcompiler_free((void *)v->semantic);
757 d3dcompiler_free(v->reg_reservation);
758 d3dcompiler_free(v);
761 static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list)
763 struct hlsl_type *type;
764 struct parse_variable_def *v, *v_next;
765 struct hlsl_ir_var *var;
766 struct hlsl_ir_node *assignment;
767 BOOL ret, local = TRUE;
768 struct list *statements_list = d3dcompiler_alloc(sizeof(*statements_list));
770 if (basic_type->type == HLSL_CLASS_MATRIX)
771 assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
773 if (!statements_list)
775 ERR("Out of memory.\n");
776 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
777 free_parse_variable_def(v);
778 d3dcompiler_free(var_list);
779 return NULL;
781 list_init(statements_list);
783 if (!var_list)
784 return statements_list;
786 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
788 var = d3dcompiler_alloc(sizeof(*var));
789 if (!var)
791 ERR("Out of memory.\n");
792 free_parse_variable_def(v);
793 continue;
795 if (v->array_size)
796 type = new_array_type(basic_type, v->array_size);
797 else
798 type = basic_type;
799 var->data_type = type;
800 var->loc = v->loc;
801 var->name = v->name;
802 var->modifiers = modifiers;
803 var->semantic = v->semantic;
804 var->reg_reservation = v->reg_reservation;
805 debug_dump_decl(type, modifiers, v->name, v->loc.line);
807 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
809 var->modifiers |= HLSL_STORAGE_UNIFORM;
810 local = FALSE;
813 if (type->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer.args_count)
815 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, "const variable without initializer");
816 free_declaration(var);
817 d3dcompiler_free(v);
818 continue;
821 ret = declare_variable(var, local);
822 if (!ret)
824 free_declaration(var);
825 d3dcompiler_free(v);
826 continue;
828 TRACE("Declared variable %s.\n", var->name);
830 if (v->initializer.args_count)
832 unsigned int size = initializer_size(&v->initializer);
833 struct hlsl_ir_load *load;
835 TRACE("Variable with initializer.\n");
836 if (type->type <= HLSL_CLASS_LAST_NUMERIC
837 && type->dimx * type->dimy != size && size != 1)
839 if (size < type->dimx * type->dimy)
841 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR,
842 "'%s' initializer does not match", v->name);
843 free_parse_initializer(&v->initializer);
844 d3dcompiler_free(v);
845 continue;
848 if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY)
849 && components_count_type(type) != size)
851 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR,
852 "'%s' initializer does not match", v->name);
853 free_parse_initializer(&v->initializer);
854 d3dcompiler_free(v);
855 continue;
858 if (type->type == HLSL_CLASS_STRUCT)
860 struct_var_initializer(statements_list, var, &v->initializer);
861 d3dcompiler_free(v);
862 continue;
864 if (type->type > HLSL_CLASS_LAST_NUMERIC)
866 FIXME("Initializers for non scalar/struct variables not supported yet.\n");
867 free_parse_initializer(&v->initializer);
868 d3dcompiler_free(v);
869 continue;
871 if (v->array_size > 0)
873 FIXME("Initializing arrays is not supported yet.\n");
874 free_parse_initializer(&v->initializer);
875 d3dcompiler_free(v);
876 continue;
878 if (v->initializer.args_count > 1)
880 FIXME("Complex initializers are not supported yet.\n");
881 free_parse_initializer(&v->initializer);
882 d3dcompiler_free(v);
883 continue;
886 list_move_tail(statements_list, v->initializer.instrs);
887 d3dcompiler_free(v->initializer.instrs);
889 load = new_var_load(var, var->loc);
890 list_add_tail(statements_list, &load->node.entry);
891 assignment = make_assignment(&load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]);
892 d3dcompiler_free(v->initializer.args);
893 list_add_tail(statements_list, &assignment->entry);
895 d3dcompiler_free(v);
897 d3dcompiler_free(var_list);
898 return statements_list;
901 static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field)
903 struct hlsl_struct_field *f;
905 LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry)
907 if (!strcmp(f->name, field->name))
908 return FALSE;
910 list_add_tail(fields, &field->entry);
911 return TRUE;
914 BOOL is_row_major(const struct hlsl_type *type)
916 /* Default to column-major if the majority isn't explicitly set, which can
917 * happen for anonymous nodes. */
918 return !!(type->modifiers & HLSL_MODIFIER_ROW_MAJOR);
921 static struct hlsl_type *apply_type_modifiers(struct hlsl_type *type,
922 unsigned int *modifiers, struct source_location loc)
924 unsigned int default_majority = 0;
925 struct hlsl_type *new_type;
927 /* This function is only used for declarations (i.e. variables and struct
928 * fields), which should inherit the matrix majority. We only explicitly set
929 * the default majority for declarations—typedefs depend on this—but we
930 * want to always set it, so that an hlsl_type object is never used to
931 * represent two different majorities (and thus can be used to store its
932 * register size, etc.) */
933 if (!(*modifiers & HLSL_MODIFIERS_MAJORITY_MASK)
934 && !(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK)
935 && type->type == HLSL_CLASS_MATRIX)
937 if (hlsl_ctx.matrix_majority == HLSL_COLUMN_MAJOR)
938 default_majority = HLSL_MODIFIER_COLUMN_MAJOR;
939 else
940 default_majority = HLSL_MODIFIER_ROW_MAJOR;
943 if (!default_majority && !(*modifiers & HLSL_TYPE_MODIFIERS_MASK))
944 return type;
946 if (!(new_type = clone_hlsl_type(type, default_majority)))
947 return NULL;
949 new_type->modifiers = add_modifiers(new_type->modifiers, *modifiers, loc);
950 *modifiers &= ~HLSL_TYPE_MODIFIERS_MASK;
952 if (new_type->type == HLSL_CLASS_MATRIX)
953 new_type->reg_size = is_row_major(new_type) ? new_type->dimy : new_type->dimx;
954 return new_type;
957 static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, struct list *fields)
959 struct parse_variable_def *v, *v_next;
960 struct hlsl_struct_field *field;
961 struct list *list;
963 if (type->type == HLSL_CLASS_MATRIX)
964 assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
966 list = d3dcompiler_alloc(sizeof(*list));
967 if (!list)
969 ERR("Out of memory.\n");
970 return NULL;
972 list_init(list);
973 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry)
975 debug_dump_decl(type, 0, v->name, v->loc.line);
976 field = d3dcompiler_alloc(sizeof(*field));
977 if (!field)
979 ERR("Out of memory.\n");
980 d3dcompiler_free(v);
981 return list;
983 if (v->array_size)
984 field->type = new_array_type(type, v->array_size);
985 else
986 field->type = type;
987 field->name = v->name;
988 field->modifiers = modifiers;
989 field->semantic = v->semantic;
990 if (v->initializer.args_count)
992 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, "struct field with an initializer.\n");
993 free_parse_initializer(&v->initializer);
995 list_add_tail(list, &field->entry);
996 d3dcompiler_free(v);
998 d3dcompiler_free(fields);
999 return list;
1002 static DWORD get_array_size(const struct hlsl_type *type)
1004 if (type->type == HLSL_CLASS_ARRAY)
1005 return get_array_size(type->e.array.type) * type->e.array.elements_count;
1006 return 1;
1009 static struct hlsl_type *new_struct_type(const char *name, struct list *fields)
1011 struct hlsl_type *type = d3dcompiler_alloc(sizeof(*type));
1012 struct hlsl_struct_field *field;
1013 unsigned int reg_size = 0;
1015 if (!type)
1017 ERR("Out of memory.\n");
1018 return NULL;
1020 type->type = HLSL_CLASS_STRUCT;
1021 type->base_type = HLSL_TYPE_VOID;
1022 type->name = name;
1023 type->dimx = 0;
1024 type->dimy = 1;
1025 type->e.elements = fields;
1027 LIST_FOR_EACH_ENTRY(field, fields, struct hlsl_struct_field, entry)
1029 field->reg_offset = reg_size;
1030 reg_size += field->type->reg_size;
1031 type->dimx += field->type->dimx * field->type->dimy * get_array_size(field->type);
1033 type->reg_size = reg_size;
1035 list_add_tail(&hlsl_ctx.types, &type->entry);
1037 return type;
1040 static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list)
1042 BOOL ret;
1043 struct hlsl_type *type;
1044 struct parse_variable_def *v, *v_next;
1046 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
1048 if (v->array_size)
1049 type = new_array_type(orig_type, v->array_size);
1050 else
1051 type = clone_hlsl_type(orig_type, 0);
1052 if (!type)
1054 ERR("Out of memory\n");
1055 return FALSE;
1057 d3dcompiler_free((void *)type->name);
1058 type->name = v->name;
1059 type->modifiers |= modifiers;
1061 if (type->type != HLSL_CLASS_MATRIX)
1062 check_invalid_matrix_modifiers(type->modifiers, v->loc);
1063 else
1064 type->reg_size = is_row_major(type) ? type->dimy : type->dimx;
1066 if ((type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
1067 && (type->modifiers & HLSL_MODIFIER_ROW_MAJOR))
1068 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, "more than one matrix majority keyword");
1070 ret = add_type_to_scope(hlsl_ctx.cur_scope, type);
1071 if (!ret)
1073 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR,
1074 "redefinition of custom type '%s'", v->name);
1076 d3dcompiler_free(v);
1078 d3dcompiler_free(list);
1079 return TRUE;
1082 static BOOL add_func_parameter(struct list *list, struct parse_parameter *param, const struct source_location loc)
1084 struct hlsl_ir_var *decl = d3dcompiler_alloc(sizeof(*decl));
1086 if (param->type->type == HLSL_CLASS_MATRIX)
1087 assert(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
1089 if (!decl)
1091 ERR("Out of memory.\n");
1092 return FALSE;
1094 decl->data_type = param->type;
1095 decl->loc = loc;
1096 decl->name = param->name;
1097 decl->semantic = param->semantic;
1098 decl->reg_reservation = param->reg_reservation;
1099 decl->modifiers = param->modifiers;
1101 if (!add_declaration(hlsl_ctx.cur_scope, decl, FALSE))
1103 free_declaration(decl);
1104 return FALSE;
1106 list_add_tail(list, &decl->param_entry);
1107 return TRUE;
1110 static struct reg_reservation *parse_reg_reservation(const char *reg_string)
1112 struct reg_reservation *reg_res;
1113 enum bwritershader_param_register_type type;
1114 DWORD regnum = 0;
1116 switch (reg_string[0])
1118 case 'c':
1119 type = BWRITERSPR_CONST;
1120 break;
1121 case 'i':
1122 type = BWRITERSPR_CONSTINT;
1123 break;
1124 case 'b':
1125 type = BWRITERSPR_CONSTBOOL;
1126 break;
1127 case 's':
1128 type = BWRITERSPR_SAMPLER;
1129 break;
1130 default:
1131 FIXME("Unsupported register type.\n");
1132 return NULL;
1135 if (!sscanf(reg_string + 1, "%u", &regnum))
1137 FIXME("Unsupported register reservation syntax.\n");
1138 return NULL;
1141 reg_res = d3dcompiler_alloc(sizeof(*reg_res));
1142 if (!reg_res)
1144 ERR("Out of memory.\n");
1145 return NULL;
1147 reg_res->type = type;
1148 reg_res->regnum = regnum;
1149 return reg_res;
1152 static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tree *funcs, char *name,
1153 struct list *params, BOOL exact_signature)
1155 struct hlsl_ir_function *func;
1156 struct wine_rb_entry *entry;
1158 entry = wine_rb_get(funcs, name);
1159 if (entry)
1161 func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
1163 entry = wine_rb_get(&func->overloads, params);
1164 if (!entry)
1166 if (!exact_signature)
1167 FIXME("No exact match, search for a compatible overloaded function (if any).\n");
1168 return NULL;
1170 return WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
1172 return NULL;
1175 static struct hlsl_ir_function_decl *get_func_entry(const char *name)
1177 struct hlsl_ir_function_decl *decl;
1178 struct hlsl_ir_function *func;
1179 struct wine_rb_entry *entry;
1181 if ((entry = wine_rb_get(&hlsl_ctx.functions, name)))
1183 func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
1184 WINE_RB_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry)
1185 return decl;
1188 return NULL;
1191 static struct list *append_unop(struct list *list, struct hlsl_ir_node *node)
1193 list_add_tail(list, &node->entry);
1194 return list;
1197 static struct list *append_binop(struct list *first, struct list *second, struct hlsl_ir_node *node)
1199 list_move_tail(first, second);
1200 d3dcompiler_free(second);
1201 list_add_tail(first, &node->entry);
1202 return first;
1205 static struct list *make_list(struct hlsl_ir_node *node)
1207 struct list *list;
1209 if (!(list = d3dcompiler_alloc(sizeof(*list))))
1211 ERR("Out of memory.\n");
1212 free_instr(node);
1213 return NULL;
1215 list_init(list);
1216 list_add_tail(list, &node->entry);
1217 return list;
1220 static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node)
1222 if (node->data_type->type != HLSL_CLASS_SCALAR)
1223 return 0;
1225 switch (node->type)
1227 case HLSL_IR_CONSTANT:
1229 struct hlsl_ir_constant *constant = constant_from_node(node);
1231 switch (constant->node.data_type->base_type)
1233 case HLSL_TYPE_UINT:
1234 return constant->v.value.u[0];
1235 case HLSL_TYPE_INT:
1236 return constant->v.value.i[0];
1237 case HLSL_TYPE_FLOAT:
1238 return constant->v.value.f[0];
1239 case HLSL_TYPE_DOUBLE:
1240 return constant->v.value.d[0];
1241 case HLSL_TYPE_BOOL:
1242 return constant->v.value.b[0];
1243 default:
1244 WARN("Invalid type %s.\n", debug_base_type(constant->node.data_type));
1245 return 0;
1248 case HLSL_IR_CONSTRUCTOR:
1249 case HLSL_IR_EXPR:
1250 case HLSL_IR_LOAD:
1251 case HLSL_IR_SWIZZLE:
1252 FIXME("Unhandled type %s.\n", debug_node_type(node->type));
1253 return 0;
1254 case HLSL_IR_ASSIGNMENT:
1255 default:
1256 WARN("Invalid node type %s.\n", debug_node_type(node->type));
1257 return 0;
1261 static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type,
1262 struct list *parameters, const char *semantic, struct source_location loc)
1264 struct hlsl_ir_function_decl *decl;
1266 if (!(decl = d3dcompiler_alloc(sizeof(*decl))))
1267 return NULL;
1268 decl->return_type = return_type;
1269 decl->parameters = parameters;
1270 decl->semantic = semantic;
1271 decl->loc = loc;
1273 if (!type_is_void(return_type))
1275 struct hlsl_ir_var *return_var;
1276 char name[28];
1278 sprintf(name, "<retval-%p>", decl);
1279 if (!(return_var = new_synthetic_var(name, return_type, loc)))
1281 d3dcompiler_free(decl);
1282 return NULL;
1284 decl->return_var = return_var;
1287 return decl;
1292 %locations
1293 %define parse.error verbose
1294 %expect 1
1296 %union
1298 struct hlsl_type *type;
1299 INT intval;
1300 FLOAT floatval;
1301 BOOL boolval;
1302 char *name;
1303 DWORD modifiers;
1304 struct hlsl_ir_node *instr;
1305 struct list *list;
1306 struct parse_function function;
1307 struct parse_parameter parameter;
1308 struct parse_initializer initializer;
1309 struct parse_variable_def *variable_def;
1310 struct parse_if_body if_body;
1311 enum parse_unary_op unary_op;
1312 enum parse_assign_op assign_op;
1313 struct reg_reservation *reg_reservation;
1314 struct parse_colon_attribute colon_attribute;
1317 %token KW_BLENDSTATE
1318 %token KW_BREAK
1319 %token KW_BUFFER
1320 %token KW_CBUFFER
1321 %token KW_COLUMN_MAJOR
1322 %token KW_COMPILE
1323 %token KW_CONST
1324 %token KW_CONTINUE
1325 %token KW_DEPTHSTENCILSTATE
1326 %token KW_DEPTHSTENCILVIEW
1327 %token KW_DISCARD
1328 %token KW_DO
1329 %token KW_DOUBLE
1330 %token KW_ELSE
1331 %token KW_EXTERN
1332 %token KW_FALSE
1333 %token KW_FOR
1334 %token KW_GEOMETRYSHADER
1335 %token KW_GROUPSHARED
1336 %token KW_IF
1337 %token KW_IN
1338 %token KW_INLINE
1339 %token KW_INOUT
1340 %token KW_MATRIX
1341 %token KW_NAMESPACE
1342 %token KW_NOINTERPOLATION
1343 %token KW_OUT
1344 %token KW_PASS
1345 %token KW_PIXELSHADER
1346 %token KW_PRECISE
1347 %token KW_RASTERIZERSTATE
1348 %token KW_RENDERTARGETVIEW
1349 %token KW_RETURN
1350 %token KW_REGISTER
1351 %token KW_ROW_MAJOR
1352 %token KW_SAMPLER
1353 %token KW_SAMPLER1D
1354 %token KW_SAMPLER2D
1355 %token KW_SAMPLER3D
1356 %token KW_SAMPLERCUBE
1357 %token KW_SAMPLER_STATE
1358 %token KW_SAMPLERCOMPARISONSTATE
1359 %token KW_SHARED
1360 %token KW_STATEBLOCK
1361 %token KW_STATEBLOCK_STATE
1362 %token KW_STATIC
1363 %token KW_STRING
1364 %token KW_STRUCT
1365 %token KW_SWITCH
1366 %token KW_TBUFFER
1367 %token KW_TECHNIQUE
1368 %token KW_TECHNIQUE10
1369 %token KW_TEXTURE
1370 %token KW_TEXTURE1D
1371 %token KW_TEXTURE1DARRAY
1372 %token KW_TEXTURE2D
1373 %token KW_TEXTURE2DARRAY
1374 %token KW_TEXTURE2DMS
1375 %token KW_TEXTURE2DMSARRAY
1376 %token KW_TEXTURE3D
1377 %token KW_TEXTURE3DARRAY
1378 %token KW_TEXTURECUBE
1379 %token KW_TRUE
1380 %token KW_TYPEDEF
1381 %token KW_UNIFORM
1382 %token KW_VECTOR
1383 %token KW_VERTEXSHADER
1384 %token KW_VOID
1385 %token KW_VOLATILE
1386 %token KW_WHILE
1388 %token OP_INC
1389 %token OP_DEC
1390 %token OP_AND
1391 %token OP_OR
1392 %token OP_EQ
1393 %token OP_LEFTSHIFT
1394 %token OP_LEFTSHIFTASSIGN
1395 %token OP_RIGHTSHIFT
1396 %token OP_RIGHTSHIFTASSIGN
1397 %token OP_ELLIPSIS
1398 %token OP_LE
1399 %token OP_GE
1400 %token OP_NE
1401 %token OP_ADDASSIGN
1402 %token OP_SUBASSIGN
1403 %token OP_MULASSIGN
1404 %token OP_DIVASSIGN
1405 %token OP_MODASSIGN
1406 %token OP_ANDASSIGN
1407 %token OP_ORASSIGN
1408 %token OP_XORASSIGN
1409 %token OP_UNKNOWN1
1410 %token OP_UNKNOWN2
1411 %token OP_UNKNOWN3
1412 %token OP_UNKNOWN4
1414 %token <intval> PRE_LINE
1416 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
1417 %type <name> any_identifier var_identifier
1418 %token <name> STRING
1419 %token <floatval> C_FLOAT
1420 %token <intval> C_INTEGER
1421 %type <boolval> boolean
1422 %type <type> base_type
1423 %type <type> type
1424 %type <list> declaration_statement
1425 %type <list> declaration
1426 %type <list> struct_declaration
1427 %type <type> struct_spec
1428 %type <type> named_struct_spec
1429 %type <type> unnamed_struct_spec
1430 %type <type> field_type
1431 %type <type> typedef_type
1432 %type <list> type_specs
1433 %type <variable_def> type_spec
1434 %type <initializer> complex_initializer
1435 %type <initializer> initializer_expr_list
1436 %type <list> initializer_expr
1437 %type <modifiers> var_modifiers
1438 %type <list> field
1439 %type <list> parameters
1440 %type <list> param_list
1441 %type <list> expr
1442 %type <intval> array
1443 %type <list> statement
1444 %type <list> statement_list
1445 %type <list> compound_statement
1446 %type <list> jump_statement
1447 %type <list> selection_statement
1448 %type <list> loop_statement
1449 %type <function> func_declaration
1450 %type <function> func_prototype
1451 %type <list> fields_list
1452 %type <parameter> parameter
1453 %type <colon_attribute> colon_attribute
1454 %type <name> semantic
1455 %type <reg_reservation> register_opt
1456 %type <variable_def> variable_def
1457 %type <list> variables_def
1458 %type <list> variables_def_optional
1459 %type <if_body> if_body
1460 %type <list> primary_expr
1461 %type <list> postfix_expr
1462 %type <list> unary_expr
1463 %type <list> mul_expr
1464 %type <list> add_expr
1465 %type <list> shift_expr
1466 %type <list> relational_expr
1467 %type <list> equality_expr
1468 %type <list> bitand_expr
1469 %type <list> bitxor_expr
1470 %type <list> bitor_expr
1471 %type <list> logicand_expr
1472 %type <list> logicor_expr
1473 %type <list> conditional_expr
1474 %type <list> assignment_expr
1475 %type <list> expr_statement
1476 %type <unary_op> unary_op
1477 %type <assign_op> assign_op
1478 %type <modifiers> input_mods
1479 %type <modifiers> input_mod
1482 hlsl_prog: /* empty */
1485 | hlsl_prog func_declaration
1487 const struct hlsl_ir_function_decl *decl;
1489 decl = get_overloaded_func(&hlsl_ctx.functions, $2.name, $2.decl->parameters, TRUE);
1490 if (decl && !decl->func->intrinsic)
1492 if (decl->body && $2.decl->body)
1494 hlsl_report_message($2.decl->loc, HLSL_LEVEL_ERROR,
1495 "redefinition of function %s", debugstr_a($2.name));
1496 YYABORT;
1498 else if (!compare_hlsl_types(decl->return_type, $2.decl->return_type))
1500 hlsl_report_message($2.decl->loc, HLSL_LEVEL_ERROR,
1501 "redefining function %s with a different return type",
1502 debugstr_a($2.name));
1503 hlsl_report_message(decl->loc, HLSL_LEVEL_NOTE,
1504 "%s previously declared here",
1505 debugstr_a($2.name));
1506 YYABORT;
1510 if (type_is_void($2.decl->return_type) && $2.decl->semantic)
1512 hlsl_report_message($2.decl->loc, HLSL_LEVEL_ERROR,
1513 "void function with a semantic");
1516 TRACE("Adding function '%s' to the function list.\n", $2.name);
1517 add_function_decl(&hlsl_ctx.functions, $2.name, $2.decl, FALSE);
1519 | hlsl_prog declaration_statement
1521 TRACE("Declaration statement parsed.\n");
1523 | hlsl_prog preproc_directive
1526 | hlsl_prog ';'
1528 TRACE("Skipping stray semicolon.\n");
1531 preproc_directive: PRE_LINE STRING
1533 const char **new_array = NULL;
1535 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
1536 hlsl_ctx.line_no = $1;
1537 if (strcmp($2, hlsl_ctx.source_file))
1538 new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
1539 sizeof(*hlsl_ctx.source_files) * (hlsl_ctx.source_files_count + 1));
1541 if (new_array)
1543 hlsl_ctx.source_files = new_array;
1544 hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
1545 hlsl_ctx.source_file = $2;
1547 else
1549 d3dcompiler_free($2);
1553 struct_declaration: var_modifiers struct_spec variables_def_optional ';'
1555 struct hlsl_type *type;
1556 DWORD modifiers = $1;
1558 if (!$3)
1560 if (!$2->name)
1562 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
1563 "anonymous struct declaration with no variables");
1565 if (modifiers)
1567 hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR,
1568 "modifier not allowed on struct type declaration");
1572 if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1))))
1573 YYABORT;
1574 $$ = declare_vars(type, modifiers, $3);
1577 struct_spec: named_struct_spec
1578 | unnamed_struct_spec
1580 named_struct_spec: KW_STRUCT any_identifier '{' fields_list '}'
1582 BOOL ret;
1584 TRACE("Structure %s declaration.\n", debugstr_a($2));
1585 $$ = new_struct_type($2, $4);
1587 if (get_variable(hlsl_ctx.cur_scope, $2))
1589 hlsl_report_message(get_location(&@2),
1590 HLSL_LEVEL_ERROR, "redefinition of '%s'", $2);
1591 YYABORT;
1594 ret = add_type_to_scope(hlsl_ctx.cur_scope, $$);
1595 if (!ret)
1597 hlsl_report_message(get_location(&@2),
1598 HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $2);
1599 YYABORT;
1603 unnamed_struct_spec: KW_STRUCT '{' fields_list '}'
1605 TRACE("Anonymous structure declaration.\n");
1606 $$ = new_struct_type(NULL, $3);
1609 any_identifier: VAR_IDENTIFIER
1610 | TYPE_IDENTIFIER
1611 | NEW_IDENTIFIER
1613 fields_list: /* Empty */
1615 $$ = d3dcompiler_alloc(sizeof(*$$));
1616 list_init($$);
1618 | fields_list field
1620 BOOL ret;
1621 struct hlsl_struct_field *field, *next;
1623 $$ = $1;
1624 LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry)
1626 ret = add_struct_field($$, field);
1627 if (ret == FALSE)
1629 hlsl_report_message(get_location(&@2),
1630 HLSL_LEVEL_ERROR, "redefinition of '%s'", field->name);
1631 d3dcompiler_free(field);
1634 d3dcompiler_free($2);
1637 field_type: type
1638 | unnamed_struct_spec
1640 field: var_modifiers field_type variables_def ';'
1642 struct hlsl_type *type;
1643 DWORD modifiers = $1;
1645 if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1))))
1646 YYABORT;
1647 $$ = gen_struct_fields(type, modifiers, $3);
1650 func_declaration: func_prototype compound_statement
1652 TRACE("Function %s parsed.\n", $1.name);
1653 $$ = $1;
1654 $$.decl->body = $2;
1655 pop_scope(&hlsl_ctx);
1657 | func_prototype ';'
1659 TRACE("Function prototype for %s.\n", $1.name);
1660 $$ = $1;
1661 pop_scope(&hlsl_ctx);
1664 /* var_modifiers is necessary to avoid shift/reduce conflicts. */
1665 func_prototype: var_modifiers type var_identifier '(' parameters ')' colon_attribute
1667 if ($1)
1669 hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR,
1670 "unexpected modifiers on a function");
1671 YYABORT;
1673 if (get_variable(hlsl_ctx.globals, $3))
1675 hlsl_report_message(get_location(&@3),
1676 HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
1677 YYABORT;
1679 if (type_is_void($2) && $7.semantic)
1681 hlsl_report_message(get_location(&@7),
1682 HLSL_LEVEL_ERROR, "void function with a semantic");
1685 if ($7.reg_reservation)
1687 FIXME("Unexpected register reservation for a function.\n");
1688 d3dcompiler_free($7.reg_reservation);
1690 if (!($$.decl = new_func_decl($2, $5, $7.semantic, get_location(&@3))))
1692 ERR("Out of memory.\n");
1693 YYABORT;
1695 $$.name = $3;
1696 hlsl_ctx.cur_function = $$.decl;
1699 compound_statement: '{' '}'
1701 $$ = d3dcompiler_alloc(sizeof(*$$));
1702 list_init($$);
1704 | '{' scope_start statement_list '}'
1706 pop_scope(&hlsl_ctx);
1707 $$ = $3;
1710 scope_start: /* Empty */
1712 push_scope(&hlsl_ctx);
1715 var_identifier: VAR_IDENTIFIER
1716 | NEW_IDENTIFIER
1718 colon_attribute: /* Empty */
1720 $$.semantic = NULL;
1721 $$.reg_reservation = NULL;
1723 | semantic
1725 $$.semantic = $1;
1726 $$.reg_reservation = NULL;
1728 | register_opt
1730 $$.semantic = NULL;
1731 $$.reg_reservation = $1;
1734 semantic: ':' any_identifier
1736 $$ = $2;
1739 /* FIXME: Writemasks */
1740 register_opt: ':' KW_REGISTER '(' any_identifier ')'
1742 $$ = parse_reg_reservation($4);
1743 d3dcompiler_free($4);
1745 | ':' KW_REGISTER '(' any_identifier ',' any_identifier ')'
1747 FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a($4));
1748 d3dcompiler_free($4);
1750 $$ = parse_reg_reservation($6);
1751 d3dcompiler_free($6);
1754 parameters: scope_start
1756 $$ = d3dcompiler_alloc(sizeof(*$$));
1757 list_init($$);
1759 | scope_start param_list
1761 $$ = $2;
1764 param_list: parameter
1766 $$ = d3dcompiler_alloc(sizeof(*$$));
1767 list_init($$);
1768 if (!add_func_parameter($$, &$1, get_location(&@1)))
1770 ERR("Error adding function parameter %s.\n", $1.name);
1771 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1772 YYABORT;
1775 | param_list ',' parameter
1777 $$ = $1;
1778 if (!add_func_parameter($$, &$3, get_location(&@3)))
1780 hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR,
1781 "duplicate parameter %s", $3.name);
1782 YYABORT;
1786 parameter: input_mods var_modifiers type any_identifier colon_attribute
1788 struct hlsl_type *type;
1789 DWORD modifiers = $2;
1791 if (!(type = apply_type_modifiers($3, &modifiers, get_location(&@2))))
1792 YYABORT;
1794 $$.modifiers = $1 ? $1 : HLSL_STORAGE_IN;
1795 $$.modifiers |= modifiers;
1796 $$.type = type;
1797 $$.name = $4;
1798 $$.semantic = $5.semantic;
1799 $$.reg_reservation = $5.reg_reservation;
1802 input_mods: /* Empty */
1804 $$ = 0;
1806 | input_mods input_mod
1808 if ($1 & $2)
1810 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
1811 "duplicate input-output modifiers");
1812 YYABORT;
1814 $$ = $1 | $2;
1817 input_mod: KW_IN
1819 $$ = HLSL_STORAGE_IN;
1821 | KW_OUT
1823 $$ = HLSL_STORAGE_OUT;
1825 | KW_INOUT
1827 $$ = HLSL_STORAGE_IN | HLSL_STORAGE_OUT;
1830 type:
1832 base_type
1834 $$ = $1;
1836 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
1838 if ($3->type != HLSL_CLASS_SCALAR)
1840 hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR,
1841 "vectors of non-scalar types are not allowed\n");
1842 YYABORT;
1844 if ($5 < 1 || $5 > 4)
1846 hlsl_report_message(get_location(&@5), HLSL_LEVEL_ERROR,
1847 "vector size must be between 1 and 4\n");
1848 YYABORT;
1851 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
1853 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
1855 if ($3->type != HLSL_CLASS_SCALAR)
1857 hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR,
1858 "matrices of non-scalar types are not allowed\n");
1859 YYABORT;
1861 if ($5 < 1 || $5 > 4)
1863 hlsl_report_message(get_location(&@5), HLSL_LEVEL_ERROR,
1864 "matrix row count must be between 1 and 4\n");
1865 YYABORT;
1867 if ($7 < 1 || $7 > 4)
1869 hlsl_report_message(get_location(&@7), HLSL_LEVEL_ERROR,
1870 "matrix column count must be between 1 and 4\n");
1871 YYABORT;
1874 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $7, $5);
1877 base_type:
1879 KW_VOID
1881 $$ = hlsl_ctx.builtin_types.Void;
1883 | KW_SAMPLER
1885 $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_GENERIC];
1887 | KW_SAMPLER1D
1889 $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_1D];
1891 | KW_SAMPLER2D
1893 $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_2D];
1895 | KW_SAMPLER3D
1897 $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_3D];
1899 | KW_SAMPLERCUBE
1901 $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_3D];
1903 | TYPE_IDENTIFIER
1905 $$ = get_type(hlsl_ctx.cur_scope, $1, TRUE);
1906 d3dcompiler_free($1);
1908 | KW_STRUCT TYPE_IDENTIFIER
1910 $$ = get_type(hlsl_ctx.cur_scope, $2, TRUE);
1911 if ($$->type != HLSL_CLASS_STRUCT)
1912 hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR, "'%s' redefined as a structure\n", $2);
1913 d3dcompiler_free($2);
1916 declaration_statement: declaration
1917 | struct_declaration
1918 | typedef
1920 $$ = d3dcompiler_alloc(sizeof(*$$));
1921 if (!$$)
1923 ERR("Out of memory\n");
1924 YYABORT;
1926 list_init($$);
1929 typedef_type: type
1930 | struct_spec
1932 typedef: KW_TYPEDEF var_modifiers typedef_type type_specs ';'
1934 if ($2 & ~HLSL_TYPE_MODIFIERS_MASK)
1936 struct parse_variable_def *v, *v_next;
1937 hlsl_report_message(get_location(&@1),
1938 HLSL_LEVEL_ERROR, "modifier not allowed on typedefs");
1939 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $4, struct parse_variable_def, entry)
1940 d3dcompiler_free(v);
1941 d3dcompiler_free($4);
1942 YYABORT;
1944 if (!add_typedef($2, $3, $4))
1945 YYABORT;
1948 type_specs: type_spec
1950 $$ = d3dcompiler_alloc(sizeof(*$$));
1951 list_init($$);
1952 list_add_head($$, &$1->entry);
1954 | type_specs ',' type_spec
1956 $$ = $1;
1957 list_add_tail($$, &$3->entry);
1960 type_spec: any_identifier array
1962 $$ = d3dcompiler_alloc(sizeof(*$$));
1963 $$->loc = get_location(&@1);
1964 $$->name = $1;
1965 $$->array_size = $2;
1968 declaration: var_modifiers type variables_def ';'
1970 struct hlsl_type *type;
1971 DWORD modifiers = $1;
1973 if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1))))
1974 YYABORT;
1975 $$ = declare_vars(type, modifiers, $3);
1978 variables_def_optional: /* Empty */
1980 $$ = NULL;
1982 | variables_def
1984 $$ = $1;
1987 variables_def: variable_def
1989 $$ = d3dcompiler_alloc(sizeof(*$$));
1990 list_init($$);
1991 list_add_head($$, &$1->entry);
1993 | variables_def ',' variable_def
1995 $$ = $1;
1996 list_add_tail($$, &$3->entry);
1999 variable_def: any_identifier array colon_attribute
2001 $$ = d3dcompiler_alloc(sizeof(*$$));
2002 $$->loc = get_location(&@1);
2003 $$->name = $1;
2004 $$->array_size = $2;
2005 $$->semantic = $3.semantic;
2006 $$->reg_reservation = $3.reg_reservation;
2008 | any_identifier array colon_attribute '=' complex_initializer
2010 TRACE("Declaration with initializer.\n");
2011 $$ = d3dcompiler_alloc(sizeof(*$$));
2012 $$->loc = get_location(&@1);
2013 $$->name = $1;
2014 $$->array_size = $2;
2015 $$->semantic = $3.semantic;
2016 $$->reg_reservation = $3.reg_reservation;
2017 $$->initializer = $5;
2020 array: /* Empty */
2022 $$ = 0;
2024 | '[' expr ']'
2026 unsigned int size = evaluate_array_dimension(node_from_list($2));
2028 free_instr_list($2);
2030 if (!size)
2032 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
2033 "array size is not a positive integer constant\n");
2034 YYABORT;
2036 TRACE("Array size %u.\n", size);
2038 if (size > 65536)
2040 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
2041 "array size must be between 1 and 65536");
2042 YYABORT;
2044 $$ = size;
2047 var_modifiers: /* Empty */
2049 $$ = 0;
2051 | KW_EXTERN var_modifiers
2053 $$ = add_modifiers($2, HLSL_STORAGE_EXTERN, get_location(&@1));
2055 | KW_NOINTERPOLATION var_modifiers
2057 $$ = add_modifiers($2, HLSL_STORAGE_NOINTERPOLATION, get_location(&@1));
2059 | KW_PRECISE var_modifiers
2061 $$ = add_modifiers($2, HLSL_MODIFIER_PRECISE, get_location(&@1));
2063 | KW_SHARED var_modifiers
2065 $$ = add_modifiers($2, HLSL_STORAGE_SHARED, get_location(&@1));
2067 | KW_GROUPSHARED var_modifiers
2069 $$ = add_modifiers($2, HLSL_STORAGE_GROUPSHARED, get_location(&@1));
2071 | KW_STATIC var_modifiers
2073 $$ = add_modifiers($2, HLSL_STORAGE_STATIC, get_location(&@1));
2075 | KW_UNIFORM var_modifiers
2077 $$ = add_modifiers($2, HLSL_STORAGE_UNIFORM, get_location(&@1));
2079 | KW_VOLATILE var_modifiers
2081 $$ = add_modifiers($2, HLSL_STORAGE_VOLATILE, get_location(&@1));
2083 | KW_CONST var_modifiers
2085 $$ = add_modifiers($2, HLSL_MODIFIER_CONST, get_location(&@1));
2087 | KW_ROW_MAJOR var_modifiers
2089 $$ = add_modifiers($2, HLSL_MODIFIER_ROW_MAJOR, get_location(&@1));
2091 | KW_COLUMN_MAJOR var_modifiers
2093 $$ = add_modifiers($2, HLSL_MODIFIER_COLUMN_MAJOR, get_location(&@1));
2096 complex_initializer: initializer_expr
2098 $$.args_count = 1;
2099 if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args))))
2100 YYABORT;
2101 $$.args[0] = node_from_list($1);
2102 $$.instrs = $1;
2104 | '{' initializer_expr_list '}'
2106 $$ = $2;
2108 | '{' initializer_expr_list ',' '}'
2110 $$ = $2;
2113 initializer_expr: assignment_expr
2115 $$ = $1;
2118 initializer_expr_list: initializer_expr
2120 $$.args_count = 1;
2121 if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args))))
2122 YYABORT;
2123 $$.args[0] = node_from_list($1);
2124 $$.instrs = $1;
2126 | initializer_expr_list ',' initializer_expr
2128 $$ = $1;
2129 if (!($$.args = d3dcompiler_realloc($$.args, ($$.args_count + 1) * sizeof(*$$.args))))
2130 YYABORT;
2131 $$.args[$$.args_count++] = node_from_list($3);
2132 list_move_tail($$.instrs, $3);
2133 d3dcompiler_free($3);
2136 boolean: KW_TRUE
2138 $$ = TRUE;
2140 | KW_FALSE
2142 $$ = FALSE;
2145 statement_list: statement
2147 $$ = $1;
2149 | statement_list statement
2151 $$ = $1;
2152 list_move_tail($$, $2);
2153 d3dcompiler_free($2);
2156 statement: declaration_statement
2157 | expr_statement
2158 | compound_statement
2159 | jump_statement
2160 | selection_statement
2161 | loop_statement
2163 jump_statement: KW_RETURN expr ';'
2165 struct hlsl_ir_jump *jump;
2166 if (!(jump = new_return(node_from_list($2), get_location(&@1))))
2167 YYABORT;
2169 $$ = $2;
2170 list_add_tail($$, &jump->node.entry);
2172 | KW_RETURN ';'
2174 struct hlsl_ir_jump *jump;
2175 if (!(jump = new_return(NULL, get_location(&@1))))
2176 YYABORT;
2177 $$ = d3dcompiler_alloc(sizeof(*$$));
2178 list_init($$);
2179 list_add_tail($$, &jump->node.entry);
2182 selection_statement: KW_IF '(' expr ')' if_body
2184 struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
2185 if (!instr)
2187 ERR("Out of memory\n");
2188 YYABORT;
2190 init_node(&instr->node, HLSL_IR_IF, NULL, get_location(&@1));
2191 instr->condition = node_from_list($3);
2192 instr->then_instrs = $5.then_instrs;
2193 instr->else_instrs = $5.else_instrs;
2194 if (instr->condition->data_type->dimx > 1 || instr->condition->data_type->dimy > 1)
2196 hlsl_report_message(instr->node.loc, HLSL_LEVEL_ERROR,
2197 "if condition requires a scalar");
2199 $$ = $3;
2200 list_add_tail($$, &instr->node.entry);
2203 if_body: statement
2205 $$.then_instrs = $1;
2206 $$.else_instrs = NULL;
2208 | statement KW_ELSE statement
2210 $$.then_instrs = $1;
2211 $$.else_instrs = $3;
2214 loop_statement: KW_WHILE '(' expr ')' statement
2216 $$ = create_loop(LOOP_WHILE, NULL, $3, NULL, $5, get_location(&@1));
2218 | KW_DO statement KW_WHILE '(' expr ')' ';'
2220 $$ = create_loop(LOOP_DO_WHILE, NULL, $5, NULL, $2, get_location(&@1));
2222 | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
2224 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1));
2225 pop_scope(&hlsl_ctx);
2227 | KW_FOR '(' scope_start declaration expr_statement expr ')' statement
2229 if (!$4)
2230 hlsl_report_message(get_location(&@4), HLSL_LEVEL_WARNING,
2231 "no expressions in for loop initializer");
2232 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1));
2233 pop_scope(&hlsl_ctx);
2236 expr_statement: ';'
2238 $$ = d3dcompiler_alloc(sizeof(*$$));
2239 list_init($$);
2241 | expr ';'
2243 $$ = $1;
2246 primary_expr: C_FLOAT
2248 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
2249 if (!c)
2251 ERR("Out of memory.\n");
2252 YYABORT;
2254 init_node(&c->node, HLSL_IR_CONSTANT,
2255 hlsl_ctx.builtin_types.scalar[HLSL_TYPE_FLOAT], get_location(&@1));
2256 c->v.value.f[0] = $1;
2257 if (!($$ = make_list(&c->node)))
2258 YYABORT;
2260 | C_INTEGER
2262 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
2263 if (!c)
2265 ERR("Out of memory.\n");
2266 YYABORT;
2268 init_node(&c->node, HLSL_IR_CONSTANT,
2269 hlsl_ctx.builtin_types.scalar[HLSL_TYPE_INT], get_location(&@1));
2270 c->v.value.i[0] = $1;
2271 if (!($$ = make_list(&c->node)))
2272 YYABORT;
2274 | boolean
2276 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
2277 if (!c)
2279 ERR("Out of memory.\n");
2280 YYABORT;
2282 init_node(&c->node, HLSL_IR_CONSTANT,
2283 hlsl_ctx.builtin_types.scalar[HLSL_TYPE_BOOL], get_location(&@1));
2284 c->v.value.b[0] = $1;
2285 if (!($$ = make_list(&c->node)))
2286 YYABORT;
2288 | VAR_IDENTIFIER
2290 struct hlsl_ir_load *load;
2291 struct hlsl_ir_var *var;
2293 if (!(var = get_variable(hlsl_ctx.cur_scope, $1)))
2295 hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR,
2296 "variable '%s' is not declared\n", $1);
2297 YYABORT;
2299 if ((load = new_var_load(var, get_location(&@1))))
2301 if (!($$ = make_list(&load->node)))
2302 YYABORT;
2304 else
2305 $$ = NULL;
2307 | '(' expr ')'
2309 $$ = $2;
2312 postfix_expr: primary_expr
2314 $$ = $1;
2316 | postfix_expr OP_INC
2318 struct source_location loc;
2319 struct hlsl_ir_node *inc;
2321 loc = get_location(&@2);
2322 if (node_from_list($1)->data_type->modifiers & HLSL_MODIFIER_CONST)
2324 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression");
2325 YYABORT;
2327 inc = new_unary_expr(HLSL_IR_UNOP_POSTINC, node_from_list($1), loc);
2328 /* Post increment/decrement expressions are considered const */
2329 inc->data_type = clone_hlsl_type(inc->data_type, 0);
2330 inc->data_type->modifiers |= HLSL_MODIFIER_CONST;
2331 $$ = append_unop($1, inc);
2333 | postfix_expr OP_DEC
2335 struct source_location loc;
2336 struct hlsl_ir_node *inc;
2338 loc = get_location(&@2);
2339 if (node_from_list($1)->data_type->modifiers & HLSL_MODIFIER_CONST)
2341 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression");
2342 YYABORT;
2344 inc = new_unary_expr(HLSL_IR_UNOP_POSTDEC, node_from_list($1), loc);
2345 /* Post increment/decrement expressions are considered const */
2346 inc->data_type = clone_hlsl_type(inc->data_type, 0);
2347 inc->data_type->modifiers |= HLSL_MODIFIER_CONST;
2348 $$ = append_unop($1, inc);
2350 | postfix_expr '.' any_identifier
2352 struct hlsl_ir_node *node = node_from_list($1);
2353 struct source_location loc;
2355 loc = get_location(&@2);
2356 if (node->data_type->type == HLSL_CLASS_STRUCT)
2358 struct hlsl_type *type = node->data_type;
2359 struct hlsl_struct_field *field;
2361 $$ = NULL;
2362 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
2364 if (!strcmp($3, field->name))
2366 if (!new_record_load(node, field, loc))
2367 YYABORT;
2368 $$ = $1;
2369 break;
2372 if (!$$)
2374 hlsl_report_message(loc, HLSL_LEVEL_ERROR,
2375 "invalid subscript %s", debugstr_a($3));
2376 YYABORT;
2379 else if (node->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
2381 struct hlsl_ir_swizzle *swizzle;
2383 swizzle = get_swizzle(node, $3, &loc);
2384 if (!swizzle)
2386 hlsl_report_message(loc, HLSL_LEVEL_ERROR,
2387 "invalid swizzle %s", debugstr_a($3));
2388 YYABORT;
2390 $$ = append_unop($1, &swizzle->node);
2392 else
2394 hlsl_report_message(loc, HLSL_LEVEL_ERROR,
2395 "invalid subscript %s", debugstr_a($3));
2396 YYABORT;
2399 | postfix_expr '[' expr ']'
2401 struct hlsl_ir_load *load;
2403 if (node_from_list($3)->data_type->type != HLSL_CLASS_SCALAR)
2405 hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR, "array index is not scalar");
2406 free_instr_list($1);
2407 free_instr_list($3);
2408 YYABORT;
2411 if (!(load = new_array_load(node_from_list($1), node_from_list($3), get_location(&@2))))
2413 free_instr_list($1);
2414 free_instr_list($3);
2415 YYABORT;
2417 $$ = append_binop($1, $3, &load->node);
2419 /* "var_modifiers" doesn't make sense in this case, but it's needed
2420 in the grammar to avoid shift/reduce conflicts. */
2421 | var_modifiers type '(' initializer_expr_list ')'
2423 struct hlsl_ir_constructor *constructor;
2425 TRACE("%s constructor.\n", debug_hlsl_type($2));
2426 if ($1)
2428 hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR,
2429 "unexpected modifier on a constructor\n");
2430 YYABORT;
2432 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
2434 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
2435 "constructors may only be used with numeric data types\n");
2436 YYABORT;
2438 if ($2->dimx * $2->dimy != initializer_size(&$4))
2440 hlsl_report_message(get_location(&@4), HLSL_LEVEL_ERROR,
2441 "expected %u components in constructor, but got %u\n",
2442 $2->dimx * $2->dimy, initializer_size(&$4));
2443 YYABORT;
2445 assert($4.args_count <= ARRAY_SIZE(constructor->args));
2447 constructor = d3dcompiler_alloc(sizeof(*constructor));
2448 init_node(&constructor->node, HLSL_IR_CONSTRUCTOR, $2, get_location(&@3));
2449 constructor->args_count = $4.args_count;
2450 memcpy(constructor->args, $4.args, $4.args_count * sizeof(*$4.args));
2451 d3dcompiler_free($4.args);
2452 $$ = append_unop($4.instrs, &constructor->node);
2455 unary_expr: postfix_expr
2457 $$ = $1;
2459 | OP_INC unary_expr
2461 struct source_location loc;
2463 loc = get_location(&@1);
2464 if (node_from_list($2)->data_type->modifiers & HLSL_MODIFIER_CONST)
2466 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression");
2467 YYABORT;
2469 $$ = append_unop($2, new_unary_expr(HLSL_IR_UNOP_PREINC, node_from_list($2), loc));
2471 | OP_DEC unary_expr
2473 struct source_location loc;
2475 loc = get_location(&@1);
2476 if (node_from_list($2)->data_type->modifiers & HLSL_MODIFIER_CONST)
2478 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression");
2479 YYABORT;
2481 $$ = append_unop($2, new_unary_expr(HLSL_IR_UNOP_PREDEC, node_from_list($2), loc));
2483 | unary_op unary_expr
2485 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
2486 HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
2488 if ($1 == UNARY_OP_PLUS)
2490 $$ = $2;
2492 else
2494 $$ = append_unop($2, new_unary_expr(ops[$1], node_from_list($2), get_location(&@1)));
2497 /* var_modifiers just to avoid shift/reduce conflicts */
2498 | '(' var_modifiers type array ')' unary_expr
2500 struct hlsl_type *src_type = node_from_list($6)->data_type;
2501 struct hlsl_type *dst_type;
2502 struct source_location loc;
2504 loc = get_location(&@3);
2505 if ($2)
2507 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "unexpected modifier in a cast");
2508 YYABORT;
2511 if ($4)
2512 dst_type = new_array_type($3, $4);
2513 else
2514 dst_type = $3;
2516 if (!compatible_data_types(src_type, dst_type))
2518 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "can't cast from %s to %s",
2519 debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
2520 YYABORT;
2523 $$ = append_unop($6, &new_cast(node_from_list($6), dst_type, &loc)->node);
2526 unary_op: '+'
2528 $$ = UNARY_OP_PLUS;
2530 | '-'
2532 $$ = UNARY_OP_MINUS;
2534 | '!'
2536 $$ = UNARY_OP_LOGICNOT;
2538 | '~'
2540 $$ = UNARY_OP_BITNOT;
2543 mul_expr: unary_expr
2545 $$ = $1;
2547 | mul_expr '*' unary_expr
2549 $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_MUL,
2550 node_from_list($1), node_from_list($3), get_location(&@2)));
2552 | mul_expr '/' unary_expr
2554 $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_DIV,
2555 node_from_list($1), node_from_list($3), get_location(&@2)));
2557 | mul_expr '%' unary_expr
2559 $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_MOD,
2560 node_from_list($1), node_from_list($3), get_location(&@2)));
2563 add_expr: mul_expr
2565 $$ = $1;
2567 | add_expr '+' mul_expr
2569 $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_ADD,
2570 node_from_list($1), node_from_list($3), get_location(&@2)));
2572 | add_expr '-' mul_expr
2574 $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_SUB,
2575 node_from_list($1), node_from_list($3), get_location(&@2)));
2578 shift_expr: add_expr
2580 $$ = $1;
2582 | shift_expr OP_LEFTSHIFT add_expr
2584 FIXME("Left shift\n");
2586 | shift_expr OP_RIGHTSHIFT add_expr
2588 FIXME("Right shift\n");
2591 relational_expr: shift_expr
2593 $$ = $1;
2595 | relational_expr '<' shift_expr
2597 $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_LESS,
2598 node_from_list($1), node_from_list($3), get_location(&@2)));
2600 | relational_expr '>' shift_expr
2602 $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_GREATER,
2603 node_from_list($1), node_from_list($3), get_location(&@2)));
2605 | relational_expr OP_LE shift_expr
2607 $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_LEQUAL,
2608 node_from_list($1), node_from_list($3), get_location(&@2)));
2610 | relational_expr OP_GE shift_expr
2612 $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_GEQUAL,
2613 node_from_list($1), node_from_list($3), get_location(&@2)));
2616 equality_expr: relational_expr
2618 $$ = $1;
2620 | equality_expr OP_EQ relational_expr
2622 $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_EQUAL,
2623 node_from_list($1), node_from_list($3), get_location(&@2)));
2625 | equality_expr OP_NE relational_expr
2627 $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_NEQUAL,
2628 node_from_list($1), node_from_list($3), get_location(&@2)));
2631 bitand_expr: equality_expr
2633 $$ = $1;
2635 | bitand_expr '&' equality_expr
2637 FIXME("bitwise AND\n");
2640 bitxor_expr: bitand_expr
2642 $$ = $1;
2644 | bitxor_expr '^' bitand_expr
2646 FIXME("bitwise XOR\n");
2649 bitor_expr: bitxor_expr
2651 $$ = $1;
2653 | bitor_expr '|' bitxor_expr
2655 FIXME("bitwise OR\n");
2658 logicand_expr: bitor_expr
2660 $$ = $1;
2662 | logicand_expr OP_AND bitor_expr
2664 FIXME("logic AND\n");
2667 logicor_expr: logicand_expr
2669 $$ = $1;
2671 | logicor_expr OP_OR logicand_expr
2673 FIXME("logic OR\n");
2676 conditional_expr: logicor_expr
2678 $$ = $1;
2680 | logicor_expr '?' expr ':' assignment_expr
2682 FIXME("ternary operator\n");
2685 assignment_expr: conditional_expr
2687 $$ = $1;
2689 | unary_expr assign_op assignment_expr
2691 struct hlsl_ir_node *instr;
2693 if (node_from_list($1)->data_type->modifiers & HLSL_MODIFIER_CONST)
2695 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR, "l-value is const");
2696 YYABORT;
2698 if (!(instr = make_assignment(node_from_list($1), $2, node_from_list($3))))
2699 YYABORT;
2700 instr->loc = get_location(&@2);
2701 $$ = append_binop($3, $1, instr);
2704 assign_op: '='
2706 $$ = ASSIGN_OP_ASSIGN;
2708 | OP_ADDASSIGN
2710 $$ = ASSIGN_OP_ADD;
2712 | OP_SUBASSIGN
2714 $$ = ASSIGN_OP_SUB;
2716 | OP_MULASSIGN
2718 $$ = ASSIGN_OP_MUL;
2720 | OP_DIVASSIGN
2722 $$ = ASSIGN_OP_DIV;
2724 | OP_MODASSIGN
2726 $$ = ASSIGN_OP_MOD;
2728 | OP_LEFTSHIFTASSIGN
2730 $$ = ASSIGN_OP_LSHIFT;
2732 | OP_RIGHTSHIFTASSIGN
2734 $$ = ASSIGN_OP_RSHIFT;
2736 | OP_ANDASSIGN
2738 $$ = ASSIGN_OP_AND;
2740 | OP_ORASSIGN
2742 $$ = ASSIGN_OP_OR;
2744 | OP_XORASSIGN
2746 $$ = ASSIGN_OP_XOR;
2749 expr: assignment_expr
2751 $$ = $1;
2753 | expr ',' assignment_expr
2755 $$ = $1;
2756 list_move_tail($$, $3);
2757 d3dcompiler_free($3);
2762 static struct source_location get_location(const struct YYLTYPE *l)
2764 const struct source_location loc =
2766 .file = hlsl_ctx.source_file,
2767 .line = l->first_line,
2768 .col = l->first_column,
2770 return loc;
2773 static void dump_function_decl(struct wine_rb_entry *entry, void *context)
2775 struct hlsl_ir_function_decl *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
2776 if (func->body)
2777 debug_dump_ir_function_decl(func);
2780 static void dump_function(struct wine_rb_entry *entry, void *context)
2782 struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
2783 wine_rb_for_each_entry(&func->overloads, dump_function_decl, NULL);
2786 /* Allocate a unique, ordered index to each instruction, which will be used for
2787 * computing liveness ranges. */
2788 static unsigned int index_instructions(struct list *instrs, unsigned int index)
2790 struct hlsl_ir_node *instr;
2792 LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry)
2794 instr->index = index++;
2796 if (instr->type == HLSL_IR_IF)
2798 struct hlsl_ir_if *iff = if_from_node(instr);
2799 index = index_instructions(iff->then_instrs, index);
2800 if (iff->else_instrs)
2801 index = index_instructions(iff->else_instrs, index);
2803 else if (instr->type == HLSL_IR_LOOP)
2805 index = index_instructions(loop_from_node(instr)->body, index);
2806 loop_from_node(instr)->next_index = index;
2810 return index;
2813 /* Compute the earliest and latest liveness for each variable. In the case that
2814 * a variable is accessed inside of a loop, we promote its liveness to extend
2815 * to at least the range of the entire loop. Note that we don't need to do this
2816 * for anonymous nodes, since there's currently no way to use a node which was
2817 * calculated in an earlier iteration of the loop. */
2818 static void compute_liveness_recurse(struct list *instrs, unsigned int loop_first, unsigned int loop_last)
2820 struct hlsl_ir_node *instr;
2821 struct hlsl_ir_var *var;
2823 LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry)
2825 switch (instr->type)
2827 case HLSL_IR_ASSIGNMENT:
2829 struct hlsl_ir_assignment *assignment = assignment_from_node(instr);
2830 var = assignment->lhs.var;
2831 if (!var->first_write)
2832 var->first_write = loop_first ? min(instr->index, loop_first) : instr->index;
2833 assignment->rhs->last_read = instr->index;
2834 if (assignment->lhs.offset)
2835 assignment->lhs.offset->last_read = instr->index;
2836 break;
2838 case HLSL_IR_CONSTRUCTOR:
2840 struct hlsl_ir_constructor *constructor = constructor_from_node(instr);
2841 unsigned int i;
2842 for (i = 0; i < constructor->args_count; ++i)
2843 constructor->args[i]->last_read = instr->index;
2844 break;
2846 case HLSL_IR_EXPR:
2848 struct hlsl_ir_expr *expr = expr_from_node(instr);
2849 expr->operands[0]->last_read = instr->index;
2850 if (expr->operands[1])
2851 expr->operands[1]->last_read = instr->index;
2852 if (expr->operands[2])
2853 expr->operands[2]->last_read = instr->index;
2854 break;
2856 case HLSL_IR_IF:
2858 struct hlsl_ir_if *iff = if_from_node(instr);
2859 compute_liveness_recurse(iff->then_instrs, loop_first, loop_last);
2860 if (iff->else_instrs)
2861 compute_liveness_recurse(iff->else_instrs, loop_first, loop_last);
2862 iff->condition->last_read = instr->index;
2863 break;
2865 case HLSL_IR_LOAD:
2867 struct hlsl_ir_load *load = load_from_node(instr);
2868 var = load->src.var;
2869 var->last_read = loop_last ? max(instr->index, loop_last) : instr->index;
2870 if (load->src.offset)
2871 load->src.offset->last_read = instr->index;
2872 break;
2874 case HLSL_IR_LOOP:
2876 struct hlsl_ir_loop *loop = loop_from_node(instr);
2877 compute_liveness_recurse(loop->body, loop_first ? loop_first : instr->index,
2878 loop_last ? loop_last : loop->next_index);
2879 break;
2881 case HLSL_IR_SWIZZLE:
2883 struct hlsl_ir_swizzle *swizzle = swizzle_from_node(instr);
2884 swizzle->val->last_read = instr->index;
2885 break;
2887 case HLSL_IR_CONSTANT:
2888 case HLSL_IR_JUMP:
2889 break;
2894 static void compute_liveness(struct hlsl_ir_function_decl *entry_func)
2896 struct hlsl_ir_var *var;
2898 LIST_FOR_EACH_ENTRY(var, &hlsl_ctx.globals->vars, struct hlsl_ir_var, scope_entry)
2900 var->first_write = 1;
2903 LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry)
2905 if (var->modifiers & HLSL_STORAGE_IN)
2906 var->first_write = 1;
2907 if (var->modifiers & HLSL_STORAGE_OUT)
2908 var->last_read = UINT_MAX;
2911 if (entry_func->return_var)
2912 entry_func->return_var->last_read = UINT_MAX;
2914 compute_liveness_recurse(entry_func->body, 0, 0);
2917 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
2918 const char *entrypoint, char **messages)
2920 struct hlsl_ir_function_decl *entry_func;
2921 struct hlsl_scope *scope, *next_scope;
2922 struct hlsl_type *hlsl_type, *next_type;
2923 struct hlsl_ir_var *var, *next_var;
2924 unsigned int i;
2926 hlsl_ctx.status = PARSE_SUCCESS;
2927 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
2928 hlsl_ctx.line_no = hlsl_ctx.column = 1;
2929 hlsl_ctx.source_file = d3dcompiler_strdup("");
2930 hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
2931 if (hlsl_ctx.source_files)
2932 hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
2933 hlsl_ctx.source_files_count = 1;
2934 hlsl_ctx.cur_scope = NULL;
2935 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
2936 list_init(&hlsl_ctx.scopes);
2937 list_init(&hlsl_ctx.types);
2938 init_functions_tree(&hlsl_ctx.functions);
2940 push_scope(&hlsl_ctx);
2941 hlsl_ctx.globals = hlsl_ctx.cur_scope;
2942 declare_predefined_types(hlsl_ctx.globals);
2944 hlsl_parse();
2946 TRACE("Compilation status = %d\n", hlsl_ctx.status);
2947 if (messages)
2949 if (hlsl_ctx.messages.size)
2950 *messages = hlsl_ctx.messages.string;
2951 else
2952 *messages = NULL;
2954 else
2956 if (hlsl_ctx.messages.capacity)
2957 d3dcompiler_free(hlsl_ctx.messages.string);
2960 for (i = 0; i < hlsl_ctx.source_files_count; ++i)
2961 d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
2962 d3dcompiler_free(hlsl_ctx.source_files);
2964 if (hlsl_ctx.status == PARSE_ERR)
2965 goto out;
2967 if (!(entry_func = get_func_entry(entrypoint)))
2969 hlsl_message("error: entry point %s is not defined\n", debugstr_a(entrypoint));
2970 goto out;
2973 /* Index 0 means unused; index 1 means function entry, so start at 2. */
2974 index_instructions(entry_func->body, 2);
2976 if (TRACE_ON(hlsl_parser))
2978 TRACE("IR dump.\n");
2979 wine_rb_for_each_entry(&hlsl_ctx.functions, dump_function, NULL);
2982 compute_liveness(entry_func);
2984 out:
2985 TRACE("Freeing functions IR.\n");
2986 wine_rb_destroy(&hlsl_ctx.functions, free_function_rb, NULL);
2988 TRACE("Freeing variables.\n");
2989 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
2991 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
2993 free_declaration(var);
2995 wine_rb_destroy(&scope->types, NULL, NULL);
2996 d3dcompiler_free(scope);
2999 TRACE("Freeing types.\n");
3000 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
3002 free_hlsl_type(hlsl_type);
3005 return NULL;