d3dcompiler: Add hlsl_report_message function to standardize error messages.
[wine/multimedia.git] / dlls / d3dcompiler_43 / hlsl.y
blob240eaaff957d29eb1ae731b133972bbafe63548b
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 void hlsl_message(const char *fmt, ...)
37 va_list args;
39 va_start(args, fmt);
40 compilation_message(&hlsl_ctx.messages, fmt, args);
41 va_end(args);
44 static const char *hlsl_get_error_level_name(enum hlsl_error_level level)
46 const char *names[] =
48 "error",
49 "warning",
50 "note",
52 return names[level];
55 void hlsl_report_message(const char *filename, DWORD line, DWORD column,
56 enum hlsl_error_level level, const char *fmt, ...)
58 va_list args;
59 char *string = NULL;
60 int rc, size = 0;
62 while (1)
64 va_start(args, fmt);
65 rc = vsnprintf(string, size, fmt, args);
66 va_end(args);
68 if (rc >= 0 && rc < size)
69 break;
71 if (rc >= size)
72 size = rc + 1;
73 else
74 size = size ? size * 2 : 32;
76 if (!string)
77 string = d3dcompiler_alloc(size);
78 else
79 string = d3dcompiler_realloc(string, size);
80 if (!string)
82 ERR("Error reallocating memory for a string.\n");
83 return;
87 hlsl_message("%s:%u:%u: %s: %s\n", filename, line, column, hlsl_get_error_level_name(level), string);
88 d3dcompiler_free(string);
90 if (level == HLSL_LEVEL_ERROR)
91 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
92 else if (level == HLSL_LEVEL_WARNING)
93 set_parse_status(&hlsl_ctx.status, PARSE_WARN);
96 static void hlsl_error(const char *s)
98 hlsl_report_message(hlsl_ctx.source_file, hlsl_ctx.line_no, 1, HLSL_LEVEL_ERROR, "%s", s);
101 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
103 TRACE("Line %u: ", line_no);
104 if (modifiers)
105 TRACE("%s ", debug_modifiers(modifiers));
106 TRACE("%s %s;\n", debug_hlsl_type(type), declname);
109 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
111 BOOL ret;
113 TRACE("Declaring variable %s.\n", decl->name);
114 if (decl->node.data_type->type == HLSL_CLASS_MATRIX)
116 if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)))
118 decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR
119 ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR;
122 if (local)
124 DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
125 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
126 if (invalid)
128 hlsl_message("Line %u: modifier '%s' invalid for local variables.\n",
129 hlsl_ctx.line_no, debug_modifiers(invalid));
130 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
133 ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
134 if (ret == FALSE)
136 struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
138 hlsl_message("Line %u: \"%s\" already declared.\n", hlsl_ctx.line_no, decl->name);
139 hlsl_message("Line %u: \"%s\" was previously declared here.\n", old->node.line, decl->name);
140 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
141 return FALSE;
143 return TRUE;
146 static DWORD add_modifier(DWORD modifiers, DWORD mod)
148 if (modifiers & mod)
150 hlsl_message("Line %u: modifier '%s' already specified.\n",
151 hlsl_ctx.line_no, debug_modifiers(mod));
152 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
153 return modifiers;
155 if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
156 && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
158 hlsl_message("Line %u: more than one matrix majority keyword.\n",
159 hlsl_ctx.line_no);
160 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
161 return modifiers;
163 return modifiers | mod;
166 static unsigned int components_count_expr_list(struct list *list)
168 struct hlsl_ir_node *node;
169 unsigned int count = 0;
171 LIST_FOR_EACH_ENTRY(node, list, struct hlsl_ir_node, entry)
173 count += components_count_type(node->data_type);
175 return count;
180 %error-verbose
182 %union
184 struct hlsl_type *type;
185 INT intval;
186 FLOAT floatval;
187 BOOL boolval;
188 char *name;
189 DWORD modifiers;
190 struct hlsl_ir_var *var;
191 struct hlsl_ir_node *instr;
192 struct list *list;
193 struct hlsl_ir_function_decl *function;
194 struct parse_parameter parameter;
195 struct parse_variable_def *variable_def;
198 %token KW_BLENDSTATE
199 %token KW_BREAK
200 %token KW_BUFFER
201 %token KW_CBUFFER
202 %token KW_COLUMN_MAJOR
203 %token KW_COMPILE
204 %token KW_CONST
205 %token KW_CONTINUE
206 %token KW_DEPTHSTENCILSTATE
207 %token KW_DEPTHSTENCILVIEW
208 %token KW_DISCARD
209 %token KW_DO
210 %token KW_DOUBLE
211 %token KW_ELSE
212 %token KW_EXTERN
213 %token KW_FALSE
214 %token KW_FOR
215 %token KW_GEOMETRYSHADER
216 %token KW_GROUPSHARED
217 %token KW_IF
218 %token KW_IN
219 %token KW_INLINE
220 %token KW_INOUT
221 %token KW_MATRIX
222 %token KW_NAMESPACE
223 %token KW_NOINTERPOLATION
224 %token KW_OUT
225 %token KW_PASS
226 %token KW_PIXELSHADER
227 %token KW_PRECISE
228 %token KW_RASTERIZERSTATE
229 %token KW_RENDERTARGETVIEW
230 %token KW_RETURN
231 %token KW_REGISTER
232 %token KW_ROW_MAJOR
233 %token KW_SAMPLER
234 %token KW_SAMPLER1D
235 %token KW_SAMPLER2D
236 %token KW_SAMPLER3D
237 %token KW_SAMPLERCUBE
238 %token KW_SAMPLER_STATE
239 %token KW_SAMPLERCOMPARISONSTATE
240 %token KW_SHARED
241 %token KW_STATEBLOCK
242 %token KW_STATEBLOCK_STATE
243 %token KW_STATIC
244 %token KW_STRING
245 %token KW_STRUCT
246 %token KW_SWITCH
247 %token KW_TBUFFER
248 %token KW_TECHNIQUE
249 %token KW_TECHNIQUE10
250 %token KW_TEXTURE
251 %token KW_TEXTURE1D
252 %token KW_TEXTURE1DARRAY
253 %token KW_TEXTURE2D
254 %token KW_TEXTURE2DARRAY
255 %token KW_TEXTURE2DMS
256 %token KW_TEXTURE2DMSARRAY
257 %token KW_TEXTURE3D
258 %token KW_TEXTURE3DARRAY
259 %token KW_TEXTURECUBE
260 %token KW_TRUE
261 %token KW_TYPEDEF
262 %token KW_UNIFORM
263 %token KW_VECTOR
264 %token KW_VERTEXSHADER
265 %token KW_VOID
266 %token KW_VOLATILE
267 %token KW_WHILE
269 %token OP_INC
270 %token OP_DEC
271 %token OP_AND
272 %token OP_OR
273 %token OP_EQ
274 %token OP_LEFTSHIFT
275 %token OP_LEFTSHIFTASSIGN
276 %token OP_RIGHTSHIFT
277 %token OP_RIGHTSHIFTASSIGN
278 %token OP_ELLIPSIS
279 %token OP_LE
280 %token OP_GE
281 %token OP_NE
282 %token OP_ADDASSIGN
283 %token OP_SUBASSIGN
284 %token OP_MULASSIGN
285 %token OP_DIVASSIGN
286 %token OP_MODASSIGN
287 %token OP_ANDASSIGN
288 %token OP_ORASSIGN
289 %token OP_XORASSIGN
290 %token OP_UNKNOWN1
291 %token OP_UNKNOWN2
292 %token OP_UNKNOWN3
293 %token OP_UNKNOWN4
295 %token <intval> PRE_LINE
297 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
298 %type <name> any_identifier var_identifier
299 %token <name> STRING
300 %token <floatval> C_FLOAT
301 %token <intval> C_INTEGER
302 %type <boolval> boolean
303 %type <type> base_type
304 %type <type> type
305 %type <list> declaration_statement
306 %type <list> complex_initializer
307 %type <list> initializer_expr_list
308 %type <instr> initializer_expr
309 %type <modifiers> var_modifiers
310 %type <list> parameters
311 %type <list> param_list
312 %type <instr> expr
313 %type <var> variable
314 %type <intval> array
315 %type <list> statement
316 %type <list> statement_list
317 %type <list> compound_statement
318 %type <function> func_declaration
319 %type <function> func_prototype
320 %type <parameter> parameter
321 %type <name> semantic
322 %type <variable_def> variable_def
323 %type <list> variables_def
324 %type <instr> primary_expr
325 %type <instr> postfix_expr
326 %type <instr> unary_expr
327 %type <instr> mul_expr
328 %type <instr> add_expr
329 %type <instr> shift_expr
330 %type <instr> relational_expr
331 %type <instr> equality_expr
332 %type <instr> bitand_expr
333 %type <instr> bitxor_expr
334 %type <instr> bitor_expr
335 %type <instr> logicand_expr
336 %type <instr> logicor_expr
337 %type <instr> conditional_expr
338 %type <instr> assignment_expr
339 %type <list> expr_statement
340 %type <modifiers> input_mod
343 hlsl_prog: /* empty */
346 | hlsl_prog func_declaration
348 FIXME("Check that the function doesn't conflict with an already declared one.\n");
349 list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
351 | hlsl_prog declaration_statement
353 TRACE("Declaration statement parsed.\n");
355 | hlsl_prog preproc_directive
359 preproc_directive: PRE_LINE STRING
361 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
362 hlsl_ctx.line_no = $1;
363 d3dcompiler_free(hlsl_ctx.source_file);
364 hlsl_ctx.source_file = $2;
367 any_identifier: VAR_IDENTIFIER
368 | TYPE_IDENTIFIER
369 | NEW_IDENTIFIER
371 func_declaration: func_prototype compound_statement
373 TRACE("Function %s parsed.\n", $1->name);
374 $$ = $1;
375 $$->body = $2;
376 pop_scope(&hlsl_ctx);
378 | func_prototype ';'
380 TRACE("Function prototype for %s.\n", $1->name);
381 $$ = $1;
382 pop_scope(&hlsl_ctx);
385 func_prototype: var_modifiers type var_identifier '(' parameters ')' semantic
387 $$ = new_func_decl($3, $2, $5);
388 if (!$$)
390 ERR("Out of memory.\n");
391 return -1;
393 $$->semantic = $7;
396 compound_statement: '{' '}'
398 $$ = d3dcompiler_alloc(sizeof(*$$));
399 list_init($$);
401 | '{' scope_start statement_list '}'
403 pop_scope(&hlsl_ctx);
404 $$ = $3;
407 scope_start: /* Empty */
409 push_scope(&hlsl_ctx);
412 var_identifier: VAR_IDENTIFIER
413 | NEW_IDENTIFIER
415 semantic: /* Empty */
417 $$ = NULL;
419 | ':' any_identifier
421 $$ = $2;
424 parameters: scope_start
426 $$ = d3dcompiler_alloc(sizeof(*$$));
427 list_init($$);
429 | scope_start param_list
431 $$ = $2;
434 param_list: parameter
436 $$ = d3dcompiler_alloc(sizeof(*$$));
437 list_init($$);
438 if (!add_func_parameter($$, &$1, hlsl_ctx.line_no))
440 ERR("Error adding function parameter %s.\n", $1.name);
441 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
442 return -1;
445 | param_list ',' parameter
447 $$ = $1;
448 if (!add_func_parameter($$, &$3, hlsl_ctx.line_no))
450 hlsl_message("Line %u: duplicate parameter %s.\n",
451 hlsl_ctx.line_no, $3.name);
452 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
453 return 1;
457 parameter: input_mod var_modifiers type any_identifier semantic
459 $$.modifiers = $1;
460 $$.modifiers |= $2;
461 $$.type = $3;
462 $$.name = $4;
463 $$.semantic = $5;
466 input_mod: /* Empty */
468 $$ = HLSL_MODIFIER_IN;
470 | KW_IN
472 $$ = HLSL_MODIFIER_IN;
474 | KW_OUT
476 $$ = HLSL_MODIFIER_OUT;
478 | KW_INOUT
480 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
483 type: base_type
485 $$ = $1;
487 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
489 if ($3->type != HLSL_CLASS_SCALAR)
491 hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
492 hlsl_ctx.line_no);
493 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
494 return 1;
496 if ($5 < 1 || $5 > 4)
498 hlsl_message("Line %u: vector size must be between 1 and 4.\n",
499 hlsl_ctx.line_no);
500 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
501 return 1;
504 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
506 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
508 if ($3->type != HLSL_CLASS_SCALAR)
510 hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
511 hlsl_ctx.line_no);
512 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
513 return 1;
515 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
517 hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
518 hlsl_ctx.line_no);
519 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
520 return 1;
523 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
526 base_type: KW_VOID
528 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_SCALAR, HLSL_TYPE_VOID, 1, 1);
530 | KW_SAMPLER
532 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
533 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
535 | KW_SAMPLER1D
537 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
538 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
540 | KW_SAMPLER2D
542 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
543 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
545 | KW_SAMPLER3D
547 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
548 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
550 | KW_SAMPLERCUBE
552 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
553 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
555 | TYPE_IDENTIFIER
557 struct hlsl_type *type;
559 TRACE("Type %s.\n", $1);
560 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
561 $$ = type;
562 d3dcompiler_free($1);
564 | KW_STRUCT TYPE_IDENTIFIER
566 struct hlsl_type *type;
568 TRACE("Struct type %s.\n", $2);
569 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
570 if (type->type != HLSL_CLASS_STRUCT)
572 hlsl_message("Line %u: redefining %s as a structure.\n",
573 hlsl_ctx.line_no, $2);
574 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
576 else
578 $$ = type;
580 d3dcompiler_free($2);
583 declaration_statement: declaration
585 $$ = d3dcompiler_alloc(sizeof(*$$));
586 list_init($$);
589 declaration: var_modifiers type variables_def ';'
591 struct parse_variable_def *v, *v_next;
592 struct hlsl_ir_var *var;
593 BOOL ret, local = TRUE;
595 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
597 debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
598 var = d3dcompiler_alloc(sizeof(*var));
599 var->node.type = HLSL_IR_VAR;
600 if (v->array_size)
601 var->node.data_type = new_array_type($2, v->array_size);
602 else
603 var->node.data_type = $2;
604 var->name = v->name;
605 var->modifiers = $1;
606 var->semantic = v->semantic;
607 var->node.line = hlsl_ctx.line_no;
608 if (v->initializer)
610 FIXME("Variable with an initializer.\n");
611 free_instr_list(v->initializer);
614 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
616 var->modifiers |= HLSL_STORAGE_UNIFORM;
617 local = FALSE;
620 ret = declare_variable(var, local);
621 if (ret == FALSE)
622 free_declaration(var);
623 else
624 TRACE("Declared variable %s.\n", var->name);
625 d3dcompiler_free(v);
627 d3dcompiler_free($3);
630 variables_def: variable_def
632 $$ = d3dcompiler_alloc(sizeof(*$$));
633 list_init($$);
634 list_add_head($$, &$1->entry);
636 | variables_def ',' variable_def
638 $$ = $1;
639 list_add_tail($$, &$3->entry);
642 /* FIXME: Local variables can't have semantics. */
643 variable_def: any_identifier array semantic
645 $$ = d3dcompiler_alloc(sizeof(*$$));
646 $$->name = $1;
647 $$->array_size = $2;
648 $$->semantic = $3;
650 | any_identifier array semantic '=' complex_initializer
652 TRACE("Declaration with initializer.\n");
653 $$ = d3dcompiler_alloc(sizeof(*$$));
654 $$->name = $1;
655 $$->array_size = $2;
656 $$->semantic = $3;
657 $$->initializer = $5;
660 array: /* Empty */
662 $$ = 0;
664 | '[' expr ']'
666 FIXME("Array.\n");
667 $$ = 0;
668 free_instr($2);
671 var_modifiers: /* Empty */
673 $$ = 0;
675 | KW_EXTERN var_modifiers
677 $$ = add_modifier($2, HLSL_STORAGE_EXTERN);
679 | KW_NOINTERPOLATION var_modifiers
681 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION);
683 | KW_PRECISE var_modifiers
685 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE);
687 | KW_SHARED var_modifiers
689 $$ = add_modifier($2, HLSL_STORAGE_SHARED);
691 | KW_GROUPSHARED var_modifiers
693 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED);
695 | KW_STATIC var_modifiers
697 $$ = add_modifier($2, HLSL_STORAGE_STATIC);
699 | KW_UNIFORM var_modifiers
701 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM);
703 | KW_VOLATILE var_modifiers
705 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE);
707 | KW_CONST var_modifiers
709 $$ = add_modifier($2, HLSL_MODIFIER_CONST);
711 | KW_ROW_MAJOR var_modifiers
713 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR);
715 | KW_COLUMN_MAJOR var_modifiers
717 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR);
720 complex_initializer: initializer_expr
722 $$ = d3dcompiler_alloc(sizeof(*$$));
723 list_init($$);
724 list_add_head($$, &$1->entry);
726 | '{' initializer_expr_list '}'
728 $$ = $2;
731 initializer_expr: assignment_expr
733 $$ = $1;
736 initializer_expr_list: initializer_expr
738 $$ = d3dcompiler_alloc(sizeof(*$$));
739 list_init($$);
740 list_add_head($$, &$1->entry);
742 | initializer_expr_list ',' initializer_expr
744 $$ = $1;
745 list_add_tail($$, &$3->entry);
748 boolean: KW_TRUE
750 $$ = TRUE;
752 | KW_FALSE
754 $$ = FALSE;
757 statement_list: statement
759 $$ = $1;
761 | statement_list statement
763 $$ = $1;
764 list_move_tail($$, $2);
765 d3dcompiler_free($2);
768 statement: declaration_statement
770 $$ = $1;
772 | expr_statement
774 $$ = $1;
776 | compound_statement
778 $$ = $1;
781 expr_statement: ';'
783 $$ = d3dcompiler_alloc(sizeof(*$$));
784 list_init($$);
786 | expr ';'
788 $$ = d3dcompiler_alloc(sizeof(*$$));
789 list_init($$);
790 if ($1)
791 list_add_head($$, &$1->entry);
794 primary_expr: C_FLOAT
796 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
797 if (!c)
799 ERR("Out of memory.\n");
800 return -1;
802 c->node.type = HLSL_IR_CONSTANT;
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;
807 | C_INTEGER
809 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
810 if (!c)
812 ERR("Out of memory.\n");
813 return -1;
815 c->node.type = HLSL_IR_CONSTANT;
816 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
817 c->v.value.i[0] = $1;
818 $$ = &c->node;
820 | boolean
822 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
823 if (!c)
825 ERR("Out of memory.\n");
826 return -1;
828 c->node.type = HLSL_IR_CONSTANT;
829 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
830 c->v.value.b[0] = $1;
831 $$ = &c->node;
833 | variable
835 struct hlsl_ir_deref *deref = new_var_deref($1);
836 $$ = deref ? &deref->node : NULL;
838 | '(' expr ')'
840 $$ = $2;
843 variable: VAR_IDENTIFIER
845 struct hlsl_ir_var *var;
846 var = get_variable(hlsl_ctx.cur_scope, $1);
847 if (!var)
849 hlsl_message("Line %d: variable '%s' not declared\n",
850 hlsl_ctx.line_no, $1);
851 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
852 return 1;
854 $$ = var;
857 postfix_expr: primary_expr
859 $$ = $1;
861 /* "var_modifiers" doesn't make sense in this case, but it's needed
862 in the grammar to avoid shift/reduce conflicts. */
863 | var_modifiers type '(' initializer_expr_list ')'
865 struct hlsl_ir_constructor *constructor;
867 TRACE("%s constructor.\n", debug_hlsl_type($2));
868 if ($1)
870 hlsl_message("Line %u: unexpected modifier in a constructor.\n",
871 hlsl_ctx.line_no);
872 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
873 return -1;
875 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
877 hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
878 hlsl_ctx.line_no);
879 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
880 return -1;
882 if ($2->dimx * $2->dimy != components_count_expr_list($4))
884 hlsl_message("Line %u: wrong number of components in constructor.\n",
885 hlsl_ctx.line_no);
886 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
887 return -1;
890 constructor = d3dcompiler_alloc(sizeof(*constructor));
891 constructor->node.type = HLSL_IR_CONSTRUCTOR;
892 constructor->node.data_type = $2;
893 constructor->arguments = $4;
895 $$ = &constructor->node;
898 unary_expr: postfix_expr
900 $$ = $1;
903 mul_expr: unary_expr
905 $$ = $1;
908 add_expr: mul_expr
910 $$ = $1;
913 shift_expr: add_expr
915 $$ = $1;
918 relational_expr: shift_expr
920 $$ = $1;
923 equality_expr: relational_expr
925 $$ = $1;
928 bitand_expr: equality_expr
930 $$ = $1;
933 bitxor_expr: bitand_expr
935 $$ = $1;
938 bitor_expr: bitxor_expr
940 $$ = $1;
943 logicand_expr: bitor_expr
945 $$ = $1;
948 logicor_expr: logicand_expr
950 $$ = $1;
953 conditional_expr: logicor_expr
955 $$ = $1;
958 assignment_expr: conditional_expr
960 $$ = $1;
963 expr: assignment_expr
965 $$ = $1;
967 | expr ',' assignment_expr
969 FIXME("Comma expression\n");
974 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
975 const char *entrypoint, char **messages)
977 struct hlsl_ir_function_decl *function;
978 struct hlsl_scope *scope, *next_scope;
979 struct hlsl_type *hlsl_type, *next_type;
980 struct hlsl_ir_var *var, *next_var;
982 hlsl_ctx.status = PARSE_SUCCESS;
983 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
984 hlsl_ctx.line_no = 1;
985 hlsl_ctx.source_file = d3dcompiler_strdup("");
986 hlsl_ctx.cur_scope = NULL;
987 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
988 list_init(&hlsl_ctx.scopes);
989 list_init(&hlsl_ctx.types);
990 list_init(&hlsl_ctx.functions);
992 push_scope(&hlsl_ctx);
993 hlsl_ctx.globals = hlsl_ctx.cur_scope;
995 hlsl_parse();
997 if (TRACE_ON(hlsl_parser))
999 struct hlsl_ir_function_decl *func;
1001 TRACE("IR dump.\n");
1002 LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1004 if (func->body)
1005 debug_dump_ir_function(func);
1009 TRACE("Compilation status = %d\n", hlsl_ctx.status);
1010 if (messages)
1012 if (hlsl_ctx.messages.size)
1013 *messages = hlsl_ctx.messages.string;
1014 else
1015 *messages = NULL;
1017 else
1019 if (hlsl_ctx.messages.capacity)
1020 d3dcompiler_free(hlsl_ctx.messages.string);
1023 d3dcompiler_free(hlsl_ctx.source_file);
1024 TRACE("Freeing functions IR.\n");
1025 LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1026 free_function(function);
1028 TRACE("Freeing variables.\n");
1029 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
1031 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
1033 free_declaration(var);
1035 d3dcompiler_free(scope);
1038 TRACE("Freeing types.\n");
1039 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
1041 free_hlsl_type(hlsl_type);
1044 return NULL;