d3dcompiler: Store location information in constants, variable dereferences and const...
[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 BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
113 {
114     BOOL ret;
115
116     TRACE("Declaring variable %s.\n", decl->name);
117     if (decl->node.data_type->type == HLSL_CLASS_MATRIX)
118     {
119         if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)))
120         {
121             decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR
122                     ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR;
123         }
124     }
125     if (local)
126     {
127         DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
128                 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
129         if (invalid)
130         {
131             hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
132                     "modifier '%s' invalid for local variables", debug_modifiers(invalid));
133         }
134     }
135     ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
136     if (ret == FALSE)
137     {
138         struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
139
140         hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
141                 "\"%s\" already declared", decl->name);
142         hlsl_report_message(old->node.loc.file, old->node.loc.line, old->node.loc.col, HLSL_LEVEL_NOTE,
143                 "\"%s\" was previously declared here", old->name);
144         return FALSE;
145     }
146     return TRUE;
147 }
148
149 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc);
150
151 static unsigned int components_count_expr_list(struct list *list)
152 {
153     struct hlsl_ir_node *node;
154     unsigned int count = 0;
155
156     LIST_FOR_EACH_ENTRY(node, list, struct hlsl_ir_node, entry)
157     {
158         count += components_count_type(node->data_type);
159     }
160     return count;
161 }
162
163 %}
164
165 %locations
166 %error-verbose
167
168 %union
169 {
170     struct hlsl_type *type;
171     INT intval;
172     FLOAT floatval;
173     BOOL boolval;
174     char *name;
175     DWORD modifiers;
176     struct hlsl_ir_var *var;
177     struct hlsl_ir_node *instr;
178     struct list *list;
179     struct hlsl_ir_function_decl *function;
180     struct parse_parameter parameter;
181     struct parse_variable_def *variable_def;
182 }
183
184 %token KW_BLENDSTATE
185 %token KW_BREAK
186 %token KW_BUFFER
187 %token KW_CBUFFER
188 %token KW_COLUMN_MAJOR
189 %token KW_COMPILE
190 %token KW_CONST
191 %token KW_CONTINUE
192 %token KW_DEPTHSTENCILSTATE
193 %token KW_DEPTHSTENCILVIEW
194 %token KW_DISCARD
195 %token KW_DO
196 %token KW_DOUBLE
197 %token KW_ELSE
198 %token KW_EXTERN
199 %token KW_FALSE
200 %token KW_FOR
201 %token KW_GEOMETRYSHADER
202 %token KW_GROUPSHARED
203 %token KW_IF
204 %token KW_IN
205 %token KW_INLINE
206 %token KW_INOUT
207 %token KW_MATRIX
208 %token KW_NAMESPACE
209 %token KW_NOINTERPOLATION
210 %token KW_OUT
211 %token KW_PASS
212 %token KW_PIXELSHADER
213 %token KW_PRECISE
214 %token KW_RASTERIZERSTATE
215 %token KW_RENDERTARGETVIEW
216 %token KW_RETURN
217 %token KW_REGISTER
218 %token KW_ROW_MAJOR
219 %token KW_SAMPLER
220 %token KW_SAMPLER1D
221 %token KW_SAMPLER2D
222 %token KW_SAMPLER3D
223 %token KW_SAMPLERCUBE
224 %token KW_SAMPLER_STATE
225 %token KW_SAMPLERCOMPARISONSTATE
226 %token KW_SHARED
227 %token KW_STATEBLOCK
228 %token KW_STATEBLOCK_STATE
229 %token KW_STATIC
230 %token KW_STRING
231 %token KW_STRUCT
232 %token KW_SWITCH
233 %token KW_TBUFFER
234 %token KW_TECHNIQUE
235 %token KW_TECHNIQUE10
236 %token KW_TEXTURE
237 %token KW_TEXTURE1D
238 %token KW_TEXTURE1DARRAY
239 %token KW_TEXTURE2D
240 %token KW_TEXTURE2DARRAY
241 %token KW_TEXTURE2DMS
242 %token KW_TEXTURE2DMSARRAY
243 %token KW_TEXTURE3D
244 %token KW_TEXTURE3DARRAY
245 %token KW_TEXTURECUBE
246 %token KW_TRUE
247 %token KW_TYPEDEF
248 %token KW_UNIFORM
249 %token KW_VECTOR
250 %token KW_VERTEXSHADER
251 %token KW_VOID
252 %token KW_VOLATILE
253 %token KW_WHILE
254
255 %token OP_INC
256 %token OP_DEC
257 %token OP_AND
258 %token OP_OR
259 %token OP_EQ
260 %token OP_LEFTSHIFT
261 %token OP_LEFTSHIFTASSIGN
262 %token OP_RIGHTSHIFT
263 %token OP_RIGHTSHIFTASSIGN
264 %token OP_ELLIPSIS
265 %token OP_LE
266 %token OP_GE
267 %token OP_NE
268 %token OP_ADDASSIGN
269 %token OP_SUBASSIGN
270 %token OP_MULASSIGN
271 %token OP_DIVASSIGN
272 %token OP_MODASSIGN
273 %token OP_ANDASSIGN
274 %token OP_ORASSIGN
275 %token OP_XORASSIGN
276 %token OP_UNKNOWN1
277 %token OP_UNKNOWN2
278 %token OP_UNKNOWN3
279 %token OP_UNKNOWN4
280
281 %token <intval> PRE_LINE
282
283 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
284 %type <name> any_identifier var_identifier
285 %token <name> STRING
286 %token <floatval> C_FLOAT
287 %token <intval> C_INTEGER
288 %type <boolval> boolean
289 %type <type> base_type
290 %type <type> type
291 %type <list> declaration_statement
292 %type <list> complex_initializer
293 %type <list> initializer_expr_list
294 %type <instr> initializer_expr
295 %type <modifiers> var_modifiers
296 %type <list> parameters
297 %type <list> param_list
298 %type <instr> expr
299 %type <var> variable
300 %type <intval> array
301 %type <list> statement
302 %type <list> statement_list
303 %type <list> compound_statement
304 %type <function> func_declaration
305 %type <function> func_prototype
306 %type <parameter> parameter
307 %type <name> semantic
308 %type <variable_def> variable_def
309 %type <list> variables_def
310 %type <instr> primary_expr
311 %type <instr> postfix_expr
312 %type <instr> unary_expr
313 %type <instr> mul_expr
314 %type <instr> add_expr
315 %type <instr> shift_expr
316 %type <instr> relational_expr
317 %type <instr> equality_expr
318 %type <instr> bitand_expr
319 %type <instr> bitxor_expr
320 %type <instr> bitor_expr
321 %type <instr> logicand_expr
322 %type <instr> logicor_expr
323 %type <instr> conditional_expr
324 %type <instr> assignment_expr
325 %type <list> expr_statement
326 %type <modifiers> input_mod
327 %%
328
329 hlsl_prog:                /* empty */
330                             {
331                             }
332                         | hlsl_prog func_declaration
333                             {
334                                 FIXME("Check that the function doesn't conflict with an already declared one.\n");
335                                 list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
336                             }
337                         | hlsl_prog declaration_statement
338                             {
339                                 TRACE("Declaration statement parsed.\n");
340                             }
341                         | hlsl_prog preproc_directive
342                             {
343                             }
344
345 preproc_directive:        PRE_LINE STRING
346                             {
347                                 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
348                                 hlsl_ctx.line_no = $1;
349                                 if (strcmp($2, hlsl_ctx.source_file))
350                                 {
351                                     const char **new_array;
352
353                                     hlsl_ctx.source_file = $2;
354                                     new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
355                                             sizeof(*hlsl_ctx.source_files) * hlsl_ctx.source_files_count + 1);
356                                     if (new_array)
357                                     {
358                                         hlsl_ctx.source_files = new_array;
359                                         hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
360                                     }
361                                 }
362                             }
363
364 any_identifier:           VAR_IDENTIFIER
365                         | TYPE_IDENTIFIER
366                         | NEW_IDENTIFIER
367
368 func_declaration:         func_prototype compound_statement
369                             {
370                                 TRACE("Function %s parsed.\n", $1->name);
371                                 $$ = $1;
372                                 $$->body = $2;
373                                 pop_scope(&hlsl_ctx);
374                             }
375                         | func_prototype ';'
376                             {
377                                 TRACE("Function prototype for %s.\n", $1->name);
378                                 $$ = $1;
379                                 pop_scope(&hlsl_ctx);
380                             }
381
382 func_prototype:           var_modifiers type var_identifier '(' parameters ')' semantic
383                             {
384                                 $$ = new_func_decl($3, $2, $5);
385                                 if (!$$)
386                                 {
387                                     ERR("Out of memory.\n");
388                                     return -1;
389                                 }
390                                 $$->semantic = $7;
391                             }
392
393 compound_statement:       '{' '}'
394                             {
395                                 $$ = d3dcompiler_alloc(sizeof(*$$));
396                                 list_init($$);
397                             }
398                         | '{' scope_start statement_list '}'
399                             {
400                                 pop_scope(&hlsl_ctx);
401                                 $$ = $3;
402                             }
403
404 scope_start:              /* Empty */
405                             {
406                                 push_scope(&hlsl_ctx);
407                             }
408
409 var_identifier:           VAR_IDENTIFIER
410                         | NEW_IDENTIFIER
411
412 semantic:                 /* Empty */
413                             {
414                                 $$ = NULL;
415                             }
416                         | ':' any_identifier
417                             {
418                                 $$ = $2;
419                             }
420
421 parameters:               scope_start
422                             {
423                                 $$ = d3dcompiler_alloc(sizeof(*$$));
424                                 list_init($$);
425                             }
426                         | scope_start param_list
427                             {
428                                 $$ = $2;
429                             }
430
431 param_list:               parameter
432                             {
433                                 $$ = d3dcompiler_alloc(sizeof(*$$));
434                                 list_init($$);
435                                 if (!add_func_parameter($$, &$1, hlsl_ctx.line_no))
436                                 {
437                                     ERR("Error adding function parameter %s.\n", $1.name);
438                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
439                                     return -1;
440                                 }
441                             }
442                         | param_list ',' parameter
443                             {
444                                 $$ = $1;
445                                 if (!add_func_parameter($$, &$3, hlsl_ctx.line_no))
446                                 {
447                                     hlsl_message("Line %u: duplicate parameter %s.\n",
448                                             hlsl_ctx.line_no, $3.name);
449                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
450                                     return 1;
451                                 }
452                             }
453
454 parameter:                input_mod var_modifiers type any_identifier semantic
455                             {
456                                 $$.modifiers = $1;
457                                 $$.modifiers |= $2;
458                                 $$.type = $3;
459                                 $$.name = $4;
460                                 $$.semantic = $5;
461                             }
462
463 input_mod:                /* Empty */
464                             {
465                                 $$ = HLSL_MODIFIER_IN;
466                             }
467                         | KW_IN
468                             {
469                                 $$ = HLSL_MODIFIER_IN;
470                             }
471                         | KW_OUT
472                             {
473                                 $$ = HLSL_MODIFIER_OUT;
474                             }
475                         | KW_INOUT
476                             {
477                                 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
478                             }
479
480 type:                     base_type
481                             {
482                                 $$ = $1;
483                             }
484                         | KW_VECTOR '<' base_type ',' C_INTEGER '>'
485                             {
486                                 if ($3->type != HLSL_CLASS_SCALAR)
487                                 {
488                                     hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
489                                             hlsl_ctx.line_no);
490                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
491                                     return 1;
492                                 }
493                                 if ($5 < 1 || $5 > 4)
494                                 {
495                                     hlsl_message("Line %u: vector size must be between 1 and 4.\n",
496                                             hlsl_ctx.line_no);
497                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
498                                     return 1;
499                                 }
500
501                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
502                             }
503                         | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
504                             {
505                                 if ($3->type != HLSL_CLASS_SCALAR)
506                                 {
507                                     hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
508                                             hlsl_ctx.line_no);
509                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
510                                     return 1;
511                                 }
512                                 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
513                                 {
514                                     hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
515                                             hlsl_ctx.line_no);
516                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
517                                     return 1;
518                                 }
519
520                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
521                             }
522
523 base_type:                KW_VOID
524                             {
525                                 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_SCALAR, HLSL_TYPE_VOID, 1, 1);
526                             }
527                         | KW_SAMPLER
528                             {
529                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
530                                 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
531                             }
532                         | KW_SAMPLER1D
533                             {
534                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
535                                 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
536                             }
537                         | KW_SAMPLER2D
538                             {
539                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
540                                 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
541                             }
542                         | KW_SAMPLER3D
543                             {
544                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
545                                 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
546                             }
547                         | KW_SAMPLERCUBE
548                             {
549                                 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
550                                 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
551                             }
552                         | TYPE_IDENTIFIER
553                             {
554                                 struct hlsl_type *type;
555
556                                 TRACE("Type %s.\n", $1);
557                                 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
558                                 $$ = type;
559                                 d3dcompiler_free($1);
560                             }
561                         | KW_STRUCT TYPE_IDENTIFIER
562                             {
563                                 struct hlsl_type *type;
564
565                                 TRACE("Struct type %s.\n", $2);
566                                 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
567                                 if (type->type != HLSL_CLASS_STRUCT)
568                                 {
569                                     hlsl_message("Line %u: redefining %s as a structure.\n",
570                                             hlsl_ctx.line_no, $2);
571                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
572                                 }
573                                 else
574                                 {
575                                     $$ = type;
576                                 }
577                                 d3dcompiler_free($2);
578                             }
579
580 declaration_statement:    declaration
581                             {
582                                 $$ = d3dcompiler_alloc(sizeof(*$$));
583                                 list_init($$);
584                             }
585
586 declaration:              var_modifiers type variables_def ';'
587                             {
588                                 struct parse_variable_def *v, *v_next;
589                                 struct hlsl_ir_var *var;
590                                 BOOL ret, local = TRUE;
591
592                                 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
593                                 {
594                                     debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
595                                     var = d3dcompiler_alloc(sizeof(*var));
596                                     var->node.type = HLSL_IR_VAR;
597                                     if (v->array_size)
598                                         var->node.data_type = new_array_type($2, v->array_size);
599                                     else
600                                         var->node.data_type = $2;
601                                     var->node.loc = v->loc;
602                                     var->name = v->name;
603                                     var->modifiers = $1;
604                                     var->semantic = v->semantic;
605                                     if (v->initializer)
606                                     {
607                                         FIXME("Variable with an initializer.\n");
608                                         free_instr_list(v->initializer);
609                                     }
610
611                                     if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
612                                     {
613                                         var->modifiers |= HLSL_STORAGE_UNIFORM;
614                                         local = FALSE;
615                                     }
616
617                                     ret = declare_variable(var, local);
618                                     if (ret == FALSE)
619                                         free_declaration(var);
620                                     else
621                                         TRACE("Declared variable %s.\n", var->name);
622                                     d3dcompiler_free(v);
623                                 }
624                                 d3dcompiler_free($3);
625                             }
626
627 variables_def:            variable_def
628                             {
629                                 $$ = d3dcompiler_alloc(sizeof(*$$));
630                                 list_init($$);
631                                 list_add_head($$, &$1->entry);
632                             }
633                         | variables_def ',' variable_def
634                             {
635                                 $$ = $1;
636                                 list_add_tail($$, &$3->entry);
637                             }
638
639                           /* FIXME: Local variables can't have semantics. */
640 variable_def:             any_identifier array semantic
641                             {
642                                 $$ = d3dcompiler_alloc(sizeof(*$$));
643                                 set_location(&$$->loc, &@1);
644                                 $$->name = $1;
645                                 $$->array_size = $2;
646                                 $$->semantic = $3;
647                             }
648                         | any_identifier array semantic '=' complex_initializer
649                             {
650                                 TRACE("Declaration with initializer.\n");
651                                 $$ = d3dcompiler_alloc(sizeof(*$$));
652                                 set_location(&$$->loc, &@1);
653                                 $$->name = $1;
654                                 $$->array_size = $2;
655                                 $$->semantic = $3;
656                                 $$->initializer = $5;
657                             }
658
659 array:                    /* Empty */
660                             {
661                                 $$ = 0;
662                             }
663                         | '[' expr ']'
664                             {
665                                 FIXME("Array.\n");
666                                 $$ = 0;
667                                 free_instr($2);
668                             }
669
670 var_modifiers:            /* Empty */
671                             {
672                                 $$ = 0;
673                             }
674                         | KW_EXTERN var_modifiers
675                             {
676                                 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
677                             }
678                         | KW_NOINTERPOLATION var_modifiers
679                             {
680                                 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
681                             }
682                         | KW_PRECISE var_modifiers
683                             {
684                                 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
685                             }
686                         | KW_SHARED var_modifiers
687                             {
688                                 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
689                             }
690                         | KW_GROUPSHARED var_modifiers
691                             {
692                                 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
693                             }
694                         | KW_STATIC var_modifiers
695                             {
696                                 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
697                             }
698                         | KW_UNIFORM var_modifiers
699                             {
700                                 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
701                             }
702                         | KW_VOLATILE var_modifiers
703                             {
704                                 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
705                             }
706                         | KW_CONST var_modifiers
707                             {
708                                 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
709                             }
710                         | KW_ROW_MAJOR var_modifiers
711                             {
712                                 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
713                             }
714                         | KW_COLUMN_MAJOR var_modifiers
715                             {
716                                 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
717                             }
718
719 complex_initializer:      initializer_expr
720                             {
721                                 $$ = d3dcompiler_alloc(sizeof(*$$));
722                                 list_init($$);
723                                 list_add_head($$, &$1->entry);
724                             }
725                         | '{' initializer_expr_list '}'
726                             {
727                                 $$ = $2;
728                             }
729
730 initializer_expr:         assignment_expr
731                             {
732                                 $$ = $1;
733                             }
734
735 initializer_expr_list:    initializer_expr
736                             {
737                                 $$ = d3dcompiler_alloc(sizeof(*$$));
738                                 list_init($$);
739                                 list_add_head($$, &$1->entry);
740                             }
741                         | initializer_expr_list ',' initializer_expr
742                             {
743                                 $$ = $1;
744                                 list_add_tail($$, &$3->entry);
745                             }
746
747 boolean:                  KW_TRUE
748                             {
749                                 $$ = TRUE;
750                             }
751                         | KW_FALSE
752                             {
753                                 $$ = FALSE;
754                             }
755
756 statement_list:           statement
757                             {
758                                 $$ = $1;
759                             }
760                         | statement_list statement
761                             {
762                                 $$ = $1;
763                                 list_move_tail($$, $2);
764                                 d3dcompiler_free($2);
765                             }
766
767 statement:                declaration_statement
768                             {
769                                 $$ = $1;
770                             }
771                         | expr_statement
772                             {
773                                 $$ = $1;
774                             }
775                         | compound_statement
776                             {
777                                 $$ = $1;
778                             }
779
780 expr_statement:           ';'
781                             {
782                                 $$ = d3dcompiler_alloc(sizeof(*$$));
783                                 list_init($$);
784                             }
785                         | expr ';'
786                             {
787                                 $$ = d3dcompiler_alloc(sizeof(*$$));
788                                 list_init($$);
789                                 if ($1)
790                                     list_add_head($$, &$1->entry);
791                             }
792
793 primary_expr:             C_FLOAT
794                             {
795                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
796                                 if (!c)
797                                 {
798                                     ERR("Out of memory.\n");
799                                     return -1;
800                                 }
801                                 c->node.type = HLSL_IR_CONSTANT;
802                                 set_location(&c->node.loc, &yylloc);
803                                 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
804                                 c->v.value.f[0] = $1;
805                                 $$ = &c->node;
806                             }
807                         | C_INTEGER
808                             {
809                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
810                                 if (!c)
811                                 {
812                                     ERR("Out of memory.\n");
813                                     return -1;
814                                 }
815                                 c->node.type = HLSL_IR_CONSTANT;
816                                 set_location(&c->node.loc, &yylloc);
817                                 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
818                                 c->v.value.i[0] = $1;
819                                 $$ = &c->node;
820                             }
821                         | boolean
822                             {
823                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
824                                 if (!c)
825                                 {
826                                     ERR("Out of memory.\n");
827                                     return -1;
828                                 }
829                                 c->node.type = HLSL_IR_CONSTANT;
830                                 set_location(&c->node.loc, &yylloc);
831                                 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
832                                 c->v.value.b[0] = $1;
833                                 $$ = &c->node;
834                             }
835                         | variable
836                             {
837                                 struct hlsl_ir_deref *deref = new_var_deref($1);
838                                 if (deref)
839                                 {
840                                     $$ = &deref->node;
841                                     set_location(&$$->loc, &@1);
842                                 }
843                                 else
844                                     $$ = NULL;
845                             }
846                         | '(' expr ')'
847                             {
848                                 $$ = $2;
849                             }
850
851 variable:                 VAR_IDENTIFIER
852                             {
853                                 struct hlsl_ir_var *var;
854                                 var = get_variable(hlsl_ctx.cur_scope, $1);
855                                 if (!var)
856                                 {
857                                     hlsl_message("Line %d: variable '%s' not declared\n",
858                                             hlsl_ctx.line_no, $1);
859                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
860                                     return 1;
861                                 }
862                                 $$ = var;
863                             }
864
865 postfix_expr:             primary_expr
866                             {
867                                 $$ = $1;
868                             }
869                           /* "var_modifiers" doesn't make sense in this case, but it's needed
870                              in the grammar to avoid shift/reduce conflicts. */
871                         | var_modifiers type '(' initializer_expr_list ')'
872                             {
873                                 struct hlsl_ir_constructor *constructor;
874
875                                 TRACE("%s constructor.\n", debug_hlsl_type($2));
876                                 if ($1)
877                                 {
878                                     hlsl_message("Line %u: unexpected modifier in a constructor.\n",
879                                             hlsl_ctx.line_no);
880                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
881                                     return -1;
882                                 }
883                                 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
884                                 {
885                                     hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
886                                             hlsl_ctx.line_no);
887                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
888                                     return -1;
889                                 }
890                                 if ($2->dimx * $2->dimy != components_count_expr_list($4))
891                                 {
892                                     hlsl_message("Line %u: wrong number of components in constructor.\n",
893                                             hlsl_ctx.line_no);
894                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
895                                     return -1;
896                                 }
897
898                                 constructor = d3dcompiler_alloc(sizeof(*constructor));
899                                 constructor->node.type = HLSL_IR_CONSTRUCTOR;
900                                 set_location(&constructor->node.loc, &@3);
901                                 constructor->node.data_type = $2;
902                                 constructor->arguments = $4;
903
904                                 $$ = &constructor->node;
905                             }
906
907 unary_expr:               postfix_expr
908                             {
909                                 $$ = $1;
910                             }
911
912 mul_expr:                 unary_expr
913                             {
914                                 $$ = $1;
915                             }
916
917 add_expr:                 mul_expr
918                             {
919                                 $$ = $1;
920                             }
921
922 shift_expr:               add_expr
923                             {
924                                 $$ = $1;
925                             }
926
927 relational_expr:          shift_expr
928                             {
929                                 $$ = $1;
930                             }
931
932 equality_expr:            relational_expr
933                             {
934                                 $$ = $1;
935                             }
936
937 bitand_expr:              equality_expr
938                             {
939                                 $$ = $1;
940                             }
941
942 bitxor_expr:              bitand_expr
943                             {
944                                 $$ = $1;
945                             }
946
947 bitor_expr:               bitxor_expr
948                             {
949                                 $$ = $1;
950                             }
951
952 logicand_expr:            bitor_expr
953                             {
954                                 $$ = $1;
955                             }
956
957 logicor_expr:             logicand_expr
958                             {
959                                 $$ = $1;
960                             }
961
962 conditional_expr:         logicor_expr
963                             {
964                                 $$ = $1;
965                             }
966
967 assignment_expr:          conditional_expr
968                             {
969                                 $$ = $1;
970                             }
971
972 expr:                     assignment_expr
973                             {
974                                 $$ = $1;
975                             }
976                         | expr ',' assignment_expr
977                             {
978                                 FIXME("Comma expression\n");
979                             }
980
981 %%
982
983 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
984 {
985     loc->file = hlsl_ctx.source_file;
986     loc->line = l->first_line;
987     loc->col = l->first_column;
988 }
989
990 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
991 {
992     if (modifiers & mod)
993     {
994         hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
995                 "modifier '%s' already specified", debug_modifiers(mod));
996         return modifiers;
997     }
998     if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
999             && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
1000     {
1001         hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
1002                 "more than one matrix majority keyword");
1003         return modifiers;
1004     }
1005     return modifiers | mod;
1006 }
1007
1008 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
1009         const char *entrypoint, char **messages)
1010 {
1011     struct hlsl_ir_function_decl *function;
1012     struct hlsl_scope *scope, *next_scope;
1013     struct hlsl_type *hlsl_type, *next_type;
1014     struct hlsl_ir_var *var, *next_var;
1015     unsigned int i;
1016
1017     hlsl_ctx.status = PARSE_SUCCESS;
1018     hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
1019     hlsl_ctx.line_no = hlsl_ctx.column = 1;
1020     hlsl_ctx.source_file = d3dcompiler_strdup("");
1021     hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
1022     if (hlsl_ctx.source_files)
1023         hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
1024     hlsl_ctx.source_files_count = 1;
1025     hlsl_ctx.cur_scope = NULL;
1026     hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
1027     list_init(&hlsl_ctx.scopes);
1028     list_init(&hlsl_ctx.types);
1029     list_init(&hlsl_ctx.functions);
1030
1031     push_scope(&hlsl_ctx);
1032     hlsl_ctx.globals = hlsl_ctx.cur_scope;
1033
1034     hlsl_parse();
1035
1036     if (TRACE_ON(hlsl_parser))
1037     {
1038         struct hlsl_ir_function_decl *func;
1039
1040         TRACE("IR dump.\n");
1041         LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1042         {
1043             if (func->body)
1044                 debug_dump_ir_function(func);
1045         }
1046     }
1047
1048     TRACE("Compilation status = %d\n", hlsl_ctx.status);
1049     if (messages)
1050     {
1051         if (hlsl_ctx.messages.size)
1052             *messages = hlsl_ctx.messages.string;
1053         else
1054             *messages = NULL;
1055     }
1056     else
1057     {
1058         if (hlsl_ctx.messages.capacity)
1059             d3dcompiler_free(hlsl_ctx.messages.string);
1060     }
1061
1062     for (i = 0; i < hlsl_ctx.source_files_count; ++i)
1063         d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
1064     d3dcompiler_free(hlsl_ctx.source_files);
1065
1066     TRACE("Freeing functions IR.\n");
1067     LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1068         free_function(function);
1069
1070     TRACE("Freeing variables.\n");
1071     LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
1072     {
1073         LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
1074         {
1075             free_declaration(var);
1076         }
1077         d3dcompiler_free(scope);
1078     }
1079
1080     TRACE("Freeing types.\n");
1081     LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
1082     {
1083         free_hlsl_type(hlsl_type);
1084     }
1085
1086     return NULL;
1087 }