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 "wine/debug.h"
27 #include "d3dcompiler_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL
(hlsl_parser
);
33 struct hlsl_parse_ctx hlsl_ctx
;
36 static struct source_location get_location
(const struct YYLTYPE *l
);
38 void WINAPIV hlsl_message
(const char *fmt
, ...
)
42 __ms_va_start
(args
, fmt
);
43 compilation_message
(&hlsl_ctx.messages
, fmt
, args
);
47 static const char *hlsl_get_error_level_name
(enum hlsl_error_level level
)
49 static const char * const names
[] =
58 void WINAPIV hlsl_report_message
(const struct source_location loc
,
59 enum hlsl_error_level level
, const char *fmt
, ...
)
67 __ms_va_start
(args
, fmt
);
68 rc
= vsnprintf
(string, size
, fmt
, args
);
71 if
(rc
>= 0 && rc
< size
)
77 size
= size ? size
* 2 : 32;
80 string = d3dcompiler_alloc
(size
);
82 string = d3dcompiler_realloc
(string, size
);
85 ERR
("Error reallocating memory for a string.\n");
90 hlsl_message
("%s:%u:%u: %s: %s\n", loc.file
, loc.line
, loc.col
,
91 hlsl_get_error_level_name
(level
), string);
92 d3dcompiler_free
(string);
94 if
(level
== HLSL_LEVEL_ERROR
)
95 set_parse_status
(&hlsl_ctx.status
, PARSE_ERR
);
96 else if
(level
== HLSL_LEVEL_WARNING
)
97 set_parse_status
(&hlsl_ctx.status
, PARSE_WARN
);
100 static void hlsl_error
(const char *s
)
102 const struct source_location loc
=
104 .file
= hlsl_ctx.source_file
,
105 .line
= hlsl_ctx.line_no
,
106 .col
= hlsl_ctx.column
,
108 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "%s", s
);
111 static void debug_dump_decl
(struct hlsl_type
*type
, DWORD modifiers
, const char *declname
, unsigned int line_no
)
113 TRACE
("Line %u: ", line_no
);
115 TRACE
("%s ", debug_modifiers
(modifiers
));
116 TRACE
("%s %s;\n", debug_hlsl_type
(type
), declname
);
119 static void check_invalid_matrix_modifiers
(DWORD modifiers
, struct source_location loc
)
121 if
(modifiers
& HLSL_MODIFIERS_MAJORITY_MASK
)
123 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
,
124 "'row_major' or 'column_major' modifiers are only allowed for matrices");
128 static BOOL type_is_single_reg
(const struct hlsl_type
*type
)
130 return type
->type
== HLSL_CLASS_SCALAR || type
->type
== HLSL_CLASS_VECTOR
;
133 static BOOL declare_variable
(struct hlsl_ir_var
*decl
, BOOL local
)
137 TRACE
("Declaring variable %s.\n", decl
->name
);
138 if
(decl
->data_type
->type
!= HLSL_CLASS_MATRIX
)
139 check_invalid_matrix_modifiers
(decl
->modifiers
, decl
->loc
);
143 DWORD invalid
= decl
->modifiers
& (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
144 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM
);
147 hlsl_report_message
(decl
->loc
, HLSL_LEVEL_ERROR
,
148 "modifier '%s' invalid for local variables", debug_modifiers
(invalid
));
152 hlsl_report_message
(decl
->loc
, HLSL_LEVEL_ERROR
,
153 "semantics are not allowed on local variables");
159 if
(find_function
(decl
->name
))
161 hlsl_report_message
(decl
->loc
, HLSL_LEVEL_ERROR
, "redefinition of '%s'", decl
->name
);
165 ret
= add_declaration
(hlsl_ctx.cur_scope
, decl
, local
);
168 struct hlsl_ir_var
*old
= get_variable
(hlsl_ctx.cur_scope
, decl
->name
);
170 hlsl_report_message
(decl
->loc
, HLSL_LEVEL_ERROR
, "\"%s\" already declared", decl
->name
);
171 hlsl_report_message
(old
->loc
, HLSL_LEVEL_NOTE
, "\"%s\" was previously declared here", old
->name
);
177 static DWORD add_modifiers
(DWORD modifiers
, DWORD mod
, const struct source_location loc
)
181 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "modifier '%s' already specified", debug_modifiers
(mod
));
184 if
((mod
& HLSL_MODIFIERS_MAJORITY_MASK
) && (modifiers
& HLSL_MODIFIERS_MAJORITY_MASK
))
186 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "more than one matrix majority keyword");
189 return modifiers | mod
;
192 static BOOL add_type_to_scope
(struct hlsl_scope
*scope
, struct hlsl_type
*def
)
194 if
(get_type
(scope
, def
->name
, FALSE
))
197 wine_rb_put
(&scope
->types
, def
->name
, &def
->scope_entry
);
201 static void declare_predefined_types
(struct hlsl_scope
*scope
)
203 struct hlsl_type
*type
;
204 unsigned int x
, y
, bt
;
205 static const char * const names
[] =
216 static const char *const sampler_names
[] =
225 for
(bt
= 0; bt
<= HLSL_TYPE_LAST_SCALAR
; ++bt
)
227 for
(y
= 1; y
<= 4; ++y
)
229 for
(x
= 1; x
<= 4; ++x
)
231 sprintf
(name
, "%s%ux%u", names
[bt
], y
, x
);
232 type
= new_hlsl_type
(d3dcompiler_strdup
(name
), HLSL_CLASS_MATRIX
, bt
, x
, y
);
233 add_type_to_scope
(scope
, type
);
237 sprintf
(name
, "%s%u", names
[bt
], x
);
238 type
= new_hlsl_type
(d3dcompiler_strdup
(name
), HLSL_CLASS_VECTOR
, bt
, x
, y
);
239 add_type_to_scope
(scope
, type
);
240 hlsl_ctx.builtin_types.vector
[bt
][x
- 1] = type
;
244 sprintf
(name
, "%s", names
[bt
]);
245 type
= new_hlsl_type
(d3dcompiler_strdup
(name
), HLSL_CLASS_SCALAR
, bt
, x
, y
);
246 add_type_to_scope
(scope
, type
);
247 hlsl_ctx.builtin_types.scalar
[bt
] = type
;
254 for
(bt
= 0; bt
<= HLSL_SAMPLER_DIM_MAX
; ++bt
)
256 type
= new_hlsl_type
(d3dcompiler_strdup
(sampler_names
[bt
]), HLSL_CLASS_OBJECT
, HLSL_TYPE_SAMPLER
, 1, 1);
257 type
->sampler_dim
= bt
;
258 hlsl_ctx.builtin_types.sampler
[bt
] = type
;
261 hlsl_ctx.builtin_types.Void
= new_hlsl_type
(d3dcompiler_strdup
("void"), HLSL_CLASS_OBJECT
, HLSL_TYPE_VOID
, 1, 1);
263 /* DX8 effects predefined types */
264 type
= new_hlsl_type
(d3dcompiler_strdup
("DWORD"), HLSL_CLASS_SCALAR
, HLSL_TYPE_INT
, 1, 1);
265 add_type_to_scope
(scope
, type
);
266 type
= new_hlsl_type
(d3dcompiler_strdup
("FLOAT"), HLSL_CLASS_SCALAR
, HLSL_TYPE_FLOAT
, 1, 1);
267 add_type_to_scope
(scope
, type
);
268 type
= new_hlsl_type
(d3dcompiler_strdup
("VECTOR"), HLSL_CLASS_VECTOR
, HLSL_TYPE_FLOAT
, 4, 1);
269 add_type_to_scope
(scope
, type
);
270 type
= new_hlsl_type
(d3dcompiler_strdup
("MATRIX"), HLSL_CLASS_MATRIX
, HLSL_TYPE_FLOAT
, 4, 4);
271 add_type_to_scope
(scope
, type
);
272 type
= new_hlsl_type
(d3dcompiler_strdup
("STRING"), HLSL_CLASS_OBJECT
, HLSL_TYPE_STRING
, 1, 1);
273 add_type_to_scope
(scope
, type
);
274 type
= new_hlsl_type
(d3dcompiler_strdup
("TEXTURE"), HLSL_CLASS_OBJECT
, HLSL_TYPE_TEXTURE
, 1, 1);
275 add_type_to_scope
(scope
, type
);
276 type
= new_hlsl_type
(d3dcompiler_strdup
("PIXELSHADER"), HLSL_CLASS_OBJECT
, HLSL_TYPE_PIXELSHADER
, 1, 1);
277 add_type_to_scope
(scope
, type
);
278 type
= new_hlsl_type
(d3dcompiler_strdup
("VERTEXSHADER"), HLSL_CLASS_OBJECT
, HLSL_TYPE_VERTEXSHADER
, 1, 1);
279 add_type_to_scope
(scope
, type
);
282 static BOOL type_is_void
(const struct hlsl_type
*type
)
284 return type
->type
== HLSL_CLASS_OBJECT
&& type
->base_type
== HLSL_TYPE_VOID
;
287 static BOOL append_conditional_break
(struct list
*cond_list
)
289 struct hlsl_ir_node
*condition
, *not
;
290 struct hlsl_ir_jump
*jump
;
291 struct hlsl_ir_if
*iff
;
293 /* E.g. "for (i = 0; ; ++i)". */
294 if
(!list_count
(cond_list
))
297 condition
= node_from_list
(cond_list
);
298 if
(!(not
= new_unary_expr
(HLSL_IR_UNOP_LOGIC_NOT
, condition
, condition
->loc
)))
300 ERR
("Out of memory.\n");
303 list_add_tail
(cond_list
, ¬
->entry
);
305 if
(!(iff
= d3dcompiler_alloc
(sizeof
(*iff
))))
307 ERR
("Out of memory.\n");
310 init_node
(&iff
->node
, HLSL_IR_IF
, NULL
, condition
->loc
);
311 iff
->condition
= not
;
312 list_add_tail
(cond_list
, &iff
->node.entry
);
314 if
(!(iff
->then_instrs
= d3dcompiler_alloc
(sizeof
(*iff
->then_instrs
))))
316 ERR
("Out of memory.\n");
319 list_init
(iff
->then_instrs
);
321 if
(!(jump
= d3dcompiler_alloc
(sizeof
(*jump
))))
323 ERR
("Out of memory.\n");
326 init_node
(&jump
->node
, HLSL_IR_JUMP
, NULL
, condition
->loc
);
327 jump
->type
= HLSL_IR_JUMP_BREAK
;
328 list_add_head
(iff
->then_instrs
, &jump
->node.entry
);
339 static struct list
*create_loop
(enum loop_type type
, struct list
*init
, struct list
*cond
,
340 struct list
*iter
, struct list
*body
, struct source_location loc
)
342 struct list
*list
= NULL
;
343 struct hlsl_ir_loop
*loop
= NULL
;
344 struct hlsl_ir_if
*cond_jump
= NULL
;
346 list
= d3dcompiler_alloc
(sizeof
(*list
));
352 list_move_head
(list
, init
);
354 loop
= d3dcompiler_alloc
(sizeof
(*loop
));
357 init_node
(&loop
->node
, HLSL_IR_LOOP
, NULL
, loc
);
358 list_add_tail
(list
, &loop
->node.entry
);
359 loop
->body
= d3dcompiler_alloc
(sizeof
(*loop
->body
));
362 list_init
(loop
->body
);
364 if
(!append_conditional_break
(cond
))
367 if
(type
!= LOOP_DO_WHILE
)
368 list_move_tail
(loop
->body
, cond
);
370 list_move_tail
(loop
->body
, body
);
373 list_move_tail
(loop
->body
, iter
);
375 if
(type
== LOOP_DO_WHILE
)
376 list_move_tail
(loop
->body
, cond
);
378 d3dcompiler_free
(init
);
379 d3dcompiler_free
(cond
);
380 d3dcompiler_free
(body
);
384 ERR
("Out of memory.\n");
386 d3dcompiler_free
(loop
->body
);
387 d3dcompiler_free
(loop
);
388 d3dcompiler_free
(cond_jump
);
389 d3dcompiler_free
(list
);
390 free_instr_list
(init
);
391 free_instr_list
(cond
);
392 free_instr_list
(iter
);
393 free_instr_list
(body
);
397 static unsigned int initializer_size
(const struct parse_initializer
*initializer
)
399 unsigned int count
= 0, i
;
401 for
(i
= 0; i
< initializer
->args_count
; ++i
)
403 count
+= components_count_type
(initializer
->args
[i
]->data_type
);
405 TRACE
("Initializer size = %u.\n", count
);
409 static void free_parse_initializer
(struct parse_initializer
*initializer
)
411 free_instr_list
(initializer
->instrs
);
412 d3dcompiler_free
(initializer
->args
);
415 static struct hlsl_ir_swizzle
*new_swizzle
(DWORD s
, unsigned int components
,
416 struct hlsl_ir_node
*val
, struct source_location
*loc
)
418 struct hlsl_ir_swizzle
*swizzle
= d3dcompiler_alloc
(sizeof
(*swizzle
));
422 init_node
(&swizzle
->node
, HLSL_IR_SWIZZLE
,
423 new_hlsl_type
(NULL
, HLSL_CLASS_VECTOR
, val
->data_type
->base_type
, components
, 1), *loc
);
425 swizzle
->swizzle
= s
;
429 static struct hlsl_ir_swizzle
*get_swizzle
(struct hlsl_ir_node
*value
, const char *swizzle
,
430 struct source_location
*loc
)
432 unsigned int len
= strlen
(swizzle
), component
= 0;
433 unsigned int i
, set
, swiz
= 0;
436 if
(value
->data_type
->type
== HLSL_CLASS_MATRIX
)
440 unsigned int inc
, x
, y
;
442 if
(len
< 3 || swizzle
[0] != '_')
444 m_swizzle
= swizzle
[1] == 'm';
445 inc
= m_swizzle ?
4 : 3;
447 if
(len % inc || len
> inc
* 4)
450 for
(i
= 0; i
< len
; i
+= inc
)
452 if
(swizzle
[i
] != '_')
456 if
(swizzle
[i
+ 1] != 'm')
458 y
= swizzle
[i
+ 2] - '0';
459 x
= swizzle
[i
+ 3] - '0';
463 y
= swizzle
[i
+ 1] - '1';
464 x
= swizzle
[i
+ 2] - '1';
467 if
(x
>= value
->data_type
->dimx || y
>= value
->data_type
->dimy
)
469 swiz |
= (y
<< 4 | x
) << component
* 8;
472 return new_swizzle
(swiz
, component
, value
, loc
);
479 for
(set
= 0; set
< 2; ++set
)
483 for
(i
= 0; i
< len
; ++i
)
485 char c
[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}};
488 for
(s
= 0; s
< 4; ++s
)
490 if
(swizzle
[i
] == c
[set
][s
])
499 if
(s
>= value
->data_type
->dimx
)
501 swiz |
= s
<< component
* 2;
505 return new_swizzle
(swiz
, component
, value
, loc
);
511 static struct hlsl_ir_var
*new_synthetic_var
(const char *name
, struct hlsl_type
*type
,
512 const struct source_location loc
)
514 struct hlsl_ir_var
*var
;
516 if
(!(var
= d3dcompiler_alloc
(sizeof
(*var
))))
518 hlsl_ctx.status
= PARSE_ERR
;
522 var
->name
= strdup
(name
);
523 var
->data_type
= type
;
525 list_add_tail
(&hlsl_ctx.globals
->vars
, &var
->scope_entry
);
529 static struct hlsl_ir_assignment
*new_assignment
(struct hlsl_ir_var
*var
, struct hlsl_ir_node
*offset
,
530 struct hlsl_ir_node
*rhs
, unsigned int writemask
, struct source_location loc
)
532 struct hlsl_ir_assignment
*assign
;
534 if
(!writemask
&& type_is_single_reg
(rhs
->data_type
))
535 writemask
= (1 << rhs
->data_type
->dimx
) - 1;
537 if
(!(assign
= d3dcompiler_alloc
(sizeof
(*assign
))))
540 init_node
(&assign
->node
, HLSL_IR_ASSIGNMENT
, NULL
, loc
);
541 assign
->lhs.var
= var
;
542 assign
->lhs.offset
= offset
;
544 assign
->writemask
= writemask
;
548 static struct hlsl_ir_assignment
*make_simple_assignment
(struct hlsl_ir_var
*lhs
, struct hlsl_ir_node
*rhs
)
550 return new_assignment
(lhs
, NULL
, rhs
, 0, rhs
->loc
);
553 static struct hlsl_ir_jump
*new_return
(struct hlsl_ir_node
*return_value
, struct source_location loc
)
555 struct hlsl_type
*return_type
= hlsl_ctx.cur_function
->return_type
;
556 struct hlsl_ir_jump
*jump
;
560 struct hlsl_ir_assignment
*assignment
;
562 if
(!(return_value
= implicit_conversion
(return_value
, return_type
, &loc
)))
565 if
(!(assignment
= make_simple_assignment
(hlsl_ctx.cur_function
->return_var
, return_value
)))
567 list_add_after
(&return_value
->entry
, &assignment
->node.entry
);
569 else if
(!type_is_void
(return_type
))
571 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "non-void function must return a value");
575 if
(!(jump
= d3dcompiler_alloc
(sizeof
(*jump
))))
577 ERR
("Out of memory\n");
580 init_node
(&jump
->node
, HLSL_IR_JUMP
, NULL
, loc
);
581 jump
->type
= HLSL_IR_JUMP_RETURN
;
586 static struct hlsl_ir_constant
*new_uint_constant
(unsigned int n
, const struct source_location loc
)
588 struct hlsl_ir_constant
*c
;
590 if
(!(c
= d3dcompiler_alloc
(sizeof
(*c
))))
592 init_node
(&c
->node
, HLSL_IR_CONSTANT
, hlsl_ctx.builtin_types.scalar
[HLSL_TYPE_UINT
], loc
);
597 static struct hlsl_ir_load
*new_var_load
(struct hlsl_ir_var
*var
, const struct source_location loc
)
599 struct hlsl_ir_load
*load
= d3dcompiler_alloc
(sizeof
(*load
));
603 ERR
("Out of memory.\n");
606 init_node
(&load
->node
, HLSL_IR_LOAD
, var
->data_type
, loc
);
611 static struct hlsl_ir_load
*new_load
(struct hlsl_ir_node
*var_node
, struct hlsl_ir_node
*offset
,
612 struct hlsl_type
*data_type
, const struct source_location loc
)
614 struct hlsl_ir_node
*add
= NULL
;
615 struct hlsl_ir_load
*load
;
616 struct hlsl_ir_var
*var
;
618 if
(var_node
->type
== HLSL_IR_LOAD
)
620 const struct hlsl_deref
*src
= &load_from_node
(var_node
)->src
;
625 if
(!(add
= new_binary_expr
(HLSL_IR_BINOP_ADD
, src
->offset
, offset
, loc
)))
627 list_add_after
(&offset
->entry
, &add
->entry
);
633 struct hlsl_ir_assignment
*assign
;
636 sprintf
(name
, "<deref-%p>", var_node
);
637 if
(!(var
= new_synthetic_var
(name
, var_node
->data_type
, var_node
->loc
)))
640 TRACE
("Synthesized variable %p for %s node.\n", var
, debug_node_type
(var_node
->type
));
642 if
(!(assign
= make_simple_assignment
(var
, var_node
)))
645 list_add_after
(&var_node
->entry
, &assign
->node.entry
);
648 if
(!(load
= d3dcompiler_alloc
(sizeof
(*load
))))
650 init_node
(&load
->node
, HLSL_IR_LOAD
, data_type
, loc
);
652 load
->src.offset
= offset
;
653 list_add_after
(&offset
->entry
, &load
->node.entry
);
657 static struct hlsl_ir_load
*new_record_load
(struct hlsl_ir_node
*record
,
658 const struct hlsl_struct_field
*field
, const struct source_location loc
)
660 struct hlsl_ir_constant
*c
;
662 if
(!(c
= new_uint_constant
(field
->reg_offset
* 4, loc
)))
664 list_add_after
(&record
->entry
, &c
->node.entry
);
666 return new_load
(record
, &c
->node
, field
->type
, loc
);
669 static struct hlsl_ir_load
*new_array_load
(struct hlsl_ir_node
*array
,
670 struct hlsl_ir_node
*index
, const struct source_location loc
)
672 const struct hlsl_type
*expr_type
= array
->data_type
;
673 struct hlsl_type
*data_type
;
674 struct hlsl_ir_constant
*c
;
675 struct hlsl_ir_node
*mul
;
677 TRACE
("Array load from type %s.\n", debug_hlsl_type
(expr_type
));
679 if
(expr_type
->type
== HLSL_CLASS_ARRAY
)
681 data_type
= expr_type
->e.array.type
;
683 else if
(expr_type
->type
== HLSL_CLASS_MATRIX || expr_type
->type
== HLSL_CLASS_VECTOR
)
685 /* This needs to be lowered now, while we still have type information. */
686 FIXME
("Index of matrix or vector type.\n");
691 if
(expr_type
->type
== HLSL_CLASS_SCALAR
)
692 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "array-indexed expression is scalar");
694 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "expression is not array-indexable");
698 if
(!(c
= new_uint_constant
(data_type
->reg_size
* 4, loc
)))
700 list_add_after
(&index
->entry
, &c
->node.entry
);
701 if
(!(mul
= new_binary_expr
(HLSL_IR_BINOP_MUL
, index
, &c
->node
, loc
)))
703 list_add_after
(&c
->node.entry
, &mul
->entry
);
706 return new_load
(array
, index
, data_type
, loc
);
709 static void struct_var_initializer
(struct list
*list
, struct hlsl_ir_var
*var
,
710 struct parse_initializer
*initializer
)
712 struct hlsl_type
*type
= var
->data_type
;
713 struct hlsl_struct_field
*field
;
716 if
(initializer_size
(initializer
) != components_count_type
(type
))
718 hlsl_report_message
(var
->loc
, HLSL_LEVEL_ERROR
, "structure initializer mismatch");
719 free_parse_initializer
(initializer
);
723 list_move_tail
(list
, initializer
->instrs
);
724 d3dcompiler_free
(initializer
->instrs
);
726 LIST_FOR_EACH_ENTRY
(field
, type
->e.elements
, struct hlsl_struct_field
, entry
)
728 struct hlsl_ir_node
*node
= initializer
->args
[i
];
729 struct hlsl_ir_assignment
*assign
;
730 struct hlsl_ir_constant
*c
;
732 if
(i
++ >= initializer
->args_count
)
735 if
(components_count_type
(field
->type
) == components_count_type
(node
->data_type
))
737 if
(!(c
= new_uint_constant
(field
->reg_offset
* 4, node
->loc
)))
739 list_add_tail
(list
, &c
->node.entry
);
741 if
(!(assign
= new_assignment
(var
, &c
->node
, node
, 0, node
->loc
)))
743 list_add_tail
(list
, &assign
->node.entry
);
746 FIXME
("Initializing with \"mismatched\" fields is not supported yet.\n");
749 d3dcompiler_free
(initializer
->args
);
752 static void free_parse_variable_def
(struct parse_variable_def
*v
)
754 free_parse_initializer
(&v
->initializer
);
755 d3dcompiler_free
(v
->name
);
756 d3dcompiler_free
((void *)v
->semantic
);
757 d3dcompiler_free
(v
->reg_reservation
);
761 static struct list
*declare_vars
(struct hlsl_type
*basic_type
, DWORD modifiers
, struct list
*var_list
)
763 struct hlsl_type
*type
;
764 struct parse_variable_def
*v
, *v_next
;
765 struct hlsl_ir_var
*var
;
766 struct hlsl_ir_node
*assignment
;
767 BOOL ret
, local
= TRUE
;
768 struct list
*statements_list
= d3dcompiler_alloc
(sizeof
(*statements_list
));
770 if
(basic_type
->type
== HLSL_CLASS_MATRIX
)
771 assert
(basic_type
->modifiers
& HLSL_MODIFIERS_MAJORITY_MASK
);
773 if
(!statements_list
)
775 ERR
("Out of memory.\n");
776 LIST_FOR_EACH_ENTRY_SAFE
(v
, v_next
, var_list
, struct parse_variable_def
, entry
)
777 free_parse_variable_def
(v
);
778 d3dcompiler_free
(var_list
);
781 list_init
(statements_list
);
784 return statements_list
;
786 LIST_FOR_EACH_ENTRY_SAFE
(v
, v_next
, var_list
, struct parse_variable_def
, entry
)
788 var
= d3dcompiler_alloc
(sizeof
(*var
));
791 ERR
("Out of memory.\n");
792 free_parse_variable_def
(v
);
796 type
= new_array_type
(basic_type
, v
->array_size
);
799 var
->data_type
= type
;
802 var
->modifiers
= modifiers
;
803 var
->semantic
= v
->semantic
;
804 var
->reg_reservation
= v
->reg_reservation
;
805 debug_dump_decl
(type
, modifiers
, v
->name
, v
->loc.line
);
807 if
(hlsl_ctx.cur_scope
== hlsl_ctx.globals
)
809 var
->modifiers |
= HLSL_STORAGE_UNIFORM
;
813 if
(type
->modifiers
& HLSL_MODIFIER_CONST
&& !(var
->modifiers
& HLSL_STORAGE_UNIFORM
) && !v
->initializer.args_count
)
815 hlsl_report_message
(v
->loc
, HLSL_LEVEL_ERROR
, "const variable without initializer");
816 free_declaration
(var
);
821 ret
= declare_variable
(var
, local
);
824 free_declaration
(var
);
828 TRACE
("Declared variable %s.\n", var
->name
);
830 if
(v
->initializer.args_count
)
832 unsigned int size
= initializer_size
(&v
->initializer
);
833 struct hlsl_ir_load
*load
;
835 TRACE
("Variable with initializer.\n");
836 if
(type
->type
<= HLSL_CLASS_LAST_NUMERIC
837 && type
->dimx
* type
->dimy
!= size
&& size
!= 1)
839 if
(size
< type
->dimx
* type
->dimy
)
841 hlsl_report_message
(v
->loc
, HLSL_LEVEL_ERROR
,
842 "'%s' initializer does not match", v
->name
);
843 free_parse_initializer
(&v
->initializer
);
848 if
((type
->type
== HLSL_CLASS_STRUCT || type
->type
== HLSL_CLASS_ARRAY
)
849 && components_count_type
(type
) != size
)
851 hlsl_report_message
(v
->loc
, HLSL_LEVEL_ERROR
,
852 "'%s' initializer does not match", v
->name
);
853 free_parse_initializer
(&v
->initializer
);
858 if
(type
->type
== HLSL_CLASS_STRUCT
)
860 struct_var_initializer
(statements_list
, var
, &v
->initializer
);
864 if
(type
->type
> HLSL_CLASS_LAST_NUMERIC
)
866 FIXME
("Initializers for non scalar/struct variables not supported yet.\n");
867 free_parse_initializer
(&v
->initializer
);
871 if
(v
->array_size
> 0)
873 FIXME
("Initializing arrays is not supported yet.\n");
874 free_parse_initializer
(&v
->initializer
);
878 if
(v
->initializer.args_count
> 1)
880 FIXME
("Complex initializers are not supported yet.\n");
881 free_parse_initializer
(&v
->initializer
);
886 list_move_tail
(statements_list
, v
->initializer.instrs
);
887 d3dcompiler_free
(v
->initializer.instrs
);
889 load
= new_var_load
(var
, var
->loc
);
890 list_add_tail
(statements_list
, &load
->node.entry
);
891 assignment
= make_assignment
(&load
->node
, ASSIGN_OP_ASSIGN
, v
->initializer.args
[0]);
892 d3dcompiler_free
(v
->initializer.args
);
893 list_add_tail
(statements_list
, &assignment
->entry
);
897 d3dcompiler_free
(var_list
);
898 return statements_list
;
901 static BOOL add_struct_field
(struct list
*fields
, struct hlsl_struct_field
*field
)
903 struct hlsl_struct_field
*f
;
905 LIST_FOR_EACH_ENTRY
(f
, fields
, struct hlsl_struct_field
, entry
)
907 if
(!strcmp
(f
->name
, field
->name
))
910 list_add_tail
(fields
, &field
->entry
);
914 BOOL is_row_major
(const struct hlsl_type
*type
)
916 /* Default to column-major if the majority isn't explicitly set, which can
917 * happen for anonymous nodes. */
918 return
!!(type
->modifiers
& HLSL_MODIFIER_ROW_MAJOR
);
921 static struct hlsl_type
*apply_type_modifiers
(struct hlsl_type
*type
,
922 unsigned int *modifiers
, struct source_location loc
)
924 unsigned int default_majority
= 0;
925 struct hlsl_type
*new_type
;
927 /* This function is only used for declarations (i.e. variables and struct
928 * fields), which should inherit the matrix majority. We only explicitly set
929 * the default majority for declarations—typedefs depend on this—but we
930 * want to always set it, so that an hlsl_type object is never used to
931 * represent two different majorities (and thus can be used to store its
932 * register size, etc.) */
933 if
(!(*modifiers
& HLSL_MODIFIERS_MAJORITY_MASK
)
934 && !(type
->modifiers
& HLSL_MODIFIERS_MAJORITY_MASK
)
935 && type
->type
== HLSL_CLASS_MATRIX
)
937 if
(hlsl_ctx.matrix_majority
== HLSL_COLUMN_MAJOR
)
938 default_majority
= HLSL_MODIFIER_COLUMN_MAJOR
;
940 default_majority
= HLSL_MODIFIER_ROW_MAJOR
;
943 if
(!default_majority
&& !(*modifiers
& HLSL_TYPE_MODIFIERS_MASK
))
946 if
(!(new_type
= clone_hlsl_type
(type
, default_majority
)))
949 new_type
->modifiers
= add_modifiers
(new_type
->modifiers
, *modifiers
, loc
);
950 *modifiers
&= ~HLSL_TYPE_MODIFIERS_MASK
;
952 if
(new_type
->type
== HLSL_CLASS_MATRIX
)
953 new_type
->reg_size
= is_row_major
(new_type
) ? new_type
->dimy
: new_type
->dimx
;
957 static struct list
*gen_struct_fields
(struct hlsl_type
*type
, DWORD modifiers
, struct list
*fields
)
959 struct parse_variable_def
*v
, *v_next
;
960 struct hlsl_struct_field
*field
;
963 if
(type
->type
== HLSL_CLASS_MATRIX
)
964 assert
(type
->modifiers
& HLSL_MODIFIERS_MAJORITY_MASK
);
966 list
= d3dcompiler_alloc
(sizeof
(*list
));
969 ERR
("Out of memory.\n");
973 LIST_FOR_EACH_ENTRY_SAFE
(v
, v_next
, fields
, struct parse_variable_def
, entry
)
975 debug_dump_decl
(type
, 0, v
->name
, v
->loc.line
);
976 field
= d3dcompiler_alloc
(sizeof
(*field
));
979 ERR
("Out of memory.\n");
984 field
->type
= new_array_type
(type
, v
->array_size
);
987 field
->name
= v
->name
;
988 field
->modifiers
= modifiers
;
989 field
->semantic
= v
->semantic
;
990 if
(v
->initializer.args_count
)
992 hlsl_report_message
(v
->loc
, HLSL_LEVEL_ERROR
, "struct field with an initializer.\n");
993 free_parse_initializer
(&v
->initializer
);
995 list_add_tail
(list
, &field
->entry
);
998 d3dcompiler_free
(fields
);
1002 static DWORD get_array_size
(const struct hlsl_type
*type
)
1004 if
(type
->type
== HLSL_CLASS_ARRAY
)
1005 return get_array_size
(type
->e.array.type
) * type
->e.array.elements_count
;
1009 static struct hlsl_type
*new_struct_type
(const char *name
, struct list
*fields
)
1011 struct hlsl_type
*type
= d3dcompiler_alloc
(sizeof
(*type
));
1012 struct hlsl_struct_field
*field
;
1013 unsigned int reg_size
= 0;
1017 ERR
("Out of memory.\n");
1020 type
->type
= HLSL_CLASS_STRUCT
;
1021 type
->base_type
= HLSL_TYPE_VOID
;
1025 type
->e.elements
= fields
;
1027 LIST_FOR_EACH_ENTRY
(field
, fields
, struct hlsl_struct_field
, entry
)
1029 field
->reg_offset
= reg_size
;
1030 reg_size
+= field
->type
->reg_size
;
1031 type
->dimx
+= field
->type
->dimx
* field
->type
->dimy
* get_array_size
(field
->type
);
1033 type
->reg_size
= reg_size
;
1035 list_add_tail
(&hlsl_ctx.types
, &type
->entry
);
1040 static BOOL add_typedef
(DWORD modifiers
, struct hlsl_type
*orig_type
, struct list
*list
)
1043 struct hlsl_type
*type
;
1044 struct parse_variable_def
*v
, *v_next
;
1046 LIST_FOR_EACH_ENTRY_SAFE
(v
, v_next
, list
, struct parse_variable_def
, entry
)
1049 type
= new_array_type
(orig_type
, v
->array_size
);
1051 type
= clone_hlsl_type
(orig_type
, 0);
1054 ERR
("Out of memory\n");
1057 d3dcompiler_free
((void *)type
->name
);
1058 type
->name
= v
->name
;
1059 type
->modifiers |
= modifiers
;
1061 if
(type
->type
!= HLSL_CLASS_MATRIX
)
1062 check_invalid_matrix_modifiers
(type
->modifiers
, v
->loc
);
1064 type
->reg_size
= is_row_major
(type
) ? type
->dimy
: type
->dimx
;
1066 if
((type
->modifiers
& HLSL_MODIFIER_COLUMN_MAJOR
)
1067 && (type
->modifiers
& HLSL_MODIFIER_ROW_MAJOR
))
1068 hlsl_report_message
(v
->loc
, HLSL_LEVEL_ERROR
, "more than one matrix majority keyword");
1070 ret
= add_type_to_scope
(hlsl_ctx.cur_scope
, type
);
1073 hlsl_report_message
(v
->loc
, HLSL_LEVEL_ERROR
,
1074 "redefinition of custom type '%s'", v
->name
);
1076 d3dcompiler_free
(v
);
1078 d3dcompiler_free
(list
);
1082 static BOOL add_func_parameter
(struct list
*list
, struct parse_parameter
*param
, const struct source_location loc
)
1084 struct hlsl_ir_var
*decl
= d3dcompiler_alloc
(sizeof
(*decl
));
1086 if
(param
->type
->type
== HLSL_CLASS_MATRIX
)
1087 assert
(param
->type
->modifiers
& HLSL_MODIFIERS_MAJORITY_MASK
);
1091 ERR
("Out of memory.\n");
1094 decl
->data_type
= param
->type
;
1096 decl
->name
= param
->name
;
1097 decl
->semantic
= param
->semantic
;
1098 decl
->reg_reservation
= param
->reg_reservation
;
1099 decl
->modifiers
= param
->modifiers
;
1101 if
(!add_declaration
(hlsl_ctx.cur_scope
, decl
, FALSE
))
1103 free_declaration
(decl
);
1106 list_add_tail
(list
, &decl
->param_entry
);
1110 static struct reg_reservation
*parse_reg_reservation
(const char *reg_string
)
1112 struct reg_reservation
*reg_res
;
1113 enum bwritershader_param_register_type type
;
1116 switch
(reg_string
[0])
1119 type
= BWRITERSPR_CONST
;
1122 type
= BWRITERSPR_CONSTINT
;
1125 type
= BWRITERSPR_CONSTBOOL
;
1128 type
= BWRITERSPR_SAMPLER
;
1131 FIXME
("Unsupported register type.\n");
1135 if
(!sscanf
(reg_string
+ 1, "%u", ®num
))
1137 FIXME
("Unsupported register reservation syntax.\n");
1141 reg_res
= d3dcompiler_alloc
(sizeof
(*reg_res
));
1144 ERR
("Out of memory.\n");
1147 reg_res
->type
= type
;
1148 reg_res
->regnum
= regnum
;
1152 static const struct hlsl_ir_function_decl
*get_overloaded_func
(struct wine_rb_tree
*funcs
, char *name
,
1153 struct list
*params
, BOOL exact_signature
)
1155 struct hlsl_ir_function
*func
;
1156 struct wine_rb_entry
*entry
;
1158 entry
= wine_rb_get
(funcs
, name
);
1161 func
= WINE_RB_ENTRY_VALUE
(entry
, struct hlsl_ir_function
, entry
);
1163 entry
= wine_rb_get
(&func
->overloads
, params
);
1166 if
(!exact_signature
)
1167 FIXME
("No exact match, search for a compatible overloaded function (if any).\n");
1170 return WINE_RB_ENTRY_VALUE
(entry
, struct hlsl_ir_function_decl
, entry
);
1175 static struct hlsl_ir_function_decl
*get_func_entry
(const char *name
)
1177 struct hlsl_ir_function_decl
*decl
;
1178 struct hlsl_ir_function
*func
;
1179 struct wine_rb_entry
*entry
;
1181 if
((entry
= wine_rb_get
(&hlsl_ctx.functions
, name
)))
1183 func
= WINE_RB_ENTRY_VALUE
(entry
, struct hlsl_ir_function
, entry
);
1184 WINE_RB_FOR_EACH_ENTRY
(decl
, &func
->overloads
, struct hlsl_ir_function_decl
, entry
)
1191 static struct list
*append_unop
(struct list
*list
, struct hlsl_ir_node
*node
)
1193 list_add_tail
(list
, &node
->entry
);
1197 static struct list
*append_binop
(struct list
*first
, struct list
*second
, struct hlsl_ir_node
*node
)
1199 list_move_tail
(first
, second
);
1200 d3dcompiler_free
(second
);
1201 list_add_tail
(first
, &node
->entry
);
1205 static struct list
*make_list
(struct hlsl_ir_node
*node
)
1209 if
(!(list
= d3dcompiler_alloc
(sizeof
(*list
))))
1211 ERR
("Out of memory.\n");
1216 list_add_tail
(list
, &node
->entry
);
1220 static unsigned int evaluate_array_dimension
(struct hlsl_ir_node
*node
)
1222 if
(node
->data_type
->type
!= HLSL_CLASS_SCALAR
)
1227 case HLSL_IR_CONSTANT
:
1229 struct hlsl_ir_constant
*constant
= constant_from_node
(node
);
1231 switch
(constant
->node.data_type
->base_type
)
1233 case HLSL_TYPE_UINT
:
1234 return constant
->v.value.u
[0];
1236 return constant
->v.value.i
[0];
1237 case HLSL_TYPE_FLOAT
:
1238 return constant
->v.value.f
[0];
1239 case HLSL_TYPE_DOUBLE
:
1240 return constant
->v.value.d
[0];
1241 case HLSL_TYPE_BOOL
:
1242 return constant
->v.value.b
[0];
1244 WARN
("Invalid type %s.\n", debug_base_type
(constant
->node.data_type
));
1248 case HLSL_IR_CONSTRUCTOR
:
1251 case HLSL_IR_SWIZZLE
:
1252 FIXME
("Unhandled type %s.\n", debug_node_type
(node
->type
));
1254 case HLSL_IR_ASSIGNMENT
:
1256 WARN
("Invalid node type %s.\n", debug_node_type
(node
->type
));
1261 static struct hlsl_ir_function_decl
*new_func_decl
(struct hlsl_type
*return_type
,
1262 struct list
*parameters
, const char *semantic
, struct source_location loc
)
1264 struct hlsl_ir_function_decl
*decl
;
1266 if
(!(decl
= d3dcompiler_alloc
(sizeof
(*decl
))))
1268 decl
->return_type
= return_type
;
1269 decl
->parameters
= parameters
;
1270 decl
->semantic
= semantic
;
1273 if
(!type_is_void
(return_type
))
1275 struct hlsl_ir_var
*return_var
;
1278 sprintf
(name
, "<retval-%p>", decl
);
1279 if
(!(return_var
= new_synthetic_var
(name
, return_type
, loc
)))
1281 d3dcompiler_free
(decl
);
1284 decl
->return_var
= return_var
;
1293 %define parse.
error verbose
1298 struct hlsl_type
*type
;
1304 struct hlsl_ir_node
*instr
;
1306 struct parse_function function
;
1307 struct parse_parameter parameter
;
1308 struct parse_initializer initializer
;
1309 struct parse_variable_def
*variable_def
;
1310 struct parse_if_body if_body
;
1311 enum parse_unary_op unary_op
;
1312 enum parse_assign_op assign_op
;
1313 struct reg_reservation
*reg_reservation
;
1314 struct parse_colon_attribute colon_attribute
;
1317 %token KW_BLENDSTATE
1321 %token KW_COLUMN_MAJOR
1325 %token KW_DEPTHSTENCILSTATE
1326 %token KW_DEPTHSTENCILVIEW
1334 %token KW_GEOMETRYSHADER
1335 %token KW_GROUPSHARED
1342 %token KW_NOINTERPOLATION
1345 %token KW_PIXELSHADER
1347 %token KW_RASTERIZERSTATE
1348 %token KW_RENDERTARGETVIEW
1356 %token KW_SAMPLERCUBE
1357 %token KW_SAMPLER_STATE
1358 %token KW_SAMPLERCOMPARISONSTATE
1360 %token KW_STATEBLOCK
1361 %token KW_STATEBLOCK_STATE
1368 %token KW_TECHNIQUE10
1371 %token KW_TEXTURE1DARRAY
1373 %token KW_TEXTURE2DARRAY
1374 %token KW_TEXTURE2DMS
1375 %token KW_TEXTURE2DMSARRAY
1377 %token KW_TEXTURE3DARRAY
1378 %token KW_TEXTURECUBE
1383 %token KW_VERTEXSHADER
1394 %token OP_LEFTSHIFTASSIGN
1395 %token OP_RIGHTSHIFT
1396 %token OP_RIGHTSHIFTASSIGN
1414 %token
<intval
> PRE_LINE
1416 %token
<name
> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
1417 %type
<name
> any_identifier var_identifier
1418 %token
<name
> STRING
1419 %token
<floatval
> C_FLOAT
1420 %token
<intval
> C_INTEGER
1421 %type
<boolval
> boolean
1422 %type
<type
> base_type
1424 %type
<list
> declaration_statement
1425 %type
<list
> declaration
1426 %type
<list
> struct_declaration
1427 %type
<type
> struct_spec
1428 %type
<type
> named_struct_spec
1429 %type
<type
> unnamed_struct_spec
1430 %type
<type
> field_type
1431 %type
<type
> typedef_type
1432 %type
<list
> type_specs
1433 %type
<variable_def
> type_spec
1434 %type
<initializer
> complex_initializer
1435 %type
<initializer
> initializer_expr_list
1436 %type
<list
> initializer_expr
1437 %type
<modifiers
> var_modifiers
1439 %type
<list
> parameters
1440 %type
<list
> param_list
1442 %type
<intval
> array
1443 %type
<list
> statement
1444 %type
<list
> statement_list
1445 %type
<list
> compound_statement
1446 %type
<list
> jump_statement
1447 %type
<list
> selection_statement
1448 %type
<list
> loop_statement
1449 %type
<function
> func_declaration
1450 %type
<function
> func_prototype
1451 %type
<list
> fields_list
1452 %type
<parameter
> parameter
1453 %type
<colon_attribute
> colon_attribute
1454 %type
<name
> semantic
1455 %type
<reg_reservation
> register_opt
1456 %type
<variable_def
> variable_def
1457 %type
<list
> variables_def
1458 %type
<list
> variables_def_optional
1459 %type
<if_body
> if_body
1460 %type
<list
> primary_expr
1461 %type
<list
> postfix_expr
1462 %type
<list
> unary_expr
1463 %type
<list
> mul_expr
1464 %type
<list
> add_expr
1465 %type
<list
> shift_expr
1466 %type
<list
> relational_expr
1467 %type
<list
> equality_expr
1468 %type
<list
> bitand_expr
1469 %type
<list
> bitxor_expr
1470 %type
<list
> bitor_expr
1471 %type
<list
> logicand_expr
1472 %type
<list
> logicor_expr
1473 %type
<list
> conditional_expr
1474 %type
<list
> assignment_expr
1475 %type
<list
> expr_statement
1476 %type
<unary_op
> unary_op
1477 %type
<assign_op
> assign_op
1478 %type
<modifiers
> input_mods
1479 %type
<modifiers
> input_mod
1482 hlsl_prog: /* empty */
1485 | hlsl_prog func_declaration
1487 const struct hlsl_ir_function_decl
*decl
;
1489 decl
= get_overloaded_func
(&hlsl_ctx.functions
, $2.name
, $2.decl
->parameters
, TRUE
);
1490 if
(decl
&& !decl
->func
->intrinsic
)
1492 if
(decl
->body
&& $2.decl
->body
)
1494 hlsl_report_message
($2.decl
->loc
, HLSL_LEVEL_ERROR
,
1495 "redefinition of function %s", debugstr_a
($2.name
));
1498 else if
(!compare_hlsl_types
(decl
->return_type
, $2.decl
->return_type
))
1500 hlsl_report_message
($2.decl
->loc
, HLSL_LEVEL_ERROR
,
1501 "redefining function %s with a different return type",
1502 debugstr_a
($2.name
));
1503 hlsl_report_message
(decl
->loc
, HLSL_LEVEL_NOTE
,
1504 "%s previously declared here",
1505 debugstr_a
($2.name
));
1510 if
(type_is_void
($2.decl
->return_type
) && $2.decl
->semantic
)
1512 hlsl_report_message
($2.decl
->loc
, HLSL_LEVEL_ERROR
,
1513 "void function with a semantic");
1516 TRACE
("Adding function '%s' to the function list.\n", $2.name
);
1517 add_function_decl
(&hlsl_ctx.functions
, $2.name
, $2.decl
, FALSE
);
1519 | hlsl_prog declaration_statement
1521 TRACE
("Declaration statement parsed.\n");
1523 | hlsl_prog preproc_directive
1528 TRACE
("Skipping stray semicolon.\n");
1531 preproc_directive: PRE_LINE STRING
1533 const char **new_array
= NULL
;
1535 TRACE
("Updating line information to file %s, line %u\n", debugstr_a
($2), $1);
1536 hlsl_ctx.line_no
= $1;
1537 if
(strcmp
($2, hlsl_ctx.source_file
))
1538 new_array
= d3dcompiler_realloc
(hlsl_ctx.source_files
,
1539 sizeof
(*hlsl_ctx.source_files
) * (hlsl_ctx.source_files_count
+ 1));
1543 hlsl_ctx.source_files
= new_array
;
1544 hlsl_ctx.source_files
[hlsl_ctx.source_files_count
++] = $2;
1545 hlsl_ctx.source_file
= $2;
1549 d3dcompiler_free
($2);
1553 struct_declaration: var_modifiers struct_spec variables_def_optional
';'
1555 struct hlsl_type
*type
;
1556 DWORD modifiers
= $1;
1562 hlsl_report_message
(get_location
(&@
2), HLSL_LEVEL_ERROR
,
1563 "anonymous struct declaration with no variables");
1567 hlsl_report_message
(get_location
(&@
1), HLSL_LEVEL_ERROR
,
1568 "modifier not allowed on struct type declaration");
1572 if
(!(type
= apply_type_modifiers
($2, &modifiers
, get_location
(&@
1))))
1574 $$
= declare_vars
(type
, modifiers
, $3);
1577 struct_spec: named_struct_spec
1578 | unnamed_struct_spec
1580 named_struct_spec: KW_STRUCT any_identifier
'{' fields_list
'}'
1584 TRACE
("Structure %s declaration.\n", debugstr_a
($2));
1585 $$
= new_struct_type
($2, $4);
1587 if
(get_variable
(hlsl_ctx.cur_scope
, $2))
1589 hlsl_report_message
(get_location
(&@
2),
1590 HLSL_LEVEL_ERROR
, "redefinition of '%s'", $2);
1594 ret
= add_type_to_scope
(hlsl_ctx.cur_scope
, $$
);
1597 hlsl_report_message
(get_location
(&@
2),
1598 HLSL_LEVEL_ERROR
, "redefinition of struct '%s'", $2);
1603 unnamed_struct_spec: KW_STRUCT
'{' fields_list
'}'
1605 TRACE
("Anonymous structure declaration.\n");
1606 $$
= new_struct_type
(NULL
, $3);
1609 any_identifier: VAR_IDENTIFIER
1613 fields_list: /* Empty */
1615 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
1621 struct hlsl_struct_field
*field
, *next
;
1624 LIST_FOR_EACH_ENTRY_SAFE
(field
, next
, $2, struct hlsl_struct_field
, entry
)
1626 ret
= add_struct_field
($$
, field
);
1629 hlsl_report_message
(get_location
(&@
2),
1630 HLSL_LEVEL_ERROR
, "redefinition of '%s'", field
->name
);
1631 d3dcompiler_free
(field
);
1634 d3dcompiler_free
($2);
1638 | unnamed_struct_spec
1640 field: var_modifiers field_type variables_def
';'
1642 struct hlsl_type
*type
;
1643 DWORD modifiers
= $1;
1645 if
(!(type
= apply_type_modifiers
($2, &modifiers
, get_location
(&@
1))))
1647 $$
= gen_struct_fields
(type
, modifiers
, $3);
1650 func_declaration: func_prototype compound_statement
1652 TRACE
("Function %s parsed.\n", $1.name
);
1655 pop_scope
(&hlsl_ctx
);
1657 | func_prototype
';'
1659 TRACE
("Function prototype for %s.\n", $1.name
);
1661 pop_scope
(&hlsl_ctx
);
1664 /* var_modifiers is necessary to avoid shift/reduce conflicts. */
1665 func_prototype: var_modifiers type var_identifier
'(' parameters
')' colon_attribute
1669 hlsl_report_message
(get_location
(&@
1), HLSL_LEVEL_ERROR
,
1670 "unexpected modifiers on a function");
1673 if
(get_variable
(hlsl_ctx.globals
, $3))
1675 hlsl_report_message
(get_location
(&@
3),
1676 HLSL_LEVEL_ERROR
, "redefinition of '%s'\n", $3);
1679 if
(type_is_void
($2) && $7.semantic
)
1681 hlsl_report_message
(get_location
(&@
7),
1682 HLSL_LEVEL_ERROR
, "void function with a semantic");
1685 if
($7.reg_reservation
)
1687 FIXME
("Unexpected register reservation for a function.\n");
1688 d3dcompiler_free
($7.reg_reservation
);
1690 if
(!($$.decl
= new_func_decl
($2, $5, $7.semantic
, get_location
(&@
3))))
1692 ERR
("Out of memory.\n");
1696 hlsl_ctx.cur_function
= $$.decl
;
1699 compound_statement: '{' '}'
1701 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
1704 |
'{' scope_start statement_list
'}'
1706 pop_scope
(&hlsl_ctx
);
1710 scope_start: /* Empty */
1712 push_scope
(&hlsl_ctx
);
1715 var_identifier: VAR_IDENTIFIER
1718 colon_attribute: /* Empty */
1721 $$.reg_reservation
= NULL
;
1726 $$.reg_reservation
= NULL
;
1731 $$.reg_reservation
= $1;
1734 semantic: ':' any_identifier
1739 /* FIXME: Writemasks */
1740 register_opt: ':' KW_REGISTER
'(' any_identifier
')'
1742 $$
= parse_reg_reservation
($4);
1743 d3dcompiler_free
($4);
1745 |
':' KW_REGISTER
'(' any_identifier
',' any_identifier
')'
1747 FIXME
("Ignoring shader target %s in a register reservation.\n", debugstr_a
($4));
1748 d3dcompiler_free
($4);
1750 $$
= parse_reg_reservation
($6);
1751 d3dcompiler_free
($6);
1754 parameters: scope_start
1756 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
1759 | scope_start param_list
1764 param_list: parameter
1766 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
1768 if
(!add_func_parameter
($$
, &$1, get_location
(&@
1)))
1770 ERR
("Error adding function parameter %s.\n", $1.name
);
1771 set_parse_status
(&hlsl_ctx.status
, PARSE_ERR
);
1775 | param_list
',' parameter
1778 if
(!add_func_parameter
($$
, &$3, get_location
(&@
3)))
1780 hlsl_report_message
(get_location
(&@
3), HLSL_LEVEL_ERROR
,
1781 "duplicate parameter %s", $3.name
);
1786 parameter: input_mods var_modifiers type any_identifier colon_attribute
1788 struct hlsl_type
*type
;
1789 DWORD modifiers
= $2;
1791 if
(!(type
= apply_type_modifiers
($3, &modifiers
, get_location
(&@
2))))
1794 $$.modifiers
= $1 ?
$1 : HLSL_STORAGE_IN
;
1795 $$.modifiers |
= modifiers
;
1798 $$.semantic
= $5.semantic
;
1799 $$.reg_reservation
= $5.reg_reservation
;
1802 input_mods: /* Empty */
1806 | input_mods input_mod
1810 hlsl_report_message
(get_location
(&@
2), HLSL_LEVEL_ERROR
,
1811 "duplicate input-output modifiers");
1819 $$
= HLSL_STORAGE_IN
;
1823 $$
= HLSL_STORAGE_OUT
;
1827 $$
= HLSL_STORAGE_IN | HLSL_STORAGE_OUT
;
1836 | KW_VECTOR
'<' base_type
',' C_INTEGER
'>'
1838 if
($3->type
!= HLSL_CLASS_SCALAR
)
1840 hlsl_report_message
(get_location
(&@
3), HLSL_LEVEL_ERROR
,
1841 "vectors of non-scalar types are not allowed\n");
1844 if
($5 < 1 ||
$5 > 4)
1846 hlsl_report_message
(get_location
(&@
5), HLSL_LEVEL_ERROR
,
1847 "vector size must be between 1 and 4\n");
1851 $$
= new_hlsl_type
(NULL
, HLSL_CLASS_VECTOR
, $3->base_type
, $5, 1);
1853 | KW_MATRIX
'<' base_type
',' C_INTEGER
',' C_INTEGER
'>'
1855 if
($3->type
!= HLSL_CLASS_SCALAR
)
1857 hlsl_report_message
(get_location
(&@
3), HLSL_LEVEL_ERROR
,
1858 "matrices of non-scalar types are not allowed\n");
1861 if
($5 < 1 ||
$5 > 4)
1863 hlsl_report_message
(get_location
(&@
5), HLSL_LEVEL_ERROR
,
1864 "matrix row count must be between 1 and 4\n");
1867 if
($7 < 1 ||
$7 > 4)
1869 hlsl_report_message
(get_location
(&@
7), HLSL_LEVEL_ERROR
,
1870 "matrix column count must be between 1 and 4\n");
1874 $$
= new_hlsl_type
(NULL
, HLSL_CLASS_MATRIX
, $3->base_type
, $7, $5);
1881 $$
= hlsl_ctx.builtin_types.Void
;
1885 $$
= hlsl_ctx.builtin_types.sampler
[HLSL_SAMPLER_DIM_GENERIC
];
1889 $$
= hlsl_ctx.builtin_types.sampler
[HLSL_SAMPLER_DIM_1D
];
1893 $$
= hlsl_ctx.builtin_types.sampler
[HLSL_SAMPLER_DIM_2D
];
1897 $$
= hlsl_ctx.builtin_types.sampler
[HLSL_SAMPLER_DIM_3D
];
1901 $$
= hlsl_ctx.builtin_types.sampler
[HLSL_SAMPLER_DIM_3D
];
1905 $$
= get_type
(hlsl_ctx.cur_scope
, $1, TRUE
);
1906 d3dcompiler_free
($1);
1908 | KW_STRUCT TYPE_IDENTIFIER
1910 $$
= get_type
(hlsl_ctx.cur_scope
, $2, TRUE
);
1911 if
($$
->type
!= HLSL_CLASS_STRUCT
)
1912 hlsl_report_message
(get_location
(&@
1), HLSL_LEVEL_ERROR
, "'%s' redefined as a structure\n", $2);
1913 d3dcompiler_free
($2);
1916 declaration_statement: declaration
1917 | struct_declaration
1920 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
1923 ERR
("Out of memory\n");
1932 typedef: KW_TYPEDEF var_modifiers typedef_type type_specs
';'
1934 if
($2 & ~HLSL_TYPE_MODIFIERS_MASK
)
1936 struct parse_variable_def
*v
, *v_next
;
1937 hlsl_report_message
(get_location
(&@
1),
1938 HLSL_LEVEL_ERROR
, "modifier not allowed on typedefs");
1939 LIST_FOR_EACH_ENTRY_SAFE
(v
, v_next
, $4, struct parse_variable_def
, entry
)
1940 d3dcompiler_free
(v
);
1941 d3dcompiler_free
($4);
1944 if
(!add_typedef
($2, $3, $4))
1948 type_specs: type_spec
1950 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
1952 list_add_head
($$
, &$1->entry
);
1954 | type_specs
',' type_spec
1957 list_add_tail
($$
, &$3->entry
);
1960 type_spec: any_identifier array
1962 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
1963 $$
->loc
= get_location
(&@
1);
1965 $$
->array_size
= $2;
1968 declaration: var_modifiers type variables_def
';'
1970 struct hlsl_type
*type
;
1971 DWORD modifiers
= $1;
1973 if
(!(type
= apply_type_modifiers
($2, &modifiers
, get_location
(&@
1))))
1975 $$
= declare_vars
(type
, modifiers
, $3);
1978 variables_def_optional: /* Empty */
1987 variables_def: variable_def
1989 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
1991 list_add_head
($$
, &$1->entry
);
1993 | variables_def
',' variable_def
1996 list_add_tail
($$
, &$3->entry
);
1999 variable_def: any_identifier array colon_attribute
2001 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
2002 $$
->loc
= get_location
(&@
1);
2004 $$
->array_size
= $2;
2005 $$
->semantic
= $3.semantic
;
2006 $$
->reg_reservation
= $3.reg_reservation
;
2008 | any_identifier array colon_attribute
'=' complex_initializer
2010 TRACE
("Declaration with initializer.\n");
2011 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
2012 $$
->loc
= get_location
(&@
1);
2014 $$
->array_size
= $2;
2015 $$
->semantic
= $3.semantic
;
2016 $$
->reg_reservation
= $3.reg_reservation
;
2017 $$
->initializer
= $5;
2026 unsigned int size
= evaluate_array_dimension
(node_from_list
($2));
2028 free_instr_list
($2);
2032 hlsl_report_message
(get_location
(&@
2), HLSL_LEVEL_ERROR
,
2033 "array size is not a positive integer constant\n");
2036 TRACE
("Array size %u.\n", size
);
2040 hlsl_report_message
(get_location
(&@
2), HLSL_LEVEL_ERROR
,
2041 "array size must be between 1 and 65536");
2047 var_modifiers: /* Empty */
2051 | KW_EXTERN var_modifiers
2053 $$
= add_modifiers
($2, HLSL_STORAGE_EXTERN
, get_location
(&@
1));
2055 | KW_NOINTERPOLATION var_modifiers
2057 $$
= add_modifiers
($2, HLSL_STORAGE_NOINTERPOLATION
, get_location
(&@
1));
2059 | KW_PRECISE var_modifiers
2061 $$
= add_modifiers
($2, HLSL_MODIFIER_PRECISE
, get_location
(&@
1));
2063 | KW_SHARED var_modifiers
2065 $$
= add_modifiers
($2, HLSL_STORAGE_SHARED
, get_location
(&@
1));
2067 | KW_GROUPSHARED var_modifiers
2069 $$
= add_modifiers
($2, HLSL_STORAGE_GROUPSHARED
, get_location
(&@
1));
2071 | KW_STATIC var_modifiers
2073 $$
= add_modifiers
($2, HLSL_STORAGE_STATIC
, get_location
(&@
1));
2075 | KW_UNIFORM var_modifiers
2077 $$
= add_modifiers
($2, HLSL_STORAGE_UNIFORM
, get_location
(&@
1));
2079 | KW_VOLATILE var_modifiers
2081 $$
= add_modifiers
($2, HLSL_STORAGE_VOLATILE
, get_location
(&@
1));
2083 | KW_CONST var_modifiers
2085 $$
= add_modifiers
($2, HLSL_MODIFIER_CONST
, get_location
(&@
1));
2087 | KW_ROW_MAJOR var_modifiers
2089 $$
= add_modifiers
($2, HLSL_MODIFIER_ROW_MAJOR
, get_location
(&@
1));
2091 | KW_COLUMN_MAJOR var_modifiers
2093 $$
= add_modifiers
($2, HLSL_MODIFIER_COLUMN_MAJOR
, get_location
(&@
1));
2096 complex_initializer: initializer_expr
2099 if
(!($$.args
= d3dcompiler_alloc
(sizeof
(*$$.args
))))
2101 $$.args
[0] = node_from_list
($1);
2104 |
'{' initializer_expr_list
'}'
2108 |
'{' initializer_expr_list
',' '}'
2113 initializer_expr: assignment_expr
2118 initializer_expr_list: initializer_expr
2121 if
(!($$.args
= d3dcompiler_alloc
(sizeof
(*$$.args
))))
2123 $$.args
[0] = node_from_list
($1);
2126 | initializer_expr_list
',' initializer_expr
2129 if
(!($$.args
= d3dcompiler_realloc
($$.args
, ($$.args_count
+ 1) * sizeof
(*$$.args
))))
2131 $$.args
[$$.args_count
++] = node_from_list
($3);
2132 list_move_tail
($$.instrs
, $3);
2133 d3dcompiler_free
($3);
2145 statement_list: statement
2149 | statement_list statement
2152 list_move_tail
($$
, $2);
2153 d3dcompiler_free
($2);
2156 statement: declaration_statement
2158 | compound_statement
2160 | selection_statement
2163 jump_statement: KW_RETURN expr
';'
2165 struct hlsl_ir_jump
*jump
;
2166 if
(!(jump
= new_return
(node_from_list
($2), get_location
(&@
1))))
2170 list_add_tail
($$
, &jump
->node.entry
);
2174 struct hlsl_ir_jump
*jump
;
2175 if
(!(jump
= new_return
(NULL
, get_location
(&@
1))))
2177 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
2179 list_add_tail
($$
, &jump
->node.entry
);
2182 selection_statement: KW_IF
'(' expr
')' if_body
2184 struct hlsl_ir_if
*instr
= d3dcompiler_alloc
(sizeof
(*instr
));
2187 ERR
("Out of memory\n");
2190 init_node
(&instr
->node
, HLSL_IR_IF
, NULL
, get_location
(&@
1));
2191 instr
->condition
= node_from_list
($3);
2192 instr
->then_instrs
= $5.then_instrs
;
2193 instr
->else_instrs
= $5.else_instrs
;
2194 if
(instr
->condition
->data_type
->dimx
> 1 || instr
->condition
->data_type
->dimy
> 1)
2196 hlsl_report_message
(instr
->node.loc
, HLSL_LEVEL_ERROR
,
2197 "if condition requires a scalar");
2200 list_add_tail
($$
, &instr
->node.entry
);
2205 $$.then_instrs
= $1;
2206 $$.else_instrs
= NULL
;
2208 | statement KW_ELSE statement
2210 $$.then_instrs
= $1;
2211 $$.else_instrs
= $3;
2214 loop_statement: KW_WHILE
'(' expr
')' statement
2216 $$
= create_loop
(LOOP_WHILE
, NULL
, $3, NULL
, $5, get_location
(&@
1));
2218 | KW_DO statement KW_WHILE
'(' expr
')' ';'
2220 $$
= create_loop
(LOOP_DO_WHILE
, NULL
, $5, NULL
, $2, get_location
(&@
1));
2222 | KW_FOR
'(' scope_start expr_statement expr_statement expr
')' statement
2224 $$
= create_loop
(LOOP_FOR
, $4, $5, $6, $8, get_location
(&@
1));
2225 pop_scope
(&hlsl_ctx
);
2227 | KW_FOR
'(' scope_start declaration expr_statement expr
')' statement
2230 hlsl_report_message
(get_location
(&@
4), HLSL_LEVEL_WARNING
,
2231 "no expressions in for loop initializer");
2232 $$
= create_loop
(LOOP_FOR
, $4, $5, $6, $8, get_location
(&@
1));
2233 pop_scope
(&hlsl_ctx
);
2238 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
2246 primary_expr: C_FLOAT
2248 struct hlsl_ir_constant
*c
= d3dcompiler_alloc
(sizeof
(*c
));
2251 ERR
("Out of memory.\n");
2254 init_node
(&c
->node
, HLSL_IR_CONSTANT
,
2255 hlsl_ctx.builtin_types.scalar
[HLSL_TYPE_FLOAT
], get_location
(&@
1));
2256 c
->v.value.f
[0] = $1;
2257 if
(!($$
= make_list
(&c
->node
)))
2262 struct hlsl_ir_constant
*c
= d3dcompiler_alloc
(sizeof
(*c
));
2265 ERR
("Out of memory.\n");
2268 init_node
(&c
->node
, HLSL_IR_CONSTANT
,
2269 hlsl_ctx.builtin_types.scalar
[HLSL_TYPE_INT
], get_location
(&@
1));
2270 c
->v.value.i
[0] = $1;
2271 if
(!($$
= make_list
(&c
->node
)))
2276 struct hlsl_ir_constant
*c
= d3dcompiler_alloc
(sizeof
(*c
));
2279 ERR
("Out of memory.\n");
2282 init_node
(&c
->node
, HLSL_IR_CONSTANT
,
2283 hlsl_ctx.builtin_types.scalar
[HLSL_TYPE_BOOL
], get_location
(&@
1));
2284 c
->v.value.b
[0] = $1;
2285 if
(!($$
= make_list
(&c
->node
)))
2290 struct hlsl_ir_load
*load
;
2291 struct hlsl_ir_var
*var
;
2293 if
(!(var
= get_variable
(hlsl_ctx.cur_scope
, $1)))
2295 hlsl_report_message
(get_location
(&@
1), HLSL_LEVEL_ERROR
,
2296 "variable '%s' is not declared\n", $1);
2299 if
((load
= new_var_load
(var
, get_location
(&@
1))))
2301 if
(!($$
= make_list
(&load
->node
)))
2312 postfix_expr: primary_expr
2316 | postfix_expr OP_INC
2318 struct source_location loc
;
2319 struct hlsl_ir_node
*inc
;
2321 loc
= get_location
(&@
2);
2322 if
(node_from_list
($1)->data_type
->modifiers
& HLSL_MODIFIER_CONST
)
2324 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "modifying a const expression");
2327 inc
= new_unary_expr
(HLSL_IR_UNOP_POSTINC
, node_from_list
($1), loc
);
2328 /* Post increment/decrement expressions are considered const */
2329 inc
->data_type
= clone_hlsl_type
(inc
->data_type
, 0);
2330 inc
->data_type
->modifiers |
= HLSL_MODIFIER_CONST
;
2331 $$
= append_unop
($1, inc
);
2333 | postfix_expr OP_DEC
2335 struct source_location loc
;
2336 struct hlsl_ir_node
*inc
;
2338 loc
= get_location
(&@
2);
2339 if
(node_from_list
($1)->data_type
->modifiers
& HLSL_MODIFIER_CONST
)
2341 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "modifying a const expression");
2344 inc
= new_unary_expr
(HLSL_IR_UNOP_POSTDEC
, node_from_list
($1), loc
);
2345 /* Post increment/decrement expressions are considered const */
2346 inc
->data_type
= clone_hlsl_type
(inc
->data_type
, 0);
2347 inc
->data_type
->modifiers |
= HLSL_MODIFIER_CONST
;
2348 $$
= append_unop
($1, inc
);
2350 | postfix_expr
'.' any_identifier
2352 struct hlsl_ir_node
*node
= node_from_list
($1);
2353 struct source_location loc
;
2355 loc
= get_location
(&@
2);
2356 if
(node
->data_type
->type
== HLSL_CLASS_STRUCT
)
2358 struct hlsl_type
*type
= node
->data_type
;
2359 struct hlsl_struct_field
*field
;
2362 LIST_FOR_EACH_ENTRY
(field
, type
->e.elements
, struct hlsl_struct_field
, entry
)
2364 if
(!strcmp
($3, field
->name
))
2366 if
(!new_record_load
(node
, field
, loc
))
2374 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
,
2375 "invalid subscript %s", debugstr_a
($3));
2379 else if
(node
->data_type
->type
<= HLSL_CLASS_LAST_NUMERIC
)
2381 struct hlsl_ir_swizzle
*swizzle
;
2383 swizzle
= get_swizzle
(node
, $3, &loc
);
2386 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
,
2387 "invalid swizzle %s", debugstr_a
($3));
2390 $$
= append_unop
($1, &swizzle
->node
);
2394 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
,
2395 "invalid subscript %s", debugstr_a
($3));
2399 | postfix_expr
'[' expr
']'
2401 struct hlsl_ir_load
*load
;
2403 if
(node_from_list
($3)->data_type
->type
!= HLSL_CLASS_SCALAR
)
2405 hlsl_report_message
(get_location
(&@
3), HLSL_LEVEL_ERROR
, "array index is not scalar");
2406 free_instr_list
($1);
2407 free_instr_list
($3);
2411 if
(!(load
= new_array_load
(node_from_list
($1), node_from_list
($3), get_location
(&@
2))))
2413 free_instr_list
($1);
2414 free_instr_list
($3);
2417 $$
= append_binop
($1, $3, &load
->node
);
2419 /* "var_modifiers" doesn't make sense in this case, but it's needed
2420 in the grammar to avoid shift/reduce conflicts. */
2421 | var_modifiers type
'(' initializer_expr_list
')'
2423 struct hlsl_ir_constructor
*constructor
;
2425 TRACE
("%s constructor.\n", debug_hlsl_type
($2));
2428 hlsl_report_message
(get_location
(&@
1), HLSL_LEVEL_ERROR
,
2429 "unexpected modifier on a constructor\n");
2432 if
($2->type
> HLSL_CLASS_LAST_NUMERIC
)
2434 hlsl_report_message
(get_location
(&@
2), HLSL_LEVEL_ERROR
,
2435 "constructors may only be used with numeric data types\n");
2438 if
($2->dimx
* $2->dimy
!= initializer_size
(&$4))
2440 hlsl_report_message
(get_location
(&@
4), HLSL_LEVEL_ERROR
,
2441 "expected %u components in constructor, but got %u\n",
2442 $2->dimx
* $2->dimy
, initializer_size
(&$4));
2445 assert
($4.args_count
<= ARRAY_SIZE
(constructor
->args
));
2447 constructor
= d3dcompiler_alloc
(sizeof
(*constructor
));
2448 init_node
(&constructor
->node
, HLSL_IR_CONSTRUCTOR
, $2, get_location
(&@
3));
2449 constructor
->args_count
= $4.args_count
;
2450 memcpy
(constructor
->args
, $4.args
, $4.args_count
* sizeof
(*$4.args
));
2451 d3dcompiler_free
($4.args
);
2452 $$
= append_unop
($4.instrs
, &constructor
->node
);
2455 unary_expr: postfix_expr
2461 struct source_location loc
;
2463 loc
= get_location
(&@
1);
2464 if
(node_from_list
($2)->data_type
->modifiers
& HLSL_MODIFIER_CONST
)
2466 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "modifying a const expression");
2469 $$
= append_unop
($2, new_unary_expr
(HLSL_IR_UNOP_PREINC
, node_from_list
($2), loc
));
2473 struct source_location loc
;
2475 loc
= get_location
(&@
1);
2476 if
(node_from_list
($2)->data_type
->modifiers
& HLSL_MODIFIER_CONST
)
2478 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "modifying a const expression");
2481 $$
= append_unop
($2, new_unary_expr
(HLSL_IR_UNOP_PREDEC
, node_from_list
($2), loc
));
2483 | unary_op unary_expr
2485 enum hlsl_ir_expr_op ops
[] = {0, HLSL_IR_UNOP_NEG
,
2486 HLSL_IR_UNOP_LOGIC_NOT
, HLSL_IR_UNOP_BIT_NOT
};
2488 if
($1 == UNARY_OP_PLUS
)
2494 $$
= append_unop
($2, new_unary_expr
(ops
[$1], node_from_list
($2), get_location
(&@
1)));
2497 /* var_modifiers just to avoid shift/reduce conflicts */
2498 |
'(' var_modifiers type array
')' unary_expr
2500 struct hlsl_type
*src_type
= node_from_list
($6)->data_type
;
2501 struct hlsl_type
*dst_type
;
2502 struct source_location loc
;
2504 loc
= get_location
(&@
3);
2507 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "unexpected modifier in a cast");
2512 dst_type
= new_array_type
($3, $4);
2516 if
(!compatible_data_types
(src_type
, dst_type
))
2518 hlsl_report_message
(loc
, HLSL_LEVEL_ERROR
, "can't cast from %s to %s",
2519 debug_hlsl_type
(src_type
), debug_hlsl_type
(dst_type
));
2523 $$
= append_unop
($6, &new_cast
(node_from_list
($6), dst_type
, &loc
)->node
);
2532 $$
= UNARY_OP_MINUS
;
2536 $$
= UNARY_OP_LOGICNOT
;
2540 $$
= UNARY_OP_BITNOT
;
2543 mul_expr: unary_expr
2547 | mul_expr
'*' unary_expr
2549 $$
= append_binop
($1, $3, new_binary_expr
(HLSL_IR_BINOP_MUL
,
2550 node_from_list
($1), node_from_list
($3), get_location
(&@
2)));
2552 | mul_expr
'/' unary_expr
2554 $$
= append_binop
($1, $3, new_binary_expr
(HLSL_IR_BINOP_DIV
,
2555 node_from_list
($1), node_from_list
($3), get_location
(&@
2)));
2557 | mul_expr
'%' unary_expr
2559 $$
= append_binop
($1, $3, new_binary_expr
(HLSL_IR_BINOP_MOD
,
2560 node_from_list
($1), node_from_list
($3), get_location
(&@
2)));
2567 | add_expr
'+' mul_expr
2569 $$
= append_binop
($1, $3, new_binary_expr
(HLSL_IR_BINOP_ADD
,
2570 node_from_list
($1), node_from_list
($3), get_location
(&@
2)));
2572 | add_expr
'-' mul_expr
2574 $$
= append_binop
($1, $3, new_binary_expr
(HLSL_IR_BINOP_SUB
,
2575 node_from_list
($1), node_from_list
($3), get_location
(&@
2)));
2578 shift_expr: add_expr
2582 | shift_expr OP_LEFTSHIFT add_expr
2584 FIXME
("Left shift\n");
2586 | shift_expr OP_RIGHTSHIFT add_expr
2588 FIXME
("Right shift\n");
2591 relational_expr: shift_expr
2595 | relational_expr
'<' shift_expr
2597 $$
= append_binop
($1, $3, new_binary_expr
(HLSL_IR_BINOP_LESS
,
2598 node_from_list
($1), node_from_list
($3), get_location
(&@
2)));
2600 | relational_expr
'>' shift_expr
2602 $$
= append_binop
($1, $3, new_binary_expr
(HLSL_IR_BINOP_GREATER
,
2603 node_from_list
($1), node_from_list
($3), get_location
(&@
2)));
2605 | relational_expr OP_LE shift_expr
2607 $$
= append_binop
($1, $3, new_binary_expr
(HLSL_IR_BINOP_LEQUAL
,
2608 node_from_list
($1), node_from_list
($3), get_location
(&@
2)));
2610 | relational_expr OP_GE shift_expr
2612 $$
= append_binop
($1, $3, new_binary_expr
(HLSL_IR_BINOP_GEQUAL
,
2613 node_from_list
($1), node_from_list
($3), get_location
(&@
2)));
2616 equality_expr: relational_expr
2620 | equality_expr OP_EQ relational_expr
2622 $$
= append_binop
($1, $3, new_binary_expr
(HLSL_IR_BINOP_EQUAL
,
2623 node_from_list
($1), node_from_list
($3), get_location
(&@
2)));
2625 | equality_expr OP_NE relational_expr
2627 $$
= append_binop
($1, $3, new_binary_expr
(HLSL_IR_BINOP_NEQUAL
,
2628 node_from_list
($1), node_from_list
($3), get_location
(&@
2)));
2631 bitand_expr: equality_expr
2635 | bitand_expr
'&' equality_expr
2637 FIXME
("bitwise AND\n");
2640 bitxor_expr: bitand_expr
2644 | bitxor_expr
'^' bitand_expr
2646 FIXME
("bitwise XOR\n");
2649 bitor_expr: bitxor_expr
2653 | bitor_expr
'|' bitxor_expr
2655 FIXME
("bitwise OR\n");
2658 logicand_expr: bitor_expr
2662 | logicand_expr OP_AND bitor_expr
2664 FIXME
("logic AND\n");
2667 logicor_expr: logicand_expr
2671 | logicor_expr OP_OR logicand_expr
2673 FIXME
("logic OR\n");
2676 conditional_expr: logicor_expr
2680 | logicor_expr
'?' expr
':' assignment_expr
2682 FIXME
("ternary operator\n");
2685 assignment_expr: conditional_expr
2689 | unary_expr assign_op assignment_expr
2691 struct hlsl_ir_node
*instr
;
2693 if
(node_from_list
($1)->data_type
->modifiers
& HLSL_MODIFIER_CONST
)
2695 hlsl_report_message
(get_location
(&@
2), HLSL_LEVEL_ERROR
, "l-value is const");
2698 if
(!(instr
= make_assignment
(node_from_list
($1), $2, node_from_list
($3))))
2700 instr
->loc
= get_location
(&@
2);
2701 $$
= append_binop
($3, $1, instr
);
2706 $$
= ASSIGN_OP_ASSIGN
;
2728 | OP_LEFTSHIFTASSIGN
2730 $$
= ASSIGN_OP_LSHIFT
;
2732 | OP_RIGHTSHIFTASSIGN
2734 $$
= ASSIGN_OP_RSHIFT
;
2749 expr: assignment_expr
2753 | expr
',' assignment_expr
2756 list_move_tail
($$
, $3);
2757 d3dcompiler_free
($3);
2762 static struct source_location get_location
(const struct YYLTYPE *l
)
2764 const struct source_location loc
=
2766 .file
= hlsl_ctx.source_file
,
2767 .line
= l
->first_line
,
2768 .col
= l
->first_column
,
2773 static void dump_function_decl
(struct wine_rb_entry
*entry
, void *context
)
2775 struct hlsl_ir_function_decl
*func
= WINE_RB_ENTRY_VALUE
(entry
, struct hlsl_ir_function_decl
, entry
);
2777 debug_dump_ir_function_decl
(func
);
2780 static void dump_function
(struct wine_rb_entry
*entry
, void *context
)
2782 struct hlsl_ir_function
*func
= WINE_RB_ENTRY_VALUE
(entry
, struct hlsl_ir_function
, entry
);
2783 wine_rb_for_each_entry
(&func
->overloads
, dump_function_decl
, NULL
);
2786 /* Allocate a unique, ordered index to each instruction, which will be used for
2787 * computing liveness ranges. */
2788 static unsigned int index_instructions
(struct list
*instrs
, unsigned int index
)
2790 struct hlsl_ir_node
*instr
;
2792 LIST_FOR_EACH_ENTRY
(instr
, instrs
, struct hlsl_ir_node
, entry
)
2794 instr
->index
= index
++;
2796 if
(instr
->type
== HLSL_IR_IF
)
2798 struct hlsl_ir_if
*iff
= if_from_node
(instr
);
2799 index
= index_instructions
(iff
->then_instrs
, index
);
2800 if
(iff
->else_instrs
)
2801 index
= index_instructions
(iff
->else_instrs
, index
);
2803 else if
(instr
->type
== HLSL_IR_LOOP
)
2805 index
= index_instructions
(loop_from_node
(instr
)->body
, index
);
2806 loop_from_node
(instr
)->next_index
= index
;
2813 /* Compute the earliest and latest liveness for each variable. In the case that
2814 * a variable is accessed inside of a loop, we promote its liveness to extend
2815 * to at least the range of the entire loop. Note that we don't need to do this
2816 * for anonymous nodes, since there's currently no way to use a node which was
2817 * calculated in an earlier iteration of the loop. */
2818 static void compute_liveness_recurse
(struct list
*instrs
, unsigned int loop_first
, unsigned int loop_last
)
2820 struct hlsl_ir_node
*instr
;
2821 struct hlsl_ir_var
*var
;
2823 LIST_FOR_EACH_ENTRY
(instr
, instrs
, struct hlsl_ir_node
, entry
)
2825 switch
(instr
->type
)
2827 case HLSL_IR_ASSIGNMENT
:
2829 struct hlsl_ir_assignment
*assignment
= assignment_from_node
(instr
);
2830 var
= assignment
->lhs.var
;
2831 if
(!var
->first_write
)
2832 var
->first_write
= loop_first ? min
(instr
->index
, loop_first
) : instr
->index
;
2833 assignment
->rhs
->last_read
= instr
->index
;
2834 if
(assignment
->lhs.offset
)
2835 assignment
->lhs.offset
->last_read
= instr
->index
;
2838 case HLSL_IR_CONSTRUCTOR
:
2840 struct hlsl_ir_constructor
*constructor
= constructor_from_node
(instr
);
2842 for
(i
= 0; i
< constructor
->args_count
; ++i
)
2843 constructor
->args
[i
]->last_read
= instr
->index
;
2848 struct hlsl_ir_expr
*expr
= expr_from_node
(instr
);
2849 expr
->operands
[0]->last_read
= instr
->index
;
2850 if
(expr
->operands
[1])
2851 expr
->operands
[1]->last_read
= instr
->index
;
2852 if
(expr
->operands
[2])
2853 expr
->operands
[2]->last_read
= instr
->index
;
2858 struct hlsl_ir_if
*iff
= if_from_node
(instr
);
2859 compute_liveness_recurse
(iff
->then_instrs
, loop_first
, loop_last
);
2860 if
(iff
->else_instrs
)
2861 compute_liveness_recurse
(iff
->else_instrs
, loop_first
, loop_last
);
2862 iff
->condition
->last_read
= instr
->index
;
2867 struct hlsl_ir_load
*load
= load_from_node
(instr
);
2868 var
= load
->src.var
;
2869 var
->last_read
= loop_last ? max
(instr
->index
, loop_last
) : instr
->index
;
2870 if
(load
->src.offset
)
2871 load
->src.offset
->last_read
= instr
->index
;
2876 struct hlsl_ir_loop
*loop
= loop_from_node
(instr
);
2877 compute_liveness_recurse
(loop
->body
, loop_first ? loop_first
: instr
->index
,
2878 loop_last ? loop_last
: loop
->next_index
);
2881 case HLSL_IR_SWIZZLE
:
2883 struct hlsl_ir_swizzle
*swizzle
= swizzle_from_node
(instr
);
2884 swizzle
->val
->last_read
= instr
->index
;
2887 case HLSL_IR_CONSTANT
:
2894 static void compute_liveness
(struct hlsl_ir_function_decl
*entry_func
)
2896 struct hlsl_ir_var
*var
;
2898 LIST_FOR_EACH_ENTRY
(var
, &hlsl_ctx.globals
->vars
, struct hlsl_ir_var
, scope_entry
)
2900 var
->first_write
= 1;
2903 LIST_FOR_EACH_ENTRY
(var
, entry_func
->parameters
, struct hlsl_ir_var
, param_entry
)
2905 if
(var
->modifiers
& HLSL_STORAGE_IN
)
2906 var
->first_write
= 1;
2907 if
(var
->modifiers
& HLSL_STORAGE_OUT
)
2908 var
->last_read
= UINT_MAX
;
2911 if
(entry_func
->return_var
)
2912 entry_func
->return_var
->last_read
= UINT_MAX
;
2914 compute_liveness_recurse
(entry_func
->body
, 0, 0);
2917 struct bwriter_shader
*parse_hlsl
(enum shader_type type
, DWORD major
, DWORD minor
,
2918 const char *entrypoint
, char **messages
)
2920 struct hlsl_ir_function_decl
*entry_func
;
2921 struct hlsl_scope
*scope
, *next_scope
;
2922 struct hlsl_type
*hlsl_type
, *next_type
;
2923 struct hlsl_ir_var
*var
, *next_var
;
2926 hlsl_ctx.status
= PARSE_SUCCESS
;
2927 hlsl_ctx.messages.size
= hlsl_ctx.messages.capacity
= 0;
2928 hlsl_ctx.line_no
= hlsl_ctx.column
= 1;
2929 hlsl_ctx.source_file
= d3dcompiler_strdup
("");
2930 hlsl_ctx.source_files
= d3dcompiler_alloc
(sizeof
(*hlsl_ctx.source_files
));
2931 if
(hlsl_ctx.source_files
)
2932 hlsl_ctx.source_files
[0] = hlsl_ctx.source_file
;
2933 hlsl_ctx.source_files_count
= 1;
2934 hlsl_ctx.cur_scope
= NULL
;
2935 hlsl_ctx.matrix_majority
= HLSL_COLUMN_MAJOR
;
2936 list_init
(&hlsl_ctx.scopes
);
2937 list_init
(&hlsl_ctx.types
);
2938 init_functions_tree
(&hlsl_ctx.functions
);
2940 push_scope
(&hlsl_ctx
);
2941 hlsl_ctx.globals
= hlsl_ctx.cur_scope
;
2942 declare_predefined_types
(hlsl_ctx.globals
);
2946 TRACE
("Compilation status = %d\n", hlsl_ctx.status
);
2949 if
(hlsl_ctx.messages.size
)
2950 *messages
= hlsl_ctx.messages.
string;
2956 if
(hlsl_ctx.messages.capacity
)
2957 d3dcompiler_free
(hlsl_ctx.messages.
string);
2960 for
(i
= 0; i
< hlsl_ctx.source_files_count
; ++i
)
2961 d3dcompiler_free
((void *)hlsl_ctx.source_files
[i
]);
2962 d3dcompiler_free
(hlsl_ctx.source_files
);
2964 if
(hlsl_ctx.status
== PARSE_ERR
)
2967 if
(!(entry_func
= get_func_entry
(entrypoint
)))
2969 hlsl_message
("error: entry point %s is not defined\n", debugstr_a
(entrypoint
));
2973 /* Index 0 means unused; index 1 means function entry, so start at 2. */
2974 index_instructions
(entry_func
->body
, 2);
2976 if
(TRACE_ON
(hlsl_parser
))
2978 TRACE
("IR dump.\n");
2979 wine_rb_for_each_entry
(&hlsl_ctx.functions
, dump_function
, NULL
);
2982 compute_liveness
(entry_func
);
2985 TRACE
("Freeing functions IR.\n");
2986 wine_rb_destroy
(&hlsl_ctx.functions
, free_function_rb
, NULL
);
2988 TRACE
("Freeing variables.\n");
2989 LIST_FOR_EACH_ENTRY_SAFE
(scope
, next_scope
, &hlsl_ctx.scopes
, struct hlsl_scope
, entry
)
2991 LIST_FOR_EACH_ENTRY_SAFE
(var
, next_var
, &scope
->vars
, struct hlsl_ir_var
, scope_entry
)
2993 free_declaration
(var
);
2995 wine_rb_destroy
(&scope
->types
, NULL
, NULL
);
2996 d3dcompiler_free
(scope
);
2999 TRACE
("Freeing types.\n");
3000 LIST_FOR_EACH_ENTRY_SAFE
(hlsl_type
, next_type
, &hlsl_ctx.types
, struct hlsl_type
, entry
)
3002 free_hlsl_type
(hlsl_type
);