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