rasapi32: Update spec file.
[wine/zf.git] / dlls / d3dcompiler_43 / hlsl.y
blobb0270b6ba2ced2fcc460c66de78f37779188d614
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 struct hlsl_ir_if *new_if(struct hlsl_ir_node *condition, struct source_location loc)
289 struct hlsl_ir_if *iff;
291 if (!(iff = d3dcompiler_alloc(sizeof(*iff))))
292 return NULL;
293 init_node(&iff->node, HLSL_IR_IF, NULL, loc);
294 hlsl_src_from_node(&iff->condition, condition);
295 list_init(&iff->then_instrs);
296 list_init(&iff->else_instrs);
297 return iff;
300 static BOOL append_conditional_break(struct list *cond_list)
302 struct hlsl_ir_node *condition, *not;
303 struct hlsl_ir_jump *jump;
304 struct hlsl_ir_if *iff;
306 /* E.g. "for (i = 0; ; ++i)". */
307 if (!list_count(cond_list))
308 return TRUE;
310 condition = node_from_list(cond_list);
311 if (!(not = new_unary_expr(HLSL_IR_UNOP_LOGIC_NOT, condition, condition->loc)))
313 ERR("Out of memory.\n");
314 return FALSE;
316 list_add_tail(cond_list, &not->entry);
318 if (!(iff = new_if(not, condition->loc)))
320 ERR("Out of memory.\n");
321 return FALSE;
323 list_add_tail(cond_list, &iff->node.entry);
325 if (!(jump = d3dcompiler_alloc(sizeof(*jump))))
327 ERR("Out of memory.\n");
328 return FALSE;
330 init_node(&jump->node, HLSL_IR_JUMP, NULL, condition->loc);
331 jump->type = HLSL_IR_JUMP_BREAK;
332 list_add_head(&iff->then_instrs, &jump->node.entry);
333 return TRUE;
336 enum loop_type
338 LOOP_FOR,
339 LOOP_WHILE,
340 LOOP_DO_WHILE
343 static struct list *create_loop(enum loop_type type, struct list *init, struct list *cond,
344 struct list *iter, struct list *body, struct source_location loc)
346 struct list *list = NULL;
347 struct hlsl_ir_loop *loop = NULL;
348 struct hlsl_ir_if *cond_jump = NULL;
350 list = d3dcompiler_alloc(sizeof(*list));
351 if (!list)
352 goto oom;
353 list_init(list);
355 if (init)
356 list_move_head(list, init);
358 loop = d3dcompiler_alloc(sizeof(*loop));
359 if (!loop)
360 goto oom;
361 init_node(&loop->node, HLSL_IR_LOOP, NULL, loc);
362 list_add_tail(list, &loop->node.entry);
363 list_init(&loop->body);
365 if (!append_conditional_break(cond))
366 goto oom;
368 if (type != LOOP_DO_WHILE)
369 list_move_tail(&loop->body, cond);
371 list_move_tail(&loop->body, body);
373 if (iter)
374 list_move_tail(&loop->body, iter);
376 if (type == LOOP_DO_WHILE)
377 list_move_tail(&loop->body, cond);
379 d3dcompiler_free(init);
380 d3dcompiler_free(cond);
381 d3dcompiler_free(body);
382 return list;
384 oom:
385 ERR("Out of memory.\n");
386 d3dcompiler_free(loop);
387 d3dcompiler_free(cond_jump);
388 d3dcompiler_free(list);
389 free_instr_list(init);
390 free_instr_list(cond);
391 free_instr_list(iter);
392 free_instr_list(body);
393 return NULL;
396 static unsigned int initializer_size(const struct parse_initializer *initializer)
398 unsigned int count = 0, i;
400 for (i = 0; i < initializer->args_count; ++i)
402 count += components_count_type(initializer->args[i]->data_type);
404 TRACE("Initializer size = %u.\n", count);
405 return count;
408 static void free_parse_initializer(struct parse_initializer *initializer)
410 free_instr_list(initializer->instrs);
411 d3dcompiler_free(initializer->args);
414 static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components,
415 struct hlsl_ir_node *val, struct source_location *loc)
417 struct hlsl_ir_swizzle *swizzle = d3dcompiler_alloc(sizeof(*swizzle));
419 if (!swizzle)
420 return NULL;
421 init_node(&swizzle->node, HLSL_IR_SWIZZLE,
422 new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1), *loc);
423 hlsl_src_from_node(&swizzle->val, val);
424 swizzle->swizzle = s;
425 return swizzle;
428 static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const char *swizzle,
429 struct source_location *loc)
431 unsigned int len = strlen(swizzle), component = 0;
432 unsigned int i, set, swiz = 0;
433 BOOL valid;
435 if (value->data_type->type == HLSL_CLASS_MATRIX)
437 /* Matrix swizzle */
438 BOOL m_swizzle;
439 unsigned int inc, x, y;
441 if (len < 3 || swizzle[0] != '_')
442 return NULL;
443 m_swizzle = swizzle[1] == 'm';
444 inc = m_swizzle ? 4 : 3;
446 if (len % inc || len > inc * 4)
447 return NULL;
449 for (i = 0; i < len; i += inc)
451 if (swizzle[i] != '_')
452 return NULL;
453 if (m_swizzle)
455 if (swizzle[i + 1] != 'm')
456 return NULL;
457 y = swizzle[i + 2] - '0';
458 x = swizzle[i + 3] - '0';
460 else
462 y = swizzle[i + 1] - '1';
463 x = swizzle[i + 2] - '1';
466 if (x >= value->data_type->dimx || y >= value->data_type->dimy)
467 return NULL;
468 swiz |= (y << 4 | x) << component * 8;
469 component++;
471 return new_swizzle(swiz, component, value, loc);
474 /* Vector swizzle */
475 if (len > 4)
476 return NULL;
478 for (set = 0; set < 2; ++set)
480 valid = TRUE;
481 component = 0;
482 for (i = 0; i < len; ++i)
484 char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}};
485 unsigned int s = 0;
487 for (s = 0; s < 4; ++s)
489 if (swizzle[i] == c[set][s])
490 break;
492 if (s == 4)
494 valid = FALSE;
495 break;
498 if (s >= value->data_type->dimx)
499 return NULL;
500 swiz |= s << component * 2;
501 component++;
503 if (valid)
504 return new_swizzle(swiz, component, value, loc);
507 return NULL;
510 static struct hlsl_ir_var *new_var(const char *name, struct hlsl_type *type, const struct source_location loc,
511 const char *semantic, unsigned int modifiers, const struct reg_reservation *reg_reservation)
513 struct hlsl_ir_var *var;
515 if (!(var = d3dcompiler_alloc(sizeof(*var))))
517 hlsl_ctx.status = PARSE_ERR;
518 return NULL;
521 var->name = name;
522 var->data_type = type;
523 var->loc = loc;
524 var->semantic = semantic;
525 var->modifiers = modifiers;
526 var->reg_reservation = reg_reservation;
527 return var;
530 static struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type *type,
531 const struct source_location loc)
533 struct hlsl_ir_var *var = new_var(strdup(name), type, loc, NULL, 0, NULL);
535 if (var)
536 list_add_tail(&hlsl_ctx.globals->vars, &var->scope_entry);
537 return var;
540 static struct hlsl_ir_assignment *new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
541 struct hlsl_ir_node *rhs, unsigned int writemask, struct source_location loc)
543 struct hlsl_ir_assignment *assign;
545 if (!writemask && type_is_single_reg(rhs->data_type))
546 writemask = (1 << rhs->data_type->dimx) - 1;
548 if (!(assign = d3dcompiler_alloc(sizeof(*assign))))
549 return NULL;
551 init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, loc);
552 assign->lhs.var = var;
553 hlsl_src_from_node(&assign->lhs.offset, offset);
554 hlsl_src_from_node(&assign->rhs, rhs);
555 assign->writemask = writemask;
556 return assign;
559 static struct hlsl_ir_assignment *new_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs)
561 return new_assignment(lhs, NULL, rhs, 0, rhs->loc);
564 static struct hlsl_ir_jump *add_return(struct list *instrs,
565 struct hlsl_ir_node *return_value, struct source_location loc)
567 struct hlsl_type *return_type = hlsl_ctx.cur_function->return_type;
568 struct hlsl_ir_jump *jump;
570 if (return_value)
572 struct hlsl_ir_assignment *assignment;
574 if (!(return_value = add_implicit_conversion(instrs, return_value, return_type, &loc)))
575 return NULL;
577 if (!(assignment = new_simple_assignment(hlsl_ctx.cur_function->return_var, return_value)))
578 return NULL;
579 list_add_after(&return_value->entry, &assignment->node.entry);
581 else if (!type_is_void(return_type))
583 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "non-void function must return a value");
584 return NULL;
587 if (!(jump = d3dcompiler_alloc(sizeof(*jump))))
589 ERR("Out of memory\n");
590 return NULL;
592 init_node(&jump->node, HLSL_IR_JUMP, NULL, loc);
593 jump->type = HLSL_IR_JUMP_RETURN;
594 list_add_tail(instrs, &jump->node.entry);
596 return jump;
599 static struct hlsl_ir_constant *new_uint_constant(unsigned int n, const struct source_location loc)
601 struct hlsl_ir_constant *c;
603 if (!(c = d3dcompiler_alloc(sizeof(*c))))
604 return NULL;
605 init_node(&c->node, HLSL_IR_CONSTANT, hlsl_ctx.builtin_types.scalar[HLSL_TYPE_UINT], loc);
606 c->value.u[0] = n;
607 return c;
610 struct hlsl_ir_node *new_unary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, struct source_location loc)
612 struct hlsl_ir_expr *expr;
614 if (!(expr = d3dcompiler_alloc(sizeof(*expr))))
615 return NULL;
616 init_node(&expr->node, HLSL_IR_EXPR, arg->data_type, loc);
617 expr->op = op;
618 hlsl_src_from_node(&expr->operands[0], arg);
619 return &expr->node;
622 struct hlsl_ir_node *new_binary_expr(enum hlsl_ir_expr_op op,
623 struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2)
625 struct hlsl_ir_expr *expr;
627 assert(compare_hlsl_types(arg1->data_type, arg2->data_type));
629 if (!(expr = d3dcompiler_alloc(sizeof(*expr))))
630 return NULL;
631 init_node(&expr->node, HLSL_IR_EXPR, arg1->data_type, arg1->loc);
632 expr->op = op;
633 hlsl_src_from_node(&expr->operands[0], arg1);
634 hlsl_src_from_node(&expr->operands[1], arg2);
635 return &expr->node;
638 static struct hlsl_ir_load *new_var_load(struct hlsl_ir_var *var, const struct source_location loc)
640 struct hlsl_ir_load *load = d3dcompiler_alloc(sizeof(*load));
642 if (!load)
644 ERR("Out of memory.\n");
645 return NULL;
647 init_node(&load->node, HLSL_IR_LOAD, var->data_type, loc);
648 load->src.var = var;
649 return load;
652 static struct hlsl_ir_load *add_load(struct list *instrs, struct hlsl_ir_node *var_node, struct hlsl_ir_node *offset,
653 struct hlsl_type *data_type, const struct source_location loc)
655 struct hlsl_ir_node *add = NULL;
656 struct hlsl_ir_load *load;
657 struct hlsl_ir_var *var;
659 if (var_node->type == HLSL_IR_LOAD)
661 const struct hlsl_deref *src = &load_from_node(var_node)->src;
663 var = src->var;
664 if (src->offset.node)
666 if (!(add = new_binary_expr(HLSL_IR_BINOP_ADD, src->offset.node, offset)))
667 return NULL;
668 list_add_tail(instrs, &add->entry);
669 offset = add;
672 else
674 struct hlsl_ir_assignment *assign;
675 char name[27];
677 sprintf(name, "<deref-%p>", var_node);
678 if (!(var = new_synthetic_var(name, var_node->data_type, var_node->loc)))
679 return NULL;
681 TRACE("Synthesized variable %p for %s node.\n", var, debug_node_type(var_node->type));
683 if (!(assign = new_simple_assignment(var, var_node)))
684 return NULL;
686 list_add_tail(instrs, &assign->node.entry);
689 if (!(load = d3dcompiler_alloc(sizeof(*load))))
690 return NULL;
691 init_node(&load->node, HLSL_IR_LOAD, data_type, loc);
692 load->src.var = var;
693 hlsl_src_from_node(&load->src.offset, offset);
694 list_add_tail(instrs, &load->node.entry);
695 return load;
698 static struct hlsl_ir_load *add_record_load(struct list *instrs, struct hlsl_ir_node *record,
699 const struct hlsl_struct_field *field, const struct source_location loc)
701 struct hlsl_ir_constant *c;
703 if (!(c = new_uint_constant(field->reg_offset * 4, loc)))
704 return NULL;
705 list_add_tail(instrs, &c->node.entry);
707 return add_load(instrs, record, &c->node, field->type, loc);
710 static struct hlsl_ir_load *add_array_load(struct list *instrs, struct hlsl_ir_node *array,
711 struct hlsl_ir_node *index, const struct source_location loc)
713 const struct hlsl_type *expr_type = array->data_type;
714 struct hlsl_type *data_type;
715 struct hlsl_ir_constant *c;
716 struct hlsl_ir_node *mul;
718 TRACE("Array load from type %s.\n", debug_hlsl_type(expr_type));
720 if (expr_type->type == HLSL_CLASS_ARRAY)
722 data_type = expr_type->e.array.type;
724 else if (expr_type->type == HLSL_CLASS_MATRIX || expr_type->type == HLSL_CLASS_VECTOR)
726 /* This needs to be lowered now, while we still have type information. */
727 FIXME("Index of matrix or vector type.\n");
728 return NULL;
730 else
732 if (expr_type->type == HLSL_CLASS_SCALAR)
733 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "array-indexed expression is scalar");
734 else
735 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "expression is not array-indexable");
736 return NULL;
739 if (!(c = new_uint_constant(data_type->reg_size * 4, loc)))
740 return NULL;
741 list_add_tail(instrs, &c->node.entry);
742 if (!(mul = new_binary_expr(HLSL_IR_BINOP_MUL, index, &c->node)))
743 return NULL;
744 list_add_tail(instrs, &mul->entry);
745 index = mul;
747 return add_load(instrs, array, index, data_type, loc);
750 static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var,
751 struct parse_initializer *initializer)
753 struct hlsl_type *type = var->data_type;
754 struct hlsl_struct_field *field;
755 unsigned int i = 0;
757 if (initializer_size(initializer) != components_count_type(type))
759 hlsl_report_message(var->loc, HLSL_LEVEL_ERROR, "structure initializer mismatch");
760 free_parse_initializer(initializer);
761 return;
764 list_move_tail(list, initializer->instrs);
765 d3dcompiler_free(initializer->instrs);
767 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
769 struct hlsl_ir_node *node = initializer->args[i];
770 struct hlsl_ir_assignment *assign;
771 struct hlsl_ir_constant *c;
773 if (i++ >= initializer->args_count)
774 break;
776 if (components_count_type(field->type) == components_count_type(node->data_type))
778 if (!(c = new_uint_constant(field->reg_offset * 4, node->loc)))
779 break;
780 list_add_tail(list, &c->node.entry);
782 if (!(assign = new_assignment(var, &c->node, node, 0, node->loc)))
783 break;
784 list_add_tail(list, &assign->node.entry);
786 else
787 FIXME("Initializing with \"mismatched\" fields is not supported yet.\n");
790 d3dcompiler_free(initializer->args);
793 static void free_parse_variable_def(struct parse_variable_def *v)
795 free_parse_initializer(&v->initializer);
796 d3dcompiler_free(v->name);
797 d3dcompiler_free((void *)v->semantic);
798 d3dcompiler_free(v->reg_reservation);
799 d3dcompiler_free(v);
802 static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list)
804 struct hlsl_type *type;
805 struct parse_variable_def *v, *v_next;
806 struct hlsl_ir_var *var;
807 BOOL ret, local = TRUE;
808 struct list *statements_list = d3dcompiler_alloc(sizeof(*statements_list));
810 if (basic_type->type == HLSL_CLASS_MATRIX)
811 assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
813 if (!statements_list)
815 ERR("Out of memory.\n");
816 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
817 free_parse_variable_def(v);
818 d3dcompiler_free(var_list);
819 return NULL;
821 list_init(statements_list);
823 if (!var_list)
824 return statements_list;
826 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
828 if (v->array_size)
829 type = new_array_type(basic_type, v->array_size);
830 else
831 type = basic_type;
833 if (!(var = new_var(v->name, type, v->loc, v->semantic, modifiers, v->reg_reservation)))
835 free_parse_variable_def(v);
836 continue;
838 debug_dump_decl(type, modifiers, v->name, v->loc.line);
840 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
842 var->modifiers |= HLSL_STORAGE_UNIFORM;
843 local = FALSE;
846 if (type->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer.args_count)
848 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, "const variable without initializer");
849 free_declaration(var);
850 d3dcompiler_free(v);
851 continue;
854 ret = declare_variable(var, local);
855 if (!ret)
857 free_declaration(var);
858 d3dcompiler_free(v);
859 continue;
861 TRACE("Declared variable %s.\n", var->name);
863 if (v->initializer.args_count)
865 unsigned int size = initializer_size(&v->initializer);
866 struct hlsl_ir_load *load;
868 TRACE("Variable with initializer.\n");
869 if (type->type <= HLSL_CLASS_LAST_NUMERIC
870 && type->dimx * type->dimy != size && size != 1)
872 if (size < type->dimx * type->dimy)
874 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR,
875 "'%s' initializer does not match", v->name);
876 free_parse_initializer(&v->initializer);
877 d3dcompiler_free(v);
878 continue;
881 if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY)
882 && components_count_type(type) != size)
884 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR,
885 "'%s' initializer does not match", v->name);
886 free_parse_initializer(&v->initializer);
887 d3dcompiler_free(v);
888 continue;
891 if (type->type == HLSL_CLASS_STRUCT)
893 struct_var_initializer(statements_list, var, &v->initializer);
894 d3dcompiler_free(v);
895 continue;
897 if (type->type > HLSL_CLASS_LAST_NUMERIC)
899 FIXME("Initializers for non scalar/struct variables not supported yet.\n");
900 free_parse_initializer(&v->initializer);
901 d3dcompiler_free(v);
902 continue;
904 if (v->array_size > 0)
906 FIXME("Initializing arrays is not supported yet.\n");
907 free_parse_initializer(&v->initializer);
908 d3dcompiler_free(v);
909 continue;
911 if (v->initializer.args_count > 1)
913 FIXME("Complex initializers are not supported yet.\n");
914 free_parse_initializer(&v->initializer);
915 d3dcompiler_free(v);
916 continue;
919 load = new_var_load(var, var->loc);
920 list_add_tail(v->initializer.instrs, &load->node.entry);
921 add_assignment(v->initializer.instrs, &load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]);
922 d3dcompiler_free(v->initializer.args);
924 if (modifiers & HLSL_STORAGE_STATIC)
925 list_move_tail(&hlsl_ctx.static_initializers, v->initializer.instrs);
926 else
927 list_move_tail(statements_list, v->initializer.instrs);
928 d3dcompiler_free(v->initializer.instrs);
930 d3dcompiler_free(v);
932 d3dcompiler_free(var_list);
933 return statements_list;
936 static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field)
938 struct hlsl_struct_field *f;
940 LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry)
942 if (!strcmp(f->name, field->name))
943 return FALSE;
945 list_add_tail(fields, &field->entry);
946 return TRUE;
949 BOOL is_row_major(const struct hlsl_type *type)
951 /* Default to column-major if the majority isn't explicitly set, which can
952 * happen for anonymous nodes. */
953 return !!(type->modifiers & HLSL_MODIFIER_ROW_MAJOR);
956 static struct hlsl_type *apply_type_modifiers(struct hlsl_type *type,
957 unsigned int *modifiers, struct source_location loc)
959 unsigned int default_majority = 0;
960 struct hlsl_type *new_type;
962 /* This function is only used for declarations (i.e. variables and struct
963 * fields), which should inherit the matrix majority. We only explicitly set
964 * the default majority for declarations—typedefs depend on this—but we
965 * want to always set it, so that an hlsl_type object is never used to
966 * represent two different majorities (and thus can be used to store its
967 * register size, etc.) */
968 if (!(*modifiers & HLSL_MODIFIERS_MAJORITY_MASK)
969 && !(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK)
970 && type->type == HLSL_CLASS_MATRIX)
972 if (hlsl_ctx.matrix_majority == HLSL_COLUMN_MAJOR)
973 default_majority = HLSL_MODIFIER_COLUMN_MAJOR;
974 else
975 default_majority = HLSL_MODIFIER_ROW_MAJOR;
978 if (!default_majority && !(*modifiers & HLSL_TYPE_MODIFIERS_MASK))
979 return type;
981 if (!(new_type = clone_hlsl_type(type, default_majority)))
982 return NULL;
984 new_type->modifiers = add_modifiers(new_type->modifiers, *modifiers, loc);
985 *modifiers &= ~HLSL_TYPE_MODIFIERS_MASK;
987 if (new_type->type == HLSL_CLASS_MATRIX)
988 new_type->reg_size = is_row_major(new_type) ? new_type->dimy : new_type->dimx;
989 return new_type;
992 static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, struct list *fields)
994 struct parse_variable_def *v, *v_next;
995 struct hlsl_struct_field *field;
996 struct list *list;
998 if (type->type == HLSL_CLASS_MATRIX)
999 assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
1001 list = d3dcompiler_alloc(sizeof(*list));
1002 if (!list)
1004 ERR("Out of memory.\n");
1005 return NULL;
1007 list_init(list);
1008 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry)
1010 debug_dump_decl(type, 0, v->name, v->loc.line);
1011 field = d3dcompiler_alloc(sizeof(*field));
1012 if (!field)
1014 ERR("Out of memory.\n");
1015 d3dcompiler_free(v);
1016 return list;
1018 if (v->array_size)
1019 field->type = new_array_type(type, v->array_size);
1020 else
1021 field->type = type;
1022 field->name = v->name;
1023 field->modifiers = modifiers;
1024 field->semantic = v->semantic;
1025 if (v->initializer.args_count)
1027 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, "struct field with an initializer.\n");
1028 free_parse_initializer(&v->initializer);
1030 list_add_tail(list, &field->entry);
1031 d3dcompiler_free(v);
1033 d3dcompiler_free(fields);
1034 return list;
1037 static DWORD get_array_size(const struct hlsl_type *type)
1039 if (type->type == HLSL_CLASS_ARRAY)
1040 return get_array_size(type->e.array.type) * type->e.array.elements_count;
1041 return 1;
1044 static struct hlsl_type *new_struct_type(const char *name, struct list *fields)
1046 struct hlsl_type *type = d3dcompiler_alloc(sizeof(*type));
1047 struct hlsl_struct_field *field;
1048 unsigned int reg_size = 0;
1050 if (!type)
1052 ERR("Out of memory.\n");
1053 return NULL;
1055 type->type = HLSL_CLASS_STRUCT;
1056 type->base_type = HLSL_TYPE_VOID;
1057 type->name = name;
1058 type->dimx = 0;
1059 type->dimy = 1;
1060 type->e.elements = fields;
1062 LIST_FOR_EACH_ENTRY(field, fields, struct hlsl_struct_field, entry)
1064 field->reg_offset = reg_size;
1065 reg_size += field->type->reg_size;
1066 type->dimx += field->type->dimx * field->type->dimy * get_array_size(field->type);
1068 type->reg_size = reg_size;
1070 list_add_tail(&hlsl_ctx.types, &type->entry);
1072 return type;
1075 static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list)
1077 BOOL ret;
1078 struct hlsl_type *type;
1079 struct parse_variable_def *v, *v_next;
1081 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
1083 if (v->array_size)
1084 type = new_array_type(orig_type, v->array_size);
1085 else
1086 type = clone_hlsl_type(orig_type, 0);
1087 if (!type)
1089 ERR("Out of memory\n");
1090 return FALSE;
1092 d3dcompiler_free((void *)type->name);
1093 type->name = v->name;
1094 type->modifiers |= modifiers;
1096 if (type->type != HLSL_CLASS_MATRIX)
1097 check_invalid_matrix_modifiers(type->modifiers, v->loc);
1098 else
1099 type->reg_size = is_row_major(type) ? type->dimy : type->dimx;
1101 if ((type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
1102 && (type->modifiers & HLSL_MODIFIER_ROW_MAJOR))
1103 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, "more than one matrix majority keyword");
1105 ret = add_type_to_scope(hlsl_ctx.cur_scope, type);
1106 if (!ret)
1108 hlsl_report_message(v->loc, HLSL_LEVEL_ERROR,
1109 "redefinition of custom type '%s'", v->name);
1111 d3dcompiler_free(v);
1113 d3dcompiler_free(list);
1114 return TRUE;
1117 static BOOL add_func_parameter(struct list *list, struct parse_parameter *param, const struct source_location loc)
1119 struct hlsl_ir_var *var;
1121 if (param->type->type == HLSL_CLASS_MATRIX)
1122 assert(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
1124 if (!(var = new_var(param->name, param->type, loc, param->semantic, param->modifiers, param->reg_reservation)))
1125 return FALSE;
1127 if (!add_declaration(hlsl_ctx.cur_scope, var, FALSE))
1129 free_declaration(var);
1130 return FALSE;
1132 list_add_tail(list, &var->param_entry);
1133 return TRUE;
1136 static struct reg_reservation *parse_reg_reservation(const char *reg_string)
1138 struct reg_reservation *reg_res;
1139 enum bwritershader_param_register_type type;
1140 DWORD regnum = 0;
1142 switch (reg_string[0])
1144 case 'c':
1145 type = BWRITERSPR_CONST;
1146 break;
1147 case 'i':
1148 type = BWRITERSPR_CONSTINT;
1149 break;
1150 case 'b':
1151 type = BWRITERSPR_CONSTBOOL;
1152 break;
1153 case 's':
1154 type = BWRITERSPR_SAMPLER;
1155 break;
1156 default:
1157 FIXME("Unsupported register type.\n");
1158 return NULL;
1161 if (!sscanf(reg_string + 1, "%u", &regnum))
1163 FIXME("Unsupported register reservation syntax.\n");
1164 return NULL;
1167 reg_res = d3dcompiler_alloc(sizeof(*reg_res));
1168 if (!reg_res)
1170 ERR("Out of memory.\n");
1171 return NULL;
1173 reg_res->type = type;
1174 reg_res->regnum = regnum;
1175 return reg_res;
1178 static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tree *funcs, char *name,
1179 struct list *params, BOOL exact_signature)
1181 struct hlsl_ir_function *func;
1182 struct wine_rb_entry *entry;
1184 entry = wine_rb_get(funcs, name);
1185 if (entry)
1187 func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
1189 entry = wine_rb_get(&func->overloads, params);
1190 if (!entry)
1192 if (!exact_signature)
1193 FIXME("No exact match, search for a compatible overloaded function (if any).\n");
1194 return NULL;
1196 return WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
1198 return NULL;
1201 static struct hlsl_ir_function_decl *get_func_entry(const char *name)
1203 struct hlsl_ir_function_decl *decl;
1204 struct hlsl_ir_function *func;
1205 struct wine_rb_entry *entry;
1207 if ((entry = wine_rb_get(&hlsl_ctx.functions, name)))
1209 func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
1210 WINE_RB_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry)
1211 return decl;
1214 return NULL;
1217 static struct list *append_unop(struct list *list, struct hlsl_ir_node *node)
1219 list_add_tail(list, &node->entry);
1220 return list;
1223 static struct list *add_binary_expr(struct list *list1, struct list *list2,
1224 enum hlsl_ir_expr_op op, struct source_location loc)
1226 struct hlsl_ir_node *args[3] = {node_from_list(list1), node_from_list(list2)};
1227 list_move_tail(list1, list2);
1228 d3dcompiler_free(list2);
1229 add_expr(list1, op, args, &loc);
1230 return list1;
1233 static struct list *make_list(struct hlsl_ir_node *node)
1235 struct list *list;
1237 if (!(list = d3dcompiler_alloc(sizeof(*list))))
1239 ERR("Out of memory.\n");
1240 free_instr(node);
1241 return NULL;
1243 list_init(list);
1244 list_add_tail(list, &node->entry);
1245 return list;
1248 static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node)
1250 if (node->data_type->type != HLSL_CLASS_SCALAR)
1251 return 0;
1253 switch (node->type)
1255 case HLSL_IR_CONSTANT:
1257 struct hlsl_ir_constant *constant = constant_from_node(node);
1259 switch (constant->node.data_type->base_type)
1261 case HLSL_TYPE_UINT:
1262 return constant->value.u[0];
1263 case HLSL_TYPE_INT:
1264 return constant->value.i[0];
1265 case HLSL_TYPE_FLOAT:
1266 return constant->value.f[0];
1267 case HLSL_TYPE_DOUBLE:
1268 return constant->value.d[0];
1269 case HLSL_TYPE_BOOL:
1270 return constant->value.b[0];
1271 default:
1272 WARN("Invalid type %s.\n", debug_base_type(constant->node.data_type));
1273 return 0;
1276 case HLSL_IR_EXPR:
1277 case HLSL_IR_LOAD:
1278 case HLSL_IR_SWIZZLE:
1279 FIXME("Unhandled type %s.\n", debug_node_type(node->type));
1280 return 0;
1281 case HLSL_IR_ASSIGNMENT:
1282 default:
1283 WARN("Invalid node type %s.\n", debug_node_type(node->type));
1284 return 0;
1288 static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type,
1289 struct list *parameters, const char *semantic, struct source_location loc)
1291 struct hlsl_ir_function_decl *decl;
1293 if (!(decl = d3dcompiler_alloc(sizeof(*decl))))
1294 return NULL;
1295 decl->return_type = return_type;
1296 decl->parameters = parameters;
1297 decl->semantic = semantic;
1298 decl->loc = loc;
1300 if (!type_is_void(return_type))
1302 struct hlsl_ir_var *return_var;
1303 char name[28];
1305 sprintf(name, "<retval-%p>", decl);
1306 if (!(return_var = new_synthetic_var(name, return_type, loc)))
1308 d3dcompiler_free(decl);
1309 return NULL;
1311 decl->return_var = return_var;
1314 return decl;
1319 %locations
1320 %define parse.error verbose
1321 %expect 1
1323 %union
1325 struct hlsl_type *type;
1326 INT intval;
1327 FLOAT floatval;
1328 BOOL boolval;
1329 char *name;
1330 DWORD modifiers;
1331 struct hlsl_ir_node *instr;
1332 struct list *list;
1333 struct parse_function function;
1334 struct parse_parameter parameter;
1335 struct parse_initializer initializer;
1336 struct parse_variable_def *variable_def;
1337 struct parse_if_body if_body;
1338 enum parse_unary_op unary_op;
1339 enum parse_assign_op assign_op;
1340 struct reg_reservation *reg_reservation;
1341 struct parse_colon_attribute colon_attribute;
1344 %token KW_BLENDSTATE
1345 %token KW_BREAK
1346 %token KW_BUFFER
1347 %token KW_CBUFFER
1348 %token KW_COLUMN_MAJOR
1349 %token KW_COMPILE
1350 %token KW_CONST
1351 %token KW_CONTINUE
1352 %token KW_DEPTHSTENCILSTATE
1353 %token KW_DEPTHSTENCILVIEW
1354 %token KW_DISCARD
1355 %token KW_DO
1356 %token KW_DOUBLE
1357 %token KW_ELSE
1358 %token KW_EXTERN
1359 %token KW_FALSE
1360 %token KW_FOR
1361 %token KW_GEOMETRYSHADER
1362 %token KW_GROUPSHARED
1363 %token KW_IF
1364 %token KW_IN
1365 %token KW_INLINE
1366 %token KW_INOUT
1367 %token KW_MATRIX
1368 %token KW_NAMESPACE
1369 %token KW_NOINTERPOLATION
1370 %token KW_OUT
1371 %token KW_PASS
1372 %token KW_PIXELSHADER
1373 %token KW_PRECISE
1374 %token KW_RASTERIZERSTATE
1375 %token KW_RENDERTARGETVIEW
1376 %token KW_RETURN
1377 %token KW_REGISTER
1378 %token KW_ROW_MAJOR
1379 %token KW_SAMPLER
1380 %token KW_SAMPLER1D
1381 %token KW_SAMPLER2D
1382 %token KW_SAMPLER3D
1383 %token KW_SAMPLERCUBE
1384 %token KW_SAMPLER_STATE
1385 %token KW_SAMPLERCOMPARISONSTATE
1386 %token KW_SHARED
1387 %token KW_STATEBLOCK
1388 %token KW_STATEBLOCK_STATE
1389 %token KW_STATIC
1390 %token KW_STRING
1391 %token KW_STRUCT
1392 %token KW_SWITCH
1393 %token KW_TBUFFER
1394 %token KW_TECHNIQUE
1395 %token KW_TECHNIQUE10
1396 %token KW_TEXTURE
1397 %token KW_TEXTURE1D
1398 %token KW_TEXTURE1DARRAY
1399 %token KW_TEXTURE2D
1400 %token KW_TEXTURE2DARRAY
1401 %token KW_TEXTURE2DMS
1402 %token KW_TEXTURE2DMSARRAY
1403 %token KW_TEXTURE3D
1404 %token KW_TEXTURE3DARRAY
1405 %token KW_TEXTURECUBE
1406 %token KW_TRUE
1407 %token KW_TYPEDEF
1408 %token KW_UNIFORM
1409 %token KW_VECTOR
1410 %token KW_VERTEXSHADER
1411 %token KW_VOID
1412 %token KW_VOLATILE
1413 %token KW_WHILE
1415 %token OP_INC
1416 %token OP_DEC
1417 %token OP_AND
1418 %token OP_OR
1419 %token OP_EQ
1420 %token OP_LEFTSHIFT
1421 %token OP_LEFTSHIFTASSIGN
1422 %token OP_RIGHTSHIFT
1423 %token OP_RIGHTSHIFTASSIGN
1424 %token OP_ELLIPSIS
1425 %token OP_LE
1426 %token OP_GE
1427 %token OP_NE
1428 %token OP_ADDASSIGN
1429 %token OP_SUBASSIGN
1430 %token OP_MULASSIGN
1431 %token OP_DIVASSIGN
1432 %token OP_MODASSIGN
1433 %token OP_ANDASSIGN
1434 %token OP_ORASSIGN
1435 %token OP_XORASSIGN
1436 %token OP_UNKNOWN1
1437 %token OP_UNKNOWN2
1438 %token OP_UNKNOWN3
1439 %token OP_UNKNOWN4
1441 %token <intval> PRE_LINE
1443 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
1444 %type <name> any_identifier var_identifier
1445 %token <name> STRING
1446 %token <floatval> C_FLOAT
1447 %token <intval> C_INTEGER
1448 %type <boolval> boolean
1449 %type <type> base_type
1450 %type <type> type
1451 %type <list> declaration_statement
1452 %type <list> declaration
1453 %type <list> struct_declaration
1454 %type <type> struct_spec
1455 %type <type> named_struct_spec
1456 %type <type> unnamed_struct_spec
1457 %type <type> field_type
1458 %type <type> typedef_type
1459 %type <list> type_specs
1460 %type <variable_def> type_spec
1461 %type <initializer> complex_initializer
1462 %type <initializer> initializer_expr_list
1463 %type <list> initializer_expr
1464 %type <modifiers> var_modifiers
1465 %type <list> field
1466 %type <list> parameters
1467 %type <list> param_list
1468 %type <list> expr
1469 %type <intval> array
1470 %type <list> statement
1471 %type <list> statement_list
1472 %type <list> compound_statement
1473 %type <list> jump_statement
1474 %type <list> selection_statement
1475 %type <list> loop_statement
1476 %type <function> func_declaration
1477 %type <function> func_prototype
1478 %type <list> fields_list
1479 %type <parameter> parameter
1480 %type <colon_attribute> colon_attribute
1481 %type <name> semantic
1482 %type <reg_reservation> register_opt
1483 %type <variable_def> variable_def
1484 %type <list> variables_def
1485 %type <list> variables_def_optional
1486 %type <if_body> if_body
1487 %type <list> primary_expr
1488 %type <list> postfix_expr
1489 %type <list> unary_expr
1490 %type <list> mul_expr
1491 %type <list> add_expr
1492 %type <list> shift_expr
1493 %type <list> relational_expr
1494 %type <list> equality_expr
1495 %type <list> bitand_expr
1496 %type <list> bitxor_expr
1497 %type <list> bitor_expr
1498 %type <list> logicand_expr
1499 %type <list> logicor_expr
1500 %type <list> conditional_expr
1501 %type <list> assignment_expr
1502 %type <list> expr_statement
1503 %type <unary_op> unary_op
1504 %type <assign_op> assign_op
1505 %type <modifiers> input_mods
1506 %type <modifiers> input_mod
1509 hlsl_prog: /* empty */
1512 | hlsl_prog func_declaration
1514 const struct hlsl_ir_function_decl *decl;
1516 decl = get_overloaded_func(&hlsl_ctx.functions, $2.name, $2.decl->parameters, TRUE);
1517 if (decl && !decl->func->intrinsic)
1519 if (decl->body && $2.decl->body)
1521 hlsl_report_message($2.decl->loc, HLSL_LEVEL_ERROR,
1522 "redefinition of function %s", debugstr_a($2.name));
1523 YYABORT;
1525 else if (!compare_hlsl_types(decl->return_type, $2.decl->return_type))
1527 hlsl_report_message($2.decl->loc, HLSL_LEVEL_ERROR,
1528 "redefining function %s with a different return type",
1529 debugstr_a($2.name));
1530 hlsl_report_message(decl->loc, HLSL_LEVEL_NOTE,
1531 "%s previously declared here",
1532 debugstr_a($2.name));
1533 YYABORT;
1537 if (type_is_void($2.decl->return_type) && $2.decl->semantic)
1539 hlsl_report_message($2.decl->loc, HLSL_LEVEL_ERROR,
1540 "void function with a semantic");
1543 TRACE("Adding function '%s' to the function list.\n", $2.name);
1544 add_function_decl(&hlsl_ctx.functions, $2.name, $2.decl, FALSE);
1546 | hlsl_prog declaration_statement
1548 TRACE("Declaration statement parsed.\n");
1550 if (!list_empty($2))
1551 FIXME("Uniform initializer.\n");
1552 free_instr_list($2);
1554 | hlsl_prog preproc_directive
1557 | hlsl_prog ';'
1559 TRACE("Skipping stray semicolon.\n");
1562 preproc_directive: PRE_LINE STRING
1564 const char **new_array = NULL;
1566 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
1567 hlsl_ctx.line_no = $1;
1568 if (strcmp($2, hlsl_ctx.source_file))
1569 new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
1570 sizeof(*hlsl_ctx.source_files) * (hlsl_ctx.source_files_count + 1));
1572 if (new_array)
1574 hlsl_ctx.source_files = new_array;
1575 hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
1576 hlsl_ctx.source_file = $2;
1578 else
1580 d3dcompiler_free($2);
1584 struct_declaration: var_modifiers struct_spec variables_def_optional ';'
1586 struct hlsl_type *type;
1587 DWORD modifiers = $1;
1589 if (!$3)
1591 if (!$2->name)
1593 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
1594 "anonymous struct declaration with no variables");
1596 if (modifiers)
1598 hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR,
1599 "modifier not allowed on struct type declaration");
1603 if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1))))
1604 YYABORT;
1605 $$ = declare_vars(type, modifiers, $3);
1608 struct_spec: named_struct_spec
1609 | unnamed_struct_spec
1611 named_struct_spec: KW_STRUCT any_identifier '{' fields_list '}'
1613 BOOL ret;
1615 TRACE("Structure %s declaration.\n", debugstr_a($2));
1616 $$ = new_struct_type($2, $4);
1618 if (get_variable(hlsl_ctx.cur_scope, $2))
1620 hlsl_report_message(get_location(&@2),
1621 HLSL_LEVEL_ERROR, "redefinition of '%s'", $2);
1622 YYABORT;
1625 ret = add_type_to_scope(hlsl_ctx.cur_scope, $$);
1626 if (!ret)
1628 hlsl_report_message(get_location(&@2),
1629 HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $2);
1630 YYABORT;
1634 unnamed_struct_spec: KW_STRUCT '{' fields_list '}'
1636 TRACE("Anonymous structure declaration.\n");
1637 $$ = new_struct_type(NULL, $3);
1640 any_identifier: VAR_IDENTIFIER
1641 | TYPE_IDENTIFIER
1642 | NEW_IDENTIFIER
1644 fields_list: /* Empty */
1646 $$ = d3dcompiler_alloc(sizeof(*$$));
1647 list_init($$);
1649 | fields_list field
1651 BOOL ret;
1652 struct hlsl_struct_field *field, *next;
1654 $$ = $1;
1655 LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry)
1657 ret = add_struct_field($$, field);
1658 if (ret == FALSE)
1660 hlsl_report_message(get_location(&@2),
1661 HLSL_LEVEL_ERROR, "redefinition of '%s'", field->name);
1662 d3dcompiler_free(field);
1665 d3dcompiler_free($2);
1668 field_type: type
1669 | unnamed_struct_spec
1671 field: var_modifiers field_type variables_def ';'
1673 struct hlsl_type *type;
1674 DWORD modifiers = $1;
1676 if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1))))
1677 YYABORT;
1678 $$ = gen_struct_fields(type, modifiers, $3);
1681 func_declaration: func_prototype compound_statement
1683 TRACE("Function %s parsed.\n", $1.name);
1684 $$ = $1;
1685 $$.decl->body = $2;
1686 pop_scope(&hlsl_ctx);
1688 | func_prototype ';'
1690 TRACE("Function prototype for %s.\n", $1.name);
1691 $$ = $1;
1692 pop_scope(&hlsl_ctx);
1695 /* var_modifiers is necessary to avoid shift/reduce conflicts. */
1696 func_prototype: var_modifiers type var_identifier '(' parameters ')' colon_attribute
1698 if ($1)
1700 hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR,
1701 "unexpected modifiers on a function");
1702 YYABORT;
1704 if (get_variable(hlsl_ctx.globals, $3))
1706 hlsl_report_message(get_location(&@3),
1707 HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
1708 YYABORT;
1710 if (type_is_void($2) && $7.semantic)
1712 hlsl_report_message(get_location(&@7),
1713 HLSL_LEVEL_ERROR, "void function with a semantic");
1716 if ($7.reg_reservation)
1718 FIXME("Unexpected register reservation for a function.\n");
1719 d3dcompiler_free($7.reg_reservation);
1721 if (!($$.decl = new_func_decl($2, $5, $7.semantic, get_location(&@3))))
1723 ERR("Out of memory.\n");
1724 YYABORT;
1726 $$.name = $3;
1727 hlsl_ctx.cur_function = $$.decl;
1730 compound_statement: '{' '}'
1732 $$ = d3dcompiler_alloc(sizeof(*$$));
1733 list_init($$);
1735 | '{' scope_start statement_list '}'
1737 pop_scope(&hlsl_ctx);
1738 $$ = $3;
1741 scope_start: /* Empty */
1743 push_scope(&hlsl_ctx);
1746 var_identifier: VAR_IDENTIFIER
1747 | NEW_IDENTIFIER
1749 colon_attribute: /* Empty */
1751 $$.semantic = NULL;
1752 $$.reg_reservation = NULL;
1754 | semantic
1756 $$.semantic = $1;
1757 $$.reg_reservation = NULL;
1759 | register_opt
1761 $$.semantic = NULL;
1762 $$.reg_reservation = $1;
1765 semantic: ':' any_identifier
1767 $$ = $2;
1770 /* FIXME: Writemasks */
1771 register_opt: ':' KW_REGISTER '(' any_identifier ')'
1773 $$ = parse_reg_reservation($4);
1774 d3dcompiler_free($4);
1776 | ':' KW_REGISTER '(' any_identifier ',' any_identifier ')'
1778 FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a($4));
1779 d3dcompiler_free($4);
1781 $$ = parse_reg_reservation($6);
1782 d3dcompiler_free($6);
1785 parameters: scope_start
1787 $$ = d3dcompiler_alloc(sizeof(*$$));
1788 list_init($$);
1790 | scope_start param_list
1792 $$ = $2;
1795 param_list: parameter
1797 $$ = d3dcompiler_alloc(sizeof(*$$));
1798 list_init($$);
1799 if (!add_func_parameter($$, &$1, get_location(&@1)))
1801 ERR("Error adding function parameter %s.\n", $1.name);
1802 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1803 YYABORT;
1806 | param_list ',' parameter
1808 $$ = $1;
1809 if (!add_func_parameter($$, &$3, get_location(&@3)))
1811 hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR,
1812 "duplicate parameter %s", $3.name);
1813 YYABORT;
1817 parameter: input_mods var_modifiers type any_identifier colon_attribute
1819 struct hlsl_type *type;
1820 DWORD modifiers = $2;
1822 if (!(type = apply_type_modifiers($3, &modifiers, get_location(&@2))))
1823 YYABORT;
1825 $$.modifiers = $1 ? $1 : HLSL_STORAGE_IN;
1826 $$.modifiers |= modifiers;
1827 $$.type = type;
1828 $$.name = $4;
1829 $$.semantic = $5.semantic;
1830 $$.reg_reservation = $5.reg_reservation;
1833 input_mods: /* Empty */
1835 $$ = 0;
1837 | input_mods input_mod
1839 if ($1 & $2)
1841 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
1842 "duplicate input-output modifiers");
1843 YYABORT;
1845 $$ = $1 | $2;
1848 input_mod: KW_IN
1850 $$ = HLSL_STORAGE_IN;
1852 | KW_OUT
1854 $$ = HLSL_STORAGE_OUT;
1856 | KW_INOUT
1858 $$ = HLSL_STORAGE_IN | HLSL_STORAGE_OUT;
1861 type:
1863 base_type
1865 $$ = $1;
1867 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
1869 if ($3->type != HLSL_CLASS_SCALAR)
1871 hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR,
1872 "vectors of non-scalar types are not allowed\n");
1873 YYABORT;
1875 if ($5 < 1 || $5 > 4)
1877 hlsl_report_message(get_location(&@5), HLSL_LEVEL_ERROR,
1878 "vector size must be between 1 and 4\n");
1879 YYABORT;
1882 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
1884 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
1886 if ($3->type != HLSL_CLASS_SCALAR)
1888 hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR,
1889 "matrices of non-scalar types are not allowed\n");
1890 YYABORT;
1892 if ($5 < 1 || $5 > 4)
1894 hlsl_report_message(get_location(&@5), HLSL_LEVEL_ERROR,
1895 "matrix row count must be between 1 and 4\n");
1896 YYABORT;
1898 if ($7 < 1 || $7 > 4)
1900 hlsl_report_message(get_location(&@7), HLSL_LEVEL_ERROR,
1901 "matrix column count must be between 1 and 4\n");
1902 YYABORT;
1905 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $7, $5);
1908 base_type:
1910 KW_VOID
1912 $$ = hlsl_ctx.builtin_types.Void;
1914 | KW_SAMPLER
1916 $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_GENERIC];
1918 | KW_SAMPLER1D
1920 $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_1D];
1922 | KW_SAMPLER2D
1924 $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_2D];
1926 | KW_SAMPLER3D
1928 $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_3D];
1930 | KW_SAMPLERCUBE
1932 $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_3D];
1934 | TYPE_IDENTIFIER
1936 $$ = get_type(hlsl_ctx.cur_scope, $1, TRUE);
1937 d3dcompiler_free($1);
1939 | KW_STRUCT TYPE_IDENTIFIER
1941 $$ = get_type(hlsl_ctx.cur_scope, $2, TRUE);
1942 if ($$->type != HLSL_CLASS_STRUCT)
1943 hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR, "'%s' redefined as a structure\n", $2);
1944 d3dcompiler_free($2);
1947 declaration_statement: declaration
1948 | struct_declaration
1949 | typedef
1951 $$ = d3dcompiler_alloc(sizeof(*$$));
1952 if (!$$)
1954 ERR("Out of memory\n");
1955 YYABORT;
1957 list_init($$);
1960 typedef_type: type
1961 | struct_spec
1963 typedef: KW_TYPEDEF var_modifiers typedef_type type_specs ';'
1965 if ($2 & ~HLSL_TYPE_MODIFIERS_MASK)
1967 struct parse_variable_def *v, *v_next;
1968 hlsl_report_message(get_location(&@1),
1969 HLSL_LEVEL_ERROR, "modifier not allowed on typedefs");
1970 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $4, struct parse_variable_def, entry)
1971 d3dcompiler_free(v);
1972 d3dcompiler_free($4);
1973 YYABORT;
1975 if (!add_typedef($2, $3, $4))
1976 YYABORT;
1979 type_specs: type_spec
1981 $$ = d3dcompiler_alloc(sizeof(*$$));
1982 list_init($$);
1983 list_add_head($$, &$1->entry);
1985 | type_specs ',' type_spec
1987 $$ = $1;
1988 list_add_tail($$, &$3->entry);
1991 type_spec: any_identifier array
1993 $$ = d3dcompiler_alloc(sizeof(*$$));
1994 $$->loc = get_location(&@1);
1995 $$->name = $1;
1996 $$->array_size = $2;
1999 declaration: var_modifiers type variables_def ';'
2001 struct hlsl_type *type;
2002 DWORD modifiers = $1;
2004 if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1))))
2005 YYABORT;
2006 $$ = declare_vars(type, modifiers, $3);
2009 variables_def_optional: /* Empty */
2011 $$ = NULL;
2013 | variables_def
2015 $$ = $1;
2018 variables_def: variable_def
2020 $$ = d3dcompiler_alloc(sizeof(*$$));
2021 list_init($$);
2022 list_add_head($$, &$1->entry);
2024 | variables_def ',' variable_def
2026 $$ = $1;
2027 list_add_tail($$, &$3->entry);
2030 variable_def: any_identifier array colon_attribute
2032 $$ = d3dcompiler_alloc(sizeof(*$$));
2033 $$->loc = get_location(&@1);
2034 $$->name = $1;
2035 $$->array_size = $2;
2036 $$->semantic = $3.semantic;
2037 $$->reg_reservation = $3.reg_reservation;
2039 | any_identifier array colon_attribute '=' complex_initializer
2041 TRACE("Declaration with initializer.\n");
2042 $$ = d3dcompiler_alloc(sizeof(*$$));
2043 $$->loc = get_location(&@1);
2044 $$->name = $1;
2045 $$->array_size = $2;
2046 $$->semantic = $3.semantic;
2047 $$->reg_reservation = $3.reg_reservation;
2048 $$->initializer = $5;
2051 array: /* Empty */
2053 $$ = 0;
2055 | '[' expr ']'
2057 unsigned int size = evaluate_array_dimension(node_from_list($2));
2059 free_instr_list($2);
2061 if (!size)
2063 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
2064 "array size is not a positive integer constant\n");
2065 YYABORT;
2067 TRACE("Array size %u.\n", size);
2069 if (size > 65536)
2071 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
2072 "array size must be between 1 and 65536");
2073 YYABORT;
2075 $$ = size;
2078 var_modifiers: /* Empty */
2080 $$ = 0;
2082 | KW_EXTERN var_modifiers
2084 $$ = add_modifiers($2, HLSL_STORAGE_EXTERN, get_location(&@1));
2086 | KW_NOINTERPOLATION var_modifiers
2088 $$ = add_modifiers($2, HLSL_STORAGE_NOINTERPOLATION, get_location(&@1));
2090 | KW_PRECISE var_modifiers
2092 $$ = add_modifiers($2, HLSL_MODIFIER_PRECISE, get_location(&@1));
2094 | KW_SHARED var_modifiers
2096 $$ = add_modifiers($2, HLSL_STORAGE_SHARED, get_location(&@1));
2098 | KW_GROUPSHARED var_modifiers
2100 $$ = add_modifiers($2, HLSL_STORAGE_GROUPSHARED, get_location(&@1));
2102 | KW_STATIC var_modifiers
2104 $$ = add_modifiers($2, HLSL_STORAGE_STATIC, get_location(&@1));
2106 | KW_UNIFORM var_modifiers
2108 $$ = add_modifiers($2, HLSL_STORAGE_UNIFORM, get_location(&@1));
2110 | KW_VOLATILE var_modifiers
2112 $$ = add_modifiers($2, HLSL_STORAGE_VOLATILE, get_location(&@1));
2114 | KW_CONST var_modifiers
2116 $$ = add_modifiers($2, HLSL_MODIFIER_CONST, get_location(&@1));
2118 | KW_ROW_MAJOR var_modifiers
2120 $$ = add_modifiers($2, HLSL_MODIFIER_ROW_MAJOR, get_location(&@1));
2122 | KW_COLUMN_MAJOR var_modifiers
2124 $$ = add_modifiers($2, HLSL_MODIFIER_COLUMN_MAJOR, get_location(&@1));
2127 complex_initializer: initializer_expr
2129 $$.args_count = 1;
2130 if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args))))
2131 YYABORT;
2132 $$.args[0] = node_from_list($1);
2133 $$.instrs = $1;
2135 | '{' initializer_expr_list '}'
2137 $$ = $2;
2139 | '{' initializer_expr_list ',' '}'
2141 $$ = $2;
2144 initializer_expr: assignment_expr
2146 $$ = $1;
2149 initializer_expr_list: initializer_expr
2151 $$.args_count = 1;
2152 if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args))))
2153 YYABORT;
2154 $$.args[0] = node_from_list($1);
2155 $$.instrs = $1;
2157 | initializer_expr_list ',' initializer_expr
2159 $$ = $1;
2160 if (!($$.args = d3dcompiler_realloc($$.args, ($$.args_count + 1) * sizeof(*$$.args))))
2161 YYABORT;
2162 $$.args[$$.args_count++] = node_from_list($3);
2163 list_move_tail($$.instrs, $3);
2164 d3dcompiler_free($3);
2167 boolean: KW_TRUE
2169 $$ = TRUE;
2171 | KW_FALSE
2173 $$ = FALSE;
2176 statement_list: statement
2178 $$ = $1;
2180 | statement_list statement
2182 $$ = $1;
2183 list_move_tail($$, $2);
2184 d3dcompiler_free($2);
2187 statement: declaration_statement
2188 | expr_statement
2189 | compound_statement
2190 | jump_statement
2191 | selection_statement
2192 | loop_statement
2194 jump_statement:
2196 KW_RETURN expr ';'
2198 if (!add_return($2, node_from_list($2), get_location(&@1)))
2199 YYABORT;
2200 $$ = $2;
2202 | KW_RETURN ';'
2204 if (!($$ = d3dcompiler_alloc(sizeof(*$$))))
2205 YYABORT;
2206 list_init($$);
2207 if (!add_return($$, NULL, get_location(&@1)))
2208 YYABORT;
2211 selection_statement: KW_IF '(' expr ')' if_body
2213 struct hlsl_ir_node *condition = node_from_list($3);
2214 struct hlsl_ir_if *instr;
2216 if (!(instr = new_if(condition, get_location(&@1))))
2217 YYABORT;
2218 list_move_tail(&instr->then_instrs, $5.then_instrs);
2219 list_move_tail(&instr->else_instrs, $5.else_instrs);
2220 d3dcompiler_free($5.then_instrs);
2221 d3dcompiler_free($5.else_instrs);
2222 if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1)
2224 hlsl_report_message(instr->node.loc, HLSL_LEVEL_ERROR,
2225 "if condition requires a scalar");
2227 $$ = $3;
2228 list_add_tail($$, &instr->node.entry);
2231 if_body: statement
2233 $$.then_instrs = $1;
2234 $$.else_instrs = NULL;
2236 | statement KW_ELSE statement
2238 $$.then_instrs = $1;
2239 $$.else_instrs = $3;
2242 loop_statement: KW_WHILE '(' expr ')' statement
2244 $$ = create_loop(LOOP_WHILE, NULL, $3, NULL, $5, get_location(&@1));
2246 | KW_DO statement KW_WHILE '(' expr ')' ';'
2248 $$ = create_loop(LOOP_DO_WHILE, NULL, $5, NULL, $2, get_location(&@1));
2250 | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
2252 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1));
2253 pop_scope(&hlsl_ctx);
2255 | KW_FOR '(' scope_start declaration expr_statement expr ')' statement
2257 if (!$4)
2258 hlsl_report_message(get_location(&@4), HLSL_LEVEL_WARNING,
2259 "no expressions in for loop initializer");
2260 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1));
2261 pop_scope(&hlsl_ctx);
2264 expr_statement: ';'
2266 $$ = d3dcompiler_alloc(sizeof(*$$));
2267 list_init($$);
2269 | expr ';'
2271 $$ = $1;
2274 primary_expr: C_FLOAT
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_FLOAT], get_location(&@1));
2284 c->value.f[0] = $1;
2285 if (!($$ = make_list(&c->node)))
2286 YYABORT;
2288 | C_INTEGER
2290 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
2291 if (!c)
2293 ERR("Out of memory.\n");
2294 YYABORT;
2296 init_node(&c->node, HLSL_IR_CONSTANT,
2297 hlsl_ctx.builtin_types.scalar[HLSL_TYPE_INT], get_location(&@1));
2298 c->value.i[0] = $1;
2299 if (!($$ = make_list(&c->node)))
2300 YYABORT;
2302 | boolean
2304 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
2305 if (!c)
2307 ERR("Out of memory.\n");
2308 YYABORT;
2310 init_node(&c->node, HLSL_IR_CONSTANT,
2311 hlsl_ctx.builtin_types.scalar[HLSL_TYPE_BOOL], get_location(&@1));
2312 c->value.b[0] = $1;
2313 if (!($$ = make_list(&c->node)))
2314 YYABORT;
2316 | VAR_IDENTIFIER
2318 struct hlsl_ir_load *load;
2319 struct hlsl_ir_var *var;
2321 if (!(var = get_variable(hlsl_ctx.cur_scope, $1)))
2323 hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR,
2324 "variable '%s' is not declared\n", $1);
2325 YYABORT;
2327 if ((load = new_var_load(var, get_location(&@1))))
2329 if (!($$ = make_list(&load->node)))
2330 YYABORT;
2332 else
2333 $$ = NULL;
2335 | '(' expr ')'
2337 $$ = $2;
2340 postfix_expr: primary_expr
2342 $$ = $1;
2344 | postfix_expr OP_INC
2346 struct source_location loc;
2347 struct hlsl_ir_node *inc;
2349 loc = get_location(&@2);
2350 if (node_from_list($1)->data_type->modifiers & HLSL_MODIFIER_CONST)
2352 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression");
2353 YYABORT;
2355 inc = new_unary_expr(HLSL_IR_UNOP_POSTINC, node_from_list($1), loc);
2356 /* Post increment/decrement expressions are considered const */
2357 inc->data_type = clone_hlsl_type(inc->data_type, 0);
2358 inc->data_type->modifiers |= HLSL_MODIFIER_CONST;
2359 $$ = append_unop($1, inc);
2361 | postfix_expr OP_DEC
2363 struct source_location loc;
2364 struct hlsl_ir_node *inc;
2366 loc = get_location(&@2);
2367 if (node_from_list($1)->data_type->modifiers & HLSL_MODIFIER_CONST)
2369 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression");
2370 YYABORT;
2372 inc = new_unary_expr(HLSL_IR_UNOP_POSTDEC, node_from_list($1), loc);
2373 /* Post increment/decrement expressions are considered const */
2374 inc->data_type = clone_hlsl_type(inc->data_type, 0);
2375 inc->data_type->modifiers |= HLSL_MODIFIER_CONST;
2376 $$ = append_unop($1, inc);
2378 | postfix_expr '.' any_identifier
2380 struct hlsl_ir_node *node = node_from_list($1);
2381 struct source_location loc;
2383 loc = get_location(&@2);
2384 if (node->data_type->type == HLSL_CLASS_STRUCT)
2386 struct hlsl_type *type = node->data_type;
2387 struct hlsl_struct_field *field;
2389 $$ = NULL;
2390 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
2392 if (!strcmp($3, field->name))
2394 if (!add_record_load($1, node, field, loc))
2395 YYABORT;
2396 $$ = $1;
2397 break;
2400 if (!$$)
2402 hlsl_report_message(loc, HLSL_LEVEL_ERROR,
2403 "invalid subscript %s", debugstr_a($3));
2404 YYABORT;
2407 else if (node->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
2409 struct hlsl_ir_swizzle *swizzle;
2411 swizzle = get_swizzle(node, $3, &loc);
2412 if (!swizzle)
2414 hlsl_report_message(loc, HLSL_LEVEL_ERROR,
2415 "invalid swizzle %s", debugstr_a($3));
2416 YYABORT;
2418 $$ = append_unop($1, &swizzle->node);
2420 else
2422 hlsl_report_message(loc, HLSL_LEVEL_ERROR,
2423 "invalid subscript %s", debugstr_a($3));
2424 YYABORT;
2427 | postfix_expr '[' expr ']'
2429 struct hlsl_ir_node *array = node_from_list($1), *index = node_from_list($3);
2431 list_move_tail($1, $3);
2432 d3dcompiler_free($3);
2434 if (index->data_type->type != HLSL_CLASS_SCALAR)
2436 hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR, "array index is not scalar");
2437 free_instr_list($1);
2438 YYABORT;
2441 if (!add_array_load($1, array, index, get_location(&@2)))
2443 free_instr_list($1);
2444 YYABORT;
2446 $$ = $1;
2449 /* "var_modifiers" doesn't make sense in this case, but it's needed
2450 in the grammar to avoid shift/reduce conflicts. */
2451 | var_modifiers type '(' initializer_expr_list ')'
2453 struct hlsl_ir_assignment *assignment;
2454 unsigned int i, writemask_offset = 0;
2455 static unsigned int counter;
2456 struct hlsl_ir_load *load;
2457 struct hlsl_ir_var *var;
2458 char name[23];
2460 if ($1)
2462 hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR,
2463 "unexpected modifier on a constructor\n");
2464 YYABORT;
2466 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
2468 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
2469 "constructors may only be used with numeric data types\n");
2470 YYABORT;
2472 if ($2->dimx * $2->dimy != initializer_size(&$4))
2474 hlsl_report_message(get_location(&@4), HLSL_LEVEL_ERROR,
2475 "expected %u components in constructor, but got %u\n",
2476 $2->dimx * $2->dimy, initializer_size(&$4));
2477 YYABORT;
2480 if ($2->type == HLSL_CLASS_MATRIX)
2481 FIXME("Matrix constructors are not supported yet.\n");
2483 sprintf(name, "<constructor-%x>", counter++);
2484 if (!(var = new_synthetic_var(name, $2, get_location(&@2))))
2485 YYABORT;
2486 for (i = 0; i < $4.args_count; ++i)
2488 struct hlsl_ir_node *arg = $4.args[i];
2489 unsigned int width;
2491 if (arg->data_type->type == HLSL_CLASS_OBJECT)
2493 hlsl_report_message(arg->loc, HLSL_LEVEL_ERROR,
2494 "invalid constructor argument");
2495 continue;
2497 width = components_count_type(arg->data_type);
2499 if (width > 4)
2501 FIXME("Constructor argument with %u components.\n", width);
2502 continue;
2505 if (!(arg = add_implicit_conversion($4.instrs, arg,
2506 hlsl_ctx.builtin_types.vector[$2->base_type][width - 1], &arg->loc)))
2507 continue;
2509 if (!(assignment = new_assignment(var, NULL, arg,
2510 ((1 << width) - 1) << writemask_offset, arg->loc)))
2511 YYABORT;
2512 writemask_offset += width;
2513 list_add_tail($4.instrs, &assignment->node.entry);
2515 d3dcompiler_free($4.args);
2516 if (!(load = new_var_load(var, get_location(&@2))))
2517 YYABORT;
2518 $$ = append_unop($4.instrs, &load->node);
2521 unary_expr: postfix_expr
2523 $$ = $1;
2525 | OP_INC unary_expr
2527 struct source_location loc;
2529 loc = get_location(&@1);
2530 if (node_from_list($2)->data_type->modifiers & HLSL_MODIFIER_CONST)
2532 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression");
2533 YYABORT;
2535 $$ = append_unop($2, new_unary_expr(HLSL_IR_UNOP_PREINC, node_from_list($2), loc));
2537 | OP_DEC unary_expr
2539 struct source_location loc;
2541 loc = get_location(&@1);
2542 if (node_from_list($2)->data_type->modifiers & HLSL_MODIFIER_CONST)
2544 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression");
2545 YYABORT;
2547 $$ = append_unop($2, new_unary_expr(HLSL_IR_UNOP_PREDEC, node_from_list($2), loc));
2549 | unary_op unary_expr
2551 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
2552 HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
2554 if ($1 == UNARY_OP_PLUS)
2556 $$ = $2;
2558 else
2560 $$ = append_unop($2, new_unary_expr(ops[$1], node_from_list($2), get_location(&@1)));
2563 /* var_modifiers just to avoid shift/reduce conflicts */
2564 | '(' var_modifiers type array ')' unary_expr
2566 struct hlsl_type *src_type = node_from_list($6)->data_type;
2567 struct hlsl_type *dst_type;
2568 struct source_location loc;
2570 loc = get_location(&@3);
2571 if ($2)
2573 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "unexpected modifier in a cast");
2574 YYABORT;
2577 if ($4)
2578 dst_type = new_array_type($3, $4);
2579 else
2580 dst_type = $3;
2582 if (!compatible_data_types(src_type, dst_type))
2584 hlsl_report_message(loc, HLSL_LEVEL_ERROR, "can't cast from %s to %s",
2585 debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
2586 YYABORT;
2589 $$ = append_unop($6, &new_cast(node_from_list($6), dst_type, &loc)->node);
2592 unary_op: '+'
2594 $$ = UNARY_OP_PLUS;
2596 | '-'
2598 $$ = UNARY_OP_MINUS;
2600 | '!'
2602 $$ = UNARY_OP_LOGICNOT;
2604 | '~'
2606 $$ = UNARY_OP_BITNOT;
2609 mul_expr:
2611 unary_expr
2612 | mul_expr '*' unary_expr
2614 $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_MUL, get_location(&@2));
2616 | mul_expr '/' unary_expr
2618 $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_DIV, get_location(&@2));
2620 | mul_expr '%' unary_expr
2622 $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_MOD, get_location(&@2));
2625 add_expr:
2627 mul_expr
2628 | add_expr '+' mul_expr
2630 $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_ADD, get_location(&@2));
2632 | add_expr '-' mul_expr
2634 $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_SUB, get_location(&@2));
2637 shift_expr: add_expr
2639 $$ = $1;
2641 | shift_expr OP_LEFTSHIFT add_expr
2643 FIXME("Left shift\n");
2645 | shift_expr OP_RIGHTSHIFT add_expr
2647 FIXME("Right shift\n");
2650 relational_expr:
2652 shift_expr
2653 | relational_expr '<' shift_expr
2655 $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_LESS, get_location(&@2));
2657 | relational_expr '>' shift_expr
2659 $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_GREATER, get_location(&@2));
2661 | relational_expr OP_LE shift_expr
2663 $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_LEQUAL, get_location(&@2));
2665 | relational_expr OP_GE shift_expr
2667 $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_GEQUAL, get_location(&@2));
2670 equality_expr:
2672 relational_expr
2673 | equality_expr OP_EQ relational_expr
2675 $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_EQUAL, get_location(&@2));
2677 | equality_expr OP_NE relational_expr
2679 $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_NEQUAL, get_location(&@2));
2682 bitand_expr: equality_expr
2684 $$ = $1;
2686 | bitand_expr '&' equality_expr
2688 FIXME("bitwise AND\n");
2691 bitxor_expr: bitand_expr
2693 $$ = $1;
2695 | bitxor_expr '^' bitand_expr
2697 FIXME("bitwise XOR\n");
2700 bitor_expr: bitxor_expr
2702 $$ = $1;
2704 | bitor_expr '|' bitxor_expr
2706 FIXME("bitwise OR\n");
2709 logicand_expr: bitor_expr
2711 $$ = $1;
2713 | logicand_expr OP_AND bitor_expr
2715 FIXME("logic AND\n");
2718 logicor_expr: logicand_expr
2720 $$ = $1;
2722 | logicor_expr OP_OR logicand_expr
2724 FIXME("logic OR\n");
2727 conditional_expr: logicor_expr
2729 $$ = $1;
2731 | logicor_expr '?' expr ':' assignment_expr
2733 FIXME("ternary operator\n");
2736 assignment_expr:
2738 conditional_expr
2739 | unary_expr assign_op assignment_expr
2741 struct hlsl_ir_node *lhs = node_from_list($1), *rhs = node_from_list($3);
2743 if (lhs->data_type->modifiers & HLSL_MODIFIER_CONST)
2745 hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR, "l-value is const");
2746 YYABORT;
2748 list_move_tail($3, $1);
2749 d3dcompiler_free($1);
2750 if (!add_assignment($3, lhs, $2, rhs))
2751 YYABORT;
2752 $$ = $3;
2755 assign_op: '='
2757 $$ = ASSIGN_OP_ASSIGN;
2759 | OP_ADDASSIGN
2761 $$ = ASSIGN_OP_ADD;
2763 | OP_SUBASSIGN
2765 $$ = ASSIGN_OP_SUB;
2767 | OP_MULASSIGN
2769 $$ = ASSIGN_OP_MUL;
2771 | OP_DIVASSIGN
2773 $$ = ASSIGN_OP_DIV;
2775 | OP_MODASSIGN
2777 $$ = ASSIGN_OP_MOD;
2779 | OP_LEFTSHIFTASSIGN
2781 $$ = ASSIGN_OP_LSHIFT;
2783 | OP_RIGHTSHIFTASSIGN
2785 $$ = ASSIGN_OP_RSHIFT;
2787 | OP_ANDASSIGN
2789 $$ = ASSIGN_OP_AND;
2791 | OP_ORASSIGN
2793 $$ = ASSIGN_OP_OR;
2795 | OP_XORASSIGN
2797 $$ = ASSIGN_OP_XOR;
2800 expr: assignment_expr
2802 $$ = $1;
2804 | expr ',' assignment_expr
2806 $$ = $1;
2807 list_move_tail($$, $3);
2808 d3dcompiler_free($3);
2813 static struct source_location get_location(const struct YYLTYPE *l)
2815 const struct source_location loc =
2817 .file = hlsl_ctx.source_file,
2818 .line = l->first_line,
2819 .col = l->first_column,
2821 return loc;
2824 static void dump_function_decl(struct wine_rb_entry *entry, void *context)
2826 struct hlsl_ir_function_decl *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
2827 if (func->body)
2828 debug_dump_ir_function_decl(func);
2831 static void dump_function(struct wine_rb_entry *entry, void *context)
2833 struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
2834 wine_rb_for_each_entry(&func->overloads, dump_function_decl, NULL);
2837 /* Allocate a unique, ordered index to each instruction, which will be used for
2838 * computing liveness ranges. */
2839 static unsigned int index_instructions(struct list *instrs, unsigned int index)
2841 struct hlsl_ir_node *instr;
2843 LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry)
2845 instr->index = index++;
2847 if (instr->type == HLSL_IR_IF)
2849 struct hlsl_ir_if *iff = if_from_node(instr);
2850 index = index_instructions(&iff->then_instrs, index);
2851 index = index_instructions(&iff->else_instrs, index);
2853 else if (instr->type == HLSL_IR_LOOP)
2855 index = index_instructions(&loop_from_node(instr)->body, index);
2856 loop_from_node(instr)->next_index = index;
2860 return index;
2863 /* Compute the earliest and latest liveness for each variable. In the case that
2864 * a variable is accessed inside of a loop, we promote its liveness to extend
2865 * to at least the range of the entire loop. Note that we don't need to do this
2866 * for anonymous nodes, since there's currently no way to use a node which was
2867 * calculated in an earlier iteration of the loop. */
2868 static void compute_liveness_recurse(struct list *instrs, unsigned int loop_first, unsigned int loop_last)
2870 struct hlsl_ir_node *instr;
2871 struct hlsl_ir_var *var;
2873 LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry)
2875 switch (instr->type)
2877 case HLSL_IR_ASSIGNMENT:
2879 struct hlsl_ir_assignment *assignment = assignment_from_node(instr);
2880 var = assignment->lhs.var;
2881 if (!var->first_write)
2882 var->first_write = loop_first ? min(instr->index, loop_first) : instr->index;
2883 assignment->rhs.node->last_read = instr->index;
2884 if (assignment->lhs.offset.node)
2885 assignment->lhs.offset.node->last_read = instr->index;
2886 break;
2888 case HLSL_IR_EXPR:
2890 struct hlsl_ir_expr *expr = expr_from_node(instr);
2891 unsigned int i;
2893 for (i = 0; i < ARRAY_SIZE(expr->operands) && expr->operands[i].node; ++i)
2894 expr->operands[i].node->last_read = instr->index;
2895 break;
2897 case HLSL_IR_IF:
2899 struct hlsl_ir_if *iff = if_from_node(instr);
2900 compute_liveness_recurse(&iff->then_instrs, loop_first, loop_last);
2901 compute_liveness_recurse(&iff->else_instrs, loop_first, loop_last);
2902 iff->condition.node->last_read = instr->index;
2903 break;
2905 case HLSL_IR_LOAD:
2907 struct hlsl_ir_load *load = load_from_node(instr);
2908 var = load->src.var;
2909 var->last_read = loop_last ? max(instr->index, loop_last) : instr->index;
2910 if (load->src.offset.node)
2911 load->src.offset.node->last_read = instr->index;
2912 break;
2914 case HLSL_IR_LOOP:
2916 struct hlsl_ir_loop *loop = loop_from_node(instr);
2917 compute_liveness_recurse(&loop->body, loop_first ? loop_first : instr->index,
2918 loop_last ? loop_last : loop->next_index);
2919 break;
2921 case HLSL_IR_SWIZZLE:
2923 struct hlsl_ir_swizzle *swizzle = swizzle_from_node(instr);
2924 swizzle->val.node->last_read = instr->index;
2925 break;
2927 case HLSL_IR_CONSTANT:
2928 case HLSL_IR_JUMP:
2929 break;
2934 static void compute_liveness(struct hlsl_ir_function_decl *entry_func)
2936 struct hlsl_ir_var *var;
2938 LIST_FOR_EACH_ENTRY(var, &hlsl_ctx.globals->vars, struct hlsl_ir_var, scope_entry)
2940 var->first_write = 1;
2943 LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry)
2945 if (var->modifiers & HLSL_STORAGE_IN)
2946 var->first_write = 1;
2947 if (var->modifiers & HLSL_STORAGE_OUT)
2948 var->last_read = UINT_MAX;
2951 if (entry_func->return_var)
2952 entry_func->return_var->last_read = UINT_MAX;
2954 compute_liveness_recurse(entry_func->body, 0, 0);
2957 HRESULT parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
2958 const char *entrypoint, ID3D10Blob **shader_blob, char **messages)
2960 struct hlsl_ir_function_decl *entry_func;
2961 struct hlsl_scope *scope, *next_scope;
2962 struct hlsl_type *hlsl_type, *next_type;
2963 struct hlsl_ir_var *var, *next_var;
2964 HRESULT hr = E_FAIL;
2965 unsigned int i;
2967 hlsl_ctx.status = PARSE_SUCCESS;
2968 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
2969 hlsl_ctx.line_no = hlsl_ctx.column = 1;
2970 hlsl_ctx.source_file = d3dcompiler_strdup("");
2971 hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
2972 if (hlsl_ctx.source_files)
2973 hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
2974 hlsl_ctx.source_files_count = 1;
2975 hlsl_ctx.cur_scope = NULL;
2976 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
2977 list_init(&hlsl_ctx.scopes);
2978 list_init(&hlsl_ctx.types);
2979 init_functions_tree(&hlsl_ctx.functions);
2980 list_init(&hlsl_ctx.static_initializers);
2982 push_scope(&hlsl_ctx);
2983 hlsl_ctx.globals = hlsl_ctx.cur_scope;
2984 declare_predefined_types(hlsl_ctx.globals);
2986 hlsl_parse();
2988 if (hlsl_ctx.status == PARSE_ERR)
2989 goto out;
2991 if (!(entry_func = get_func_entry(entrypoint)))
2993 hlsl_message("error: entry point %s is not defined\n", debugstr_a(entrypoint));
2994 goto out;
2997 if (!type_is_void(entry_func->return_type)
2998 && entry_func->return_type->type != HLSL_CLASS_STRUCT && !entry_func->semantic)
3000 hlsl_report_message(entry_func->loc, HLSL_LEVEL_ERROR,
3001 "entry point \"%s\" is missing a return value semantic", entry_func->func->name);
3004 list_move_head(entry_func->body, &hlsl_ctx.static_initializers);
3006 /* Index 0 means unused; index 1 means function entry, so start at 2. */
3007 index_instructions(entry_func->body, 2);
3009 if (TRACE_ON(hlsl_parser))
3011 TRACE("IR dump.\n");
3012 wine_rb_for_each_entry(&hlsl_ctx.functions, dump_function, NULL);
3015 compute_liveness(entry_func);
3017 if (hlsl_ctx.status != PARSE_ERR)
3018 hr = E_NOTIMPL;
3020 out:
3021 if (messages)
3023 if (hlsl_ctx.messages.size)
3024 *messages = hlsl_ctx.messages.string;
3025 else
3026 *messages = NULL;
3028 else
3030 if (hlsl_ctx.messages.capacity)
3031 d3dcompiler_free(hlsl_ctx.messages.string);
3034 for (i = 0; i < hlsl_ctx.source_files_count; ++i)
3035 d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
3036 d3dcompiler_free(hlsl_ctx.source_files);
3038 TRACE("Freeing functions IR.\n");
3039 wine_rb_destroy(&hlsl_ctx.functions, free_function_rb, NULL);
3041 TRACE("Freeing variables.\n");
3042 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
3044 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
3046 free_declaration(var);
3048 wine_rb_destroy(&scope->types, NULL, NULL);
3049 d3dcompiler_free(scope);
3052 TRACE("Freeing types.\n");
3053 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
3055 free_hlsl_type(hlsl_type);
3058 return hr;