mshtml: Use inner window directly in HTMLImageElementFactory implementation.
[wine] / dlls / d3dcompiler_43 / hlsl.y
1 /*
2  * HLSL parser
3  *
4  * Copyright 2008 Stefan Dösinger
5  * Copyright 2012 Matteo Bruni for CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 %{
22 #include "config.h"
23 #include "wine/debug.h"
24
25 #include <stdio.h>
26
27 #include "d3dcompiler_private.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser);
30
31 int hlsl_lex(void);
32
33 struct hlsl_parse_ctx hlsl_ctx;
34
35 struct YYLTYPE;
36 static void set_location(struct source_location *loc, const struct YYLTYPE *l);
37
38 void hlsl_message(const char *fmt, ...)
39 {
40     va_list args;
41
42     va_start(args, fmt);
43     compilation_message(&hlsl_ctx.messages, fmt, args);
44     va_end(args);
45 }
46
47 static const char *hlsl_get_error_level_name(enum hlsl_error_level level)
48 {
49     const char *names[] =
50     {
51         "error",
52         "warning",
53         "note",
54     };
55     return names[level];
56 }
57
58 void hlsl_report_message(const char *filename, DWORD line, DWORD column,
59         enum hlsl_error_level level, const char *fmt, ...)
60 {
61     va_list args;
62     char *string = NULL;
63     int rc, size = 0;
64
65     while (1)
66     {
67         va_start(args, fmt);
68         rc = vsnprintf(string, size, fmt, args);
69         va_end(args);
70
71         if (rc >= 0 && rc < size)
72             break;
73
74         if (rc >= size)
75             size = rc + 1;
76         else
77             size = size ? size * 2 : 32;
78
79         if (!string)
80             string = d3dcompiler_alloc(size);
81         else
82             string = d3dcompiler_realloc(string, size);
83         if (!string)
84         {
85             ERR("Error reallocating memory for a string.\n");
86             return;
87         }
88     }
89
90     hlsl_message("%s:%u:%u: %s: %s\n", filename, line, column, hlsl_get_error_level_name(level), string);
91     d3dcompiler_free(string);
92
93     if (level == HLSL_LEVEL_ERROR)
94         set_parse_status(&hlsl_ctx.status, PARSE_ERR);
95     else if (level == HLSL_LEVEL_WARNING)
96         set_parse_status(&hlsl_ctx.status, PARSE_WARN);
97 }
98
99 static void hlsl_error(const char *s)
100 {
101     hlsl_report_message(hlsl_ctx.source_file, hlsl_ctx.line_no, hlsl_ctx.column, HLSL_LEVEL_ERROR, "%s", s);
102 }
103
104 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
105 {
106     TRACE("Line %u: ", line_no);
107     if (modifiers)
108         TRACE("%s ", debug_modifiers(modifiers));
109     TRACE("%s %s;\n", debug_hlsl_type(type), declname);
110 }
111
112 static void check_invalid_matrix_modifiers(DWORD modifiers, struct source_location *loc)
113 {
114     if (modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
115     {
116         hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
117                 "'row_major' or 'column_major' modifiers are only allowed for matrices");
118     }
119 }
120
121 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
122 {
123     BOOL ret;
124
125     TRACE("Declaring variable %s.\n", decl->name);
126     if (decl->node.data_type->type == HLSL_CLASS_MATRIX)
127     {
128         if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)))
129         {
130             decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR
131                     ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR;
132         }
133     }
134     else
135         check_invalid_matrix_modifiers(decl->modifiers, &decl->node.loc);
136
137     if (local)
138     {
139         DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
140                 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
141         if (invalid)
142         {
143             hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
144                     "modifier '%s' invalid for local variables", debug_modifiers(invalid));
145         }
146         if (decl->semantic)
147         {
148             hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
149                     "semantics are not allowed on local variables");
150             return FALSE;
151         }
152     }
153     else
154     {
155         if (find_function(decl->name))
156         {
157             hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
158                     "redefinition of '%s'", decl->name);
159             return FALSE;
160         }
161     }
162     ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
163     if (!ret)
164     {
165         struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
166
167         hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
168                 "\"%s\" already declared", decl->name);
169         hlsl_report_message(old->node.loc.file, old->node.loc.line, old->node.loc.col, HLSL_LEVEL_NOTE,
170                 "\"%s\" was previously declared here", old->name);
171         return FALSE;
172     }
173     return TRUE;
174 }
175
176 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc);
177
178 static unsigned int components_count_expr_list(struct list *list)
179 {
180     struct hlsl_ir_node *node;
181     unsigned int count = 0;
182
183     LIST_FOR_EACH_ENTRY(node, list, struct hlsl_ir_node, entry)
184     {
185         count += components_count_type(node->data_type);
186     }
187     return count;
188 }
189
190 %}
191
192 %locations
193 %error-verbose
194
195 %union
196 {
197     struct hlsl_type *type;
198     INT intval;
199     FLOAT floatval;
200     BOOL boolval;
201     char *name;
202     DWORD modifiers;
203     struct hlsl_ir_var *var;
204     struct hlsl_ir_node *instr;
205     struct list *list;
206     struct hlsl_ir_function_decl *function;
207     struct parse_parameter parameter;
208     struct parse_variable_def *variable_def;
209     enum parse_unary_op unary_op;
210     enum parse_assign_op assign_op;
211 }
212
213 %token KW_BLENDSTATE
214 %token KW_BREAK
215 %token KW_BUFFER
216 %token KW_CBUFFER
217 %token KW_COLUMN_MAJOR
218 %token KW_COMPILE
219 %token KW_CONST
220 %token KW_CONTINUE
221 %token KW_DEPTHSTENCILSTATE
222 %token KW_DEPTHSTENCILVIEW
223 %token KW_DISCARD
224 %token KW_DO
225 %token KW_DOUBLE
226 %token KW_ELSE
227 %token KW_EXTERN
228 %token KW_FALSE
229 %token KW_FOR
230 %token KW_GEOMETRYSHADER
231 %token KW_GROUPSHARED
232 %token KW_IF
233 %token KW_IN
234 %token KW_INLINE
235 %token KW_INOUT
236 %token KW_MATRIX
237 %token KW_NAMESPACE
238 %token KW_NOINTERPOLATION
239 %token KW_OUT
240 %token KW_PASS
241 %token KW_PIXELSHADER
242 %token KW_PRECISE
243 %token KW_RASTERIZERSTATE
244 %token KW_RENDERTARGETVIEW
245 %token KW_RETURN
246 %token KW_REGISTER
247 %token KW_ROW_MAJOR
248 %token KW_SAMPLER
249 %token KW_SAMPLER1D
250 %token KW_SAMPLER2D
251 %token KW_SAMPLER3D
252 %token KW_SAMPLERCUBE
253 %token KW_SAMPLER_STATE
254 %token KW_SAMPLERCOMPARISONSTATE
255 %token KW_SHARED
256 %token KW_STATEBLOCK
257 %token KW_STATEBLOCK_STATE
258 %token KW_STATIC
259 %token KW_STRING
260 %token KW_STRUCT
261 %token KW_SWITCH
262 %token KW_TBUFFER
263 %token KW_TECHNIQUE
264 %token KW_TECHNIQUE10
265 %token KW_TEXTURE
266 %token KW_TEXTURE1D
267 %token KW_TEXTURE1DARRAY
268 %token KW_TEXTURE2D
269 %token KW_TEXTURE2DARRAY
270 %token KW_TEXTURE2DMS
271 %token KW_TEXTURE2DMSARRAY
272 %token KW_TEXTURE3D
273 %token KW_TEXTURE3DARRAY
274 %token KW_TEXTURECUBE
275 %token KW_TRUE
276 %token KW_TYPEDEF
277 %token KW_UNIFORM
278 %token KW_VECTOR
279 %token KW_VERTEXSHADER
280 %token KW_VOID
281 %token KW_VOLATILE
282 %token KW_WHILE
283
284 %token OP_INC
285 %token OP_DEC
286 %token OP_AND
287 %token OP_OR
288 %token OP_EQ
289 %token OP_LEFTSHIFT
290 %token OP_LEFTSHIFTASSIGN
291 %token OP_RIGHTSHIFT
292 %token OP_RIGHTSHIFTASSIGN
293 %token OP_ELLIPSIS
294 %token OP_LE
295 %token OP_GE
296 %token OP_NE
297 %token OP_ADDASSIGN
298 %token OP_SUBASSIGN
299 %token OP_MULASSIGN
300 %token OP_DIVASSIGN
301 %token OP_MODASSIGN
302 %token OP_ANDASSIGN
303 %token OP_ORASSIGN
304 %token OP_XORASSIGN
305 %token OP_UNKNOWN1
306 %token OP_UNKNOWN2
307 %token OP_UNKNOWN3
308 %token OP_UNKNOWN4
309
310 %token <intval> PRE_LINE
311
312 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
313 %type <name> any_identifier var_identifier
314 %token <name> STRING
315 %token <floatval> C_FLOAT
316 %token <intval> C_INTEGER
317 %type <boolval> boolean
318 %type <type> base_type
319 %type <type> type
320 %type <list> declaration_statement
321 %type <list> complex_initializer
322 %type <list> initializer_expr_list
323 %type <instr> initializer_expr
324 %type <modifiers> var_modifiers
325 %type <list> parameters
326 %type <list> param_list
327 %type <instr> expr
328 %type <var> variable
329 %type <intval> array
330 %type <list> statement
331 %type <list> statement_list
332 %type <list> compound_statement
333 %type <function> func_declaration
334 %type <function> func_prototype
335 %type <parameter> parameter
336 %type <name> semantic
337 %type <variable_def> variable_def
338 %type <list> variables_def
339 %type <instr> primary_expr
340 %type <instr> postfix_expr
341 %type <instr> unary_expr
342 %type <instr> mul_expr
343 %type <instr> add_expr
344 %type <instr> shift_expr
345 %type <instr> relational_expr
346 %type <instr> equality_expr
347 %type <instr> bitand_expr
348 %type <instr> bitxor_expr
349 %type <instr> bitor_expr
350 %type <instr> logicand_expr
351 %type <instr> logicor_expr
352 %type <instr> conditional_expr
353 %type <instr> assignment_expr
354 %type <list> expr_statement
355 %type <unary_op> unary_op
356 %type <assign_op> assign_op
357 %type <modifiers> input_mod
358 %%
359
360 hlsl_prog:                /* empty */
361                             {
362                             }
363                         | hlsl_prog func_declaration
364                             {
365                                 FIXME("Check that the function doesn't conflict with an already declared one.\n");
366                                 list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
367                             }
368                         | hlsl_prog declaration_statement
369                             {
370                                 TRACE("Declaration statement parsed.\n");
371                             }
372                         | hlsl_prog preproc_directive
373                             {
374                             }
375
376 preproc_directive:        PRE_LINE STRING
377                             {
378                                 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
379                                 hlsl_ctx.line_no = $1;
380                                 if (strcmp($2, hlsl_ctx.source_file))
381                                 {
382                                     const char **new_array;
383
384                                     hlsl_ctx.source_file = $2;
385                                     new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
386                                             sizeof(*hlsl_ctx.source_files) * hlsl_ctx.source_files_count + 1);
387                                     if (new_array)
388                                     {
389                                         hlsl_ctx.source_files = new_array;
390                                         hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
391                                     }
392                                 }
393                             }
394
395 any_identifier:           VAR_IDENTIFIER
396                         | TYPE_IDENTIFIER
397                         | NEW_IDENTIFIER
398
399 func_declaration:         func_prototype compound_statement
400                             {
401                                 TRACE("Function %s parsed.\n", $1->name);
402                                 $$ = $1;
403                                 $$->body = $2;
404                                 pop_scope(&hlsl_ctx);
405                             }
406                         | func_prototype ';'
407                             {
408                                 TRACE("Function prototype for %s.\n", $1->name);
409                                 $$ = $1;
410                                 pop_scope(&hlsl_ctx);
411                             }
412
413 func_prototype:           var_modifiers type var_identifier '(' parameters ')' semantic
414                             {
415                                 if (get_variable(hlsl_ctx.globals, $3))
416                                 {
417                                     hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
418                                             HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
419                                     return 1;
420                                 }
421                                 if ($2->base_type == HLSL_TYPE_VOID && $7)
422                                 {
423                                     hlsl_report_message(hlsl_ctx.source_file, @7.first_line, @7.first_column,
424                                             HLSL_LEVEL_ERROR, "void function with a semantic");
425                                 }
426
427                                 $$ = new_func_decl($3, $2, $5);
428                                 if (!$$)
429                                 {
430                                     ERR("Out of memory.\n");
431                                     return -1;
432                                 }
433                                 $$->semantic = $7;
434                             }
435
436 compound_statement:       '{' '}'
437                             {
438                                 $$ = d3dcompiler_alloc(sizeof(*$$));
439                                 list_init($$);
440                             }
441                         | '{' scope_start statement_list '}'
442                             {
443                                 pop_scope(&hlsl_ctx);
444                                 $$ = $3;
445                             }
446
447 scope_start:              /* Empty */
448                             {
449                                 push_scope(&hlsl_ctx);
450                             }
451
452 var_identifier:           VAR_IDENTIFIER
453                         | NEW_IDENTIFIER
454
455 semantic:                 /* Empty */
456                             {
457                                 $$ = NULL;
458                             }
459                         | ':' any_identifier
460                             {
461                                 $$ = $2;
462                             }
463
464 parameters:               scope_start
465                             {
466                                 $$ = d3dcompiler_alloc(sizeof(*$$));
467                                 list_init($$);
468                             }
469                         | scope_start param_list
470                             {
471                                 $$ = $2;
472                             }
473
474 param_list:               parameter
475                             {
476                                 struct source_location loc;
477
478                                 $$ = d3dcompiler_alloc(sizeof(*$$));
479                                 list_init($$);
480                                 set_location(&loc, &@1);
481                                 if (!add_func_parameter($$, &$1, &loc))
482                                 {
483                                     ERR("Error adding function parameter %s.\n", $1.name);
484                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
485                                     return -1;
486                                 }
487                             }
488                         | param_list ',' parameter
489                             {
490                                 struct source_location loc;
491
492                                 $$ = $1;
493                                 set_location(&loc, &@3);
494                                 if (!add_func_parameter($$, &$3, &loc))
495                                 {
496                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
497                                             "duplicate parameter %s", $3.name);
498                                     return 1;
499                                 }
500                             }
501
502 parameter:                input_mod var_modifiers type any_identifier semantic
503                             {
504                                 $$.modifiers = $1;
505                                 $$.modifiers |= $2;
506                                 $$.type = $3;
507                                 $$.name = $4;
508                                 $$.semantic = $5;
509                             }
510
511 input_mod:                /* Empty */
512                             {
513                                 $$ = HLSL_MODIFIER_IN;
514                             }
515                         | KW_IN
516                             {
517                                 $$ = HLSL_MODIFIER_IN;
518                             }
519                         | KW_OUT
520                             {
521                                 $$ = HLSL_MODIFIER_OUT;
522                             }
523                         | KW_INOUT
524                             {
525                                 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
526                             }
527
528 type:                     base_type
529                             {
530                                 $$ = $1;
531                             }
532                         | KW_VECTOR '<' base_type ',' C_INTEGER '>'
533                             {
534                                 if ($3->type != HLSL_CLASS_SCALAR)
535                                 {
536                                     hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
537                                             hlsl_ctx.line_no);
538                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
539                                     return 1;
540                                 }
541                                 if ($5 < 1 || $5 > 4)
542                                 {
543                                     hlsl_message("Line %u: vector size must be between 1 and 4.\n",
544                                             hlsl_ctx.line_no);
545                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
546                                     return 1;
547                                 }
548
549                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
550                             }
551                         | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
552                             {
553                                 if ($3->type != HLSL_CLASS_SCALAR)
554                                 {
555                                     hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
556                                             hlsl_ctx.line_no);
557                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
558                                     return 1;
559                                 }
560                                 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
561                                 {
562                                     hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
563                                             hlsl_ctx.line_no);
564                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
565                                     return 1;
566                                 }
567
568                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
569                             }
570
571 base_type:                KW_VOID
572                             {
573                                 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
574                             }
575                         | KW_SAMPLER
576                             {
577                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
578                                 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
579                             }
580                         | KW_SAMPLER1D
581                             {
582                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
583                                 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
584                             }
585                         | KW_SAMPLER2D
586                             {
587                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
588                                 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
589                             }
590                         | KW_SAMPLER3D
591                             {
592                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
593                                 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
594                             }
595                         | KW_SAMPLERCUBE
596                             {
597                                 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
598                                 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
599                             }
600                         | TYPE_IDENTIFIER
601                             {
602                                 struct hlsl_type *type;
603
604                                 TRACE("Type %s.\n", $1);
605                                 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
606                                 $$ = type;
607                                 d3dcompiler_free($1);
608                             }
609                         | KW_STRUCT TYPE_IDENTIFIER
610                             {
611                                 struct hlsl_type *type;
612
613                                 TRACE("Struct type %s.\n", $2);
614                                 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
615                                 if (type->type != HLSL_CLASS_STRUCT)
616                                 {
617                                     hlsl_message("Line %u: redefining %s as a structure.\n",
618                                             hlsl_ctx.line_no, $2);
619                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
620                                 }
621                                 else
622                                 {
623                                     $$ = type;
624                                 }
625                                 d3dcompiler_free($2);
626                             }
627
628 declaration_statement:    declaration
629                             {
630                                 $$ = d3dcompiler_alloc(sizeof(*$$));
631                                 list_init($$);
632                             }
633
634 declaration:              var_modifiers type variables_def ';'
635                             {
636                                 struct parse_variable_def *v, *v_next;
637                                 struct hlsl_ir_var *var;
638                                 BOOL ret, local = TRUE;
639
640                                 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
641                                 {
642                                     debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
643                                     var = d3dcompiler_alloc(sizeof(*var));
644                                     var->node.type = HLSL_IR_VAR;
645                                     if (v->array_size)
646                                         var->node.data_type = new_array_type($2, v->array_size);
647                                     else
648                                         var->node.data_type = $2;
649                                     var->node.loc = v->loc;
650                                     var->name = v->name;
651                                     var->modifiers = $1;
652                                     var->semantic = v->semantic;
653
654                                     if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
655                                     {
656                                         var->modifiers |= HLSL_STORAGE_UNIFORM;
657                                         local = FALSE;
658                                     }
659
660                                     if (var->modifiers & HLSL_MODIFIER_CONST && !v->initializer)
661                                     {
662                                         hlsl_report_message(v->loc.file, v->loc.line, v->loc.col,
663                                                 HLSL_LEVEL_ERROR, "const variable without initializer");
664                                         free_declaration(var);
665                                         d3dcompiler_free(v);
666                                         continue;
667                                     }
668
669                                     ret = declare_variable(var, local);
670                                     if (!ret)
671                                         free_declaration(var);
672                                     else
673                                         TRACE("Declared variable %s.\n", var->name);
674
675                                     if (v->initializer)
676                                     {
677                                         FIXME("Variable with an initializer.\n");
678                                         free_instr_list(v->initializer);
679                                     }
680
681                                     d3dcompiler_free(v);
682                                 }
683                                 d3dcompiler_free($3);
684                             }
685
686 variables_def:            variable_def
687                             {
688                                 $$ = d3dcompiler_alloc(sizeof(*$$));
689                                 list_init($$);
690                                 list_add_head($$, &$1->entry);
691                             }
692                         | variables_def ',' variable_def
693                             {
694                                 $$ = $1;
695                                 list_add_tail($$, &$3->entry);
696                             }
697
698 variable_def:             any_identifier array semantic
699                             {
700                                 $$ = d3dcompiler_alloc(sizeof(*$$));
701                                 set_location(&$$->loc, &@1);
702                                 $$->name = $1;
703                                 $$->array_size = $2;
704                                 $$->semantic = $3;
705                             }
706                         | any_identifier array semantic '=' complex_initializer
707                             {
708                                 TRACE("Declaration with initializer.\n");
709                                 $$ = d3dcompiler_alloc(sizeof(*$$));
710                                 set_location(&$$->loc, &@1);
711                                 $$->name = $1;
712                                 $$->array_size = $2;
713                                 $$->semantic = $3;
714                                 $$->initializer = $5;
715                             }
716
717 array:                    /* Empty */
718                             {
719                                 $$ = 0;
720                             }
721                         | '[' expr ']'
722                             {
723                                 FIXME("Array.\n");
724                                 $$ = 0;
725                                 free_instr($2);
726                             }
727
728 var_modifiers:            /* Empty */
729                             {
730                                 $$ = 0;
731                             }
732                         | KW_EXTERN var_modifiers
733                             {
734                                 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
735                             }
736                         | KW_NOINTERPOLATION var_modifiers
737                             {
738                                 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
739                             }
740                         | KW_PRECISE var_modifiers
741                             {
742                                 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
743                             }
744                         | KW_SHARED var_modifiers
745                             {
746                                 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
747                             }
748                         | KW_GROUPSHARED var_modifiers
749                             {
750                                 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
751                             }
752                         | KW_STATIC var_modifiers
753                             {
754                                 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
755                             }
756                         | KW_UNIFORM var_modifiers
757                             {
758                                 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
759                             }
760                         | KW_VOLATILE var_modifiers
761                             {
762                                 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
763                             }
764                         | KW_CONST var_modifiers
765                             {
766                                 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
767                             }
768                         | KW_ROW_MAJOR var_modifiers
769                             {
770                                 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
771                             }
772                         | KW_COLUMN_MAJOR var_modifiers
773                             {
774                                 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
775                             }
776
777 complex_initializer:      initializer_expr
778                             {
779                                 $$ = d3dcompiler_alloc(sizeof(*$$));
780                                 list_init($$);
781                                 list_add_head($$, &$1->entry);
782                             }
783                         | '{' initializer_expr_list '}'
784                             {
785                                 $$ = $2;
786                             }
787
788 initializer_expr:         assignment_expr
789                             {
790                                 $$ = $1;
791                             }
792
793 initializer_expr_list:    initializer_expr
794                             {
795                                 $$ = d3dcompiler_alloc(sizeof(*$$));
796                                 list_init($$);
797                                 list_add_head($$, &$1->entry);
798                             }
799                         | initializer_expr_list ',' initializer_expr
800                             {
801                                 $$ = $1;
802                                 list_add_tail($$, &$3->entry);
803                             }
804
805 boolean:                  KW_TRUE
806                             {
807                                 $$ = TRUE;
808                             }
809                         | KW_FALSE
810                             {
811                                 $$ = FALSE;
812                             }
813
814 statement_list:           statement
815                             {
816                                 $$ = $1;
817                             }
818                         | statement_list statement
819                             {
820                                 $$ = $1;
821                                 list_move_tail($$, $2);
822                                 d3dcompiler_free($2);
823                             }
824
825 statement:                declaration_statement
826                             {
827                                 $$ = $1;
828                             }
829                         | expr_statement
830                             {
831                                 $$ = $1;
832                             }
833                         | compound_statement
834                             {
835                                 $$ = $1;
836                             }
837
838 expr_statement:           ';'
839                             {
840                                 $$ = d3dcompiler_alloc(sizeof(*$$));
841                                 list_init($$);
842                             }
843                         | expr ';'
844                             {
845                                 $$ = d3dcompiler_alloc(sizeof(*$$));
846                                 list_init($$);
847                                 if ($1)
848                                     list_add_head($$, &$1->entry);
849                             }
850
851 primary_expr:             C_FLOAT
852                             {
853                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
854                                 if (!c)
855                                 {
856                                     ERR("Out of memory.\n");
857                                     return -1;
858                                 }
859                                 c->node.type = HLSL_IR_CONSTANT;
860                                 set_location(&c->node.loc, &yylloc);
861                                 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
862                                 c->v.value.f[0] = $1;
863                                 $$ = &c->node;
864                             }
865                         | C_INTEGER
866                             {
867                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
868                                 if (!c)
869                                 {
870                                     ERR("Out of memory.\n");
871                                     return -1;
872                                 }
873                                 c->node.type = HLSL_IR_CONSTANT;
874                                 set_location(&c->node.loc, &yylloc);
875                                 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
876                                 c->v.value.i[0] = $1;
877                                 $$ = &c->node;
878                             }
879                         | boolean
880                             {
881                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
882                                 if (!c)
883                                 {
884                                     ERR("Out of memory.\n");
885                                     return -1;
886                                 }
887                                 c->node.type = HLSL_IR_CONSTANT;
888                                 set_location(&c->node.loc, &yylloc);
889                                 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
890                                 c->v.value.b[0] = $1;
891                                 $$ = &c->node;
892                             }
893                         | variable
894                             {
895                                 struct hlsl_ir_deref *deref = new_var_deref($1);
896                                 if (deref)
897                                 {
898                                     $$ = &deref->node;
899                                     set_location(&$$->loc, &@1);
900                                 }
901                                 else
902                                     $$ = NULL;
903                             }
904                         | '(' expr ')'
905                             {
906                                 $$ = $2;
907                             }
908
909 variable:                 VAR_IDENTIFIER
910                             {
911                                 struct hlsl_ir_var *var;
912                                 var = get_variable(hlsl_ctx.cur_scope, $1);
913                                 if (!var)
914                                 {
915                                     hlsl_message("Line %d: variable '%s' not declared\n",
916                                             hlsl_ctx.line_no, $1);
917                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
918                                     return 1;
919                                 }
920                                 $$ = var;
921                             }
922
923 postfix_expr:             primary_expr
924                             {
925                                 $$ = $1;
926                             }
927                         | postfix_expr OP_INC
928                             {
929                                 struct hlsl_ir_node *operands[3];
930                                 struct source_location loc;
931
932                                 operands[0] = $1;
933                                 operands[1] = operands[2] = NULL;
934                                 set_location(&loc, &@2);
935                                 $$ = &new_expr(HLSL_IR_BINOP_POSTINC, operands, &loc)->node;
936                             }
937                         | postfix_expr OP_DEC
938                             {
939                                 struct hlsl_ir_node *operands[3];
940                                 struct source_location loc;
941
942                                 operands[0] = $1;
943                                 operands[1] = operands[2] = NULL;
944                                 set_location(&loc, &@2);
945                                 $$ = &new_expr(HLSL_IR_BINOP_POSTDEC, operands, &loc)->node;
946                             }
947                           /* "var_modifiers" doesn't make sense in this case, but it's needed
948                              in the grammar to avoid shift/reduce conflicts. */
949                         | var_modifiers type '(' initializer_expr_list ')'
950                             {
951                                 struct hlsl_ir_constructor *constructor;
952
953                                 TRACE("%s constructor.\n", debug_hlsl_type($2));
954                                 if ($1)
955                                 {
956                                     hlsl_message("Line %u: unexpected modifier in a constructor.\n",
957                                             hlsl_ctx.line_no);
958                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
959                                     return -1;
960                                 }
961                                 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
962                                 {
963                                     hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
964                                             hlsl_ctx.line_no);
965                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
966                                     return -1;
967                                 }
968                                 if ($2->dimx * $2->dimy != components_count_expr_list($4))
969                                 {
970                                     hlsl_message("Line %u: wrong number of components in constructor.\n",
971                                             hlsl_ctx.line_no);
972                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
973                                     return -1;
974                                 }
975
976                                 constructor = d3dcompiler_alloc(sizeof(*constructor));
977                                 constructor->node.type = HLSL_IR_CONSTRUCTOR;
978                                 set_location(&constructor->node.loc, &@3);
979                                 constructor->node.data_type = $2;
980                                 constructor->arguments = $4;
981
982                                 $$ = &constructor->node;
983                             }
984
985 unary_expr:               postfix_expr
986                             {
987                                 $$ = $1;
988                             }
989                         | OP_INC unary_expr
990                             {
991                                 struct hlsl_ir_node *operands[3];
992                                 struct source_location loc;
993
994                                 operands[0] = $2;
995                                 operands[1] = operands[2] = NULL;
996                                 set_location(&loc, &@1);
997                                 $$ = &new_expr(HLSL_IR_BINOP_PREINC, operands, &loc)->node;
998                             }
999                         | OP_DEC unary_expr
1000                             {
1001                                 struct hlsl_ir_node *operands[3];
1002                                 struct source_location loc;
1003
1004                                 operands[0] = $2;
1005                                 operands[1] = operands[2] = NULL;
1006                                 set_location(&loc, &@1);
1007                                 $$ = &new_expr(HLSL_IR_BINOP_PREDEC, operands, &loc)->node;
1008                             }
1009                         | unary_op unary_expr
1010                             {
1011                                 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
1012                                         HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
1013                                 struct hlsl_ir_node *operands[3];
1014                                 struct source_location loc;
1015
1016                                 if ($1 == UNARY_OP_PLUS)
1017                                 {
1018                                     $$ = $2;
1019                                 }
1020                                 else
1021                                 {
1022                                     operands[0] = $2;
1023                                     operands[1] = operands[2] = NULL;
1024                                     set_location(&loc, &@1);
1025                                     $$ = &new_expr(ops[$1], operands, &loc)->node;
1026                                 }
1027                             }
1028
1029 unary_op:                 '+'
1030                             {
1031                                 $$ = UNARY_OP_PLUS;
1032                             }
1033                         | '-'
1034                             {
1035                                 $$ = UNARY_OP_MINUS;
1036                             }
1037                         | '!'
1038                             {
1039                                 $$ = UNARY_OP_LOGICNOT;
1040                             }
1041                         | '~'
1042                             {
1043                                 $$ = UNARY_OP_BITNOT;
1044                             }
1045
1046 mul_expr:                 unary_expr
1047                             {
1048                                 $$ = $1;
1049                             }
1050                         | mul_expr '*' unary_expr
1051                             {
1052                                 struct source_location loc;
1053
1054                                 set_location(&loc, &@2);
1055                                 $$ = &hlsl_mul($1, $3, &loc)->node;
1056                             }
1057                         | mul_expr '/' unary_expr
1058                             {
1059                                 struct source_location loc;
1060
1061                                 set_location(&loc, &@2);
1062                                 $$ = &hlsl_div($1, $3, &loc)->node;
1063                             }
1064                         | mul_expr '%' unary_expr
1065                             {
1066                                 struct source_location loc;
1067
1068                                 set_location(&loc, &@2);
1069                                 $$ = &hlsl_mod($1, $3, &loc)->node;
1070                             }
1071
1072 add_expr:                 mul_expr
1073                             {
1074                                 $$ = $1;
1075                             }
1076                         | add_expr '+' mul_expr
1077                             {
1078                                 struct source_location loc;
1079
1080                                 set_location(&loc, &@2);
1081                                 $$ = &hlsl_add($1, $3, &loc)->node;
1082                             }
1083                         | add_expr '-' mul_expr
1084                             {
1085                                 struct source_location loc;
1086
1087                                 set_location(&loc, &@2);
1088                                 $$ = &hlsl_sub($1, $3, &loc)->node;
1089                             }
1090
1091 shift_expr:               add_expr
1092                             {
1093                                 $$ = $1;
1094                             }
1095                         | shift_expr OP_LEFTSHIFT add_expr
1096                             {
1097                                 FIXME("Left shift\n");
1098                             }
1099                         | shift_expr OP_RIGHTSHIFT add_expr
1100                             {
1101                                 FIXME("Right shift\n");
1102                             }
1103
1104 relational_expr:          shift_expr
1105                             {
1106                                 $$ = $1;
1107                             }
1108                         | relational_expr '<' shift_expr
1109                             {
1110                                 struct source_location loc;
1111
1112                                 set_location(&loc, &@2);
1113                                 $$ = &hlsl_lt($1, $3, &loc)->node;
1114                             }
1115                         | relational_expr '>' shift_expr
1116                             {
1117                                 struct source_location loc;
1118
1119                                 set_location(&loc, &@2);
1120                                 $$ = &hlsl_gt($1, $3, &loc)->node;
1121                             }
1122                         | relational_expr OP_LE shift_expr
1123                             {
1124                                 struct source_location loc;
1125
1126                                 set_location(&loc, &@2);
1127                                 $$ = &hlsl_le($1, $3, &loc)->node;
1128                             }
1129                         | relational_expr OP_GE shift_expr
1130                             {
1131                                 struct source_location loc;
1132
1133                                 set_location(&loc, &@2);
1134                                 $$ = &hlsl_ge($1, $3, &loc)->node;
1135                             }
1136
1137 equality_expr:            relational_expr
1138                             {
1139                                 $$ = $1;
1140                             }
1141                         | equality_expr OP_EQ relational_expr
1142                             {
1143                                 struct source_location loc;
1144
1145                                 set_location(&loc, &@2);
1146                                 $$ = &hlsl_eq($1, $3, &loc)->node;
1147                             }
1148                         | equality_expr OP_NE relational_expr
1149                             {
1150                                 struct source_location loc;
1151
1152                                 set_location(&loc, &@2);
1153                                 $$ = &hlsl_ne($1, $3, &loc)->node;
1154                             }
1155
1156 bitand_expr:              equality_expr
1157                             {
1158                                 $$ = $1;
1159                             }
1160                         | bitand_expr '&' equality_expr
1161                             {
1162                                 FIXME("bitwise AND\n");
1163                             }
1164
1165 bitxor_expr:              bitand_expr
1166                             {
1167                                 $$ = $1;
1168                             }
1169                         | bitxor_expr '^' bitand_expr
1170                             {
1171                                 FIXME("bitwise XOR\n");
1172                             }
1173
1174 bitor_expr:               bitxor_expr
1175                             {
1176                                 $$ = $1;
1177                             }
1178                         | bitor_expr '|' bitxor_expr
1179                             {
1180                                 FIXME("bitwise OR\n");
1181                             }
1182
1183 logicand_expr:            bitor_expr
1184                             {
1185                                 $$ = $1;
1186                             }
1187                         | logicand_expr OP_AND bitor_expr
1188                             {
1189                                 FIXME("logic AND\n");
1190                             }
1191
1192 logicor_expr:             logicand_expr
1193                             {
1194                                 $$ = $1;
1195                             }
1196                         | logicor_expr OP_OR logicand_expr
1197                             {
1198                                 FIXME("logic OR\n");
1199                             }
1200
1201 conditional_expr:         logicor_expr
1202                             {
1203                                 $$ = $1;
1204                             }
1205                         | logicor_expr '?' expr ':' assignment_expr
1206                             {
1207                                 FIXME("ternary operator\n");
1208                             }
1209
1210 assignment_expr:          conditional_expr
1211                             {
1212                                 $$ = $1;
1213                             }
1214                         | unary_expr assign_op assignment_expr
1215                             {
1216                                 $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
1217                                 if (!$$)
1218                                     return 1;
1219                                 set_location(&$$->loc, &@2);
1220                             }
1221
1222 assign_op:                '='
1223                             {
1224                                 $$ = ASSIGN_OP_ASSIGN;
1225                             }
1226                         | OP_ADDASSIGN
1227                             {
1228                                 $$ = ASSIGN_OP_ADD;
1229                             }
1230                         | OP_SUBASSIGN
1231                             {
1232                                 $$ = ASSIGN_OP_SUB;
1233                             }
1234                         | OP_MULASSIGN
1235                             {
1236                                 $$ = ASSIGN_OP_MUL;
1237                             }
1238                         | OP_DIVASSIGN
1239                             {
1240                                 $$ = ASSIGN_OP_DIV;
1241                             }
1242                         | OP_MODASSIGN
1243                             {
1244                                 $$ = ASSIGN_OP_MOD;
1245                             }
1246                         | OP_LEFTSHIFTASSIGN
1247                             {
1248                                 $$ = ASSIGN_OP_LSHIFT;
1249                             }
1250                         | OP_RIGHTSHIFTASSIGN
1251                             {
1252                                 $$ = ASSIGN_OP_RSHIFT;
1253                             }
1254                         | OP_ANDASSIGN
1255                             {
1256                                 $$ = ASSIGN_OP_AND;
1257                             }
1258                         | OP_ORASSIGN
1259                             {
1260                                 $$ = ASSIGN_OP_OR;
1261                             }
1262                         | OP_XORASSIGN
1263                             {
1264                                 $$ = ASSIGN_OP_XOR;
1265                             }
1266
1267 expr:                     assignment_expr
1268                             {
1269                                 $$ = $1;
1270                             }
1271                         | expr ',' assignment_expr
1272                             {
1273                                 FIXME("Comma expression\n");
1274                             }
1275
1276 %%
1277
1278 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
1279 {
1280     loc->file = hlsl_ctx.source_file;
1281     loc->line = l->first_line;
1282     loc->col = l->first_column;
1283 }
1284
1285 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
1286 {
1287     if (modifiers & mod)
1288     {
1289         hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
1290                 "modifier '%s' already specified", debug_modifiers(mod));
1291         return modifiers;
1292     }
1293     if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
1294             && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
1295     {
1296         hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
1297                 "more than one matrix majority keyword");
1298         return modifiers;
1299     }
1300     return modifiers | mod;
1301 }
1302
1303 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
1304         const char *entrypoint, char **messages)
1305 {
1306     struct hlsl_ir_function_decl *function;
1307     struct hlsl_scope *scope, *next_scope;
1308     struct hlsl_type *hlsl_type, *next_type;
1309     struct hlsl_ir_var *var, *next_var;
1310     unsigned int i;
1311
1312     hlsl_ctx.status = PARSE_SUCCESS;
1313     hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
1314     hlsl_ctx.line_no = hlsl_ctx.column = 1;
1315     hlsl_ctx.source_file = d3dcompiler_strdup("");
1316     hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
1317     if (hlsl_ctx.source_files)
1318         hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
1319     hlsl_ctx.source_files_count = 1;
1320     hlsl_ctx.cur_scope = NULL;
1321     hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
1322     list_init(&hlsl_ctx.scopes);
1323     list_init(&hlsl_ctx.types);
1324     list_init(&hlsl_ctx.functions);
1325
1326     push_scope(&hlsl_ctx);
1327     hlsl_ctx.globals = hlsl_ctx.cur_scope;
1328
1329     hlsl_parse();
1330
1331     if (TRACE_ON(hlsl_parser))
1332     {
1333         struct hlsl_ir_function_decl *func;
1334
1335         TRACE("IR dump.\n");
1336         LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1337         {
1338             if (func->body)
1339                 debug_dump_ir_function(func);
1340         }
1341     }
1342
1343     TRACE("Compilation status = %d\n", hlsl_ctx.status);
1344     if (messages)
1345     {
1346         if (hlsl_ctx.messages.size)
1347             *messages = hlsl_ctx.messages.string;
1348         else
1349             *messages = NULL;
1350     }
1351     else
1352     {
1353         if (hlsl_ctx.messages.capacity)
1354             d3dcompiler_free(hlsl_ctx.messages.string);
1355     }
1356
1357     for (i = 0; i < hlsl_ctx.source_files_count; ++i)
1358         d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
1359     d3dcompiler_free(hlsl_ctx.source_files);
1360
1361     TRACE("Freeing functions IR.\n");
1362     LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1363         free_function(function);
1364
1365     TRACE("Freeing variables.\n");
1366     LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
1367     {
1368         LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
1369         {
1370             free_declaration(var);
1371         }
1372         d3dcompiler_free(scope);
1373     }
1374
1375     TRACE("Freeing types.\n");
1376     LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
1377     {
1378         free_hlsl_type(hlsl_type);
1379     }
1380
1381     return NULL;
1382 }