gdi32: Set the font anti-aliasing flags from the fontconfig information if available.
[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
1069 preproc_directive:        PRE_LINE STRING
1070                             {
1071                                 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
1072                                 hlsl_ctx.line_no = $1;
1073                                 if (strcmp($2, hlsl_ctx.source_file))
1074                                 {
1075                                     const char **new_array;
1076
1077                                     hlsl_ctx.source_file = $2;
1078                                     new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
1079                                             sizeof(*hlsl_ctx.source_files) * hlsl_ctx.source_files_count + 1);
1080                                     if (new_array)
1081                                     {
1082                                         hlsl_ctx.source_files = new_array;
1083                                         hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
1084                                     }
1085                                 }
1086                             }
1087
1088 struct_declaration:       struct_spec variables_def_optional ';'
1089                             {
1090                                 struct source_location loc;
1091
1092                                 set_location(&loc, &@3);
1093                                 if (!$2)
1094                                 {
1095                                     if (!$1->name)
1096                                     {
1097                                         hlsl_report_message(loc.file, loc.line, loc.col,
1098                                                 HLSL_LEVEL_ERROR, "anonymous struct declaration with no variables");
1099                                     }
1100                                     check_type_modifiers($1->modifiers, &loc);
1101                                 }
1102                                 $$ = declare_vars($1, 0, $2);
1103                             }
1104
1105 struct_spec:              named_struct_spec
1106                         | unnamed_struct_spec
1107
1108 named_struct_spec:        var_modifiers KW_STRUCT any_identifier '{' fields_list '}'
1109                             {
1110                                 BOOL ret;
1111                                 struct source_location loc;
1112
1113                                 TRACE("Structure %s declaration.\n", debugstr_a($3));
1114                                 set_location(&loc, &@1);
1115                                 check_invalid_matrix_modifiers($1, &loc);
1116                                 $$ = new_struct_type($3, $1, $5);
1117
1118                                 if (get_variable(hlsl_ctx.cur_scope, $3))
1119                                 {
1120                                     hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1121                                             HLSL_LEVEL_ERROR, "redefinition of '%s'", $3);
1122                                     return 1;
1123                                 }
1124
1125                                 ret = add_type_to_scope(hlsl_ctx.cur_scope, $$);
1126                                 if (!ret)
1127                                 {
1128                                     hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1129                                             HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $3);
1130                                     return 1;
1131                                 }
1132                             }
1133
1134 unnamed_struct_spec:      var_modifiers KW_STRUCT '{' fields_list '}'
1135                             {
1136                                 struct source_location loc;
1137
1138                                 TRACE("Anonymous structure declaration.\n");
1139                                 set_location(&loc, &@1);
1140                                 check_invalid_matrix_modifiers($1, &loc);
1141                                 $$ = new_struct_type(NULL, $1, $4);
1142                             }
1143
1144 any_identifier:           VAR_IDENTIFIER
1145                         | TYPE_IDENTIFIER
1146                         | NEW_IDENTIFIER
1147
1148 fields_list:              /* Empty */
1149                             {
1150                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1151                                 list_init($$);
1152                             }
1153                         | fields_list field
1154                             {
1155                                 BOOL ret;
1156                                 struct hlsl_struct_field *field, *next;
1157
1158                                 $$ = $1;
1159                                 LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry)
1160                                 {
1161                                     ret = add_struct_field($$, field);
1162                                     if (ret == FALSE)
1163                                     {
1164                                         hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1165                                                 HLSL_LEVEL_ERROR, "redefinition of '%s'", field->name);
1166                                         d3dcompiler_free(field);
1167                                     }
1168                                 }
1169                                 d3dcompiler_free($2);
1170                             }
1171
1172 field:                    var_modifiers type variables_def ';'
1173                             {
1174                                 $$ = gen_struct_fields($2, $1, $3);
1175                             }
1176                         | unnamed_struct_spec variables_def ';'
1177                             {
1178                                 $$ = gen_struct_fields($1, 0, $2);
1179                             }
1180
1181 func_declaration:         func_prototype compound_statement
1182                             {
1183                                 TRACE("Function %s parsed.\n", $1.name);
1184                                 $$ = $1;
1185                                 $$.decl->body = $2;
1186                                 pop_scope(&hlsl_ctx);
1187                             }
1188                         | func_prototype ';'
1189                             {
1190                                 TRACE("Function prototype for %s.\n", $1.name);
1191                                 $$ = $1;
1192                                 pop_scope(&hlsl_ctx);
1193                             }
1194
1195 func_prototype:           var_modifiers type var_identifier '(' parameters ')' semantic
1196                             {
1197                                 if (get_variable(hlsl_ctx.globals, $3))
1198                                 {
1199                                     hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1200                                             HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
1201                                     return 1;
1202                                 }
1203                                 if ($2->base_type == HLSL_TYPE_VOID && $7)
1204                                 {
1205                                     hlsl_report_message(hlsl_ctx.source_file, @7.first_line, @7.first_column,
1206                                             HLSL_LEVEL_ERROR, "void function with a semantic");
1207                                 }
1208
1209                                 $$.decl = new_func_decl($2, $5);
1210                                 if (!$$.decl)
1211                                 {
1212                                     ERR("Out of memory.\n");
1213                                     return -1;
1214                                 }
1215                                 $$.name = $3;
1216                                 $$.decl->semantic = $7;
1217                                 set_location(&$$.decl->node.loc, &@3);
1218                             }
1219
1220 compound_statement:       '{' '}'
1221                             {
1222                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1223                                 list_init($$);
1224                             }
1225                         | '{' scope_start statement_list '}'
1226                             {
1227                                 pop_scope(&hlsl_ctx);
1228                                 $$ = $3;
1229                             }
1230
1231 scope_start:              /* Empty */
1232                             {
1233                                 push_scope(&hlsl_ctx);
1234                             }
1235
1236 var_identifier:           VAR_IDENTIFIER
1237                         | NEW_IDENTIFIER
1238
1239 semantic:                 /* Empty */
1240                             {
1241                                 $$ = NULL;
1242                             }
1243                         | ':' any_identifier
1244                             {
1245                                 $$ = $2;
1246                             }
1247
1248 parameters:               scope_start
1249                             {
1250                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1251                                 list_init($$);
1252                             }
1253                         | scope_start param_list
1254                             {
1255                                 $$ = $2;
1256                             }
1257
1258 param_list:               parameter
1259                             {
1260                                 struct source_location loc;
1261
1262                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1263                                 list_init($$);
1264                                 set_location(&loc, &@1);
1265                                 if (!add_func_parameter($$, &$1, &loc))
1266                                 {
1267                                     ERR("Error adding function parameter %s.\n", $1.name);
1268                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1269                                     return -1;
1270                                 }
1271                             }
1272                         | param_list ',' parameter
1273                             {
1274                                 struct source_location loc;
1275
1276                                 $$ = $1;
1277                                 set_location(&loc, &@3);
1278                                 if (!add_func_parameter($$, &$3, &loc))
1279                                 {
1280                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1281                                             "duplicate parameter %s", $3.name);
1282                                     return 1;
1283                                 }
1284                             }
1285
1286 parameter:                input_mods var_modifiers type any_identifier semantic
1287                             {
1288                                 $$.modifiers = $1 ? $1 : HLSL_MODIFIER_IN;
1289                                 $$.modifiers |= $2;
1290                                 $$.type = $3;
1291                                 $$.name = $4;
1292                                 $$.semantic = $5;
1293                             }
1294
1295 input_mods:               /* Empty */
1296                             {
1297                                 $$ = 0;
1298                             }
1299                         | input_mods input_mod
1300                             {
1301                                 if ($1 & $2)
1302                                 {
1303                                     hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1304                                             HLSL_LEVEL_ERROR, "duplicate input-output modifiers");
1305                                     return 1;
1306                                 }
1307                                 $$ = $1 | $2;
1308                             }
1309
1310 input_mod:                KW_IN
1311                             {
1312                                 $$ = HLSL_MODIFIER_IN;
1313                             }
1314                         | KW_OUT
1315                             {
1316                                 $$ = HLSL_MODIFIER_OUT;
1317                             }
1318                         | KW_INOUT
1319                             {
1320                                 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
1321                             }
1322
1323 type:                     base_type
1324                             {
1325                                 $$ = $1;
1326                             }
1327                         | KW_VECTOR '<' base_type ',' C_INTEGER '>'
1328                             {
1329                                 if ($3->type != HLSL_CLASS_SCALAR)
1330                                 {
1331                                     hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
1332                                             hlsl_ctx.line_no);
1333                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1334                                     return 1;
1335                                 }
1336                                 if ($5 < 1 || $5 > 4)
1337                                 {
1338                                     hlsl_message("Line %u: vector size must be between 1 and 4.\n",
1339                                             hlsl_ctx.line_no);
1340                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1341                                     return 1;
1342                                 }
1343
1344                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
1345                             }
1346                         | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
1347                             {
1348                                 if ($3->type != HLSL_CLASS_SCALAR)
1349                                 {
1350                                     hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
1351                                             hlsl_ctx.line_no);
1352                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1353                                     return 1;
1354                                 }
1355                                 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
1356                                 {
1357                                     hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
1358                                             hlsl_ctx.line_no);
1359                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1360                                     return 1;
1361                                 }
1362
1363                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
1364                             }
1365
1366 base_type:                KW_VOID
1367                             {
1368                                 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
1369                             }
1370                         | KW_SAMPLER
1371                             {
1372                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1373                                 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
1374                             }
1375                         | KW_SAMPLER1D
1376                             {
1377                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1378                                 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
1379                             }
1380                         | KW_SAMPLER2D
1381                             {
1382                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1383                                 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
1384                             }
1385                         | KW_SAMPLER3D
1386                             {
1387                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1388                                 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
1389                             }
1390                         | KW_SAMPLERCUBE
1391                             {
1392                                 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1393                                 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
1394                             }
1395                         | TYPE_IDENTIFIER
1396                             {
1397                                 struct hlsl_type *type;
1398
1399                                 TRACE("Type %s.\n", $1);
1400                                 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
1401                                 $$ = type;
1402                                 d3dcompiler_free($1);
1403                             }
1404                         | KW_STRUCT TYPE_IDENTIFIER
1405                             {
1406                                 struct hlsl_type *type;
1407
1408                                 TRACE("Struct type %s.\n", $2);
1409                                 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
1410                                 if (type->type != HLSL_CLASS_STRUCT)
1411                                 {
1412                                     hlsl_message("Line %u: redefining %s as a structure.\n",
1413                                             hlsl_ctx.line_no, $2);
1414                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1415                                 }
1416                                 else
1417                                 {
1418                                     $$ = type;
1419                                 }
1420                                 d3dcompiler_free($2);
1421                             }
1422
1423 declaration_statement:    declaration
1424                         | struct_declaration
1425                         | typedef
1426                             {
1427                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1428                                 if (!$$)
1429                                 {
1430                                     ERR("Out of memory\n");
1431                                     return -1;
1432                                 }
1433                                 list_init($$);
1434                             }
1435
1436 typedef:                  KW_TYPEDEF var_modifiers type type_specs ';'
1437                             {
1438                                 struct source_location loc;
1439
1440                                 set_location(&loc, &@1);
1441                                 if (!add_typedef($2, $3, $4, &loc))
1442                                     return 1;
1443                             }
1444                         | KW_TYPEDEF struct_spec type_specs ';'
1445                             {
1446                                 struct source_location loc;
1447
1448                                 set_location(&loc, &@1);
1449                                 if (!add_typedef(0, $2, $3, &loc))
1450                                     return 1;
1451                             }
1452
1453 type_specs:               type_spec
1454                             {
1455                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1456                                 list_init($$);
1457                                 list_add_head($$, &$1->entry);
1458                             }
1459                         | type_specs ',' type_spec
1460                             {
1461                                 $$ = $1;
1462                                 list_add_tail($$, &$3->entry);
1463                             }
1464
1465 type_spec:                any_identifier array
1466                             {
1467                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1468                                 set_location(&$$->loc, &@1);
1469                                 $$->name = $1;
1470                                 $$->array_size = $2;
1471                             }
1472
1473 declaration:              var_modifiers type variables_def ';'
1474                             {
1475                                 $$ = declare_vars($2, $1, $3);
1476                             }
1477
1478 variables_def_optional:   /* Empty */
1479                             {
1480                                 $$ = NULL;
1481                             }
1482                         | variables_def
1483                             {
1484                                 $$ = $1;
1485                             }
1486
1487 variables_def:            variable_def
1488                             {
1489                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1490                                 list_init($$);
1491                                 list_add_head($$, &$1->entry);
1492                             }
1493                         | variables_def ',' variable_def
1494                             {
1495                                 $$ = $1;
1496                                 list_add_tail($$, &$3->entry);
1497                             }
1498
1499 variable_def:             any_identifier array semantic
1500                             {
1501                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1502                                 set_location(&$$->loc, &@1);
1503                                 $$->name = $1;
1504                                 $$->array_size = $2;
1505                                 $$->semantic = $3;
1506                             }
1507                         | any_identifier array semantic '=' complex_initializer
1508                             {
1509                                 TRACE("Declaration with initializer.\n");
1510                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1511                                 set_location(&$$->loc, &@1);
1512                                 $$->name = $1;
1513                                 $$->array_size = $2;
1514                                 $$->semantic = $3;
1515                                 $$->initializer = $5;
1516                             }
1517
1518 array:                    /* Empty */
1519                             {
1520                                 $$ = 0;
1521                             }
1522                         | '[' expr ']'
1523                             {
1524                                 FIXME("Array.\n");
1525                                 $$ = 0;
1526                                 free_instr($2);
1527                             }
1528
1529 var_modifiers:            /* Empty */
1530                             {
1531                                 $$ = 0;
1532                             }
1533                         | KW_EXTERN var_modifiers
1534                             {
1535                                 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
1536                             }
1537                         | KW_NOINTERPOLATION var_modifiers
1538                             {
1539                                 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
1540                             }
1541                         | KW_PRECISE var_modifiers
1542                             {
1543                                 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
1544                             }
1545                         | KW_SHARED var_modifiers
1546                             {
1547                                 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
1548                             }
1549                         | KW_GROUPSHARED var_modifiers
1550                             {
1551                                 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
1552                             }
1553                         | KW_STATIC var_modifiers
1554                             {
1555                                 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
1556                             }
1557                         | KW_UNIFORM var_modifiers
1558                             {
1559                                 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
1560                             }
1561                         | KW_VOLATILE var_modifiers
1562                             {
1563                                 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
1564                             }
1565                         | KW_CONST var_modifiers
1566                             {
1567                                 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
1568                             }
1569                         | KW_ROW_MAJOR var_modifiers
1570                             {
1571                                 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
1572                             }
1573                         | KW_COLUMN_MAJOR var_modifiers
1574                             {
1575                                 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
1576                             }
1577
1578 complex_initializer:      initializer_expr
1579                             {
1580                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1581                                 list_init($$);
1582                                 list_add_head($$, &$1->entry);
1583                             }
1584                         | '{' initializer_expr_list '}'
1585                             {
1586                                 $$ = $2;
1587                             }
1588
1589 initializer_expr:         assignment_expr
1590                             {
1591                                 $$ = $1;
1592                             }
1593
1594 initializer_expr_list:    initializer_expr
1595                             {
1596                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1597                                 list_init($$);
1598                                 list_add_head($$, &$1->entry);
1599                             }
1600                         | initializer_expr_list ',' initializer_expr
1601                             {
1602                                 $$ = $1;
1603                                 list_add_tail($$, &$3->entry);
1604                             }
1605
1606 boolean:                  KW_TRUE
1607                             {
1608                                 $$ = TRUE;
1609                             }
1610                         | KW_FALSE
1611                             {
1612                                 $$ = FALSE;
1613                             }
1614
1615 statement_list:           statement
1616                             {
1617                                 $$ = $1;
1618                             }
1619                         | statement_list statement
1620                             {
1621                                 $$ = $1;
1622                                 list_move_tail($$, $2);
1623                                 d3dcompiler_free($2);
1624                             }
1625
1626 statement:                declaration_statement
1627                         | expr_statement
1628                         | compound_statement
1629                         | jump_statement
1630                         | selection_statement
1631                         | loop_statement
1632
1633                           /* FIXME: add rule for return with no value */
1634 jump_statement:           KW_RETURN expr ';'
1635                             {
1636                                 struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump));
1637                                 if (!jump)
1638                                 {
1639                                     ERR("Out of memory\n");
1640                                     return -1;
1641                                 }
1642                                 jump->node.type = HLSL_IR_JUMP;
1643                                 set_location(&jump->node.loc, &@1);
1644                                 jump->type = HLSL_IR_JUMP_RETURN;
1645                                 jump->node.data_type = $2->data_type;
1646                                 jump->return_value = $2;
1647
1648                                 FIXME("Check for valued return on void function.\n");
1649                                 FIXME("Implicit conversion to the return type if needed, "
1650                                         "error out if conversion not possible.\n");
1651
1652                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1653                                 list_init($$);
1654                                 list_add_tail($$, &jump->node.entry);
1655                             }
1656
1657 selection_statement:      KW_IF '(' expr ')' if_body
1658                             {
1659                                 struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
1660                                 if (!instr)
1661                                 {
1662                                     ERR("Out of memory\n");
1663                                     return -1;
1664                                 }
1665                                 instr->node.type = HLSL_IR_IF;
1666                                 set_location(&instr->node.loc, &@1);
1667                                 instr->condition = $3;
1668                                 instr->then_instrs = $5.then_instrs;
1669                                 instr->else_instrs = $5.else_instrs;
1670                                 if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1)
1671                                 {
1672                                     hlsl_report_message(instr->node.loc.file, instr->node.loc.line,
1673                                             instr->node.loc.col, HLSL_LEVEL_ERROR,
1674                                             "if condition requires a scalar");
1675                                 }
1676                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1677                                 list_init($$);
1678                                 list_add_head($$, &instr->node.entry);
1679                             }
1680
1681 if_body:                  statement
1682                             {
1683                                 $$.then_instrs = $1;
1684                                 $$.else_instrs = NULL;
1685                             }
1686                         | statement KW_ELSE statement
1687                             {
1688                                 $$.then_instrs = $1;
1689                                 $$.else_instrs = $3;
1690                             }
1691
1692 loop_statement:           KW_WHILE '(' expr ')' statement
1693                             {
1694                                 struct source_location loc;
1695                                 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1696
1697                                 if (!cond)
1698                                 {
1699                                     ERR("Out of memory.\n");
1700                                     return -1;
1701                                 }
1702                                 list_init(cond);
1703                                 list_add_head(cond, &$3->entry);
1704                                 set_location(&loc, &@1);
1705                                 $$ = create_loop(LOOP_WHILE, NULL, cond, NULL, $5, &loc);
1706                             }
1707                         | KW_DO statement KW_WHILE '(' expr ')' ';'
1708                             {
1709                                 struct source_location loc;
1710                                 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1711
1712                                 if (!cond)
1713                                 {
1714                                     ERR("Out of memory.\n");
1715                                     return -1;
1716                                 }
1717                                 list_init(cond);
1718                                 list_add_head(cond, &$5->entry);
1719                                 set_location(&loc, &@1);
1720                                 $$ = create_loop(LOOP_DO_WHILE, NULL, cond, NULL, $2, &loc);
1721                             }
1722                         | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
1723                             {
1724                                 struct source_location loc;
1725
1726                                 set_location(&loc, &@1);
1727                                 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1728                                 pop_scope(&hlsl_ctx);
1729                             }
1730                         | KW_FOR '(' scope_start declaration expr_statement expr ')' statement
1731                             {
1732                                 struct source_location loc;
1733
1734                                 set_location(&loc, &@1);
1735                                 if (!$4)
1736                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_WARNING,
1737                                             "no expressions in for loop initializer");
1738                                 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1739                                 pop_scope(&hlsl_ctx);
1740                             }
1741
1742 expr_statement:           ';'
1743                             {
1744                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1745                                 list_init($$);
1746                             }
1747                         | expr ';'
1748                             {
1749                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1750                                 list_init($$);
1751                                 if ($1)
1752                                     list_add_head($$, &$1->entry);
1753                             }
1754
1755 primary_expr:             C_FLOAT
1756                             {
1757                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1758                                 if (!c)
1759                                 {
1760                                     ERR("Out of memory.\n");
1761                                     return -1;
1762                                 }
1763                                 c->node.type = HLSL_IR_CONSTANT;
1764                                 set_location(&c->node.loc, &yylloc);
1765                                 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
1766                                 c->v.value.f[0] = $1;
1767                                 $$ = &c->node;
1768                             }
1769                         | C_INTEGER
1770                             {
1771                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1772                                 if (!c)
1773                                 {
1774                                     ERR("Out of memory.\n");
1775                                     return -1;
1776                                 }
1777                                 c->node.type = HLSL_IR_CONSTANT;
1778                                 set_location(&c->node.loc, &yylloc);
1779                                 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
1780                                 c->v.value.i[0] = $1;
1781                                 $$ = &c->node;
1782                             }
1783                         | boolean
1784                             {
1785                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1786                                 if (!c)
1787                                 {
1788                                     ERR("Out of memory.\n");
1789                                     return -1;
1790                                 }
1791                                 c->node.type = HLSL_IR_CONSTANT;
1792                                 set_location(&c->node.loc, &yylloc);
1793                                 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
1794                                 c->v.value.b[0] = $1;
1795                                 $$ = &c->node;
1796                             }
1797                         | variable
1798                             {
1799                                 struct hlsl_ir_deref *deref = new_var_deref($1);
1800                                 if (deref)
1801                                 {
1802                                     $$ = &deref->node;
1803                                     set_location(&$$->loc, &@1);
1804                                 }
1805                                 else
1806                                     $$ = NULL;
1807                             }
1808                         | '(' expr ')'
1809                             {
1810                                 $$ = $2;
1811                             }
1812
1813 variable:                 VAR_IDENTIFIER
1814                             {
1815                                 struct hlsl_ir_var *var;
1816                                 var = get_variable(hlsl_ctx.cur_scope, $1);
1817                                 if (!var)
1818                                 {
1819                                     hlsl_message("Line %d: variable '%s' not declared\n",
1820                                             hlsl_ctx.line_no, $1);
1821                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1822                                     return 1;
1823                                 }
1824                                 $$ = var;
1825                             }
1826
1827 postfix_expr:             primary_expr
1828                             {
1829                                 $$ = $1;
1830                             }
1831                         | postfix_expr OP_INC
1832                             {
1833                                 struct hlsl_ir_node *operands[3];
1834                                 struct source_location loc;
1835
1836                                 set_location(&loc, &@2);
1837                                 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1838                                 {
1839                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1840                                             "modifying a const expression");
1841                                     return 1;
1842                                 }
1843                                 operands[0] = $1;
1844                                 operands[1] = operands[2] = NULL;
1845                                 $$ = &new_expr(HLSL_IR_BINOP_POSTINC, operands, &loc)->node;
1846                                 /* Post increment/decrement expressions are considered const */
1847                                 $$->data_type = clone_hlsl_type($$->data_type);
1848                                 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1849                             }
1850                         | postfix_expr OP_DEC
1851                             {
1852                                 struct hlsl_ir_node *operands[3];
1853                                 struct source_location loc;
1854
1855                                 set_location(&loc, &@2);
1856                                 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1857                                 {
1858                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1859                                             "modifying a const expression");
1860                                     return 1;
1861                                 }
1862                                 operands[0] = $1;
1863                                 operands[1] = operands[2] = NULL;
1864                                 $$ = &new_expr(HLSL_IR_BINOP_POSTDEC, operands, &loc)->node;
1865                                 /* Post increment/decrement expressions are considered const */
1866                                 $$->data_type = clone_hlsl_type($$->data_type);
1867                                 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1868                             }
1869                         | postfix_expr '.' any_identifier
1870                             {
1871                                 struct source_location loc;
1872
1873                                 set_location(&loc, &@2);
1874                                 if ($1->data_type->type == HLSL_CLASS_STRUCT)
1875                                 {
1876                                     struct hlsl_type *type = $1->data_type;
1877                                     struct hlsl_struct_field *field;
1878
1879                                     $$ = NULL;
1880                                     LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
1881                                     {
1882                                         if (!strcmp($3, field->name))
1883                                         {
1884                                             struct hlsl_ir_deref *deref = new_record_deref($1, field);
1885
1886                                             if (!deref)
1887                                             {
1888                                                 ERR("Out of memory\n");
1889                                                 return -1;
1890                                             }
1891                                             deref->node.loc = loc;
1892                                             $$ = &deref->node;
1893                                             break;
1894                                         }
1895                                     }
1896                                     if (!$$)
1897                                     {
1898                                         hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1899                                                 "invalid subscript %s", debugstr_a($3));
1900                                         return 1;
1901                                     }
1902                                 }
1903                                 else if ($1->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
1904                                 {
1905                                     struct hlsl_ir_swizzle *swizzle;
1906
1907                                     swizzle = get_swizzle($1, $3, &loc);
1908                                     if (!swizzle)
1909                                     {
1910                                         hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1911                                                 "invalid swizzle %s", debugstr_a($3));
1912                                         return 1;
1913                                     }
1914                                     $$ = &swizzle->node;
1915                                 }
1916                                 else
1917                                 {
1918                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1919                                             "invalid subscript %s", debugstr_a($3));
1920                                     return 1;
1921                                 }
1922                             }
1923                         | postfix_expr '[' expr ']'
1924                             {
1925                                 /* This may be an array dereference or a vector/matrix
1926                                  * subcomponent access.
1927                                  * We store it as an array dereference in any case. */
1928                                 struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
1929                                 struct hlsl_type *expr_type = $1->data_type;
1930                                 struct source_location loc;
1931
1932                                 TRACE("Array dereference from type %s\n", debug_hlsl_type(expr_type));
1933                                 if (!deref)
1934                                 {
1935                                     ERR("Out of memory\n");
1936                                     return -1;
1937                                 }
1938                                 deref->node.type = HLSL_IR_DEREF;
1939                                 set_location(&loc, &@2);
1940                                 deref->node.loc = loc;
1941                                 if (expr_type->type == HLSL_CLASS_ARRAY)
1942                                 {
1943                                     deref->node.data_type = expr_type->e.array.type;
1944                                 }
1945                                 else if (expr_type->type == HLSL_CLASS_MATRIX)
1946                                 {
1947                                     deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, expr_type->base_type, expr_type->dimx, 1);
1948                                 }
1949                                 else if (expr_type->type == HLSL_CLASS_VECTOR)
1950                                 {
1951                                     deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_SCALAR, expr_type->base_type, 1, 1);
1952                                 }
1953                                 else
1954                                 {
1955                                     if (expr_type->type == HLSL_CLASS_SCALAR)
1956                                         hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1957                                                 "array-indexed expression is scalar");
1958                                     else
1959                                         hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1960                                                 "expression is not array-indexable");
1961                                     d3dcompiler_free(deref);
1962                                     free_instr($1);
1963                                     free_instr($3);
1964                                     return 1;
1965                                 }
1966                                 if ($3->data_type->type != HLSL_CLASS_SCALAR)
1967                                 {
1968                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1969                                             "array index is not scalar");
1970                                     d3dcompiler_free(deref);
1971                                     free_instr($1);
1972                                     free_instr($3);
1973                                     return 1;
1974                                 }
1975                                 deref->type = HLSL_IR_DEREF_ARRAY;
1976                                 deref->v.array.array = $1;
1977                                 deref->v.array.index = $3;
1978
1979                                 $$ = &deref->node;
1980                             }
1981                           /* "var_modifiers" doesn't make sense in this case, but it's needed
1982                              in the grammar to avoid shift/reduce conflicts. */
1983                         | var_modifiers type '(' initializer_expr_list ')'
1984                             {
1985                                 struct hlsl_ir_constructor *constructor;
1986
1987                                 TRACE("%s constructor.\n", debug_hlsl_type($2));
1988                                 if ($1)
1989                                 {
1990                                     hlsl_message("Line %u: unexpected modifier in a constructor.\n",
1991                                             hlsl_ctx.line_no);
1992                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1993                                     return -1;
1994                                 }
1995                                 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
1996                                 {
1997                                     hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
1998                                             hlsl_ctx.line_no);
1999                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2000                                     return -1;
2001                                 }
2002                                 if ($2->dimx * $2->dimy != components_count_expr_list($4))
2003                                 {
2004                                     hlsl_message("Line %u: wrong number of components in constructor.\n",
2005                                             hlsl_ctx.line_no);
2006                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2007                                     return -1;
2008                                 }
2009
2010                                 constructor = d3dcompiler_alloc(sizeof(*constructor));
2011                                 constructor->node.type = HLSL_IR_CONSTRUCTOR;
2012                                 set_location(&constructor->node.loc, &@3);
2013                                 constructor->node.data_type = $2;
2014                                 constructor->arguments = $4;
2015
2016                                 $$ = &constructor->node;
2017                             }
2018
2019 unary_expr:               postfix_expr
2020                             {
2021                                 $$ = $1;
2022                             }
2023                         | OP_INC unary_expr
2024                             {
2025                                 struct hlsl_ir_node *operands[3];
2026                                 struct source_location loc;
2027
2028                                 set_location(&loc, &@1);
2029                                 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2030                                 {
2031                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2032                                             "modifying a const expression");
2033                                     return 1;
2034                                 }
2035                                 operands[0] = $2;
2036                                 operands[1] = operands[2] = NULL;
2037                                 $$ = &new_expr(HLSL_IR_BINOP_PREINC, operands, &loc)->node;
2038                             }
2039                         | OP_DEC unary_expr
2040                             {
2041                                 struct hlsl_ir_node *operands[3];
2042                                 struct source_location loc;
2043
2044                                 set_location(&loc, &@1);
2045                                 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2046                                 {
2047                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2048                                             "modifying a const expression");
2049                                     return 1;
2050                                 }
2051                                 operands[0] = $2;
2052                                 operands[1] = operands[2] = NULL;
2053                                 $$ = &new_expr(HLSL_IR_BINOP_PREDEC, operands, &loc)->node;
2054                             }
2055                         | unary_op unary_expr
2056                             {
2057                                 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
2058                                         HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
2059                                 struct hlsl_ir_node *operands[3];
2060                                 struct source_location loc;
2061
2062                                 if ($1 == UNARY_OP_PLUS)
2063                                 {
2064                                     $$ = $2;
2065                                 }
2066                                 else
2067                                 {
2068                                     operands[0] = $2;
2069                                     operands[1] = operands[2] = NULL;
2070                                     set_location(&loc, &@1);
2071                                     $$ = &new_expr(ops[$1], operands, &loc)->node;
2072                                 }
2073                             }
2074                           /* var_modifiers just to avoid shift/reduce conflicts */
2075                         | '(' var_modifiers type array ')' unary_expr
2076                             {
2077                                 struct hlsl_ir_expr *expr;
2078                                 struct hlsl_type *src_type = $6->data_type;
2079                                 struct hlsl_type *dst_type;
2080                                 struct source_location loc;
2081
2082                                 set_location(&loc, &@3);
2083                                 if ($2)
2084                                 {
2085                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2086                                             "unexpected modifier in a cast");
2087                                     return 1;
2088                                 }
2089
2090                                 if ($4)
2091                                     dst_type = new_array_type($3, $4);
2092                                 else
2093                                     dst_type = $3;
2094
2095                                 if (!compatible_data_types(src_type, dst_type))
2096                                 {
2097                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2098                                             "can't cast from %s to %s",
2099                                             debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
2100                                     return 1;
2101                                 }
2102
2103                                 expr = new_cast($6, dst_type, &loc);
2104                                 $$ = expr ? &expr->node : NULL;
2105                             }
2106
2107 unary_op:                 '+'
2108                             {
2109                                 $$ = UNARY_OP_PLUS;
2110                             }
2111                         | '-'
2112                             {
2113                                 $$ = UNARY_OP_MINUS;
2114                             }
2115                         | '!'
2116                             {
2117                                 $$ = UNARY_OP_LOGICNOT;
2118                             }
2119                         | '~'
2120                             {
2121                                 $$ = UNARY_OP_BITNOT;
2122                             }
2123
2124 mul_expr:                 unary_expr
2125                             {
2126                                 $$ = $1;
2127                             }
2128                         | mul_expr '*' unary_expr
2129                             {
2130                                 struct source_location loc;
2131
2132                                 set_location(&loc, &@2);
2133                                 $$ = &hlsl_mul($1, $3, &loc)->node;
2134                             }
2135                         | mul_expr '/' unary_expr
2136                             {
2137                                 struct source_location loc;
2138
2139                                 set_location(&loc, &@2);
2140                                 $$ = &hlsl_div($1, $3, &loc)->node;
2141                             }
2142                         | mul_expr '%' unary_expr
2143                             {
2144                                 struct source_location loc;
2145
2146                                 set_location(&loc, &@2);
2147                                 $$ = &hlsl_mod($1, $3, &loc)->node;
2148                             }
2149
2150 add_expr:                 mul_expr
2151                             {
2152                                 $$ = $1;
2153                             }
2154                         | add_expr '+' mul_expr
2155                             {
2156                                 struct source_location loc;
2157
2158                                 set_location(&loc, &@2);
2159                                 $$ = &hlsl_add($1, $3, &loc)->node;
2160                             }
2161                         | add_expr '-' mul_expr
2162                             {
2163                                 struct source_location loc;
2164
2165                                 set_location(&loc, &@2);
2166                                 $$ = &hlsl_sub($1, $3, &loc)->node;
2167                             }
2168
2169 shift_expr:               add_expr
2170                             {
2171                                 $$ = $1;
2172                             }
2173                         | shift_expr OP_LEFTSHIFT add_expr
2174                             {
2175                                 FIXME("Left shift\n");
2176                             }
2177                         | shift_expr OP_RIGHTSHIFT add_expr
2178                             {
2179                                 FIXME("Right shift\n");
2180                             }
2181
2182 relational_expr:          shift_expr
2183                             {
2184                                 $$ = $1;
2185                             }
2186                         | relational_expr '<' shift_expr
2187                             {
2188                                 struct source_location loc;
2189
2190                                 set_location(&loc, &@2);
2191                                 $$ = &hlsl_lt($1, $3, &loc)->node;
2192                             }
2193                         | relational_expr '>' shift_expr
2194                             {
2195                                 struct source_location loc;
2196
2197                                 set_location(&loc, &@2);
2198                                 $$ = &hlsl_gt($1, $3, &loc)->node;
2199                             }
2200                         | relational_expr OP_LE shift_expr
2201                             {
2202                                 struct source_location loc;
2203
2204                                 set_location(&loc, &@2);
2205                                 $$ = &hlsl_le($1, $3, &loc)->node;
2206                             }
2207                         | relational_expr OP_GE shift_expr
2208                             {
2209                                 struct source_location loc;
2210
2211                                 set_location(&loc, &@2);
2212                                 $$ = &hlsl_ge($1, $3, &loc)->node;
2213                             }
2214
2215 equality_expr:            relational_expr
2216                             {
2217                                 $$ = $1;
2218                             }
2219                         | equality_expr OP_EQ relational_expr
2220                             {
2221                                 struct source_location loc;
2222
2223                                 set_location(&loc, &@2);
2224                                 $$ = &hlsl_eq($1, $3, &loc)->node;
2225                             }
2226                         | equality_expr OP_NE relational_expr
2227                             {
2228                                 struct source_location loc;
2229
2230                                 set_location(&loc, &@2);
2231                                 $$ = &hlsl_ne($1, $3, &loc)->node;
2232                             }
2233
2234 bitand_expr:              equality_expr
2235                             {
2236                                 $$ = $1;
2237                             }
2238                         | bitand_expr '&' equality_expr
2239                             {
2240                                 FIXME("bitwise AND\n");
2241                             }
2242
2243 bitxor_expr:              bitand_expr
2244                             {
2245                                 $$ = $1;
2246                             }
2247                         | bitxor_expr '^' bitand_expr
2248                             {
2249                                 FIXME("bitwise XOR\n");
2250                             }
2251
2252 bitor_expr:               bitxor_expr
2253                             {
2254                                 $$ = $1;
2255                             }
2256                         | bitor_expr '|' bitxor_expr
2257                             {
2258                                 FIXME("bitwise OR\n");
2259                             }
2260
2261 logicand_expr:            bitor_expr
2262                             {
2263                                 $$ = $1;
2264                             }
2265                         | logicand_expr OP_AND bitor_expr
2266                             {
2267                                 FIXME("logic AND\n");
2268                             }
2269
2270 logicor_expr:             logicand_expr
2271                             {
2272                                 $$ = $1;
2273                             }
2274                         | logicor_expr OP_OR logicand_expr
2275                             {
2276                                 FIXME("logic OR\n");
2277                             }
2278
2279 conditional_expr:         logicor_expr
2280                             {
2281                                 $$ = $1;
2282                             }
2283                         | logicor_expr '?' expr ':' assignment_expr
2284                             {
2285                                 FIXME("ternary operator\n");
2286                             }
2287
2288 assignment_expr:          conditional_expr
2289                             {
2290                                 $$ = $1;
2291                             }
2292                         | unary_expr assign_op assignment_expr
2293                             {
2294                                 struct source_location loc;
2295
2296                                 set_location(&loc, &@2);
2297                                 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
2298                                 {
2299                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2300                                             "l-value is const");
2301                                     return 1;
2302                                 }
2303                                 $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
2304                                 if (!$$)
2305                                     return 1;
2306                                 $$->loc = loc;
2307                             }
2308
2309 assign_op:                '='
2310                             {
2311                                 $$ = ASSIGN_OP_ASSIGN;
2312                             }
2313                         | OP_ADDASSIGN
2314                             {
2315                                 $$ = ASSIGN_OP_ADD;
2316                             }
2317                         | OP_SUBASSIGN
2318                             {
2319                                 $$ = ASSIGN_OP_SUB;
2320                             }
2321                         | OP_MULASSIGN
2322                             {
2323                                 $$ = ASSIGN_OP_MUL;
2324                             }
2325                         | OP_DIVASSIGN
2326                             {
2327                                 $$ = ASSIGN_OP_DIV;
2328                             }
2329                         | OP_MODASSIGN
2330                             {
2331                                 $$ = ASSIGN_OP_MOD;
2332                             }
2333                         | OP_LEFTSHIFTASSIGN
2334                             {
2335                                 $$ = ASSIGN_OP_LSHIFT;
2336                             }
2337                         | OP_RIGHTSHIFTASSIGN
2338                             {
2339                                 $$ = ASSIGN_OP_RSHIFT;
2340                             }
2341                         | OP_ANDASSIGN
2342                             {
2343                                 $$ = ASSIGN_OP_AND;
2344                             }
2345                         | OP_ORASSIGN
2346                             {
2347                                 $$ = ASSIGN_OP_OR;
2348                             }
2349                         | OP_XORASSIGN
2350                             {
2351                                 $$ = ASSIGN_OP_XOR;
2352                             }
2353
2354 expr:                     assignment_expr
2355                             {
2356                                 $$ = $1;
2357                             }
2358                         | expr ',' assignment_expr
2359                             {
2360                                 FIXME("Comma expression\n");
2361                             }
2362
2363 %%
2364
2365 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
2366 {
2367     loc->file = hlsl_ctx.source_file;
2368     loc->line = l->first_line;
2369     loc->col = l->first_column;
2370 }
2371
2372 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
2373 {
2374     if (modifiers & mod)
2375     {
2376         hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2377                 "modifier '%s' already specified", debug_modifiers(mod));
2378         return modifiers;
2379     }
2380     if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
2381             && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
2382     {
2383         hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2384                 "more than one matrix majority keyword");
2385         return modifiers;
2386     }
2387     return modifiers | mod;
2388 }
2389
2390 static void dump_function_decl(struct wine_rb_entry *entry, void *context)
2391 {
2392     struct hlsl_ir_function_decl *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
2393     if (func->body)
2394         debug_dump_ir_function_decl(func);
2395 }
2396
2397 static void dump_function(struct wine_rb_entry *entry, void *context)
2398 {
2399     struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
2400     wine_rb_for_each_entry(&func->overloads, dump_function_decl, NULL);
2401 }
2402
2403 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
2404         const char *entrypoint, char **messages)
2405 {
2406     struct hlsl_scope *scope, *next_scope;
2407     struct hlsl_type *hlsl_type, *next_type;
2408     struct hlsl_ir_var *var, *next_var;
2409     unsigned int i;
2410
2411     hlsl_ctx.status = PARSE_SUCCESS;
2412     hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
2413     hlsl_ctx.line_no = hlsl_ctx.column = 1;
2414     hlsl_ctx.source_file = d3dcompiler_strdup("");
2415     hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
2416     if (hlsl_ctx.source_files)
2417         hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
2418     hlsl_ctx.source_files_count = 1;
2419     hlsl_ctx.cur_scope = NULL;
2420     hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
2421     list_init(&hlsl_ctx.scopes);
2422     list_init(&hlsl_ctx.types);
2423     init_functions_tree(&hlsl_ctx.functions);
2424
2425     push_scope(&hlsl_ctx);
2426     hlsl_ctx.globals = hlsl_ctx.cur_scope;
2427     declare_predefined_types(hlsl_ctx.globals);
2428
2429     hlsl_parse();
2430
2431     if (TRACE_ON(hlsl_parser))
2432     {
2433         TRACE("IR dump.\n");
2434         wine_rb_for_each_entry(&hlsl_ctx.functions, dump_function, NULL);
2435     }
2436
2437     TRACE("Compilation status = %d\n", hlsl_ctx.status);
2438     if (messages)
2439     {
2440         if (hlsl_ctx.messages.size)
2441             *messages = hlsl_ctx.messages.string;
2442         else
2443             *messages = NULL;
2444     }
2445     else
2446     {
2447         if (hlsl_ctx.messages.capacity)
2448             d3dcompiler_free(hlsl_ctx.messages.string);
2449     }
2450
2451     for (i = 0; i < hlsl_ctx.source_files_count; ++i)
2452         d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
2453     d3dcompiler_free(hlsl_ctx.source_files);
2454
2455     TRACE("Freeing functions IR.\n");
2456     wine_rb_destroy(&hlsl_ctx.functions, free_function_rb, NULL);
2457
2458     TRACE("Freeing variables.\n");
2459     LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
2460     {
2461         LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
2462         {
2463             free_declaration(var);
2464         }
2465         wine_rb_destroy(&scope->types, NULL, NULL);
2466         d3dcompiler_free(scope);
2467     }
2468
2469     TRACE("Freeing types.\n");
2470     LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
2471     {
2472         free_hlsl_type(hlsl_type);
2473     }
2474
2475     return NULL;
2476 }