xref: /reactos/dll/directx/wine/d3dcompiler_43/hlsl.y (revision 407c54ba)
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     static const char * const 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 * const 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         var->reg_reservation = v->reg_reservation;
601         debug_dump_decl(type, modifiers, v->name, v->loc.line);
602 
603         if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
604         {
605             var->modifiers |= HLSL_STORAGE_UNIFORM;
606             local = FALSE;
607         }
608 
609         if (var->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer)
610         {
611             hlsl_report_message(v->loc.file, v->loc.line, v->loc.col,
612                     HLSL_LEVEL_ERROR, "const variable without initializer");
613             free_declaration(var);
614             d3dcompiler_free(v);
615             continue;
616         }
617 
618         ret = declare_variable(var, local);
619         if (!ret)
620         {
621             free_declaration(var);
622             d3dcompiler_free(v);
623             continue;
624         }
625         TRACE("Declared variable %s.\n", var->name);
626 
627         if (v->initializer)
628         {
629             unsigned int size = initializer_size(v->initializer);
630             struct hlsl_ir_node *node;
631 
632             TRACE("Variable with initializer.\n");
633             if (type->type <= HLSL_CLASS_LAST_NUMERIC
634                     && type->dimx * type->dimy != size && size != 1)
635             {
636                 if (size < type->dimx * type->dimy)
637                 {
638                     hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
639                             "'%s' initializer does not match", v->name);
640                     free_instr_list(v->initializer);
641                     d3dcompiler_free(v);
642                     continue;
643                 }
644             }
645             if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY)
646                     && components_count_type(type) != size)
647             {
648                 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
649                         "'%s' initializer does not match", v->name);
650                 free_instr_list(v->initializer);
651                 d3dcompiler_free(v);
652                 continue;
653             }
654 
655             if (type->type == HLSL_CLASS_STRUCT)
656             {
657                 struct_var_initializer(statements_list, var, v->initializer);
658                 d3dcompiler_free(v);
659                 continue;
660             }
661             if (type->type > HLSL_CLASS_LAST_NUMERIC)
662             {
663                 FIXME("Initializers for non scalar/struct variables not supported yet.\n");
664                 free_instr_list(v->initializer);
665                 d3dcompiler_free(v);
666                 continue;
667             }
668             if (v->array_size > 0)
669             {
670                 FIXME("Initializing arrays is not supported yet.\n");
671                 free_instr_list(v->initializer);
672                 d3dcompiler_free(v);
673                 continue;
674             }
675             if (list_count(v->initializer) > 1)
676             {
677                 FIXME("Complex initializers are not supported yet.\n");
678                 free_instr_list(v->initializer);
679                 d3dcompiler_free(v);
680                 continue;
681             }
682             node = LIST_ENTRY(list_head(v->initializer), struct hlsl_ir_node, entry);
683             assignment = make_assignment(&var->node, ASSIGN_OP_ASSIGN,
684                     BWRITERSP_WRITEMASK_ALL, node);
685             list_add_tail(statements_list, &assignment->entry);
686             d3dcompiler_free(v->initializer);
687         }
688         d3dcompiler_free(v);
689     }
690     d3dcompiler_free(var_list);
691     return statements_list;
692 }
693 
694 static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field)
695 {
696     struct hlsl_struct_field *f;
697 
698     LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry)
699     {
700         if (!strcmp(f->name, field->name))
701             return FALSE;
702     }
703     list_add_tail(fields, &field->entry);
704     return TRUE;
705 }
706 
707 static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, struct list *fields)
708 {
709     struct parse_variable_def *v, *v_next;
710     struct hlsl_struct_field *field;
711     struct list *list;
712 
713     list = d3dcompiler_alloc(sizeof(*list));
714     if (!list)
715     {
716         ERR("Out of memory.\n");
717         return NULL;
718     }
719     list_init(list);
720     LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry)
721     {
722         debug_dump_decl(type, 0, v->name, v->loc.line);
723         field = d3dcompiler_alloc(sizeof(*field));
724         if (!field)
725         {
726             ERR("Out of memory.\n");
727             d3dcompiler_free(v);
728             return list;
729         }
730         field->type = type;
731         field->name = v->name;
732         field->modifiers = modifiers;
733         field->semantic = v->semantic;
734         if (v->initializer)
735         {
736             hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
737                     "struct field with an initializer.\n");
738             free_instr_list(v->initializer);
739         }
740         list_add_tail(list, &field->entry);
741         d3dcompiler_free(v);
742     }
743     d3dcompiler_free(fields);
744     return list;
745 }
746 
747 static struct hlsl_type *new_struct_type(const char *name, DWORD modifiers, struct list *fields)
748 {
749     struct hlsl_type *type = d3dcompiler_alloc(sizeof(*type));
750 
751     if (!type)
752     {
753         ERR("Out of memory.\n");
754         return NULL;
755     }
756     type->type = HLSL_CLASS_STRUCT;
757     type->name = name;
758     type->dimx = type->dimy = 1;
759     type->modifiers = modifiers;
760     type->e.elements = fields;
761 
762     list_add_tail(&hlsl_ctx.types, &type->entry);
763 
764     return type;
765 }
766 
767 static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list,
768         struct source_location *loc)
769 {
770     BOOL ret;
771     struct hlsl_type *type;
772     struct parse_variable_def *v, *v_next;
773 
774     if (!check_type_modifiers(modifiers, loc))
775     {
776         LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
777             d3dcompiler_free(v);
778         d3dcompiler_free(list);
779         return FALSE;
780     }
781 
782     LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
783     {
784         if (v->array_size)
785             type = new_array_type(orig_type, v->array_size);
786         else
787             type = clone_hlsl_type(orig_type);
788         if (!type)
789         {
790             ERR("Out of memory\n");
791             return FALSE;
792         }
793         d3dcompiler_free((void *)type->name);
794         type->name = v->name;
795         type->modifiers |= modifiers;
796 
797         if (type->type != HLSL_CLASS_MATRIX)
798             check_invalid_matrix_modifiers(type->modifiers, &v->loc);
799 
800         ret = add_type_to_scope(hlsl_ctx.cur_scope, type);
801         if (!ret)
802         {
803             hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
804                     "redefinition of custom type '%s'", v->name);
805         }
806         d3dcompiler_free(v);
807     }
808     d3dcompiler_free(list);
809     return TRUE;
810 }
811 
812 static BOOL add_func_parameter(struct list *list, struct parse_parameter *param, const struct source_location *loc)
813 {
814     struct hlsl_ir_var *decl = d3dcompiler_alloc(sizeof(*decl));
815 
816     if (!decl)
817     {
818         ERR("Out of memory.\n");
819         return FALSE;
820     }
821     decl->node.type = HLSL_IR_VAR;
822     decl->node.data_type = param->type;
823     decl->node.loc = *loc;
824     decl->name = param->name;
825     decl->semantic = param->semantic;
826     decl->reg_reservation = param->reg_reservation;
827     decl->modifiers = param->modifiers;
828 
829     if (!add_declaration(hlsl_ctx.cur_scope, decl, FALSE))
830     {
831         free_declaration(decl);
832         return FALSE;
833     }
834     list_add_tail(list, &decl->node.entry);
835     return TRUE;
836 }
837 
838 static struct reg_reservation *parse_reg_reservation(const char *reg_string)
839 {
840     struct reg_reservation *reg_res;
841     enum bwritershader_param_register_type type;
842     DWORD regnum = 0;
843 
844     switch (reg_string[0])
845     {
846         case 'c':
847             type = BWRITERSPR_CONST;
848             break;
849         case 'i':
850             type = BWRITERSPR_CONSTINT;
851             break;
852         case 'b':
853             type = BWRITERSPR_CONSTBOOL;
854             break;
855         case 's':
856             type = BWRITERSPR_SAMPLER;
857             break;
858         default:
859             FIXME("Unsupported register type.\n");
860             return NULL;
861      }
862 
863     if (!sscanf(reg_string + 1, "%u", &regnum))
864     {
865         FIXME("Unsupported register reservation syntax.\n");
866         return NULL;
867     }
868 
869     reg_res = d3dcompiler_alloc(sizeof(*reg_res));
870     if (!reg_res)
871     {
872         ERR("Out of memory.\n");
873         return NULL;
874     }
875     reg_res->type = type;
876     reg_res->regnum = regnum;
877     return reg_res;
878 }
879 
880 static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tree *funcs, char *name,
881         struct list *params, BOOL exact_signature)
882 {
883     struct hlsl_ir_function *func;
884     struct wine_rb_entry *entry;
885 
886     entry = wine_rb_get(funcs, name);
887     if (entry)
888     {
889         func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
890 
891         entry = wine_rb_get(&func->overloads, params);
892         if (!entry)
893         {
894             if (!exact_signature)
895                 FIXME("No exact match, search for a compatible overloaded function (if any).\n");
896             return NULL;
897         }
898         return WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
899     }
900     return NULL;
901 }
902 
903 %}
904 
905 %locations
906 %error-verbose
907 %expect 1
908 
909 %union
910 {
911     struct hlsl_type *type;
912     INT intval;
913     FLOAT floatval;
914     BOOL boolval;
915     char *name;
916     DWORD modifiers;
917     struct hlsl_ir_var *var;
918     struct hlsl_ir_node *instr;
919     struct list *list;
920     struct parse_function function;
921     struct parse_parameter parameter;
922     struct parse_variable_def *variable_def;
923     struct parse_if_body if_body;
924     enum parse_unary_op unary_op;
925     enum parse_assign_op assign_op;
926     struct reg_reservation *reg_reservation;
927     struct parse_colon_attribute colon_attribute;
928 }
929 
930 %token KW_BLENDSTATE
931 %token KW_BREAK
932 %token KW_BUFFER
933 %token KW_CBUFFER
934 %token KW_COLUMN_MAJOR
935 %token KW_COMPILE
936 %token KW_CONST
937 %token KW_CONTINUE
938 %token KW_DEPTHSTENCILSTATE
939 %token KW_DEPTHSTENCILVIEW
940 %token KW_DISCARD
941 %token KW_DO
942 %token KW_DOUBLE
943 %token KW_ELSE
944 %token KW_EXTERN
945 %token KW_FALSE
946 %token KW_FOR
947 %token KW_GEOMETRYSHADER
948 %token KW_GROUPSHARED
949 %token KW_IF
950 %token KW_IN
951 %token KW_INLINE
952 %token KW_INOUT
953 %token KW_MATRIX
954 %token KW_NAMESPACE
955 %token KW_NOINTERPOLATION
956 %token KW_OUT
957 %token KW_PASS
958 %token KW_PIXELSHADER
959 %token KW_PRECISE
960 %token KW_RASTERIZERSTATE
961 %token KW_RENDERTARGETVIEW
962 %token KW_RETURN
963 %token KW_REGISTER
964 %token KW_ROW_MAJOR
965 %token KW_SAMPLER
966 %token KW_SAMPLER1D
967 %token KW_SAMPLER2D
968 %token KW_SAMPLER3D
969 %token KW_SAMPLERCUBE
970 %token KW_SAMPLER_STATE
971 %token KW_SAMPLERCOMPARISONSTATE
972 %token KW_SHARED
973 %token KW_STATEBLOCK
974 %token KW_STATEBLOCK_STATE
975 %token KW_STATIC
976 %token KW_STRING
977 %token KW_STRUCT
978 %token KW_SWITCH
979 %token KW_TBUFFER
980 %token KW_TECHNIQUE
981 %token KW_TECHNIQUE10
982 %token KW_TEXTURE
983 %token KW_TEXTURE1D
984 %token KW_TEXTURE1DARRAY
985 %token KW_TEXTURE2D
986 %token KW_TEXTURE2DARRAY
987 %token KW_TEXTURE2DMS
988 %token KW_TEXTURE2DMSARRAY
989 %token KW_TEXTURE3D
990 %token KW_TEXTURE3DARRAY
991 %token KW_TEXTURECUBE
992 %token KW_TRUE
993 %token KW_TYPEDEF
994 %token KW_UNIFORM
995 %token KW_VECTOR
996 %token KW_VERTEXSHADER
997 %token KW_VOID
998 %token KW_VOLATILE
999 %token KW_WHILE
1000 
1001 %token OP_INC
1002 %token OP_DEC
1003 %token OP_AND
1004 %token OP_OR
1005 %token OP_EQ
1006 %token OP_LEFTSHIFT
1007 %token OP_LEFTSHIFTASSIGN
1008 %token OP_RIGHTSHIFT
1009 %token OP_RIGHTSHIFTASSIGN
1010 %token OP_ELLIPSIS
1011 %token OP_LE
1012 %token OP_GE
1013 %token OP_NE
1014 %token OP_ADDASSIGN
1015 %token OP_SUBASSIGN
1016 %token OP_MULASSIGN
1017 %token OP_DIVASSIGN
1018 %token OP_MODASSIGN
1019 %token OP_ANDASSIGN
1020 %token OP_ORASSIGN
1021 %token OP_XORASSIGN
1022 %token OP_UNKNOWN1
1023 %token OP_UNKNOWN2
1024 %token OP_UNKNOWN3
1025 %token OP_UNKNOWN4
1026 
1027 %token <intval> PRE_LINE
1028 
1029 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
1030 %type <name> any_identifier var_identifier
1031 %token <name> STRING
1032 %token <floatval> C_FLOAT
1033 %token <intval> C_INTEGER
1034 %type <boolval> boolean
1035 %type <type> base_type
1036 %type <type> type
1037 %type <list> declaration_statement
1038 %type <list> declaration
1039 %type <list> struct_declaration
1040 %type <type> struct_spec
1041 %type <type> named_struct_spec
1042 %type <type> unnamed_struct_spec
1043 %type <list> type_specs
1044 %type <variable_def> type_spec
1045 %type <list> complex_initializer
1046 %type <list> initializer_expr_list
1047 %type <instr> initializer_expr
1048 %type <modifiers> var_modifiers
1049 %type <list> field
1050 %type <list> parameters
1051 %type <list> param_list
1052 %type <instr> expr
1053 %type <var> variable
1054 %type <intval> array
1055 %type <list> statement
1056 %type <list> statement_list
1057 %type <list> compound_statement
1058 %type <list> jump_statement
1059 %type <list> selection_statement
1060 %type <list> loop_statement
1061 %type <function> func_declaration
1062 %type <function> func_prototype
1063 %type <list> fields_list
1064 %type <parameter> parameter
1065 %type <colon_attribute> colon_attribute
1066 %type <name> semantic
1067 %type <reg_reservation> register_opt
1068 %type <variable_def> variable_def
1069 %type <list> variables_def
1070 %type <list> variables_def_optional
1071 %type <if_body> if_body
1072 %type <instr> primary_expr
1073 %type <instr> postfix_expr
1074 %type <instr> unary_expr
1075 %type <instr> mul_expr
1076 %type <instr> add_expr
1077 %type <instr> shift_expr
1078 %type <instr> relational_expr
1079 %type <instr> equality_expr
1080 %type <instr> bitand_expr
1081 %type <instr> bitxor_expr
1082 %type <instr> bitor_expr
1083 %type <instr> logicand_expr
1084 %type <instr> logicor_expr
1085 %type <instr> conditional_expr
1086 %type <instr> assignment_expr
1087 %type <list> expr_statement
1088 %type <unary_op> unary_op
1089 %type <assign_op> assign_op
1090 %type <modifiers> input_mods
1091 %type <modifiers> input_mod
1092 %%
1093 
1094 hlsl_prog:                /* empty */
1095                             {
1096                             }
1097                         | hlsl_prog func_declaration
1098                             {
1099                                 const struct hlsl_ir_function_decl *decl;
1100 
1101                                 decl = get_overloaded_func(&hlsl_ctx.functions, $2.name, $2.decl->parameters, TRUE);
1102                                 if (decl && !decl->func->intrinsic)
1103                                 {
1104                                     if (decl->body && $2.decl->body)
1105                                     {
1106                                         hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
1107                                                 $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
1108                                                 "redefinition of function %s", debugstr_a($2.name));
1109                                         return 1;
1110                                     }
1111                                     else if (!compare_hlsl_types(decl->node.data_type, $2.decl->node.data_type))
1112                                     {
1113                                         hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
1114                                                 $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
1115                                                 "redefining function %s with a different return type",
1116                                                 debugstr_a($2.name));
1117                                         hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_NOTE,
1118                                                 "%s previously declared here",
1119                                                 debugstr_a($2.name));
1120                                         return 1;
1121                                     }
1122                                 }
1123 
1124                                 if ($2.decl->node.data_type->base_type == HLSL_TYPE_VOID && $2.decl->semantic)
1125                                 {
1126                                     hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line,
1127                                             $2.decl->node.loc.col, HLSL_LEVEL_ERROR,
1128                                             "void function with a semantic");
1129                                 }
1130 
1131                                 TRACE("Adding function '%s' to the function list.\n", $2.name);
1132                                 add_function_decl(&hlsl_ctx.functions, $2.name, $2.decl, FALSE);
1133                             }
1134                         | hlsl_prog declaration_statement
1135                             {
1136                                 TRACE("Declaration statement parsed.\n");
1137                             }
1138                         | hlsl_prog preproc_directive
1139                             {
1140                             }
1141                         | hlsl_prog ';'
1142                             {
1143                                 TRACE("Skipping stray semicolon.\n");
1144                             }
1145 
1146 preproc_directive:        PRE_LINE STRING
1147                             {
1148                                 const char **new_array = NULL;
1149 
1150                                 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
1151                                 hlsl_ctx.line_no = $1;
1152                                 if (strcmp($2, hlsl_ctx.source_file))
1153                                     new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
1154                                             sizeof(*hlsl_ctx.source_files) * (hlsl_ctx.source_files_count + 1));
1155 
1156                                 if (new_array)
1157                                 {
1158                                     hlsl_ctx.source_files = new_array;
1159                                     hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
1160                                     hlsl_ctx.source_file = $2;
1161                                 }
1162                                 else
1163                                 {
1164                                     d3dcompiler_free($2);
1165                                 }
1166                             }
1167 
1168 struct_declaration:       struct_spec variables_def_optional ';'
1169                             {
1170                                 struct source_location loc;
1171 
1172                                 set_location(&loc, &@3);
1173                                 if (!$2)
1174                                 {
1175                                     if (!$1->name)
1176                                     {
1177                                         hlsl_report_message(loc.file, loc.line, loc.col,
1178                                                 HLSL_LEVEL_ERROR, "anonymous struct declaration with no variables");
1179                                     }
1180                                     check_type_modifiers($1->modifiers, &loc);
1181                                 }
1182                                 $$ = declare_vars($1, 0, $2);
1183                             }
1184 
1185 struct_spec:              named_struct_spec
1186                         | unnamed_struct_spec
1187 
1188 named_struct_spec:        var_modifiers KW_STRUCT any_identifier '{' fields_list '}'
1189                             {
1190                                 BOOL ret;
1191                                 struct source_location loc;
1192 
1193                                 TRACE("Structure %s declaration.\n", debugstr_a($3));
1194                                 set_location(&loc, &@1);
1195                                 check_invalid_matrix_modifiers($1, &loc);
1196                                 $$ = new_struct_type($3, $1, $5);
1197 
1198                                 if (get_variable(hlsl_ctx.cur_scope, $3))
1199                                 {
1200                                     hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1201                                             HLSL_LEVEL_ERROR, "redefinition of '%s'", $3);
1202                                     return 1;
1203                                 }
1204 
1205                                 ret = add_type_to_scope(hlsl_ctx.cur_scope, $$);
1206                                 if (!ret)
1207                                 {
1208                                     hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1209                                             HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $3);
1210                                     return 1;
1211                                 }
1212                             }
1213 
1214 unnamed_struct_spec:      var_modifiers KW_STRUCT '{' fields_list '}'
1215                             {
1216                                 struct source_location loc;
1217 
1218                                 TRACE("Anonymous structure declaration.\n");
1219                                 set_location(&loc, &@1);
1220                                 check_invalid_matrix_modifiers($1, &loc);
1221                                 $$ = new_struct_type(NULL, $1, $4);
1222                             }
1223 
1224 any_identifier:           VAR_IDENTIFIER
1225                         | TYPE_IDENTIFIER
1226                         | NEW_IDENTIFIER
1227 
1228 fields_list:              /* Empty */
1229                             {
1230                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1231                                 list_init($$);
1232                             }
1233                         | fields_list field
1234                             {
1235                                 BOOL ret;
1236                                 struct hlsl_struct_field *field, *next;
1237 
1238                                 $$ = $1;
1239                                 LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry)
1240                                 {
1241                                     ret = add_struct_field($$, field);
1242                                     if (ret == FALSE)
1243                                     {
1244                                         hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1245                                                 HLSL_LEVEL_ERROR, "redefinition of '%s'", field->name);
1246                                         d3dcompiler_free(field);
1247                                     }
1248                                 }
1249                                 d3dcompiler_free($2);
1250                             }
1251 
1252 field:                    var_modifiers type variables_def ';'
1253                             {
1254                                 $$ = gen_struct_fields($2, $1, $3);
1255                             }
1256                         | unnamed_struct_spec variables_def ';'
1257                             {
1258                                 $$ = gen_struct_fields($1, 0, $2);
1259                             }
1260 
1261 func_declaration:         func_prototype compound_statement
1262                             {
1263                                 TRACE("Function %s parsed.\n", $1.name);
1264                                 $$ = $1;
1265                                 $$.decl->body = $2;
1266                                 pop_scope(&hlsl_ctx);
1267                             }
1268                         | func_prototype ';'
1269                             {
1270                                 TRACE("Function prototype for %s.\n", $1.name);
1271                                 $$ = $1;
1272                                 pop_scope(&hlsl_ctx);
1273                             }
1274 
1275 func_prototype:           var_modifiers type var_identifier '(' parameters ')' colon_attribute
1276                             {
1277                                 if (get_variable(hlsl_ctx.globals, $3))
1278                                 {
1279                                     hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
1280                                             HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
1281                                     return 1;
1282                                 }
1283                                 if ($2->base_type == HLSL_TYPE_VOID && $7.semantic)
1284                                 {
1285                                     hlsl_report_message(hlsl_ctx.source_file, @7.first_line, @7.first_column,
1286                                             HLSL_LEVEL_ERROR, "void function with a semantic");
1287                                 }
1288 
1289                                 if ($7.reg_reservation)
1290                                 {
1291                                     FIXME("Unexpected register reservation for a function.\n");
1292                                     d3dcompiler_free($7.reg_reservation);
1293                                 }
1294                                 $$.decl = new_func_decl($2, $5);
1295                                 if (!$$.decl)
1296                                 {
1297                                     ERR("Out of memory.\n");
1298                                     return -1;
1299                                 }
1300                                 $$.name = $3;
1301                                 $$.decl->semantic = $7.semantic;
1302                                 set_location(&$$.decl->node.loc, &@3);
1303                             }
1304 
1305 compound_statement:       '{' '}'
1306                             {
1307                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1308                                 list_init($$);
1309                             }
1310                         | '{' scope_start statement_list '}'
1311                             {
1312                                 pop_scope(&hlsl_ctx);
1313                                 $$ = $3;
1314                             }
1315 
1316 scope_start:              /* Empty */
1317                             {
1318                                 push_scope(&hlsl_ctx);
1319                             }
1320 
1321 var_identifier:           VAR_IDENTIFIER
1322                         | NEW_IDENTIFIER
1323 
1324 colon_attribute:          /* Empty */
1325                             {
1326                                 $$.semantic = NULL;
1327                                 $$.reg_reservation = NULL;
1328                             }
1329                         | semantic
1330                             {
1331                                 $$.semantic = $1;
1332                                 $$.reg_reservation = NULL;
1333                             }
1334                         | register_opt
1335                             {
1336                                 $$.semantic = NULL;
1337                                 $$.reg_reservation = $1;
1338                             }
1339 
1340 semantic:                 ':' any_identifier
1341                             {
1342                                 $$ = $2;
1343                             }
1344 
1345                           /* FIXME: Writemasks */
1346 register_opt:             ':' KW_REGISTER '(' any_identifier ')'
1347                             {
1348                                 $$ = parse_reg_reservation($4);
1349                                 d3dcompiler_free($4);
1350                             }
1351                         | ':' KW_REGISTER '(' any_identifier ',' any_identifier ')'
1352                             {
1353                                 FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a($4));
1354                                 d3dcompiler_free($4);
1355 
1356                                 $$ = parse_reg_reservation($6);
1357                                 d3dcompiler_free($6);
1358                             }
1359 
1360 parameters:               scope_start
1361                             {
1362                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1363                                 list_init($$);
1364                             }
1365                         | scope_start param_list
1366                             {
1367                                 $$ = $2;
1368                             }
1369 
1370 param_list:               parameter
1371                             {
1372                                 struct source_location loc;
1373 
1374                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1375                                 list_init($$);
1376                                 set_location(&loc, &@1);
1377                                 if (!add_func_parameter($$, &$1, &loc))
1378                                 {
1379                                     ERR("Error adding function parameter %s.\n", $1.name);
1380                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1381                                     return -1;
1382                                 }
1383                             }
1384                         | param_list ',' parameter
1385                             {
1386                                 struct source_location loc;
1387 
1388                                 $$ = $1;
1389                                 set_location(&loc, &@3);
1390                                 if (!add_func_parameter($$, &$3, &loc))
1391                                 {
1392                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1393                                             "duplicate parameter %s", $3.name);
1394                                     return 1;
1395                                 }
1396                             }
1397 
1398 parameter:                input_mods var_modifiers type any_identifier colon_attribute
1399                             {
1400                                 $$.modifiers = $1 ? $1 : HLSL_MODIFIER_IN;
1401                                 $$.modifiers |= $2;
1402                                 $$.type = $3;
1403                                 $$.name = $4;
1404                                 $$.semantic = $5.semantic;
1405                                 $$.reg_reservation = $5.reg_reservation;
1406                             }
1407 
1408 input_mods:               /* Empty */
1409                             {
1410                                 $$ = 0;
1411                             }
1412                         | input_mods input_mod
1413                             {
1414                                 if ($1 & $2)
1415                                 {
1416                                     hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column,
1417                                             HLSL_LEVEL_ERROR, "duplicate input-output modifiers");
1418                                     return 1;
1419                                 }
1420                                 $$ = $1 | $2;
1421                             }
1422 
1423 input_mod:                KW_IN
1424                             {
1425                                 $$ = HLSL_MODIFIER_IN;
1426                             }
1427                         | KW_OUT
1428                             {
1429                                 $$ = HLSL_MODIFIER_OUT;
1430                             }
1431                         | KW_INOUT
1432                             {
1433                                 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
1434                             }
1435 
1436 type:                     base_type
1437                             {
1438                                 $$ = $1;
1439                             }
1440                         | KW_VECTOR '<' base_type ',' C_INTEGER '>'
1441                             {
1442                                 if ($3->type != HLSL_CLASS_SCALAR)
1443                                 {
1444                                     hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
1445                                             hlsl_ctx.line_no);
1446                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1447                                     return 1;
1448                                 }
1449                                 if ($5 < 1 || $5 > 4)
1450                                 {
1451                                     hlsl_message("Line %u: vector size must be between 1 and 4.\n",
1452                                             hlsl_ctx.line_no);
1453                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1454                                     return 1;
1455                                 }
1456 
1457                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
1458                             }
1459                         | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
1460                             {
1461                                 if ($3->type != HLSL_CLASS_SCALAR)
1462                                 {
1463                                     hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
1464                                             hlsl_ctx.line_no);
1465                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1466                                     return 1;
1467                                 }
1468                                 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
1469                                 {
1470                                     hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
1471                                             hlsl_ctx.line_no);
1472                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1473                                     return 1;
1474                                 }
1475 
1476                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
1477                             }
1478 
1479 base_type:                KW_VOID
1480                             {
1481                                 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
1482                             }
1483                         | KW_SAMPLER
1484                             {
1485                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1486                                 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
1487                             }
1488                         | KW_SAMPLER1D
1489                             {
1490                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1491                                 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
1492                             }
1493                         | KW_SAMPLER2D
1494                             {
1495                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1496                                 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
1497                             }
1498                         | KW_SAMPLER3D
1499                             {
1500                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1501                                 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
1502                             }
1503                         | KW_SAMPLERCUBE
1504                             {
1505                                 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
1506                                 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
1507                             }
1508                         | TYPE_IDENTIFIER
1509                             {
1510                                 struct hlsl_type *type;
1511 
1512                                 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
1513                                 $$ = type;
1514                                 d3dcompiler_free($1);
1515                             }
1516                         | KW_STRUCT TYPE_IDENTIFIER
1517                             {
1518                                 struct hlsl_type *type;
1519 
1520                                 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
1521                                 if (type->type != HLSL_CLASS_STRUCT)
1522                                 {
1523                                     hlsl_message("Line %u: redefining %s as a structure.\n",
1524                                             hlsl_ctx.line_no, $2);
1525                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1526                                 }
1527                                 else
1528                                 {
1529                                     $$ = type;
1530                                 }
1531                                 d3dcompiler_free($2);
1532                             }
1533 
1534 declaration_statement:    declaration
1535                         | struct_declaration
1536                         | typedef
1537                             {
1538                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1539                                 if (!$$)
1540                                 {
1541                                     ERR("Out of memory\n");
1542                                     return -1;
1543                                 }
1544                                 list_init($$);
1545                             }
1546 
1547 typedef:                  KW_TYPEDEF var_modifiers type type_specs ';'
1548                             {
1549                                 struct source_location loc;
1550 
1551                                 set_location(&loc, &@1);
1552                                 if (!add_typedef($2, $3, $4, &loc))
1553                                     return 1;
1554                             }
1555                         | KW_TYPEDEF struct_spec type_specs ';'
1556                             {
1557                                 struct source_location loc;
1558 
1559                                 set_location(&loc, &@1);
1560                                 if (!add_typedef(0, $2, $3, &loc))
1561                                     return 1;
1562                             }
1563 
1564 type_specs:               type_spec
1565                             {
1566                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1567                                 list_init($$);
1568                                 list_add_head($$, &$1->entry);
1569                             }
1570                         | type_specs ',' type_spec
1571                             {
1572                                 $$ = $1;
1573                                 list_add_tail($$, &$3->entry);
1574                             }
1575 
1576 type_spec:                any_identifier array
1577                             {
1578                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1579                                 set_location(&$$->loc, &@1);
1580                                 $$->name = $1;
1581                                 $$->array_size = $2;
1582                             }
1583 
1584 declaration:              var_modifiers type variables_def ';'
1585                             {
1586                                 $$ = declare_vars($2, $1, $3);
1587                             }
1588 
1589 variables_def_optional:   /* Empty */
1590                             {
1591                                 $$ = NULL;
1592                             }
1593                         | variables_def
1594                             {
1595                                 $$ = $1;
1596                             }
1597 
1598 variables_def:            variable_def
1599                             {
1600                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1601                                 list_init($$);
1602                                 list_add_head($$, &$1->entry);
1603                             }
1604                         | variables_def ',' variable_def
1605                             {
1606                                 $$ = $1;
1607                                 list_add_tail($$, &$3->entry);
1608                             }
1609 
1610 variable_def:             any_identifier array colon_attribute
1611                             {
1612                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1613                                 set_location(&$$->loc, &@1);
1614                                 $$->name = $1;
1615                                 $$->array_size = $2;
1616                                 $$->semantic = $3.semantic;
1617                                 $$->reg_reservation = $3.reg_reservation;
1618                             }
1619                         | any_identifier array colon_attribute '=' complex_initializer
1620                             {
1621                                 TRACE("Declaration with initializer.\n");
1622                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1623                                 set_location(&$$->loc, &@1);
1624                                 $$->name = $1;
1625                                 $$->array_size = $2;
1626                                 $$->semantic = $3.semantic;
1627                                 $$->reg_reservation = $3.reg_reservation;
1628                                 $$->initializer = $5;
1629                             }
1630 
1631 array:                    /* Empty */
1632                             {
1633                                 $$ = 0;
1634                             }
1635                         | '[' expr ']'
1636                             {
1637                                 FIXME("Array.\n");
1638                                 $$ = 0;
1639                                 free_instr($2);
1640                             }
1641 
1642 var_modifiers:            /* Empty */
1643                             {
1644                                 $$ = 0;
1645                             }
1646                         | KW_EXTERN var_modifiers
1647                             {
1648                                 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
1649                             }
1650                         | KW_NOINTERPOLATION var_modifiers
1651                             {
1652                                 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
1653                             }
1654                         | KW_PRECISE var_modifiers
1655                             {
1656                                 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
1657                             }
1658                         | KW_SHARED var_modifiers
1659                             {
1660                                 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
1661                             }
1662                         | KW_GROUPSHARED var_modifiers
1663                             {
1664                                 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
1665                             }
1666                         | KW_STATIC var_modifiers
1667                             {
1668                                 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
1669                             }
1670                         | KW_UNIFORM var_modifiers
1671                             {
1672                                 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
1673                             }
1674                         | KW_VOLATILE var_modifiers
1675                             {
1676                                 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
1677                             }
1678                         | KW_CONST var_modifiers
1679                             {
1680                                 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
1681                             }
1682                         | KW_ROW_MAJOR var_modifiers
1683                             {
1684                                 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
1685                             }
1686                         | KW_COLUMN_MAJOR var_modifiers
1687                             {
1688                                 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
1689                             }
1690 
1691 complex_initializer:      initializer_expr
1692                             {
1693                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1694                                 list_init($$);
1695                                 list_add_head($$, &$1->entry);
1696                             }
1697                         | '{' initializer_expr_list '}'
1698                             {
1699                                 $$ = $2;
1700                             }
1701                         | '{' initializer_expr_list ',' '}'
1702                             {
1703                                 $$ = $2;
1704                             }
1705 
1706 initializer_expr:         assignment_expr
1707                             {
1708                                 $$ = $1;
1709                             }
1710 
1711 initializer_expr_list:    initializer_expr
1712                             {
1713                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1714                                 list_init($$);
1715                                 list_add_head($$, &$1->entry);
1716                             }
1717                         | initializer_expr_list ',' initializer_expr
1718                             {
1719                                 $$ = $1;
1720                                 list_add_tail($$, &$3->entry);
1721                             }
1722 
1723 boolean:                  KW_TRUE
1724                             {
1725                                 $$ = TRUE;
1726                             }
1727                         | KW_FALSE
1728                             {
1729                                 $$ = FALSE;
1730                             }
1731 
1732 statement_list:           statement
1733                             {
1734                                 $$ = $1;
1735                             }
1736                         | statement_list statement
1737                             {
1738                                 $$ = $1;
1739                                 list_move_tail($$, $2);
1740                                 d3dcompiler_free($2);
1741                             }
1742 
1743 statement:                declaration_statement
1744                         | expr_statement
1745                         | compound_statement
1746                         | jump_statement
1747                         | selection_statement
1748                         | loop_statement
1749 
1750                           /* FIXME: add rule for return with no value */
1751 jump_statement:           KW_RETURN expr ';'
1752                             {
1753                                 struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump));
1754                                 if (!jump)
1755                                 {
1756                                     ERR("Out of memory\n");
1757                                     return -1;
1758                                 }
1759                                 jump->node.type = HLSL_IR_JUMP;
1760                                 set_location(&jump->node.loc, &@1);
1761                                 jump->type = HLSL_IR_JUMP_RETURN;
1762                                 jump->node.data_type = $2->data_type;
1763                                 jump->return_value = $2;
1764 
1765                                 FIXME("Check for valued return on void function.\n");
1766                                 FIXME("Implicit conversion to the return type if needed, "
1767 				        "error out if conversion not possible.\n");
1768 
1769                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1770                                 list_init($$);
1771                                 list_add_tail($$, &jump->node.entry);
1772                             }
1773 
1774 selection_statement:      KW_IF '(' expr ')' if_body
1775                             {
1776                                 struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
1777                                 if (!instr)
1778                                 {
1779                                     ERR("Out of memory\n");
1780                                     return -1;
1781                                 }
1782                                 instr->node.type = HLSL_IR_IF;
1783                                 set_location(&instr->node.loc, &@1);
1784                                 instr->condition = $3;
1785                                 instr->then_instrs = $5.then_instrs;
1786                                 instr->else_instrs = $5.else_instrs;
1787                                 if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1)
1788                                 {
1789                                     hlsl_report_message(instr->node.loc.file, instr->node.loc.line,
1790                                             instr->node.loc.col, HLSL_LEVEL_ERROR,
1791                                             "if condition requires a scalar");
1792                                 }
1793                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1794                                 list_init($$);
1795                                 list_add_head($$, &instr->node.entry);
1796                             }
1797 
1798 if_body:                  statement
1799                             {
1800                                 $$.then_instrs = $1;
1801                                 $$.else_instrs = NULL;
1802                             }
1803                         | statement KW_ELSE statement
1804                             {
1805                                 $$.then_instrs = $1;
1806                                 $$.else_instrs = $3;
1807                             }
1808 
1809 loop_statement:           KW_WHILE '(' expr ')' statement
1810                             {
1811                                 struct source_location loc;
1812                                 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1813 
1814                                 if (!cond)
1815                                 {
1816                                     ERR("Out of memory.\n");
1817                                     return -1;
1818                                 }
1819                                 list_init(cond);
1820                                 list_add_head(cond, &$3->entry);
1821                                 set_location(&loc, &@1);
1822                                 $$ = create_loop(LOOP_WHILE, NULL, cond, NULL, $5, &loc);
1823                             }
1824                         | KW_DO statement KW_WHILE '(' expr ')' ';'
1825                             {
1826                                 struct source_location loc;
1827                                 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1828 
1829                                 if (!cond)
1830                                 {
1831                                     ERR("Out of memory.\n");
1832                                     return -1;
1833                                 }
1834                                 list_init(cond);
1835                                 list_add_head(cond, &$5->entry);
1836                                 set_location(&loc, &@1);
1837                                 $$ = create_loop(LOOP_DO_WHILE, NULL, cond, NULL, $2, &loc);
1838                             }
1839                         | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
1840                             {
1841                                 struct source_location loc;
1842 
1843                                 set_location(&loc, &@1);
1844                                 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1845                                 pop_scope(&hlsl_ctx);
1846                             }
1847                         | KW_FOR '(' scope_start declaration expr_statement expr ')' statement
1848                             {
1849                                 struct source_location loc;
1850 
1851                                 set_location(&loc, &@1);
1852                                 if (!$4)
1853                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_WARNING,
1854                                             "no expressions in for loop initializer");
1855                                 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc);
1856                                 pop_scope(&hlsl_ctx);
1857                             }
1858 
1859 expr_statement:           ';'
1860                             {
1861                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1862                                 list_init($$);
1863                             }
1864                         | expr ';'
1865                             {
1866                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1867                                 list_init($$);
1868                                 if ($1)
1869                                     list_add_head($$, &$1->entry);
1870                             }
1871 
1872 primary_expr:             C_FLOAT
1873                             {
1874                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1875                                 if (!c)
1876                                 {
1877                                     ERR("Out of memory.\n");
1878                                     return -1;
1879                                 }
1880                                 c->node.type = HLSL_IR_CONSTANT;
1881                                 set_location(&c->node.loc, &yylloc);
1882                                 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("float"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
1883                                 c->v.value.f[0] = $1;
1884                                 $$ = &c->node;
1885                             }
1886                         | C_INTEGER
1887                             {
1888                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1889                                 if (!c)
1890                                 {
1891                                     ERR("Out of memory.\n");
1892                                     return -1;
1893                                 }
1894                                 c->node.type = HLSL_IR_CONSTANT;
1895                                 set_location(&c->node.loc, &yylloc);
1896                                 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("int"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
1897                                 c->v.value.i[0] = $1;
1898                                 $$ = &c->node;
1899                             }
1900                         | boolean
1901                             {
1902                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1903                                 if (!c)
1904                                 {
1905                                     ERR("Out of memory.\n");
1906                                     return -1;
1907                                 }
1908                                 c->node.type = HLSL_IR_CONSTANT;
1909                                 set_location(&c->node.loc, &yylloc);
1910                                 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("bool"), HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
1911                                 c->v.value.b[0] = $1;
1912                                 $$ = &c->node;
1913                             }
1914                         | variable
1915                             {
1916                                 struct hlsl_ir_deref *deref = new_var_deref($1);
1917                                 if (deref)
1918                                 {
1919                                     $$ = &deref->node;
1920                                     set_location(&$$->loc, &@1);
1921                                 }
1922                                 else
1923                                     $$ = NULL;
1924                             }
1925                         | '(' expr ')'
1926                             {
1927                                 $$ = $2;
1928                             }
1929 
1930 variable:                 VAR_IDENTIFIER
1931                             {
1932                                 struct hlsl_ir_var *var;
1933                                 var = get_variable(hlsl_ctx.cur_scope, $1);
1934                                 if (!var)
1935                                 {
1936                                     hlsl_message("Line %d: variable '%s' not declared\n",
1937                                             hlsl_ctx.line_no, $1);
1938                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1939                                     return 1;
1940                                 }
1941                                 $$ = var;
1942                             }
1943 
1944 postfix_expr:             primary_expr
1945                             {
1946                                 $$ = $1;
1947                             }
1948                         | postfix_expr OP_INC
1949                             {
1950                                 struct hlsl_ir_node *operands[3];
1951                                 struct source_location loc;
1952 
1953                                 set_location(&loc, &@2);
1954                                 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1955                                 {
1956                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1957                                             "modifying a const expression");
1958                                     return 1;
1959                                 }
1960                                 operands[0] = $1;
1961                                 operands[1] = operands[2] = NULL;
1962                                 $$ = &new_expr(HLSL_IR_UNOP_POSTINC, operands, &loc)->node;
1963                                 /* Post increment/decrement expressions are considered const */
1964                                 $$->data_type = clone_hlsl_type($$->data_type);
1965                                 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1966                             }
1967                         | postfix_expr OP_DEC
1968                             {
1969                                 struct hlsl_ir_node *operands[3];
1970                                 struct source_location loc;
1971 
1972                                 set_location(&loc, &@2);
1973                                 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1974                                 {
1975                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1976                                             "modifying a const expression");
1977                                     return 1;
1978                                 }
1979                                 operands[0] = $1;
1980                                 operands[1] = operands[2] = NULL;
1981                                 $$ = &new_expr(HLSL_IR_UNOP_POSTDEC, operands, &loc)->node;
1982                                 /* Post increment/decrement expressions are considered const */
1983                                 $$->data_type = clone_hlsl_type($$->data_type);
1984                                 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1985                             }
1986                         | postfix_expr '.' any_identifier
1987                             {
1988                                 struct source_location loc;
1989 
1990                                 set_location(&loc, &@2);
1991                                 if ($1->data_type->type == HLSL_CLASS_STRUCT)
1992                                 {
1993                                     struct hlsl_type *type = $1->data_type;
1994                                     struct hlsl_struct_field *field;
1995 
1996                                     $$ = NULL;
1997                                     LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
1998                                     {
1999                                         if (!strcmp($3, field->name))
2000                                         {
2001                                             struct hlsl_ir_deref *deref = new_record_deref($1, field);
2002 
2003                                             if (!deref)
2004                                             {
2005                                                 ERR("Out of memory\n");
2006                                                 return -1;
2007                                             }
2008                                             deref->node.loc = loc;
2009                                             $$ = &deref->node;
2010                                             break;
2011                                         }
2012                                     }
2013                                     if (!$$)
2014                                     {
2015                                         hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2016                                                 "invalid subscript %s", debugstr_a($3));
2017                                         return 1;
2018                                     }
2019                                 }
2020                                 else if ($1->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
2021                                 {
2022                                     struct hlsl_ir_swizzle *swizzle;
2023 
2024                                     swizzle = get_swizzle($1, $3, &loc);
2025                                     if (!swizzle)
2026                                     {
2027                                         hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2028                                                 "invalid swizzle %s", debugstr_a($3));
2029                                         return 1;
2030                                     }
2031                                     $$ = &swizzle->node;
2032                                 }
2033                                 else
2034                                 {
2035                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2036                                             "invalid subscript %s", debugstr_a($3));
2037                                     return 1;
2038                                 }
2039                             }
2040                         | postfix_expr '[' expr ']'
2041                             {
2042                                 /* This may be an array dereference or a vector/matrix
2043                                  * subcomponent access.
2044                                  * We store it as an array dereference in any case. */
2045                                 struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
2046                                 struct hlsl_type *expr_type = $1->data_type;
2047                                 struct source_location loc;
2048 
2049                                 TRACE("Array dereference from type %s\n", debug_hlsl_type(expr_type));
2050                                 if (!deref)
2051                                 {
2052                                     ERR("Out of memory\n");
2053                                     return -1;
2054                                 }
2055                                 deref->node.type = HLSL_IR_DEREF;
2056                                 set_location(&loc, &@2);
2057                                 deref->node.loc = loc;
2058                                 if (expr_type->type == HLSL_CLASS_ARRAY)
2059                                 {
2060                                     deref->node.data_type = expr_type->e.array.type;
2061                                 }
2062                                 else if (expr_type->type == HLSL_CLASS_MATRIX)
2063                                 {
2064                                     deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, expr_type->base_type, expr_type->dimx, 1);
2065                                 }
2066                                 else if (expr_type->type == HLSL_CLASS_VECTOR)
2067                                 {
2068                                     deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_SCALAR, expr_type->base_type, 1, 1);
2069                                 }
2070                                 else
2071                                 {
2072                                     if (expr_type->type == HLSL_CLASS_SCALAR)
2073                                         hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2074                                                 "array-indexed expression is scalar");
2075                                     else
2076                                         hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2077                                                 "expression is not array-indexable");
2078                                     d3dcompiler_free(deref);
2079                                     free_instr($1);
2080                                     free_instr($3);
2081                                     return 1;
2082                                 }
2083                                 if ($3->data_type->type != HLSL_CLASS_SCALAR)
2084                                 {
2085                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2086                                             "array index is not scalar");
2087                                     d3dcompiler_free(deref);
2088                                     free_instr($1);
2089                                     free_instr($3);
2090                                     return 1;
2091                                 }
2092                                 deref->type = HLSL_IR_DEREF_ARRAY;
2093                                 deref->v.array.array = $1;
2094                                 deref->v.array.index = $3;
2095 
2096                                 $$ = &deref->node;
2097                             }
2098                           /* "var_modifiers" doesn't make sense in this case, but it's needed
2099                              in the grammar to avoid shift/reduce conflicts. */
2100                         | var_modifiers type '(' initializer_expr_list ')'
2101                             {
2102                                 struct hlsl_ir_constructor *constructor;
2103 
2104                                 TRACE("%s constructor.\n", debug_hlsl_type($2));
2105                                 if ($1)
2106                                 {
2107                                     hlsl_message("Line %u: unexpected modifier in a constructor.\n",
2108                                             hlsl_ctx.line_no);
2109                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2110                                     return -1;
2111                                 }
2112                                 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
2113                                 {
2114                                     hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
2115                                             hlsl_ctx.line_no);
2116                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2117                                     return -1;
2118                                 }
2119                                 if ($2->dimx * $2->dimy != components_count_expr_list($4))
2120                                 {
2121                                     hlsl_message("Line %u: wrong number of components in constructor.\n",
2122                                             hlsl_ctx.line_no);
2123                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
2124                                     return -1;
2125                                 }
2126 
2127                                 constructor = d3dcompiler_alloc(sizeof(*constructor));
2128                                 constructor->node.type = HLSL_IR_CONSTRUCTOR;
2129                                 set_location(&constructor->node.loc, &@3);
2130                                 constructor->node.data_type = $2;
2131                                 constructor->arguments = $4;
2132 
2133                                 $$ = &constructor->node;
2134                             }
2135 
2136 unary_expr:               postfix_expr
2137                             {
2138                                 $$ = $1;
2139                             }
2140                         | OP_INC unary_expr
2141                             {
2142                                 struct hlsl_ir_node *operands[3];
2143                                 struct source_location loc;
2144 
2145                                 set_location(&loc, &@1);
2146                                 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2147                                 {
2148                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2149                                             "modifying a const expression");
2150                                     return 1;
2151                                 }
2152                                 operands[0] = $2;
2153                                 operands[1] = operands[2] = NULL;
2154                                 $$ = &new_expr(HLSL_IR_UNOP_PREINC, operands, &loc)->node;
2155                             }
2156                         | OP_DEC unary_expr
2157                             {
2158                                 struct hlsl_ir_node *operands[3];
2159                                 struct source_location loc;
2160 
2161                                 set_location(&loc, &@1);
2162                                 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
2163                                 {
2164                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2165                                             "modifying a const expression");
2166                                     return 1;
2167                                 }
2168                                 operands[0] = $2;
2169                                 operands[1] = operands[2] = NULL;
2170                                 $$ = &new_expr(HLSL_IR_UNOP_PREDEC, operands, &loc)->node;
2171                             }
2172                         | unary_op unary_expr
2173                             {
2174                                 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
2175                                         HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
2176                                 struct hlsl_ir_node *operands[3];
2177                                 struct source_location loc;
2178 
2179                                 if ($1 == UNARY_OP_PLUS)
2180                                 {
2181                                     $$ = $2;
2182                                 }
2183                                 else
2184                                 {
2185                                     operands[0] = $2;
2186                                     operands[1] = operands[2] = NULL;
2187                                     set_location(&loc, &@1);
2188                                     $$ = &new_expr(ops[$1], operands, &loc)->node;
2189                                 }
2190                             }
2191                           /* var_modifiers just to avoid shift/reduce conflicts */
2192                         | '(' var_modifiers type array ')' unary_expr
2193                             {
2194                                 struct hlsl_ir_expr *expr;
2195                                 struct hlsl_type *src_type = $6->data_type;
2196                                 struct hlsl_type *dst_type;
2197                                 struct source_location loc;
2198 
2199                                 set_location(&loc, &@3);
2200                                 if ($2)
2201                                 {
2202                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2203                                             "unexpected modifier in a cast");
2204                                     return 1;
2205                                 }
2206 
2207                                 if ($4)
2208                                     dst_type = new_array_type($3, $4);
2209                                 else
2210                                     dst_type = $3;
2211 
2212                                 if (!compatible_data_types(src_type, dst_type))
2213                                 {
2214                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2215                                             "can't cast from %s to %s",
2216                                             debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
2217                                     return 1;
2218                                 }
2219 
2220                                 expr = new_cast($6, dst_type, &loc);
2221                                 $$ = expr ? &expr->node : NULL;
2222                             }
2223 
2224 unary_op:                 '+'
2225                             {
2226                                 $$ = UNARY_OP_PLUS;
2227                             }
2228                         | '-'
2229                             {
2230                                 $$ = UNARY_OP_MINUS;
2231                             }
2232                         | '!'
2233                             {
2234                                 $$ = UNARY_OP_LOGICNOT;
2235                             }
2236                         | '~'
2237                             {
2238                                 $$ = UNARY_OP_BITNOT;
2239                             }
2240 
2241 mul_expr:                 unary_expr
2242                             {
2243                                 $$ = $1;
2244                             }
2245                         | mul_expr '*' unary_expr
2246                             {
2247                                 struct source_location loc;
2248 
2249                                 set_location(&loc, &@2);
2250                                 $$ = &hlsl_mul($1, $3, &loc)->node;
2251                             }
2252                         | mul_expr '/' unary_expr
2253                             {
2254                                 struct source_location loc;
2255 
2256                                 set_location(&loc, &@2);
2257                                 $$ = &hlsl_div($1, $3, &loc)->node;
2258                             }
2259                         | mul_expr '%' unary_expr
2260                             {
2261                                 struct source_location loc;
2262 
2263                                 set_location(&loc, &@2);
2264                                 $$ = &hlsl_mod($1, $3, &loc)->node;
2265                             }
2266 
2267 add_expr:                 mul_expr
2268                             {
2269                                 $$ = $1;
2270                             }
2271                         | add_expr '+' mul_expr
2272                             {
2273                                 struct source_location loc;
2274 
2275                                 set_location(&loc, &@2);
2276                                 $$ = &hlsl_add($1, $3, &loc)->node;
2277                             }
2278                         | add_expr '-' mul_expr
2279                             {
2280                                 struct source_location loc;
2281 
2282                                 set_location(&loc, &@2);
2283                                 $$ = &hlsl_sub($1, $3, &loc)->node;
2284                             }
2285 
2286 shift_expr:               add_expr
2287                             {
2288                                 $$ = $1;
2289                             }
2290                         | shift_expr OP_LEFTSHIFT add_expr
2291                             {
2292                                 FIXME("Left shift\n");
2293                             }
2294                         | shift_expr OP_RIGHTSHIFT add_expr
2295                             {
2296                                 FIXME("Right shift\n");
2297                             }
2298 
2299 relational_expr:          shift_expr
2300                             {
2301                                 $$ = $1;
2302                             }
2303                         | relational_expr '<' shift_expr
2304                             {
2305                                 struct source_location loc;
2306 
2307                                 set_location(&loc, &@2);
2308                                 $$ = &hlsl_lt($1, $3, &loc)->node;
2309                             }
2310                         | relational_expr '>' shift_expr
2311                             {
2312                                 struct source_location loc;
2313 
2314                                 set_location(&loc, &@2);
2315                                 $$ = &hlsl_gt($1, $3, &loc)->node;
2316                             }
2317                         | relational_expr OP_LE shift_expr
2318                             {
2319                                 struct source_location loc;
2320 
2321                                 set_location(&loc, &@2);
2322                                 $$ = &hlsl_le($1, $3, &loc)->node;
2323                             }
2324                         | relational_expr OP_GE shift_expr
2325                             {
2326                                 struct source_location loc;
2327 
2328                                 set_location(&loc, &@2);
2329                                 $$ = &hlsl_ge($1, $3, &loc)->node;
2330                             }
2331 
2332 equality_expr:            relational_expr
2333                             {
2334                                 $$ = $1;
2335                             }
2336                         | equality_expr OP_EQ relational_expr
2337                             {
2338                                 struct source_location loc;
2339 
2340                                 set_location(&loc, &@2);
2341                                 $$ = &hlsl_eq($1, $3, &loc)->node;
2342                             }
2343                         | equality_expr OP_NE relational_expr
2344                             {
2345                                 struct source_location loc;
2346 
2347                                 set_location(&loc, &@2);
2348                                 $$ = &hlsl_ne($1, $3, &loc)->node;
2349                             }
2350 
2351 bitand_expr:              equality_expr
2352                             {
2353                                 $$ = $1;
2354                             }
2355                         | bitand_expr '&' equality_expr
2356                             {
2357                                 FIXME("bitwise AND\n");
2358                             }
2359 
2360 bitxor_expr:              bitand_expr
2361                             {
2362                                 $$ = $1;
2363                             }
2364                         | bitxor_expr '^' bitand_expr
2365                             {
2366                                 FIXME("bitwise XOR\n");
2367                             }
2368 
2369 bitor_expr:               bitxor_expr
2370                             {
2371                                 $$ = $1;
2372                             }
2373                         | bitor_expr '|' bitxor_expr
2374                             {
2375                                 FIXME("bitwise OR\n");
2376                             }
2377 
2378 logicand_expr:            bitor_expr
2379                             {
2380                                 $$ = $1;
2381                             }
2382                         | logicand_expr OP_AND bitor_expr
2383                             {
2384                                 FIXME("logic AND\n");
2385                             }
2386 
2387 logicor_expr:             logicand_expr
2388                             {
2389                                 $$ = $1;
2390                             }
2391                         | logicor_expr OP_OR logicand_expr
2392                             {
2393                                 FIXME("logic OR\n");
2394                             }
2395 
2396 conditional_expr:         logicor_expr
2397                             {
2398                                 $$ = $1;
2399                             }
2400                         | logicor_expr '?' expr ':' assignment_expr
2401                             {
2402                                 FIXME("ternary operator\n");
2403                             }
2404 
2405 assignment_expr:          conditional_expr
2406                             {
2407                                 $$ = $1;
2408                             }
2409                         | unary_expr assign_op assignment_expr
2410                             {
2411                                 struct source_location loc;
2412 
2413                                 set_location(&loc, &@2);
2414                                 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
2415                                 {
2416                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
2417                                             "l-value is const");
2418                                     return 1;
2419                                 }
2420                                 $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
2421                                 if (!$$)
2422                                     return 1;
2423                                 $$->loc = loc;
2424                             }
2425 
2426 assign_op:                '='
2427                             {
2428                                 $$ = ASSIGN_OP_ASSIGN;
2429                             }
2430                         | OP_ADDASSIGN
2431                             {
2432                                 $$ = ASSIGN_OP_ADD;
2433                             }
2434                         | OP_SUBASSIGN
2435                             {
2436                                 $$ = ASSIGN_OP_SUB;
2437                             }
2438                         | OP_MULASSIGN
2439                             {
2440                                 $$ = ASSIGN_OP_MUL;
2441                             }
2442                         | OP_DIVASSIGN
2443                             {
2444                                 $$ = ASSIGN_OP_DIV;
2445                             }
2446                         | OP_MODASSIGN
2447                             {
2448                                 $$ = ASSIGN_OP_MOD;
2449                             }
2450                         | OP_LEFTSHIFTASSIGN
2451                             {
2452                                 $$ = ASSIGN_OP_LSHIFT;
2453                             }
2454                         | OP_RIGHTSHIFTASSIGN
2455                             {
2456                                 $$ = ASSIGN_OP_RSHIFT;
2457                             }
2458                         | OP_ANDASSIGN
2459                             {
2460                                 $$ = ASSIGN_OP_AND;
2461                             }
2462                         | OP_ORASSIGN
2463                             {
2464                                 $$ = ASSIGN_OP_OR;
2465                             }
2466                         | OP_XORASSIGN
2467                             {
2468                                 $$ = ASSIGN_OP_XOR;
2469                             }
2470 
2471 expr:                     assignment_expr
2472                             {
2473                                 $$ = $1;
2474                             }
2475                         | expr ',' assignment_expr
2476                             {
2477                                 FIXME("Comma expression\n");
2478                             }
2479 
2480 %%
2481 
2482 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
2483 {
2484     loc->file = hlsl_ctx.source_file;
2485     loc->line = l->first_line;
2486     loc->col = l->first_column;
2487 }
2488 
2489 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
2490 {
2491     if (modifiers & mod)
2492     {
2493         hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2494                 "modifier '%s' already specified", debug_modifiers(mod));
2495         return modifiers;
2496     }
2497     if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
2498             && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
2499     {
2500         hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
2501                 "more than one matrix majority keyword");
2502         return modifiers;
2503     }
2504     return modifiers | mod;
2505 }
2506 
2507 static void dump_function_decl(struct wine_rb_entry *entry, void *context)
2508 {
2509     struct hlsl_ir_function_decl *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry);
2510     if (func->body)
2511         debug_dump_ir_function_decl(func);
2512 }
2513 
2514 static void dump_function(struct wine_rb_entry *entry, void *context)
2515 {
2516     struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
2517     wine_rb_for_each_entry(&func->overloads, dump_function_decl, NULL);
2518 }
2519 
2520 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
2521         const char *entrypoint, char **messages)
2522 {
2523     struct hlsl_scope *scope, *next_scope;
2524     struct hlsl_type *hlsl_type, *next_type;
2525     struct hlsl_ir_var *var, *next_var;
2526     unsigned int i;
2527 
2528     hlsl_ctx.status = PARSE_SUCCESS;
2529     hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
2530     hlsl_ctx.line_no = hlsl_ctx.column = 1;
2531     hlsl_ctx.source_file = d3dcompiler_strdup("");
2532     hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
2533     if (hlsl_ctx.source_files)
2534         hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
2535     hlsl_ctx.source_files_count = 1;
2536     hlsl_ctx.cur_scope = NULL;
2537     hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
2538     list_init(&hlsl_ctx.scopes);
2539     list_init(&hlsl_ctx.types);
2540     init_functions_tree(&hlsl_ctx.functions);
2541 
2542     push_scope(&hlsl_ctx);
2543     hlsl_ctx.globals = hlsl_ctx.cur_scope;
2544     declare_predefined_types(hlsl_ctx.globals);
2545 
2546     hlsl_parse();
2547 
2548     if (TRACE_ON(hlsl_parser))
2549     {
2550         TRACE("IR dump.\n");
2551         wine_rb_for_each_entry(&hlsl_ctx.functions, dump_function, NULL);
2552     }
2553 
2554     TRACE("Compilation status = %d\n", hlsl_ctx.status);
2555     if (messages)
2556     {
2557         if (hlsl_ctx.messages.size)
2558             *messages = hlsl_ctx.messages.string;
2559         else
2560             *messages = NULL;
2561     }
2562     else
2563     {
2564         if (hlsl_ctx.messages.capacity)
2565             d3dcompiler_free(hlsl_ctx.messages.string);
2566     }
2567 
2568     for (i = 0; i < hlsl_ctx.source_files_count; ++i)
2569         d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
2570     d3dcompiler_free(hlsl_ctx.source_files);
2571 
2572     TRACE("Freeing functions IR.\n");
2573     wine_rb_destroy(&hlsl_ctx.functions, free_function_rb, NULL);
2574 
2575     TRACE("Freeing variables.\n");
2576     LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
2577     {
2578         LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
2579         {
2580             free_declaration(var);
2581         }
2582         wine_rb_destroy(&scope->types, NULL, NULL);
2583         d3dcompiler_free(scope);
2584     }
2585 
2586     TRACE("Freeing types.\n");
2587     LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
2588     {
2589         free_hlsl_type(hlsl_type);
2590     }
2591 
2592     return NULL;
2593 }
2594