d3dcompiler: Variables and functions can't have the same name.
[wine/multimedia.git] / dlls / d3dcompiler_43 / hlsl.y
blobeedf357b3d91eb462996f52c1061e800756bf0e3
1 /*
2 * HLSL parser
4 * Copyright 2008 Stefan Dösinger
5 * Copyright 2012 Matteo Bruni for CodeWeavers
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.
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.
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
22 #include "config.h"
23 #include "wine/debug.h"
25 #include <stdio.h>
27 #include "d3dcompiler_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser);
31 int hlsl_lex(void);
33 struct hlsl_parse_ctx hlsl_ctx;
35 struct YYLTYPE;
36 static void set_location(struct source_location *loc, const struct YYLTYPE *l);
38 void hlsl_message(const char *fmt, ...)
40 va_list args;
42 va_start(args, fmt);
43 compilation_message(&hlsl_ctx.messages, fmt, args);
44 va_end(args);
47 static const char *hlsl_get_error_level_name(enum hlsl_error_level level)
49 const char *names[] =
51 "error",
52 "warning",
53 "note",
55 return names[level];
58 void hlsl_report_message(const char *filename, DWORD line, DWORD column,
59 enum hlsl_error_level level, const char *fmt, ...)
61 va_list args;
62 char *string = NULL;
63 int rc, size = 0;
65 while (1)
67 va_start(args, fmt);
68 rc = vsnprintf(string, size, fmt, args);
69 va_end(args);
71 if (rc >= 0 && rc < size)
72 break;
74 if (rc >= size)
75 size = rc + 1;
76 else
77 size = size ? size * 2 : 32;
79 if (!string)
80 string = d3dcompiler_alloc(size);
81 else
82 string = d3dcompiler_realloc(string, size);
83 if (!string)
85 ERR("Error reallocating memory for a string.\n");
86 return;
90 hlsl_message("%s:%u:%u: %s: %s\n", filename, line, column, hlsl_get_error_level_name(level), string);
91 d3dcompiler_free(string);
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);
99 static void hlsl_error(const char *s)
101 hlsl_report_message(hlsl_ctx.source_file, hlsl_ctx.line_no, hlsl_ctx.column, HLSL_LEVEL_ERROR, "%s", s);
104 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
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);
112 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
114 BOOL ret;
116 TRACE("Declaring variable %s.\n", decl->name);
117 if (decl->node.data_type->type == HLSL_CLASS_MATRIX)
119 if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)))
121 decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR
122 ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR;
125 if (local)
127 DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
128 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
129 if (invalid)
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));
135 else
137 if (find_function(decl->name))
139 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
140 "redefinition of '%s'", decl->name);
141 return FALSE;
144 ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
145 if (!ret)
147 struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
149 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
150 "\"%s\" already declared", decl->name);
151 hlsl_report_message(old->node.loc.file, old->node.loc.line, old->node.loc.col, HLSL_LEVEL_NOTE,
152 "\"%s\" was previously declared here", old->name);
153 return FALSE;
155 return TRUE;
158 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc);
160 static unsigned int components_count_expr_list(struct list *list)
162 struct hlsl_ir_node *node;
163 unsigned int count = 0;
165 LIST_FOR_EACH_ENTRY(node, list, struct hlsl_ir_node, entry)
167 count += components_count_type(node->data_type);
169 return count;
174 %locations
175 %error-verbose
177 %union
179 struct hlsl_type *type;
180 INT intval;
181 FLOAT floatval;
182 BOOL boolval;
183 char *name;
184 DWORD modifiers;
185 struct hlsl_ir_var *var;
186 struct hlsl_ir_node *instr;
187 struct list *list;
188 struct hlsl_ir_function_decl *function;
189 struct parse_parameter parameter;
190 struct parse_variable_def *variable_def;
193 %token KW_BLENDSTATE
194 %token KW_BREAK
195 %token KW_BUFFER
196 %token KW_CBUFFER
197 %token KW_COLUMN_MAJOR
198 %token KW_COMPILE
199 %token KW_CONST
200 %token KW_CONTINUE
201 %token KW_DEPTHSTENCILSTATE
202 %token KW_DEPTHSTENCILVIEW
203 %token KW_DISCARD
204 %token KW_DO
205 %token KW_DOUBLE
206 %token KW_ELSE
207 %token KW_EXTERN
208 %token KW_FALSE
209 %token KW_FOR
210 %token KW_GEOMETRYSHADER
211 %token KW_GROUPSHARED
212 %token KW_IF
213 %token KW_IN
214 %token KW_INLINE
215 %token KW_INOUT
216 %token KW_MATRIX
217 %token KW_NAMESPACE
218 %token KW_NOINTERPOLATION
219 %token KW_OUT
220 %token KW_PASS
221 %token KW_PIXELSHADER
222 %token KW_PRECISE
223 %token KW_RASTERIZERSTATE
224 %token KW_RENDERTARGETVIEW
225 %token KW_RETURN
226 %token KW_REGISTER
227 %token KW_ROW_MAJOR
228 %token KW_SAMPLER
229 %token KW_SAMPLER1D
230 %token KW_SAMPLER2D
231 %token KW_SAMPLER3D
232 %token KW_SAMPLERCUBE
233 %token KW_SAMPLER_STATE
234 %token KW_SAMPLERCOMPARISONSTATE
235 %token KW_SHARED
236 %token KW_STATEBLOCK
237 %token KW_STATEBLOCK_STATE
238 %token KW_STATIC
239 %token KW_STRING
240 %token KW_STRUCT
241 %token KW_SWITCH
242 %token KW_TBUFFER
243 %token KW_TECHNIQUE
244 %token KW_TECHNIQUE10
245 %token KW_TEXTURE
246 %token KW_TEXTURE1D
247 %token KW_TEXTURE1DARRAY
248 %token KW_TEXTURE2D
249 %token KW_TEXTURE2DARRAY
250 %token KW_TEXTURE2DMS
251 %token KW_TEXTURE2DMSARRAY
252 %token KW_TEXTURE3D
253 %token KW_TEXTURE3DARRAY
254 %token KW_TEXTURECUBE
255 %token KW_TRUE
256 %token KW_TYPEDEF
257 %token KW_UNIFORM
258 %token KW_VECTOR
259 %token KW_VERTEXSHADER
260 %token KW_VOID
261 %token KW_VOLATILE
262 %token KW_WHILE
264 %token OP_INC
265 %token OP_DEC
266 %token OP_AND
267 %token OP_OR
268 %token OP_EQ
269 %token OP_LEFTSHIFT
270 %token OP_LEFTSHIFTASSIGN
271 %token OP_RIGHTSHIFT
272 %token OP_RIGHTSHIFTASSIGN
273 %token OP_ELLIPSIS
274 %token OP_LE
275 %token OP_GE
276 %token OP_NE
277 %token OP_ADDASSIGN
278 %token OP_SUBASSIGN
279 %token OP_MULASSIGN
280 %token OP_DIVASSIGN
281 %token OP_MODASSIGN
282 %token OP_ANDASSIGN
283 %token OP_ORASSIGN
284 %token OP_XORASSIGN
285 %token OP_UNKNOWN1
286 %token OP_UNKNOWN2
287 %token OP_UNKNOWN3
288 %token OP_UNKNOWN4
290 %token <intval> PRE_LINE
292 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
293 %type <name> any_identifier var_identifier
294 %token <name> STRING
295 %token <floatval> C_FLOAT
296 %token <intval> C_INTEGER
297 %type <boolval> boolean
298 %type <type> base_type
299 %type <type> type
300 %type <list> declaration_statement
301 %type <list> complex_initializer
302 %type <list> initializer_expr_list
303 %type <instr> initializer_expr
304 %type <modifiers> var_modifiers
305 %type <list> parameters
306 %type <list> param_list
307 %type <instr> expr
308 %type <var> variable
309 %type <intval> array
310 %type <list> statement
311 %type <list> statement_list
312 %type <list> compound_statement
313 %type <function> func_declaration
314 %type <function> func_prototype
315 %type <parameter> parameter
316 %type <name> semantic
317 %type <variable_def> variable_def
318 %type <list> variables_def
319 %type <instr> primary_expr
320 %type <instr> postfix_expr
321 %type <instr> unary_expr
322 %type <instr> mul_expr
323 %type <instr> add_expr
324 %type <instr> shift_expr
325 %type <instr> relational_expr
326 %type <instr> equality_expr
327 %type <instr> bitand_expr
328 %type <instr> bitxor_expr
329 %type <instr> bitor_expr
330 %type <instr> logicand_expr
331 %type <instr> logicor_expr
332 %type <instr> conditional_expr
333 %type <instr> assignment_expr
334 %type <list> expr_statement
335 %type <modifiers> input_mod
338 hlsl_prog: /* empty */
341 | hlsl_prog func_declaration
343 FIXME("Check that the function doesn't conflict with an already declared one.\n");
344 list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
346 | hlsl_prog declaration_statement
348 TRACE("Declaration statement parsed.\n");
350 | hlsl_prog preproc_directive
354 preproc_directive: PRE_LINE STRING
356 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
357 hlsl_ctx.line_no = $1;
358 if (strcmp($2, hlsl_ctx.source_file))
360 const char **new_array;
362 hlsl_ctx.source_file = $2;
363 new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
364 sizeof(*hlsl_ctx.source_files) * hlsl_ctx.source_files_count + 1);
365 if (new_array)
367 hlsl_ctx.source_files = new_array;
368 hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
373 any_identifier: VAR_IDENTIFIER
374 | TYPE_IDENTIFIER
375 | NEW_IDENTIFIER
377 func_declaration: func_prototype compound_statement
379 TRACE("Function %s parsed.\n", $1->name);
380 $$ = $1;
381 $$->body = $2;
382 pop_scope(&hlsl_ctx);
384 | func_prototype ';'
386 TRACE("Function prototype for %s.\n", $1->name);
387 $$ = $1;
388 pop_scope(&hlsl_ctx);
391 func_prototype: var_modifiers type var_identifier '(' parameters ')' semantic
393 if (get_variable(hlsl_ctx.globals, $3))
395 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
396 HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
397 return 1;
400 $$ = new_func_decl($3, $2, $5);
401 if (!$$)
403 ERR("Out of memory.\n");
404 return -1;
406 $$->semantic = $7;
409 compound_statement: '{' '}'
411 $$ = d3dcompiler_alloc(sizeof(*$$));
412 list_init($$);
414 | '{' scope_start statement_list '}'
416 pop_scope(&hlsl_ctx);
417 $$ = $3;
420 scope_start: /* Empty */
422 push_scope(&hlsl_ctx);
425 var_identifier: VAR_IDENTIFIER
426 | NEW_IDENTIFIER
428 semantic: /* Empty */
430 $$ = NULL;
432 | ':' any_identifier
434 $$ = $2;
437 parameters: scope_start
439 $$ = d3dcompiler_alloc(sizeof(*$$));
440 list_init($$);
442 | scope_start param_list
444 $$ = $2;
447 param_list: parameter
449 struct source_location loc;
451 $$ = d3dcompiler_alloc(sizeof(*$$));
452 list_init($$);
453 set_location(&loc, &@1);
454 if (!add_func_parameter($$, &$1, &loc))
456 ERR("Error adding function parameter %s.\n", $1.name);
457 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
458 return -1;
461 | param_list ',' parameter
463 struct source_location loc;
465 $$ = $1;
466 set_location(&loc, &@3);
467 if (!add_func_parameter($$, &$3, &loc))
469 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
470 "duplicate parameter %s", $3.name);
471 return 1;
475 parameter: input_mod var_modifiers type any_identifier semantic
477 $$.modifiers = $1;
478 $$.modifiers |= $2;
479 $$.type = $3;
480 $$.name = $4;
481 $$.semantic = $5;
484 input_mod: /* Empty */
486 $$ = HLSL_MODIFIER_IN;
488 | KW_IN
490 $$ = HLSL_MODIFIER_IN;
492 | KW_OUT
494 $$ = HLSL_MODIFIER_OUT;
496 | KW_INOUT
498 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
501 type: base_type
503 $$ = $1;
505 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
507 if ($3->type != HLSL_CLASS_SCALAR)
509 hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
510 hlsl_ctx.line_no);
511 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
512 return 1;
514 if ($5 < 1 || $5 > 4)
516 hlsl_message("Line %u: vector size must be between 1 and 4.\n",
517 hlsl_ctx.line_no);
518 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
519 return 1;
522 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
524 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
526 if ($3->type != HLSL_CLASS_SCALAR)
528 hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
529 hlsl_ctx.line_no);
530 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
531 return 1;
533 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
535 hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
536 hlsl_ctx.line_no);
537 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
538 return 1;
541 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
544 base_type: KW_VOID
546 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_SCALAR, HLSL_TYPE_VOID, 1, 1);
548 | KW_SAMPLER
550 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
551 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
553 | KW_SAMPLER1D
555 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
556 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
558 | KW_SAMPLER2D
560 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
561 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
563 | KW_SAMPLER3D
565 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
566 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
568 | KW_SAMPLERCUBE
570 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
571 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
573 | TYPE_IDENTIFIER
575 struct hlsl_type *type;
577 TRACE("Type %s.\n", $1);
578 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
579 $$ = type;
580 d3dcompiler_free($1);
582 | KW_STRUCT TYPE_IDENTIFIER
584 struct hlsl_type *type;
586 TRACE("Struct type %s.\n", $2);
587 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
588 if (type->type != HLSL_CLASS_STRUCT)
590 hlsl_message("Line %u: redefining %s as a structure.\n",
591 hlsl_ctx.line_no, $2);
592 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
594 else
596 $$ = type;
598 d3dcompiler_free($2);
601 declaration_statement: declaration
603 $$ = d3dcompiler_alloc(sizeof(*$$));
604 list_init($$);
607 declaration: var_modifiers type variables_def ';'
609 struct parse_variable_def *v, *v_next;
610 struct hlsl_ir_var *var;
611 BOOL ret, local = TRUE;
613 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
615 debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
616 var = d3dcompiler_alloc(sizeof(*var));
617 var->node.type = HLSL_IR_VAR;
618 if (v->array_size)
619 var->node.data_type = new_array_type($2, v->array_size);
620 else
621 var->node.data_type = $2;
622 var->node.loc = v->loc;
623 var->name = v->name;
624 var->modifiers = $1;
625 var->semantic = v->semantic;
626 if (v->initializer)
628 FIXME("Variable with an initializer.\n");
629 free_instr_list(v->initializer);
632 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
634 var->modifiers |= HLSL_STORAGE_UNIFORM;
635 local = FALSE;
638 ret = declare_variable(var, local);
639 if (ret == FALSE)
640 free_declaration(var);
641 else
642 TRACE("Declared variable %s.\n", var->name);
643 d3dcompiler_free(v);
645 d3dcompiler_free($3);
648 variables_def: variable_def
650 $$ = d3dcompiler_alloc(sizeof(*$$));
651 list_init($$);
652 list_add_head($$, &$1->entry);
654 | variables_def ',' variable_def
656 $$ = $1;
657 list_add_tail($$, &$3->entry);
660 /* FIXME: Local variables can't have semantics. */
661 variable_def: any_identifier array semantic
663 $$ = d3dcompiler_alloc(sizeof(*$$));
664 set_location(&$$->loc, &@1);
665 $$->name = $1;
666 $$->array_size = $2;
667 $$->semantic = $3;
669 | any_identifier array semantic '=' complex_initializer
671 TRACE("Declaration with initializer.\n");
672 $$ = d3dcompiler_alloc(sizeof(*$$));
673 set_location(&$$->loc, &@1);
674 $$->name = $1;
675 $$->array_size = $2;
676 $$->semantic = $3;
677 $$->initializer = $5;
680 array: /* Empty */
682 $$ = 0;
684 | '[' expr ']'
686 FIXME("Array.\n");
687 $$ = 0;
688 free_instr($2);
691 var_modifiers: /* Empty */
693 $$ = 0;
695 | KW_EXTERN var_modifiers
697 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
699 | KW_NOINTERPOLATION var_modifiers
701 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
703 | KW_PRECISE var_modifiers
705 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
707 | KW_SHARED var_modifiers
709 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
711 | KW_GROUPSHARED var_modifiers
713 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
715 | KW_STATIC var_modifiers
717 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
719 | KW_UNIFORM var_modifiers
721 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
723 | KW_VOLATILE var_modifiers
725 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
727 | KW_CONST var_modifiers
729 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
731 | KW_ROW_MAJOR var_modifiers
733 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
735 | KW_COLUMN_MAJOR var_modifiers
737 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
740 complex_initializer: initializer_expr
742 $$ = d3dcompiler_alloc(sizeof(*$$));
743 list_init($$);
744 list_add_head($$, &$1->entry);
746 | '{' initializer_expr_list '}'
748 $$ = $2;
751 initializer_expr: assignment_expr
753 $$ = $1;
756 initializer_expr_list: initializer_expr
758 $$ = d3dcompiler_alloc(sizeof(*$$));
759 list_init($$);
760 list_add_head($$, &$1->entry);
762 | initializer_expr_list ',' initializer_expr
764 $$ = $1;
765 list_add_tail($$, &$3->entry);
768 boolean: KW_TRUE
770 $$ = TRUE;
772 | KW_FALSE
774 $$ = FALSE;
777 statement_list: statement
779 $$ = $1;
781 | statement_list statement
783 $$ = $1;
784 list_move_tail($$, $2);
785 d3dcompiler_free($2);
788 statement: declaration_statement
790 $$ = $1;
792 | expr_statement
794 $$ = $1;
796 | compound_statement
798 $$ = $1;
801 expr_statement: ';'
803 $$ = d3dcompiler_alloc(sizeof(*$$));
804 list_init($$);
806 | expr ';'
808 $$ = d3dcompiler_alloc(sizeof(*$$));
809 list_init($$);
810 if ($1)
811 list_add_head($$, &$1->entry);
814 primary_expr: C_FLOAT
816 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
817 if (!c)
819 ERR("Out of memory.\n");
820 return -1;
822 c->node.type = HLSL_IR_CONSTANT;
823 set_location(&c->node.loc, &yylloc);
824 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
825 c->v.value.f[0] = $1;
826 $$ = &c->node;
828 | C_INTEGER
830 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
831 if (!c)
833 ERR("Out of memory.\n");
834 return -1;
836 c->node.type = HLSL_IR_CONSTANT;
837 set_location(&c->node.loc, &yylloc);
838 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
839 c->v.value.i[0] = $1;
840 $$ = &c->node;
842 | boolean
844 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
845 if (!c)
847 ERR("Out of memory.\n");
848 return -1;
850 c->node.type = HLSL_IR_CONSTANT;
851 set_location(&c->node.loc, &yylloc);
852 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
853 c->v.value.b[0] = $1;
854 $$ = &c->node;
856 | variable
858 struct hlsl_ir_deref *deref = new_var_deref($1);
859 if (deref)
861 $$ = &deref->node;
862 set_location(&$$->loc, &@1);
864 else
865 $$ = NULL;
867 | '(' expr ')'
869 $$ = $2;
872 variable: VAR_IDENTIFIER
874 struct hlsl_ir_var *var;
875 var = get_variable(hlsl_ctx.cur_scope, $1);
876 if (!var)
878 hlsl_message("Line %d: variable '%s' not declared\n",
879 hlsl_ctx.line_no, $1);
880 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
881 return 1;
883 $$ = var;
886 postfix_expr: primary_expr
888 $$ = $1;
890 /* "var_modifiers" doesn't make sense in this case, but it's needed
891 in the grammar to avoid shift/reduce conflicts. */
892 | var_modifiers type '(' initializer_expr_list ')'
894 struct hlsl_ir_constructor *constructor;
896 TRACE("%s constructor.\n", debug_hlsl_type($2));
897 if ($1)
899 hlsl_message("Line %u: unexpected modifier in a constructor.\n",
900 hlsl_ctx.line_no);
901 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
902 return -1;
904 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
906 hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
907 hlsl_ctx.line_no);
908 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
909 return -1;
911 if ($2->dimx * $2->dimy != components_count_expr_list($4))
913 hlsl_message("Line %u: wrong number of components in constructor.\n",
914 hlsl_ctx.line_no);
915 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
916 return -1;
919 constructor = d3dcompiler_alloc(sizeof(*constructor));
920 constructor->node.type = HLSL_IR_CONSTRUCTOR;
921 set_location(&constructor->node.loc, &@3);
922 constructor->node.data_type = $2;
923 constructor->arguments = $4;
925 $$ = &constructor->node;
928 unary_expr: postfix_expr
930 $$ = $1;
933 mul_expr: unary_expr
935 $$ = $1;
938 add_expr: mul_expr
940 $$ = $1;
943 shift_expr: add_expr
945 $$ = $1;
948 relational_expr: shift_expr
950 $$ = $1;
953 equality_expr: relational_expr
955 $$ = $1;
958 bitand_expr: equality_expr
960 $$ = $1;
963 bitxor_expr: bitand_expr
965 $$ = $1;
968 bitor_expr: bitxor_expr
970 $$ = $1;
973 logicand_expr: bitor_expr
975 $$ = $1;
978 logicor_expr: logicand_expr
980 $$ = $1;
983 conditional_expr: logicor_expr
985 $$ = $1;
988 assignment_expr: conditional_expr
990 $$ = $1;
993 expr: assignment_expr
995 $$ = $1;
997 | expr ',' assignment_expr
999 FIXME("Comma expression\n");
1004 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
1006 loc->file = hlsl_ctx.source_file;
1007 loc->line = l->first_line;
1008 loc->col = l->first_column;
1011 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
1013 if (modifiers & mod)
1015 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
1016 "modifier '%s' already specified", debug_modifiers(mod));
1017 return modifiers;
1019 if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
1020 && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
1022 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
1023 "more than one matrix majority keyword");
1024 return modifiers;
1026 return modifiers | mod;
1029 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
1030 const char *entrypoint, char **messages)
1032 struct hlsl_ir_function_decl *function;
1033 struct hlsl_scope *scope, *next_scope;
1034 struct hlsl_type *hlsl_type, *next_type;
1035 struct hlsl_ir_var *var, *next_var;
1036 unsigned int i;
1038 hlsl_ctx.status = PARSE_SUCCESS;
1039 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
1040 hlsl_ctx.line_no = hlsl_ctx.column = 1;
1041 hlsl_ctx.source_file = d3dcompiler_strdup("");
1042 hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
1043 if (hlsl_ctx.source_files)
1044 hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
1045 hlsl_ctx.source_files_count = 1;
1046 hlsl_ctx.cur_scope = NULL;
1047 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
1048 list_init(&hlsl_ctx.scopes);
1049 list_init(&hlsl_ctx.types);
1050 list_init(&hlsl_ctx.functions);
1052 push_scope(&hlsl_ctx);
1053 hlsl_ctx.globals = hlsl_ctx.cur_scope;
1055 hlsl_parse();
1057 if (TRACE_ON(hlsl_parser))
1059 struct hlsl_ir_function_decl *func;
1061 TRACE("IR dump.\n");
1062 LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1064 if (func->body)
1065 debug_dump_ir_function(func);
1069 TRACE("Compilation status = %d\n", hlsl_ctx.status);
1070 if (messages)
1072 if (hlsl_ctx.messages.size)
1073 *messages = hlsl_ctx.messages.string;
1074 else
1075 *messages = NULL;
1077 else
1079 if (hlsl_ctx.messages.capacity)
1080 d3dcompiler_free(hlsl_ctx.messages.string);
1083 for (i = 0; i < hlsl_ctx.source_files_count; ++i)
1084 d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
1085 d3dcompiler_free(hlsl_ctx.source_files);
1087 TRACE("Freeing functions IR.\n");
1088 LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1089 free_function(function);
1091 TRACE("Freeing variables.\n");
1092 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
1094 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
1096 free_declaration(var);
1098 d3dcompiler_free(scope);
1101 TRACE("Freeing types.\n");
1102 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
1104 free_hlsl_type(hlsl_type);
1107 return NULL;