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