1 /*
2 * HLSL parser
3 *
4 * Copyright 2008 Stefan Dösinger
5 * Copyright 2012 Matteo Bruni for CodeWeavers
6 *
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.
11 *
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.
16 *
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
20 */
21 %{
22 #include "wine/debug.h"
23
24 #include <stdio.h>
25
26 #include "d3dcompiler_private.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser);
29
30 int hlsl_lex(void);
31
32 struct hlsl_parse_ctx hlsl_ctx;
33
34 struct YYLTYPE;
35 static void set_location(struct source_location *loc, const struct YYLTYPE *l);
36
hlsl_message(const char * fmt,...)37 void WINAPIV hlsl_message(const char *fmt, ...)
38 {
39 __ms_va_list args;
40
41 __ms_va_start(args, fmt);
42 compilation_message(&hlsl_ctx.messages, fmt, args);
43 __ms_va_end(args);
44 }
45
hlsl_get_error_level_name(enum hlsl_error_level level)46 static const char *hlsl_get_error_level_name(enum hlsl_error_level level)
47 {
48 static const char * const names[] =
49 {
50 "error",
51 "warning",
52 "note",
53 };
54 return names[level];
55 }
56
hlsl_report_message(const char * filename,DWORD line,DWORD column,enum hlsl_error_level level,const char * fmt,...)57 void WINAPIV hlsl_report_message(const char *filename, DWORD line, DWORD column,
58 enum hlsl_error_level level, const char *fmt, ...)
59 {
60 __ms_va_list args;
61 char *string = NULL;
62 int rc, size = 0;
63
64 while (1)
65 {
66 __ms_va_start(args, fmt);
67 rc = vsnprintf(string, size, fmt, args);
68 __ms_va_end(args);
69
70 if (rc >= 0 && rc < size)
71 break;
72
73 if (rc >= size)
74 size = rc + 1;
75 else
76 size = size ? size * 2 : 32;
77
78 if (!string)
79 string = d3dcompiler_alloc(size);
80 else
81 string = d3dcompiler_realloc(string, size);
82 if (!string)
83 {
84 ERR("Error reallocating memory for a string.\n");
85 return;
86 }
87 }
88
89 hlsl_message("%s:%u:%u: %s: %s\n", filename, line, column, hlsl_get_error_level_name(level), string);
90 d3dcompiler_free(string);
91
92 if (level == HLSL_LEVEL_ERROR)
93 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
94 else if (level == HLSL_LEVEL_WARNING)
95 set_parse_status(&hlsl_ctx.status, PARSE_WARN);
96 }
97
hlsl_error(const char * s)98 static void hlsl_error(const char *s)
99 {
100 hlsl_report_message(hlsl_ctx.source_file, hlsl_ctx.line_no, hlsl_ctx.column, HLSL_LEVEL_ERROR, "%s", s);
101 }
102
debug_dump_decl(struct hlsl_type * type,DWORD modifiers,const char * declname,unsigned int line_no)103 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
104 {
105 TRACE("Line %u: ", line_no);
106 if (modifiers)
107 TRACE("%s ", debug_modifiers(modifiers));
108 TRACE("%s %s;\n", debug_hlsl_type(type), declname);
109 }
110
check_invalid_matrix_modifiers(DWORD modifiers,struct source_location * loc)111 static void check_invalid_matrix_modifiers(DWORD modifiers, struct source_location *loc)
112 {
113 if (modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
114 {
115 hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
116 "'row_major' or 'column_major' modifiers are only allowed for matrices");
117 }
118 }
119
declare_variable(struct hlsl_ir_var * decl,BOOL local)120 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
121 {
122 BOOL ret;
123
124 TRACE("Declaring variable %s.\n", decl->name);
125 if (decl->data_type->type == HLSL_CLASS_MATRIX)
126 {
127 if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)))
128 {
129 decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR
130 ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR;
131 }
132 }
133 else
134 check_invalid_matrix_modifiers(decl->modifiers, &decl->loc);
135
136 if (local)
137 {
138 DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
139 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
140 if (invalid)
141 {
142 hlsl_report_message(decl->loc.file, decl->loc.line, decl->loc.col, HLSL_LEVEL_ERROR,
143 "modifier '%s' invalid for local variables", debug_modifiers(invalid));
144 }
145 if (decl->semantic)
146 {
147 hlsl_report_message(decl->loc.file, decl->loc.line, decl->loc.col, HLSL_LEVEL_ERROR,
148 "semantics are not allowed on local variables");
149 return FALSE;
150 }
151 }
152 else
153 {
154 if (find_function(decl->name))
155 {
156 hlsl_report_message(decl->loc.file, decl->loc.line, decl->loc.col, HLSL_LEVEL_ERROR,
157 "redefinition of '%s'", decl->name);
158 return FALSE;
159 }
160 }
161 ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
162 if (!ret)
163 {
164 struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
165
166 hlsl_report_message(decl->loc.file, decl->loc.line, decl->loc.col, HLSL_LEVEL_ERROR,
167 "\"%s\" already declared", decl->name);
168 hlsl_report_message(old->loc.file, old->loc.line, old->loc.col, HLSL_LEVEL_NOTE,
169 "\"%s\" was previously declared here", old->name);
170 return FALSE;
171 }
172 return TRUE;
173 }
174
175 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc);
176
check_type_modifiers(DWORD modifiers,struct source_location * loc)177 static BOOL check_type_modifiers(DWORD modifiers, struct source_location *loc)
178 {
179 if (modifiers & ~HLSL_TYPE_MODIFIERS_MASK)
180 {
181 hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
182 "modifier not allowed on typedefs");
183 return FALSE;
184 }
185 return TRUE;
186 }
187
add_type_to_scope(struct hlsl_scope * scope,struct hlsl_type * def)188 static BOOL add_type_to_scope(struct hlsl_scope *scope, struct hlsl_type *def)
189 {
190 if (get_type(scope, def->name, FALSE))
191 return FALSE;
192
193 wine_rb_put(&scope->types, def->name, &def->scope_entry);
194 return TRUE;
195 }
196
declare_predefined_types(struct hlsl_scope * scope)197 static void declare_predefined_types(struct hlsl_scope *scope)
198 {
199 struct hlsl_type *type;
200 unsigned int x, y, bt;
201 static const char * const names[] =
202 {
203 "float",
204 "half",
205 "double",
206 "int",
207 "uint",
208 "bool",
209 };
210 char name[10];
211
212 for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt)
213 {
214 for (y = 1; y <= 4; ++y)
215 {
216 for (x = 1; x <= 4; ++x)
217 {
218 sprintf(name, "%s%ux%u", names[bt], x, y);
219 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_MATRIX, bt, x, y);
220 add_type_to_scope(scope, type);
221
222 if (y == 1)
223 {
224 sprintf(name, "%s%u", names[bt], x);
225 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_VECTOR, bt, x, y);
226 add_type_to_scope(scope, type);
227
228 if (x == 1)
229 {
230 sprintf(name, "%s", names[bt]);
231 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_SCALAR, bt, x, y);
232 add_type_to_scope(scope, type);
233 }
234 }
235 }
236 }
237 }
238
239 /* DX8 effects predefined types */
240 type = new_hlsl_type(d3dcompiler_strdup("DWORD"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
241 add_type_to_scope(scope, type);
242 type = new_hlsl_type(d3dcompiler_strdup("FLOAT"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
243 add_type_to_scope(scope, type);
244 type = new_hlsl_type(d3dcompiler_strdup("VECTOR"), HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1);
245 add_type_to_scope(scope, type);
246 type = new_hlsl_type(d3dcompiler_strdup("MATRIX"), HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4);
247 add_type_to_scope(scope, type);
248 type = new_hlsl_type(d3dcompiler_strdup("STRING"), HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1);
249 add_type_to_scope(scope, type);
250 type = new_hlsl_type(d3dcompiler_strdup("TEXTURE"), HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1);
251 add_type_to_scope(scope, type);
252 type = new_hlsl_type(d3dcompiler_strdup("PIXELSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1);
253 add_type_to_scope(scope, type);
254 type = new_hlsl_type(d3dcompiler_strdup("VERTEXSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1);
255 add_type_to_scope(scope, type);
256 }
257
loop_condition(struct list * cond_list)258 static struct hlsl_ir_if *loop_condition(struct list *cond_list)
259 {
260 struct hlsl_ir_node *cond, *not_cond;
261 struct hlsl_ir_if *out_cond;
262 struct hlsl_ir_jump *jump;
263 unsigned int count = list_count(cond_list);
264
265 if (!count)
266 return NULL;
267 if (count != 1)
268 ERR("Got multiple expressions in a for condition.\n");
269
270 cond = LIST_ENTRY(list_head(cond_list), struct hlsl_ir_node, entry);
271 out_cond = d3dcompiler_alloc(sizeof(*out_cond));
272 if (!out_cond)
273 {
274 ERR("Out of memory.\n");
275 return NULL;
276 }
277 out_cond->node.type = HLSL_IR_IF;
278 if (!(not_cond = new_unary_expr(HLSL_IR_UNOP_LOGIC_NOT, cond, cond->loc)))
279 {
280 ERR("Out of memory.\n");
281 d3dcompiler_free(out_cond);
282 return NULL;
283 }
284 out_cond->condition = not_cond;
285 jump = d3dcompiler_alloc(sizeof(*jump));
286 if (!jump)
287 {
288 ERR("Out of memory.\n");
289 d3dcompiler_free(out_cond);
290 d3dcompiler_free(not_cond);
291 return NULL;
292 }
293 jump->node.type = HLSL_IR_JUMP;
294 jump->type = HLSL_IR_JUMP_BREAK;
295 out_cond->then_instrs = d3dcompiler_alloc(sizeof(*out_cond->then_instrs));
296 if (!out_cond->then_instrs)
297 {
298 ERR("Out of memory.\n");
299 d3dcompiler_free(out_cond);
300 d3dcompiler_free(not_cond);
301 d3dcompiler_free(jump);
302 return NULL;
303 }
304 list_init(out_cond->then_instrs);
305 list_add_head(out_cond->then_instrs, &jump->node.entry);
306
307 return out_cond;
308 }
309
310 enum loop_type
311 {
312 LOOP_FOR,
313 LOOP_WHILE,
314 LOOP_DO_WHILE
315 };
316
create_loop(enum loop_type type,struct list * init,struct list * cond,struct hlsl_ir_node * iter,struct list * body,struct source_location * loc)317 static struct list *create_loop(enum loop_type type, struct list *init, struct list *cond,
318 struct hlsl_ir_node *iter, struct list *body, struct source_location *loc)
319 {
320 struct list *list = NULL;
321 struct hlsl_ir_loop *loop = NULL;
322 struct hlsl_ir_if *cond_jump = NULL;
323
324 list = d3dcompiler_alloc(sizeof(*list));
325 if (!list)
326 goto oom;
327 list_init(list);
328
329 if (init)
330 list_move_head(list, init);
331
332 loop = d3dcompiler_alloc(sizeof(*loop));
333 if (!loop)
334 goto oom;
335 loop->node.type = HLSL_IR_LOOP;
336 loop->node.loc = *loc;
337 list_add_tail(list, &loop->node.entry);
338 loop->body = d3dcompiler_alloc(sizeof(*loop->body));
339 if (!loop->body)
340 goto oom;
341 list_init(loop->body);
342
343 cond_jump = loop_condition(cond);
344 if (!cond_jump)
345 goto oom;
346
347 if (type != LOOP_DO_WHILE)
348 list_add_tail(loop->body, &cond_jump->node.entry);
349
350 list_move_tail(loop->body, body);
351
352 if (iter)
353 list_add_tail(loop->body, &iter->entry);
354
355 if (type == LOOP_DO_WHILE)
356 list_add_tail(loop->body, &cond_jump->node.entry);
357
358 d3dcompiler_free(init);
359 d3dcompiler_free(cond);
360 d3dcompiler_free(body);
361 return list;
362
363 oom:
364 ERR("Out of memory.\n");
365 if (loop)
366 d3dcompiler_free(loop->body);
367 d3dcompiler_free(loop);
368 d3dcompiler_free(cond_jump);
369 d3dcompiler_free(list);
370 free_instr_list(init);
371 free_instr_list(cond);
372 free_instr(iter);
373 free_instr_list(body);
374 return NULL;
375 }
376
initializer_size(const struct parse_initializer * initializer)377 static unsigned int initializer_size(const struct parse_initializer *initializer)
378 {
379 unsigned int count = 0, i;
380
381 for (i = 0; i < initializer->args_count; ++i)
382 {
383 count += components_count_type(initializer->args[i]->data_type);
384 }
385 TRACE("Initializer size = %u.\n", count);
386 return count;
387 }
388
free_parse_initializer(struct parse_initializer * initializer)389 static void free_parse_initializer(struct parse_initializer *initializer)
390 {
391 unsigned int i;
392 for (i = 0; i < initializer->args_count; ++i)
393 free_instr(initializer->args[i]);
394 d3dcompiler_free(initializer->args);
395 }
396
new_swizzle(DWORD s,unsigned int components,struct hlsl_ir_node * val,struct source_location * loc)397 static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components,
398 struct hlsl_ir_node *val, struct source_location *loc)
399 {
400 struct hlsl_ir_swizzle *swizzle = d3dcompiler_alloc(sizeof(*swizzle));
401
402 if (!swizzle)
403 return NULL;
404 swizzle->node.type = HLSL_IR_SWIZZLE;
405 swizzle->node.loc = *loc;
406 swizzle->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1);
407 swizzle->val = val;
408 swizzle->swizzle = s;
409 return swizzle;
410 }
411
get_swizzle(struct hlsl_ir_node * value,const char * swizzle,struct source_location * loc)412 static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const char *swizzle,
413 struct source_location *loc)
414 {
415 unsigned int len = strlen(swizzle), component = 0;
416 unsigned int i, set, swiz = 0;
417 BOOL valid;
418
419 if (value->data_type->type == HLSL_CLASS_MATRIX)
420 {
421 /* Matrix swizzle */
422 BOOL m_swizzle;
423 unsigned int inc, x, y;
424
425 if (len < 3 || swizzle[0] != '_')
426 return NULL;
427 m_swizzle = swizzle[1] == 'm';
428 inc = m_swizzle ? 4 : 3;
429
430 if (len % inc || len > inc * 4)
431 return NULL;
432
433 for (i = 0; i < len; i += inc)
434 {
435 if (swizzle[i] != '_')
436 return NULL;
437 if (m_swizzle)
438 {
439 if (swizzle[i + 1] != 'm')
440 return NULL;
441 x = swizzle[i + 2] - '0';
442 y = swizzle[i + 3] - '0';
443 }
444 else
445 {
446 x = swizzle[i + 1] - '1';
447 y = swizzle[i + 2] - '1';
448 }
449
450 if (x >= value->data_type->dimx || y >= value->data_type->dimy)
451 return NULL;
452 swiz |= (y << 4 | x) << component * 8;
453 component++;
454 }
455 return new_swizzle(swiz, component, value, loc);
456 }
457
458 /* Vector swizzle */
459 if (len > 4)
460 return NULL;
461
462 for (set = 0; set < 2; ++set)
463 {
464 valid = TRUE;
465 component = 0;
466 for (i = 0; i < len; ++i)
467 {
468 char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}};
469 unsigned int s = 0;
470
471 for (s = 0; s < 4; ++s)
472 {
473 if (swizzle[i] == c[set][s])
474 break;
475 }
476 if (s == 4)
477 {
478 valid = FALSE;
479 break;
480 }
481
482 if (s >= value->data_type->dimx)
483 return NULL;
484 swiz |= s << component * 2;
485 component++;
486 }
487 if (valid)
488 return new_swizzle(swiz, component, value, loc);
489 }
490
491 return NULL;
492 }
493
struct_var_initializer(struct list * list,struct hlsl_ir_var * var,struct parse_initializer * initializer)494 static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var,
495 struct parse_initializer *initializer)
496 {
497 struct hlsl_type *type = var->data_type;
498 struct hlsl_struct_field *field;
499 struct hlsl_ir_node *assignment;
500 struct hlsl_ir_deref *deref;
501 unsigned int i = 0;
502
503 if (initializer_size(initializer) != components_count_type(type))
504 {
505 hlsl_report_message(var->loc.file, var->loc.line, var->loc.col, HLSL_LEVEL_ERROR,
506 "structure initializer mismatch");
507 free_parse_initializer(initializer);
508 return;
509 }
510
511 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
512 {
513 struct hlsl_ir_node *node = initializer->args[i];
514
515 if (i++ >= initializer->args_count)
516 {
517 d3dcompiler_free(initializer->args);
518 return;
519 }
520 if (components_count_type(field->type) == components_count_type(node->data_type))
521 {
522 deref = new_record_deref(&new_var_deref(var)->node, field);
523 if (!deref)
524 {
525 ERR("Out of memory.\n");
526 break;
527 }
528 deref->node.loc = node->loc;
529 assignment = make_assignment(&deref->node, ASSIGN_OP_ASSIGN, BWRITERSP_WRITEMASK_ALL, node);
530 list_add_tail(list, &assignment->entry);
531 }
532 else
533 FIXME("Initializing with \"mismatched\" fields is not supported yet.\n");
534 }
535
536 /* Free initializer elements in excess. */
537 for (; i < initializer->args_count; ++i)
538 free_instr(initializer->args[i]);
539 d3dcompiler_free(initializer->args);
540 }
541
declare_vars(struct hlsl_type * basic_type,DWORD modifiers,struct list * var_list)542 static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list)
543 {
544 struct hlsl_type *type;
545 struct parse_variable_def *v, *v_next;
546 struct hlsl_ir_var *var;
547 struct hlsl_ir_node *assignment;
548 BOOL ret, local = TRUE;
549 struct list *statements_list = d3dcompiler_alloc(sizeof(*statements_list));
550
551 if (!statements_list)
552 {
553 ERR("Out of memory.\n");
554 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
555 d3dcompiler_free(v);
556 d3dcompiler_free(var_list);
557 return NULL;
558 }
559 list_init(statements_list);
560
561 if (!var_list)
562 return statements_list;
563
564 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
565 {
566 var = d3dcompiler_alloc(sizeof(*var));
567 if (!var)
568 {
569 ERR("Out of memory.\n");
570 d3dcompiler_free(v);
571 continue;
572 }
573 if (v->array_size)
574 type = new_array_type(basic_type, v->array_size);
575 else
576 type = basic_type;
577 var->data_type = type;
578 var->loc = v->loc;
579 var->name = v->name;
580 var->modifiers = modifiers;
581 var->semantic = v->semantic;
582 var->reg_reservation = v->reg_reservation;
583 debug_dump_decl(type, modifiers, v->name, v->loc.line);
584
585 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
586 {
587 var->modifiers |= HLSL_STORAGE_UNIFORM;
588 local = FALSE;
589 }
590
591 if (var->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer.args_count)
592 {
593 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col,
594 HLSL_LEVEL_ERROR, "const variable without initializer");
595 free_declaration(var);
596 d3dcompiler_free(v);
597 continue;
598 }
599
600 ret = declare_variable(var, local);
601 if (!ret)
602 {
603 free_declaration(var);
604 d3dcompiler_free(v);
605 continue;
606 }
607 TRACE("Declared variable %s.\n", var->name);
608
609 if (v->initializer.args_count)
610 {
611 unsigned int size = initializer_size(&v->initializer);
612
613 TRACE("Variable with initializer.\n");
614 if (type->type <= HLSL_CLASS_LAST_NUMERIC
615 && type->dimx * type->dimy != size && size != 1)
616 {
617 if (size < type->dimx * type->dimy)
618 {
619 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
620 "'%s' initializer does not match", v->name);
621 free_parse_initializer(&v->initializer);
622 d3dcompiler_free(v);
623 continue;
624 }
625 }
626 if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY)
627 && components_count_type(type) != size)
628 {
629 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
630 "'%s' initializer does not match", v->name);
631 free_parse_initializer(&v->initializer);
632 d3dcompiler_free(v);
633 continue;
634 }
635
636 if (type->type == HLSL_CLASS_STRUCT)
637 {
638 struct_var_initializer(statements_list, var, &v->initializer);
639 d3dcompiler_free(v);
640 continue;
641 }
642 if (type->type > HLSL_CLASS_LAST_NUMERIC)
643 {
644 FIXME("Initializers for non scalar/struct variables not supported yet.\n");
645 free_parse_initializer(&v->initializer);
646 d3dcompiler_free(v);
647 continue;
648 }
649 if (v->array_size > 0)
650 {
651 FIXME("Initializing arrays is not supported yet.\n");
652 free_parse_initializer(&v->initializer);
653 d3dcompiler_free(v);
654 continue;
655 }
656 if (v->initializer.args_count > 1)
657 {
658 FIXME("Complex initializers are not supported yet.\n");
659 free_parse_initializer(&v->initializer);
660 d3dcompiler_free(v);
661 continue;
662 }
663
664 assignment = make_assignment(&new_var_deref(var)->node, ASSIGN_OP_ASSIGN,
665 BWRITERSP_WRITEMASK_ALL, v->initializer.args[0]);
666 d3dcompiler_free(v->initializer.args);
667 list_add_tail(statements_list, &assignment->entry);
668 }
669 d3dcompiler_free(v);
670 }
671 d3dcompiler_free(var_list);
672 return statements_list;
673 }
674
add_struct_field(struct list * fields,struct hlsl_struct_field * field)675 static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field)
676 {
677 struct hlsl_struct_field *f;
678
679 LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry)
680 {
681 if (!strcmp(f->name, field->name))
682 return FALSE;
683 }
684 list_add_tail(fields, &field->entry);
685 return TRUE;
686 }
687
gen_struct_fields(struct hlsl_type * type,DWORD modifiers,struct list * fields)688 static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, struct list *fields)
689 {
690 struct parse_variable_def *v, *v_next;
691 struct hlsl_struct_field *field;
692 struct list *list;
693
694 list = d3dcompiler_alloc(sizeof(*list));
695 if (!list)
696 {
697 ERR("Out of memory.\n");
698 return NULL;
699 }
700 list_init(list);
701 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry)
702 {
703 debug_dump_decl(type, 0, v->name, v->loc.line);
704 field = d3dcompiler_alloc(sizeof(*field));
705 if (!field)
706 {
707 ERR("Out of memory.\n");
708 d3dcompiler_free(v);
709 return list;
710 }
711 field->type = type;
712 field->name = v->name;
713 field->modifiers = modifiers;
714 field->semantic = v->semantic;
715 if (v->initializer.args_count)
716 {
717 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
718 "struct field with an initializer.\n");
719 free_parse_initializer(&v->initializer);
720 }
721 list_add_tail(list, &field->entry);
722 d3dcompiler_free(v);
723 }
724 d3dcompiler_free(fields);
725 return list;
726 }
727
new_struct_type(const char * name,DWORD modifiers,struct list * fields)728 static struct hlsl_type *new_struct_type(const char *name, DWORD modifiers, struct list *fields)
729 {
730 struct hlsl_type *type = d3dcompiler_alloc(sizeof(*type));
731
732 if (!type)
733 {
734 ERR("Out of memory.\n");
735 return NULL;
736 }
737 type->type = HLSL_CLASS_STRUCT;
738 type->name = name;
739 type->dimx = type->dimy = 1;
740 type->modifiers = modifiers;
741 type->e.elements = fields;
742
743 list_add_tail(&hlsl_ctx.types, &type->entry);
744
745 return type;
746 }
747
add_typedef(DWORD modifiers,struct hlsl_type * orig_type,struct list * list,struct source_location * loc)748 static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list,
749 struct source_location *loc)
750 {
751 BOOL ret;
752 struct hlsl_type *type;
753 struct parse_variable_def *v, *v_next;
754
755 if (!check_type_modifiers(modifiers, loc))
756 {
757 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
758 d3dcompiler_free(v);
759 d3dcompiler_free(list);
760 return FALSE;
761 }
762
763 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
764 {
765 if (v->array_size)
766 type = new_array_type(orig_type, v->array_size);
767 else
768 type = clone_hlsl_type(orig_type);
769 if (!type)
770 {
771 ERR("Out of memory\n");
772 return FALSE;
773 }
774 d3dcompiler_free((void *)type->name);
775 type->name = v->name;
776 type->modifiers |= modifiers;
777
778 if (type->type != HLSL_CLASS_MATRIX)
779 check_invalid_matrix_modifiers(type->modifiers, &v->loc);
780
781 ret = add_type_to_scope(hlsl_ctx.cur_scope, type);
782 if (!ret)
783 {
784 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
785 "redefinition of custom type '%s'", v->name);
786 }
787 d3dcompiler_free(v);
788 }
789 d3dcompiler_free(list);
790 return TRUE;
791 }
792
add_func_parameter(struct list * list,struct parse_parameter * param,const struct source_location * loc)793 static BOOL add_func_parameter(struct list *list, struct parse_parameter *param, const struct source_location *loc)
794 {
795 struct hlsl_ir_var *decl = d3dcompiler_alloc(sizeof(*decl));
796
797 if (!decl)
798 {
799 ERR("Out of memory.\n");
800 return FALSE;
801 }
802 decl->data_type = param->type;
803 decl->loc = *loc;
804 decl->name = param->name;
805 decl->semantic = param->semantic;
806 decl->reg_reservation = param->reg_reservation;
807 decl->modifiers = param->modifiers;
808
809 if (!add_declaration(hlsl_ctx.cur_scope, decl, FALSE))
810 {
811 free_declaration(decl);
812 return FALSE;
813 }
814 list_add_tail(list, &decl->param_entry);
815 return TRUE;
816 }
817
parse_reg_reservation(const char * reg_string)818 static struct reg_reservation *parse_reg_reservation(const char *reg_string)
819 {
820 struct reg_reservation *reg_res;
821 enum bwritershader_param_register_type type;
822 DWORD regnum = 0;
823
824 switch (reg_string[0])
825 {
826 case 'c':
827 type = BWRITERSPR_CONST;
828 break;
829 case 'i':
830 type = BWRITERSPR_CONSTINT;
831 break;
832 case 'b':
833 type = BWRITERSPR_CONSTBOOL;
834 break;
835 case 's':
836 type = BWRITERSPR_SAMPLER;
837 break;
838 default:
839 FIXME("Unsupported register type.\n");
840 return NULL;
841 }
842
843 if (!sscanf(reg_string + 1, "%u", ®num))
844 {
845 FIXME("Unsupported register reservation syntax.\n");
846 return NULL;
847 }
848
849 reg_res = d3dcompiler_alloc(sizeof(*reg_res));
850 if (!reg_res)
851 {
852 ERR("Out of memory.\n");
853 return NULL;
854 }
855 reg_res->type = type;
856 reg_res->regnum = regnum;
857 return reg_res;
858 }
859
get_overloaded_func(struct wine_rb_tree * funcs,char * name,struct list * params,BOOL exact_signature)860 static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tree *funcs, char *name,
861 struct list *params, BOOL exact_signature)
862 {
863 struct hlsl_ir_function *func;
864 struct wine_rb_entry *entry;
865
866 entry = wine_rb_get(funcs, name);
867 if (entry)
868 {
869 func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
870
871 entry = wine_rb_get(&func->overloads, params);
872 if (!entry)
873 {
874 if (!exact_signature)
875 FIXME("No exact match, search for a compatible overloaded function (if any).\n");
876 return NULL;
877 }
878 return WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
879 }
880 return NULL;
881 }
882
883 %}
884
885 %locations
886 %define parse.error verbose
887 %expect 1
888
889 %union
890 {
891 struct hlsl_type *type;
892 INT intval;
893 FLOAT floatval;
894 BOOL boolval;
895 char *name;
896 DWORD modifiers;
897 struct hlsl_ir_node *instr;
898 struct list *list;
899 struct parse_function function;
900 struct parse_parameter parameter;
901 struct parse_initializer initializer;
902 struct parse_variable_def *variable_def;
903 struct parse_if_body if_body;
904 enum parse_unary_op unary_op;
905 enum parse_assign_op assign_op;
906 struct reg_reservation *reg_reservation;
907 struct parse_colon_attribute colon_attribute;
908 }
909
910 %token KW_BLENDSTATE
911 %token KW_BREAK
912 %token KW_BUFFER
913 %token KW_CBUFFER
914 %token KW_COLUMN_MAJOR
915 %token KW_COMPILE
916 %token KW_CONST
917 %token KW_CONTINUE
918 %token KW_DEPTHSTENCILSTATE
919 %token KW_DEPTHSTENCILVIEW
920 %token KW_DISCARD
921 %token KW_DO
922 %token KW_DOUBLE
923 %token KW_ELSE
924 %token KW_EXTERN
925 %token KW_FALSE
926 %token KW_FOR
927 %token KW_GEOMETRYSHADER
928 %token KW_GROUPSHARED
929 %token KW_IF
930 %token KW_IN
931 %token KW_INLINE
932 %token KW_INOUT
933 %token KW_MATRIX
934 %token KW_NAMESPACE
935 %token KW_NOINTERPOLATION
936 %token KW_OUT
937 %token KW_PASS
938 %token KW_PIXELSHADER
939 %token KW_PRECISE
940 %token KW_RASTERIZERSTATE
941 %token KW_RENDERTARGETVIEW
942 %token KW_RETURN
943 %token KW_REGISTER
944 %token KW_ROW_MAJOR
945 %token KW_SAMPLER
946 %token KW_SAMPLER1D
947 %token KW_SAMPLER2D
948 %token KW_SAMPLER3D
949 %token KW_SAMPLERCUBE
950 %token KW_SAMPLER_STATE
951 %token KW_SAMPLERCOMPARISONSTATE
952 %token KW_SHARED
953 %token KW_STATEBLOCK
954 %token KW_STATEBLOCK_STATE
955 %token KW_STATIC
956 %token KW_STRING
957 %token KW_STRUCT
958 %token KW_SWITCH
959 %token KW_TBUFFER
960 %token KW_TECHNIQUE
961 %token KW_TECHNIQUE10
962 %token KW_TEXTURE
963 %token KW_TEXTURE1D
964 %token KW_TEXTURE1DARRAY
965 %token KW_TEXTURE2D
966 %token KW_TEXTURE2DARRAY
967 %token KW_TEXTURE2DMS
968 %token KW_TEXTURE2DMSARRAY
969 %token KW_TEXTURE3D
970 %token KW_TEXTURE3DARRAY
971 %token KW_TEXTURECUBE
972 %token KW_TRUE
973 %token KW_TYPEDEF
974 %token KW_UNIFORM
975 %token KW_VECTOR
976 %token KW_VERTEXSHADER
977 %token KW_VOID
978 %token KW_VOLATILE
979 %token KW_WHILE
980
981 %token OP_INC
982 %token OP_DEC
983 %token OP_AND
984 %token OP_OR
985 %token OP_EQ
986 %token OP_LEFTSHIFT
987 %token OP_LEFTSHIFTASSIGN
988 %token OP_RIGHTSHIFT
989 %token OP_RIGHTSHIFTASSIGN
990 %token OP_ELLIPSIS
991 %token OP_LE
992 %token OP_GE
993 %token OP_NE
994 %token OP_ADDASSIGN
995 %token OP_SUBASSIGN
996 %token OP_MULASSIGN
997 %token OP_DIVASSIGN
998 %token OP_MODASSIGN
999 %token OP_ANDASSIGN
1000 %token OP_ORASSIGN
1001 %token OP_XORASSIGN
1002 %token OP_UNKNOWN1
1003 %token OP_UNKNOWN2
1004 %token OP_UNKNOWN3
1005 %token OP_UNKNOWN4
1006
1007 %token <intval> PRE_LINE
1008
1009 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
1010 %type <name> any_identifier var_identifier
1011 %token <name> STRING
1012 %token <floatval> C_FLOAT
1013 %token <intval> C_INTEGER
1014 %type <boolval> boolean
1015 %type <type> base_type
1016 %type <type> type
1017 %type <list> declaration_statement
1018 %type <list> declaration
1019 %type <list> struct_declaration
1020 %type <type> struct_spec
1021 %type <type> named_struct_spec
1022 %type <type> unnamed_struct_spec
1023 %type <list> type_specs
1024 %type <variable_def> type_spec
1025 %type <initializer> complex_initializer
1026 %type <initializer> initializer_expr_list
1027 %type <instr> initializer_expr
1028 %type <modifiers> var_modifiers
1029 %type <list> field
1030 %type <list> parameters
1031 %type <list> param_list
1032 %type <instr> expr
1033 %type <intval> array
1034 %type <list> statement
1035 %type <list> statement_list
1036 %type <list> compound_statement
1037 %type <list> jump_statement
1038 %type <list> selection_statement
1039 %type <list> loop_statement
1040 %type <function> func_declaration
1041 %type <function> func_prototype
1042 %type <list> fields_list
1043 %type <parameter> parameter
1044 %type <colon_attribute> colon_attribute
1045 %type <name> semantic
1046 %type <reg_reservation> register_opt
1047 %type <variable_def> variable_def
1048 %type <list> variables_def
1049 %type <list> variables_def_optional
1050 %type <if_body> if_body
1051 %type <instr> primary_expr
1052 %type <instr> postfix_expr
1053 %type <instr> unary_expr
1054 %type <instr> mul_expr
1055 %type <instr> add_expr
1056 %type <instr> shift_expr
1057 %type <instr> relational_expr
1058 %type <instr> equality_expr
1059 %type <instr> bitand_expr
1060 %type <instr> bitxor_expr
1061 %type <instr> bitor_expr
1062 %type <instr> logicand_expr
1063 %type <instr> logicor_expr
1064 %type <instr> conditional_expr
1065 %type <instr> assignment_expr
1066 %type <list> expr_statement
1067 %type <unary_op> unary_op
1068 %type <assign_op> assign_op
1069 %type <modifiers> input_mods
1070 %type <modifiers> input_mod
1071 %%
1072
1073 hlsl_prog: /* empty */
1074 {
1075 }
1076 | hlsl_prog func_declaration
1077 {
1078 const struct hlsl_ir_function_decl *decl;
1079
1080 decl = get_overloaded_func(&hlsl_ctx.functions, $2.name, $2.decl->parameters, TRUE);
1081 if (decl && !decl->func->intrinsic)
1082 {
1083 if (decl->body && $2.decl->body)
1084 {
1085 hlsl_report_message($2.decl->loc.file, $2.decl->loc.line,
1086 $2.decl->loc.col, HLSL_LEVEL_ERROR,
1087 "redefinition of function %s", debugstr_a($2.name));
1088 YYABORT;
1089 }
1090 else if (!compare_hlsl_types(decl->return_type, $2.decl->return_type))
1091 {
1092 hlsl_report_message($2.decl->loc.file, $2.decl->loc.line,
1093 $2.decl->loc.col, HLSL_LEVEL_ERROR,
1094 "redefining function %s with a different return type",
1095 debugstr_a($2.name));
1096 hlsl_report_message(decl->loc.file, decl->loc.line, decl->loc.col, HLSL_LEVEL_NOTE,
1097 "%s previously declared here",
1098 debugstr_a($2.name));
1099 YYABORT;
1100 }
1101 }
1102
1103 if ($2.decl->return_type->base_type == HLSL_TYPE_VOID && $2.decl->semantic)
1104 {
1105 hlsl_report_message($2.decl->loc.file, $2.decl->loc.line,
1106 $2.decl->loc.col, HLSL_LEVEL_ERROR,
1107 "void function with a semantic");
1108 }
1109
1110 TRACE("Adding function '%s' to the function list.\n", $2.name);
1111 add_function_decl(&hlsl_ctx.functions, $2.name, $2.decl, FALSE);
1112 }
1113 | hlsl_prog declaration_statement
1114 {
1115 TRACE("Declaration statement parsed.\n");
1116 }
1117 | hlsl_prog preproc_directive
1118 {
1119 }
1120 | hlsl_prog ';'
1121 {
1122 TRACE("Skipping stray semicolon.\n");
1123 }
1124
1125 preproc_directive: PRE_LINE STRING
1126 {
1127 const char **new_array = NULL;
1128
1129 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
1130 hlsl_ctx.line_no = $1;
1131 if (strcmp($2, hlsl_ctx.source_file))
1132 new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
1133 sizeof(*hlsl_ctx.source_files) * (hlsl_ctx.source_files_count + 1));
1134
1135 if (new_array)
1136 {
1137 hlsl_ctx.source_files = new_array;
1138 hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
1139 hlsl_ctx.source_file = $2;
1140 }
1141 else
1142 {
1143 d3dcompiler_free($2);
1144 }
1145 }
1146
1147 struct_declaration: struct_spec variables_def_optional ';'
1148 {
1149 struct source_location loc;
1150
1151 set_location(&loc, &@3);
1152 if (!$2)
1153 {
1154 if (!$1->name)
1155 {
1156 hlsl_report_message(loc.file, loc.line, loc.col,
1157 HLSL_LEVEL_ERROR, "anonymous struct declaration with no variables");
1158 }
1159 check_type_modifiers($1->modifiers, &loc);
1160 }
1161 $$ = declare_vars($1, 0, $2);
1162 }
1163
1164 struct_spec: named_struct_spec
1165 | unnamed_struct_spec
1166
1167 named_struct_spec: var_modifiers KW_STRUCT any_identifier '{' fields_list '}'
1168 {
1169 BOOL ret;
1170 struct source_location loc;
1171
1172 TRACE("Structure %s declaration.\n", debugstr_a($3));
1173 set_location(&loc, &@1);
1174 check_invalid_matrix_modifiers($1, &loc);
1175 $$ = new_struct_type($3, $1, $5);
1176
1177 if (get_variable(hlsl_ctx.cur_scope, $3))
1178 {
1179 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1180 HLSL_LEVEL_ERROR, "redefinition of '%s'", $3);
1181 YYABORT;
1182 }
1183
1184 ret = add_type_to_scope(hlsl_ctx.cur_scope, $$);
1185 if (!ret)
1186 {
1187 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1188 HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $3);
1189 YYABORT;
1190 }
1191 }
1192
1193 unnamed_struct_spec: var_modifiers KW_STRUCT '{' fields_list '}'
1194 {
1195 struct source_location loc;
1196
1197 TRACE("Anonymous structure declaration.\n");
1198 set_location(&loc, &@1);
1199 check_invalid_matrix_modifiers($1, &loc);
1200 $$ = new_struct_type(NULL, $1, $4);
1201 }
1202
1203 any_identifier: VAR_IDENTIFIER
1204 | TYPE_IDENTIFIER
1205 | NEW_IDENTIFIER
1206
1207 fields_list: /* Empty */
1208 {
1209 $$ = d3dcompiler_alloc(sizeof(*$$));
1210 list_init($$);
1211 }
1212 | fields_list field
1213 {
1214 BOOL ret;
1215 struct hlsl_struct_field *field, *next;
1216
1217 $$ = $1;
LIST_FOR_EACH_ENTRY_SAFE(field,next,$2,struct hlsl_struct_field,entry)1218 LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry)
1219 {
1220 ret = add_struct_field($$, field);
1221 if (ret == FALSE)
1222 {
1223 hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1224 HLSL_LEVEL_ERROR, "redefinition of '%s'", field->name);
1225 d3dcompiler_free(field);
1226 }
1227 }
1228 d3dcompiler_free($2);
1229 }
1230
1231 field: var_modifiers type variables_def ';'
1232 {
1233 $$ = gen_struct_fields($2, $1, $3);
1234 }
1235 | unnamed_struct_spec variables_def ';'
1236 {
1237 $$ = gen_struct_fields($1, 0, $2);
1238 }
1239
1240 func_declaration: func_prototype compound_statement
1241 {
1242 TRACE("Function %s parsed.\n", $1.name);
1243 $$ = $1;
1244 $$.decl->body = $2;
1245 pop_scope(&hlsl_ctx);
1246 }
1247 | func_prototype ';'
1248 {
1249 TRACE("Function prototype for %s.\n", $1.name);
1250 $$ = $1;
1251 pop_scope(&hlsl_ctx);
1252 }
1253
1254 func_prototype: var_modifiers type var_identifier '(' parameters ')' colon_attribute
1255 {
1256 if (get_variable(hlsl_ctx.globals, $3))
1257 {
1258 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1259 HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
1260 YYABORT;
1261 }
1262 if ($2->base_type == HLSL_TYPE_VOID && $7.semantic)
1263 {
1264 hlsl_report_message(hlsl_ctx.source_file, @7.first_line, @7.first_column,
1265 HLSL_LEVEL_ERROR, "void function with a semantic");
1266 }
1267
1268 if ($7.reg_reservation)
1269 {
1270 FIXME("Unexpected register reservation for a function.\n");
1271 d3dcompiler_free($7.reg_reservation);
1272 }
1273 $$.decl = new_func_decl($2, $5);
1274 if (!$$.decl)
1275 {
1276 ERR("Out of memory.\n");
1277 YYABORT;
1278 }
1279 $$.name = $3;
1280 $$.decl->semantic = $7.semantic;
1281 set_location(&$$.decl->loc, &@3);
1282 }
1283
1284 compound_statement: '{' '}'
1285 {
1286 $$ = d3dcompiler_alloc(sizeof(*$$));
1287 list_init($$);
1288 }
1289 | '{' scope_start statement_list '}'
1290 {
1291 pop_scope(&hlsl_ctx);
1292 $$ = $3;
1293 }
1294
1295 scope_start: /* Empty */
1296 {
1297 push_scope(&hlsl_ctx);
1298 }
1299
1300 var_identifier: VAR_IDENTIFIER
1301 | NEW_IDENTIFIER
1302
1303 colon_attribute: /* Empty */
1304 {
1305 $$.semantic = NULL;
1306 $$.reg_reservation = NULL;
1307 }
1308 | semantic
1309 {
1310 $$.semantic = $1;
1311 $$.reg_reservation = NULL;
1312 }
1313 | register_opt
1314 {
1315 $$.semantic = NULL;
1316 $$.reg_reservation = $1;
1317 }
1318
1319 semantic: ':' any_identifier
1320 {
1321 $$ = $2;
1322 }
1323
1324 /* FIXME: Writemasks */
1325 register_opt: ':' KW_REGISTER '(' any_identifier ')'
1326 {
1327 $$ = parse_reg_reservation($4);
1328 d3dcompiler_free($4);
1329 }
1330 | ':' KW_REGISTER '(' any_identifier ',' any_identifier ')'
1331 {
1332 FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a($4));
1333 d3dcompiler_free($4);
1334
1335 $$ = parse_reg_reservation($6);
1336 d3dcompiler_free($6);
1337 }
1338
1339 parameters: scope_start
1340 {
1341 $$ = d3dcompiler_alloc(sizeof(*$$));
1342 list_init($$);
1343 }
1344 | scope_start param_list
1345 {
1346 $$ = $2;
1347 }
1348
1349 param_list: parameter
1350 {
1351 struct source_location loc;
1352
1353 $$ = d3dcompiler_alloc(sizeof(*$$));
1354 list_init($$);
1355 set_location(&loc, &@1);
1356 if (!add_func_parameter($$, &$1, &loc))
1357 {
1358 ERR("Error adding function parameter %s.\n", $1.name);
1359 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1360 YYABORT;
1361 }
1362 }
1363 | param_list ',' parameter
1364 {
1365 struct source_location loc;
1366
1367 $$ = $1;
1368 set_location(&loc, &@3);
1369 if (!add_func_parameter($$, &$3, &loc))
1370 {
1371 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1372 "duplicate parameter %s", $3.name);
1373 YYABORT;
1374 }
1375 }
1376
1377 parameter: input_mods var_modifiers type any_identifier colon_attribute
1378 {
1379 $$.modifiers = $1 ? $1 : HLSL_MODIFIER_IN;
1380 $$.modifiers |= $2;
1381 $$.type = $3;
1382 $$.name = $4;
1383 $$.semantic = $5.semantic;
1384 $$.reg_reservation = $5.reg_reservation;
1385 }
1386
1387 input_mods: /* Empty */
1388 {
1389 $$ = 0;
1390 }
1391 | input_mods input_mod
1392 {
1393 if ($1 & $2)
1394 {
1395 hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1396 HLSL_LEVEL_ERROR, "duplicate input-output modifiers");
1397 YYABORT;
1398 }
1399 $$ = $1 | $2;
1400 }
1401
1402 input_mod: KW_IN
1403 {
1404 $$ = HLSL_MODIFIER_IN;
1405 }
1406 | KW_OUT
1407 {
1408 $$ = HLSL_MODIFIER_OUT;
1409 }
1410 | KW_INOUT
1411 {
1412 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
1413 }
1414
1415 type: base_type
1416 {
1417 $$ = $1;
1418 }
1419 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
1420 {
1421 if ($3->type != HLSL_CLASS_SCALAR)
1422 {
1423 hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
1424 hlsl_ctx.line_no);
1425 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1426 YYABORT;
1427 }
1428 if ($5 < 1 || $5 > 4)
1429 {
1430 hlsl_message("Line %u: vector size must be between 1 and 4.\n",
1431 hlsl_ctx.line_no);
1432 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1433 YYABORT;
1434 }
1435
1436 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
1437 }
1438 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
1439 {
1440 if ($3->type != HLSL_CLASS_SCALAR)
1441 {
1442 hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
1443 hlsl_ctx.line_no);
1444 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1445 YYABORT;
1446 }
1447 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
1448 {
1449 hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
1450 hlsl_ctx.line_no);
1451 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1452 YYABORT;
1453 }
1454
1455 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
1456 }
1457
1458 base_type: KW_VOID
1459 {
1460 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
1461 }
1462 | KW_SAMPLER
1463 {
1464 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1465 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
1466 }
1467 | KW_SAMPLER1D
1468 {
1469 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1470 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
1471 }
1472 | KW_SAMPLER2D
1473 {
1474 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1475 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
1476 }
1477 | KW_SAMPLER3D
1478 {
1479 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1480 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
1481 }
1482 | KW_SAMPLERCUBE
1483 {
1484 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1485 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
1486 }
1487 | TYPE_IDENTIFIER
1488 {
1489 struct hlsl_type *type;
1490
1491 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
1492 $$ = type;
1493 d3dcompiler_free($1);
1494 }
1495 | KW_STRUCT TYPE_IDENTIFIER
1496 {
1497 struct hlsl_type *type;
1498
1499 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
1500 if (type->type != HLSL_CLASS_STRUCT)
1501 {
1502 hlsl_message("Line %u: redefining %s as a structure.\n",
1503 hlsl_ctx.line_no, $2);
1504 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1505 }
1506 else
1507 {
1508 $$ = type;
1509 }
1510 d3dcompiler_free($2);
1511 }
1512
1513 declaration_statement: declaration
1514 | struct_declaration
1515 | typedef
1516 {
1517 $$ = d3dcompiler_alloc(sizeof(*$$));
1518 if (!$$)
1519 {
1520 ERR("Out of memory\n");
1521 YYABORT;
1522 }
1523 list_init($$);
1524 }
1525
1526 typedef: KW_TYPEDEF var_modifiers type type_specs ';'
1527 {
1528 struct source_location loc;
1529
1530 set_location(&loc, &@1);
1531 if (!add_typedef($2, $3, $4, &loc))
1532 YYABORT;
1533 }
1534 | KW_TYPEDEF struct_spec type_specs ';'
1535 {
1536 struct source_location loc;
1537
1538 set_location(&loc, &@1);
1539 if (!add_typedef(0, $2, $3, &loc))
1540 YYABORT;
1541 }
1542
1543 type_specs: type_spec
1544 {
1545 $$ = d3dcompiler_alloc(sizeof(*$$));
1546 list_init($$);
1547 list_add_head($$, &$1->entry);
1548 }
1549 | type_specs ',' type_spec
1550 {
1551 $$ = $1;
1552 list_add_tail($$, &$3->entry);
1553 }
1554
1555 type_spec: any_identifier array
1556 {
1557 $$ = d3dcompiler_alloc(sizeof(*$$));
1558 set_location(&$$->loc, &@1);
1559 $$->name = $1;
1560 $$->array_size = $2;
1561 }
1562
1563 declaration: var_modifiers type variables_def ';'
1564 {
1565 $$ = declare_vars($2, $1, $3);
1566 }
1567
1568 variables_def_optional: /* Empty */
1569 {
1570 $$ = NULL;
1571 }
1572 | variables_def
1573 {
1574 $$ = $1;
1575 }
1576
1577 variables_def: variable_def
1578 {
1579 $$ = d3dcompiler_alloc(sizeof(*$$));
1580 list_init($$);
1581 list_add_head($$, &$1->entry);
1582 }
1583 | variables_def ',' variable_def
1584 {
1585 $$ = $1;
1586 list_add_tail($$, &$3->entry);
1587 }
1588
1589 variable_def: any_identifier array colon_attribute
1590 {
1591 $$ = d3dcompiler_alloc(sizeof(*$$));
1592 set_location(&$$->loc, &@1);
1593 $$->name = $1;
1594 $$->array_size = $2;
1595 $$->semantic = $3.semantic;
1596 $$->reg_reservation = $3.reg_reservation;
1597 }
1598 | any_identifier array colon_attribute '=' complex_initializer
1599 {
1600 TRACE("Declaration with initializer.\n");
1601 $$ = d3dcompiler_alloc(sizeof(*$$));
1602 set_location(&$$->loc, &@1);
1603 $$->name = $1;
1604 $$->array_size = $2;
1605 $$->semantic = $3.semantic;
1606 $$->reg_reservation = $3.reg_reservation;
1607 $$->initializer = $5;
1608 }
1609
1610 array: /* Empty */
1611 {
1612 $$ = 0;
1613 }
1614 | '[' expr ']'
1615 {
1616 FIXME("Array.\n");
1617 $$ = 0;
1618 free_instr($2);
1619 }
1620
1621 var_modifiers: /* Empty */
1622 {
1623 $$ = 0;
1624 }
1625 | KW_EXTERN var_modifiers
1626 {
1627 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
1628 }
1629 | KW_NOINTERPOLATION var_modifiers
1630 {
1631 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
1632 }
1633 | KW_PRECISE var_modifiers
1634 {
1635 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
1636 }
1637 | KW_SHARED var_modifiers
1638 {
1639 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
1640 }
1641 | KW_GROUPSHARED var_modifiers
1642 {
1643 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
1644 }
1645 | KW_STATIC var_modifiers
1646 {
1647 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
1648 }
1649 | KW_UNIFORM var_modifiers
1650 {
1651 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
1652 }
1653 | KW_VOLATILE var_modifiers
1654 {
1655 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
1656 }
1657 | KW_CONST var_modifiers
1658 {
1659 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
1660 }
1661 | KW_ROW_MAJOR var_modifiers
1662 {
1663 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
1664 }
1665 | KW_COLUMN_MAJOR var_modifiers
1666 {
1667 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
1668 }
1669
1670 complex_initializer: initializer_expr
1671 {
1672 $$.args_count = 1;
1673 if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args))))
1674 YYABORT;
1675 $$.args[0] = $1;
1676 }
1677 | '{' initializer_expr_list '}'
1678 {
1679 $$ = $2;
1680 }
1681 | '{' initializer_expr_list ',' '}'
1682 {
1683 $$ = $2;
1684 }
1685
1686 initializer_expr: assignment_expr
1687 {
1688 $$ = $1;
1689 }
1690
1691 initializer_expr_list: initializer_expr
1692 {
1693 $$.args_count = 1;
1694 if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args))))
1695 YYABORT;
1696 $$.args[0] = $1;
1697 }
1698 | initializer_expr_list ',' initializer_expr
1699 {
1700 $$ = $1;
1701 if (!($$.args = d3dcompiler_realloc($$.args, ($$.args_count + 1) * sizeof(*$$.args))))
1702 YYABORT;
1703 $$.args[$$.args_count++] = $3;
1704 }
1705
1706 boolean: KW_TRUE
1707 {
1708 $$ = TRUE;
1709 }
1710 | KW_FALSE
1711 {
1712 $$ = FALSE;
1713 }
1714
1715 statement_list: statement
1716 {
1717 $$ = $1;
1718 }
1719 | statement_list statement
1720 {
1721 $$ = $1;
1722 list_move_tail($$, $2);
1723 d3dcompiler_free($2);
1724 }
1725
1726 statement: declaration_statement
1727 | expr_statement
1728 | compound_statement
1729 | jump_statement
1730 | selection_statement
1731 | loop_statement
1732
1733 /* FIXME: add rule for return with no value */
1734 jump_statement: KW_RETURN expr ';'
1735 {
1736 struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump));
1737 if (!jump)
1738 {
1739 ERR("Out of memory\n");
1740 YYABORT;
1741 }
1742 jump->node.type = HLSL_IR_JUMP;
1743 set_location(&jump->node.loc, &@1);
1744 jump->type = HLSL_IR_JUMP_RETURN;
1745 jump->node.data_type = $2->data_type;
1746 jump->return_value = $2;
1747
1748 FIXME("Check for valued return on void function.\n");
1749 FIXME("Implicit conversion to the return type if needed, "
1750 "error out if conversion not possible.\n");
1751
1752 $$ = d3dcompiler_alloc(sizeof(*$$));
1753 list_init($$);
1754 list_add_tail($$, &jump->node.entry);
1755 }
1756
1757 selection_statement: KW_IF '(' expr ')' if_body
1758 {
1759 struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
1760 if (!instr)
1761 {
1762 ERR("Out of memory\n");
1763 YYABORT;
1764 }
1765 instr->node.type = HLSL_IR_IF;
1766 set_location(&instr->node.loc, &@1);
1767 instr->condition = $3;
1768 instr->then_instrs = $5.then_instrs;
1769 instr->else_instrs = $5.else_instrs;
1770 if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1)
1771 {
1772 hlsl_report_message(instr->node.loc.file, instr->node.loc.line,
1773 instr->node.loc.col, HLSL_LEVEL_ERROR,
1774 "if condition requires a scalar");
1775 }
1776 $$ = d3dcompiler_alloc(sizeof(*$$));
1777 list_init($$);
1778 list_add_head($$, &instr->node.entry);
1779 }
1780
1781 if_body: statement
1782 {
1783 $$.then_instrs = $1;
1784 $$.else_instrs = NULL;
1785 }
1786 | statement KW_ELSE statement
1787 {
1788 $$.then_instrs = $1;
1789 $$.else_instrs = $3;
1790 }
1791
1792 loop_statement: KW_WHILE '(' expr ')' statement
1793 {
1794 struct source_location loc;
1795 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1796
1797 if (!cond)
1798 {
1799 ERR("Out of memory.\n");
1800 YYABORT;
1801 }
1802 list_init(cond);
1803 list_add_head(cond, &$3->entry);
1804 set_location(&loc, &@1);
1805 $$ = create_loop(LOOP_WHILE, NULL, cond, NULL, $5, &loc);
1806 }
1807 | KW_DO statement KW_WHILE '(' expr ')' ';'
1808 {
1809 struct source_location loc;
1810 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1811
1812 if (!cond)
1813 {
1814 ERR("Out of memory.\n");
1815 YYABORT;
1816 }
1817 list_init(cond);
1818 list_add_head(cond, &$5->entry);
1819 set_location(&loc, &@1);
1820 $$ = create_loop(LOOP_DO_WHILE, NULL, cond, NULL, $2, &loc);
1821 }
1822 | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
1823 {
1824 struct source_location loc;
1825
1826 set_location(&loc, &@1);
1827 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1828 pop_scope(&hlsl_ctx);
1829 }
1830 | KW_FOR '(' scope_start declaration expr_statement expr ')' statement
1831 {
1832 struct source_location loc;
1833
1834 set_location(&loc, &@1);
1835 if (!$4)
1836 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_WARNING,
1837 "no expressions in for loop initializer");
1838 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1839 pop_scope(&hlsl_ctx);
1840 }
1841
1842 expr_statement: ';'
1843 {
1844 $$ = d3dcompiler_alloc(sizeof(*$$));
1845 list_init($$);
1846 }
1847 | expr ';'
1848 {
1849 $$ = d3dcompiler_alloc(sizeof(*$$));
1850 list_init($$);
1851 if ($1)
1852 list_add_head($$, &$1->entry);
1853 }
1854
1855 primary_expr: C_FLOAT
1856 {
1857 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1858 if (!c)
1859 {
1860 ERR("Out of memory.\n");
1861 YYABORT;
1862 }
1863 c->node.type = HLSL_IR_CONSTANT;
1864 set_location(&c->node.loc, &yylloc);
1865 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("float"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
1866 c->v.value.f[0] = $1;
1867 $$ = &c->node;
1868 }
1869 | C_INTEGER
1870 {
1871 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1872 if (!c)
1873 {
1874 ERR("Out of memory.\n");
1875 YYABORT;
1876 }
1877 c->node.type = HLSL_IR_CONSTANT;
1878 set_location(&c->node.loc, &yylloc);
1879 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("int"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
1880 c->v.value.i[0] = $1;
1881 $$ = &c->node;
1882 }
1883 | boolean
1884 {
1885 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1886 if (!c)
1887 {
1888 ERR("Out of memory.\n");
1889 YYABORT;
1890 }
1891 c->node.type = HLSL_IR_CONSTANT;
1892 set_location(&c->node.loc, &yylloc);
1893 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("bool"), HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
1894 c->v.value.b[0] = $1;
1895 $$ = &c->node;
1896 }
1897 | VAR_IDENTIFIER
1898 {
1899 struct hlsl_ir_deref *deref;
1900 struct hlsl_ir_var *var;
1901
1902 if (!(var = get_variable(hlsl_ctx.cur_scope, $1)))
1903 {
1904 hlsl_message("Line %d: variable '%s' not declared\n",
1905 hlsl_ctx.line_no, $1);
1906 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1907 YYABORT;
1908 }
1909 if ((deref = new_var_deref(var)))
1910 {
1911 $$ = &deref->node;
1912 set_location(&$$->loc, &@1);
1913 }
1914 else
1915 $$ = NULL;
1916 }
1917 | '(' expr ')'
1918 {
1919 $$ = $2;
1920 }
1921
1922 postfix_expr: primary_expr
1923 {
1924 $$ = $1;
1925 }
1926 | postfix_expr OP_INC
1927 {
1928 struct source_location loc;
1929
1930 set_location(&loc, &@2);
1931 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1932 {
1933 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1934 "modifying a const expression");
1935 YYABORT;
1936 }
1937 $$ = new_unary_expr(HLSL_IR_UNOP_POSTINC, $1, loc);
1938 /* Post increment/decrement expressions are considered const */
1939 $$->data_type = clone_hlsl_type($$->data_type);
1940 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1941 }
1942 | postfix_expr OP_DEC
1943 {
1944 struct source_location loc;
1945
1946 set_location(&loc, &@2);
1947 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1948 {
1949 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1950 "modifying a const expression");
1951 YYABORT;
1952 }
1953 $$ = new_unary_expr(HLSL_IR_UNOP_POSTDEC, $1, loc);
1954 /* Post increment/decrement expressions are considered const */
1955 $$->data_type = clone_hlsl_type($$->data_type);
1956 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1957 }
1958 | postfix_expr '.' any_identifier
1959 {
1960 struct source_location loc;
1961
1962 set_location(&loc, &@2);
1963 if ($1->data_type->type == HLSL_CLASS_STRUCT)
1964 {
1965 struct hlsl_type *type = $1->data_type;
1966 struct hlsl_struct_field *field;
1967
1968 $$ = NULL;
1969 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
1970 {
1971 if (!strcmp($3, field->name))
1972 {
1973 struct hlsl_ir_deref *deref = new_record_deref($1, field);
1974
1975 if (!deref)
1976 {
1977 ERR("Out of memory\n");
1978 YYABORT;
1979 }
1980 deref->node.loc = loc;
1981 $$ = &deref->node;
1982 break;
1983 }
1984 }
1985 if (!$$)
1986 {
1987 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1988 "invalid subscript %s", debugstr_a($3));
1989 YYABORT;
1990 }
1991 }
1992 else if ($1->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
1993 {
1994 struct hlsl_ir_swizzle *swizzle;
1995
1996 swizzle = get_swizzle($1, $3, &loc);
1997 if (!swizzle)
1998 {
1999 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2000 "invalid swizzle %s", debugstr_a($3));
2001 YYABORT;
2002 }
2003 $$ = &swizzle->node;
2004 }
2005 else
2006 {
2007 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2008 "invalid subscript %s", debugstr_a($3));
2009 YYABORT;
2010 }
2011 }
2012 | postfix_expr '[' expr ']'
2013 {
2014 /* This may be an array dereference or a vector/matrix
2015 * subcomponent access.
2016 * We store it as an array dereference in any case. */
2017 struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
2018 struct hlsl_type *expr_type = $1->data_type;
2019 struct source_location loc;
2020
2021 TRACE("Array dereference from type %s\n", debug_hlsl_type(expr_type));
2022 if (!deref)
2023 {
2024 ERR("Out of memory\n");
2025 YYABORT;
2026 }
2027 deref->node.type = HLSL_IR_DEREF;
2028 set_location(&loc, &@2);
2029 deref->node.loc = loc;
2030 if (expr_type->type == HLSL_CLASS_ARRAY)
2031 {
2032 deref->node.data_type = expr_type->e.array.type;
2033 }
2034 else if (expr_type->type == HLSL_CLASS_MATRIX)
2035 {
2036 deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, expr_type->base_type, expr_type->dimx, 1);
2037 }
2038 else if (expr_type->type == HLSL_CLASS_VECTOR)
2039 {
2040 deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_SCALAR, expr_type->base_type, 1, 1);
2041 }
2042 else
2043 {
2044 if (expr_type->type == HLSL_CLASS_SCALAR)
2045 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2046 "array-indexed expression is scalar");
2047 else
2048 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2049 "expression is not array-indexable");
2050 d3dcompiler_free(deref);
2051 free_instr($1);
2052 free_instr($3);
2053 YYABORT;
2054 }
2055 if ($3->data_type->type != HLSL_CLASS_SCALAR)
2056 {
2057 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2058 "array index is not scalar");
2059 d3dcompiler_free(deref);
2060 free_instr($1);
2061 free_instr($3);
2062 YYABORT;
2063 }
2064 deref->type = HLSL_IR_DEREF_ARRAY;
2065 deref->v.array.array = $1;
2066 deref->v.array.index = $3;
2067
2068 $$ = &deref->node;
2069 }
2070 /* "var_modifiers" doesn't make sense in this case, but it's needed
2071 in the grammar to avoid shift/reduce conflicts. */
2072 | var_modifiers type '(' initializer_expr_list ')'
2073 {
2074 struct hlsl_ir_constructor *constructor;
2075
2076 TRACE("%s constructor.\n", debug_hlsl_type($2));
2077 if ($1)
2078 {
2079 hlsl_message("Line %u: unexpected modifier in a constructor.\n",
2080 hlsl_ctx.line_no);
2081 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2082 YYABORT;
2083 }
2084 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
2085 {
2086 hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
2087 hlsl_ctx.line_no);
2088 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2089 YYABORT;
2090 }
2091 if ($2->dimx * $2->dimy != initializer_size(&$4))
2092 {
2093 hlsl_message("Line %u: wrong number of components in constructor.\n",
2094 hlsl_ctx.line_no);
2095 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2096 YYABORT;
2097 }
2098 assert($4.args_count <= ARRAY_SIZE(constructor->args));
2099
2100 constructor = d3dcompiler_alloc(sizeof(*constructor));
2101 constructor->node.type = HLSL_IR_CONSTRUCTOR;
2102 set_location(&constructor->node.loc, &@3);
2103 constructor->node.data_type = $2;
2104 constructor->args_count = $4.args_count;
2105 memcpy(constructor->args, $4.args, $4.args_count * sizeof(*$4.args));
2106 d3dcompiler_free($4.args);
2107 $$ = &constructor->node;
2108 }
2109
2110 unary_expr: postfix_expr
2111 {
2112 $$ = $1;
2113 }
2114 | OP_INC unary_expr
2115 {
2116 struct source_location loc;
2117
2118 set_location(&loc, &@1);
2119 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2120 {
2121 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2122 "modifying a const expression");
2123 YYABORT;
2124 }
2125 $$ = new_unary_expr(HLSL_IR_UNOP_PREINC, $2, loc);
2126 }
2127 | OP_DEC unary_expr
2128 {
2129 struct source_location loc;
2130
2131 set_location(&loc, &@1);
2132 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2133 {
2134 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2135 "modifying a const expression");
2136 YYABORT;
2137 }
2138 $$ = new_unary_expr(HLSL_IR_UNOP_PREDEC, $2, loc);
2139 }
2140 | unary_op unary_expr
2141 {
2142 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
2143 HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
2144 struct source_location loc;
2145
2146 if ($1 == UNARY_OP_PLUS)
2147 {
2148 $$ = $2;
2149 }
2150 else
2151 {
2152 set_location(&loc, &@1);
2153 $$ = new_unary_expr(ops[$1], $2, loc);
2154 }
2155 }
2156 /* var_modifiers just to avoid shift/reduce conflicts */
2157 | '(' var_modifiers type array ')' unary_expr
2158 {
2159 struct hlsl_ir_expr *expr;
2160 struct hlsl_type *src_type = $6->data_type;
2161 struct hlsl_type *dst_type;
2162 struct source_location loc;
2163
2164 set_location(&loc, &@3);
2165 if ($2)
2166 {
2167 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2168 "unexpected modifier in a cast");
2169 YYABORT;
2170 }
2171
2172 if ($4)
2173 dst_type = new_array_type($3, $4);
2174 else
2175 dst_type = $3;
2176
2177 if (!compatible_data_types(src_type, dst_type))
2178 {
2179 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2180 "can't cast from %s to %s",
2181 debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
2182 YYABORT;
2183 }
2184
2185 expr = new_cast($6, dst_type, &loc);
2186 $$ = expr ? &expr->node : NULL;
2187 }
2188
2189 unary_op: '+'
2190 {
2191 $$ = UNARY_OP_PLUS;
2192 }
2193 | '-'
2194 {
2195 $$ = UNARY_OP_MINUS;
2196 }
2197 | '!'
2198 {
2199 $$ = UNARY_OP_LOGICNOT;
2200 }
2201 | '~'
2202 {
2203 $$ = UNARY_OP_BITNOT;
2204 }
2205
2206 mul_expr: unary_expr
2207 {
2208 $$ = $1;
2209 }
2210 | mul_expr '*' unary_expr
2211 {
2212 struct source_location loc;
2213
2214 set_location(&loc, &@2);
2215 $$ = new_binary_expr(HLSL_IR_BINOP_MUL, $1, $3, loc);
2216 }
2217 | mul_expr '/' unary_expr
2218 {
2219 struct source_location loc;
2220
2221 set_location(&loc, &@2);
2222 $$ = new_binary_expr(HLSL_IR_BINOP_DIV, $1, $3, loc);
2223 }
2224 | mul_expr '%' unary_expr
2225 {
2226 struct source_location loc;
2227
2228 set_location(&loc, &@2);
2229 $$ = new_binary_expr(HLSL_IR_BINOP_MOD, $1, $3, loc);
2230 }
2231
2232 add_expr: mul_expr
2233 {
2234 $$ = $1;
2235 }
2236 | add_expr '+' mul_expr
2237 {
2238 struct source_location loc;
2239
2240 set_location(&loc, &@2);
2241 $$ = new_binary_expr(HLSL_IR_BINOP_ADD, $1, $3, loc);
2242 }
2243 | add_expr '-' mul_expr
2244 {
2245 struct source_location loc;
2246
2247 set_location(&loc, &@2);
2248 $$ = new_binary_expr(HLSL_IR_BINOP_SUB, $1, $3, loc);
2249 }
2250
2251 shift_expr: add_expr
2252 {
2253 $$ = $1;
2254 }
2255 | shift_expr OP_LEFTSHIFT add_expr
2256 {
2257 FIXME("Left shift\n");
2258 }
2259 | shift_expr OP_RIGHTSHIFT add_expr
2260 {
2261 FIXME("Right shift\n");
2262 }
2263
2264 relational_expr: shift_expr
2265 {
2266 $$ = $1;
2267 }
2268 | relational_expr '<' shift_expr
2269 {
2270 struct source_location loc;
2271
2272 set_location(&loc, &@2);
2273 $$ = new_binary_expr(HLSL_IR_BINOP_LESS, $1, $3, loc);
2274 }
2275 | relational_expr '>' shift_expr
2276 {
2277 struct source_location loc;
2278
2279 set_location(&loc, &@2);
2280 $$ = new_binary_expr(HLSL_IR_BINOP_GREATER, $1, $3, loc);
2281 }
2282 | relational_expr OP_LE shift_expr
2283 {
2284 struct source_location loc;
2285
2286 set_location(&loc, &@2);
2287 $$ = new_binary_expr(HLSL_IR_BINOP_LEQUAL, $1, $3, loc);
2288 }
2289 | relational_expr OP_GE shift_expr
2290 {
2291 struct source_location loc;
2292
2293 set_location(&loc, &@2);
2294 $$ = new_binary_expr(HLSL_IR_BINOP_GEQUAL, $1, $3, loc);
2295 }
2296
2297 equality_expr: relational_expr
2298 {
2299 $$ = $1;
2300 }
2301 | equality_expr OP_EQ relational_expr
2302 {
2303 struct source_location loc;
2304
2305 set_location(&loc, &@2);
2306 $$ = new_binary_expr(HLSL_IR_BINOP_EQUAL, $1, $3, loc);
2307 }
2308 | equality_expr OP_NE relational_expr
2309 {
2310 struct source_location loc;
2311
2312 set_location(&loc, &@2);
2313 $$ = new_binary_expr(HLSL_IR_BINOP_NEQUAL, $1, $3, loc);
2314 }
2315
2316 bitand_expr: equality_expr
2317 {
2318 $$ = $1;
2319 }
2320 | bitand_expr '&' equality_expr
2321 {
2322 FIXME("bitwise AND\n");
2323 }
2324
2325 bitxor_expr: bitand_expr
2326 {
2327 $$ = $1;
2328 }
2329 | bitxor_expr '^' bitand_expr
2330 {
2331 FIXME("bitwise XOR\n");
2332 }
2333
2334 bitor_expr: bitxor_expr
2335 {
2336 $$ = $1;
2337 }
2338 | bitor_expr '|' bitxor_expr
2339 {
2340 FIXME("bitwise OR\n");
2341 }
2342
2343 logicand_expr: bitor_expr
2344 {
2345 $$ = $1;
2346 }
2347 | logicand_expr OP_AND bitor_expr
2348 {
2349 FIXME("logic AND\n");
2350 }
2351
2352 logicor_expr: logicand_expr
2353 {
2354 $$ = $1;
2355 }
2356 | logicor_expr OP_OR logicand_expr
2357 {
2358 FIXME("logic OR\n");
2359 }
2360
2361 conditional_expr: logicor_expr
2362 {
2363 $$ = $1;
2364 }
2365 | logicor_expr '?' expr ':' assignment_expr
2366 {
2367 FIXME("ternary operator\n");
2368 }
2369
2370 assignment_expr: conditional_expr
2371 {
2372 $$ = $1;
2373 }
2374 | unary_expr assign_op assignment_expr
2375 {
2376 struct source_location loc;
2377
2378 set_location(&loc, &@2);
2379 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
2380 {
2381 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2382 "l-value is const");
2383 YYABORT;
2384 }
2385 $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
2386 if (!$$)
2387 YYABORT;
2388 $$->loc = loc;
2389 }
2390
2391 assign_op: '='
2392 {
2393 $$ = ASSIGN_OP_ASSIGN;
2394 }
2395 | OP_ADDASSIGN
2396 {
2397 $$ = ASSIGN_OP_ADD;
2398 }
2399 | OP_SUBASSIGN
2400 {
2401 $$ = ASSIGN_OP_SUB;
2402 }
2403 | OP_MULASSIGN
2404 {
2405 $$ = ASSIGN_OP_MUL;
2406 }
2407 | OP_DIVASSIGN
2408 {
2409 $$ = ASSIGN_OP_DIV;
2410 }
2411 | OP_MODASSIGN
2412 {
2413 $$ = ASSIGN_OP_MOD;
2414 }
2415 | OP_LEFTSHIFTASSIGN
2416 {
2417 $$ = ASSIGN_OP_LSHIFT;
2418 }
2419 | OP_RIGHTSHIFTASSIGN
2420 {
2421 $$ = ASSIGN_OP_RSHIFT;
2422 }
2423 | OP_ANDASSIGN
2424 {
2425 $$ = ASSIGN_OP_AND;
2426 }
2427 | OP_ORASSIGN
2428 {
2429 $$ = ASSIGN_OP_OR;
2430 }
2431 | OP_XORASSIGN
2432 {
2433 $$ = ASSIGN_OP_XOR;
2434 }
2435
2436 expr: assignment_expr
2437 {
2438 $$ = $1;
2439 }
2440 | expr ',' assignment_expr
2441 {
2442 FIXME("Comma expression\n");
2443 }
2444
2445 %%
2446
set_location(struct source_location * loc,const struct YYLTYPE * l)2447 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
2448 {
2449 loc->file = hlsl_ctx.source_file;
2450 loc->line = l->first_line;
2451 loc->col = l->first_column;
2452 }
2453
add_modifier(DWORD modifiers,DWORD mod,const struct YYLTYPE * loc)2454 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
2455 {
2456 if (modifiers & mod)
2457 {
2458 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2459 "modifier '%s' already specified", debug_modifiers(mod));
2460 return modifiers;
2461 }
2462 if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
2463 && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
2464 {
2465 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2466 "more than one matrix majority keyword");
2467 return modifiers;
2468 }
2469 return modifiers | mod;
2470 }
2471
dump_function_decl(struct wine_rb_entry * entry,void * context)2472 static void dump_function_decl(struct wine_rb_entry *entry, void *context)
2473 {
2474 struct hlsl_ir_function_decl *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
2475 if (func->body)
2476 debug_dump_ir_function_decl(func);
2477 }
2478
dump_function(struct wine_rb_entry * entry,void * context)2479 static void dump_function(struct wine_rb_entry *entry, void *context)
2480 {
2481 struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
2482 wine_rb_for_each_entry(&func->overloads, dump_function_decl, NULL);
2483 }
2484
parse_hlsl(enum shader_type type,DWORD major,DWORD minor,const char * entrypoint,char ** messages)2485 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
2486 const char *entrypoint, char **messages)
2487 {
2488 struct hlsl_scope *scope, *next_scope;
2489 struct hlsl_type *hlsl_type, *next_type;
2490 struct hlsl_ir_var *var, *next_var;
2491 unsigned int i;
2492
2493 hlsl_ctx.status = PARSE_SUCCESS;
2494 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
2495 hlsl_ctx.line_no = hlsl_ctx.column = 1;
2496 hlsl_ctx.source_file = d3dcompiler_strdup("");
2497 hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
2498 if (hlsl_ctx.source_files)
2499 hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
2500 hlsl_ctx.source_files_count = 1;
2501 hlsl_ctx.cur_scope = NULL;
2502 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
2503 list_init(&hlsl_ctx.scopes);
2504 list_init(&hlsl_ctx.types);
2505 init_functions_tree(&hlsl_ctx.functions);
2506
2507 push_scope(&hlsl_ctx);
2508 hlsl_ctx.globals = hlsl_ctx.cur_scope;
2509 declare_predefined_types(hlsl_ctx.globals);
2510
2511 hlsl_parse();
2512
2513 if (TRACE_ON(hlsl_parser))
2514 {
2515 TRACE("IR dump.\n");
2516 wine_rb_for_each_entry(&hlsl_ctx.functions, dump_function, NULL);
2517 }
2518
2519 TRACE("Compilation status = %d\n", hlsl_ctx.status);
2520 if (messages)
2521 {
2522 if (hlsl_ctx.messages.size)
2523 *messages = hlsl_ctx.messages.string;
2524 else
2525 *messages = NULL;
2526 }
2527 else
2528 {
2529 if (hlsl_ctx.messages.capacity)
2530 d3dcompiler_free(hlsl_ctx.messages.string);
2531 }
2532
2533 for (i = 0; i < hlsl_ctx.source_files_count; ++i)
2534 d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
2535 d3dcompiler_free(hlsl_ctx.source_files);
2536
2537 TRACE("Freeing functions IR.\n");
2538 wine_rb_destroy(&hlsl_ctx.functions, free_function_rb, NULL);
2539
2540 TRACE("Freeing variables.\n");
2541 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
2542 {
2543 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
2544 {
2545 free_declaration(var);
2546 }
2547 wine_rb_destroy(&scope->types, NULL, NULL);
2548 d3dcompiler_free(scope);
2549 }
2550
2551 TRACE("Freeing types.\n");
2552 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
2553 {
2554 free_hlsl_type(hlsl_type);
2555 }
2556
2557 return NULL;
2558 }
2559