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
23 #include "wine/debug.h"
27 #include "d3dcompiler_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL
(hlsl_parser
);
33 struct hlsl_parse_ctx hlsl_ctx
;
35 void hlsl_message
(const char *fmt
, ...
)
40 compilation_message
(&hlsl_ctx.messages
, fmt
, args
);
44 static void hlsl_error
(const char *s
)
46 hlsl_message
("Line %u: %s\n", hlsl_ctx.line_no
, s
);
47 set_parse_status
(&hlsl_ctx.status
, PARSE_ERR
);
50 static void debug_dump_decl
(struct hlsl_type
*type
, DWORD modifiers
, const char *declname
, unsigned int line_no
)
52 TRACE
("Line %u: ", line_no
);
54 TRACE
("%s ", debug_modifiers
(modifiers
));
55 TRACE
("%s %s;\n", debug_hlsl_type
(type
), declname
);
58 static BOOL declare_variable
(struct hlsl_ir_var
*decl
, BOOL local
)
62 TRACE
("Declaring variable %s.\n", decl
->name
);
63 if
(decl
->node.data_type
->type
== HLSL_CLASS_MATRIX
)
65 if
(!(decl
->modifiers
& (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR
)))
67 decl
->modifiers |
= hlsl_ctx.matrix_majority
== HLSL_ROW_MAJOR
68 ? HLSL_MODIFIER_ROW_MAJOR
: HLSL_MODIFIER_COLUMN_MAJOR
;
73 DWORD invalid
= decl
->modifiers
& (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
74 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM
);
77 hlsl_message
("Line %u: modifier '%s' invalid for local variables.\n",
78 hlsl_ctx.line_no
, debug_modifiers
(invalid
));
79 set_parse_status
(&hlsl_ctx.status
, PARSE_ERR
);
82 ret
= add_declaration
(hlsl_ctx.cur_scope
, decl
, local
);
85 struct hlsl_ir_var
*old
= get_variable
(hlsl_ctx.cur_scope
, decl
->name
);
87 hlsl_message
("Line %u: \"%s\" already declared.\n", hlsl_ctx.line_no
, decl
->name
);
88 hlsl_message
("Line %u: \"%s\" was previously declared here.\n", old
->node.line
, decl
->name
);
89 set_parse_status
(&hlsl_ctx.status
, PARSE_ERR
);
95 static DWORD add_modifier
(DWORD modifiers
, DWORD mod
)
99 hlsl_message
("Line %u: modifier '%s' already specified.\n",
100 hlsl_ctx.line_no
, debug_modifiers
(mod
));
101 set_parse_status
(&hlsl_ctx.status
, PARSE_ERR
);
104 if
(mod
& (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR
)
105 && modifiers
& (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR
))
107 hlsl_message
("Line %u: more than one matrix majority keyword.\n",
109 set_parse_status
(&hlsl_ctx.status
, PARSE_ERR
);
112 return modifiers | mod
;
121 struct hlsl_type
*type
;
127 struct hlsl_ir_var
*var
;
128 struct hlsl_ir_node
*instr
;
130 struct parse_variable_def
*variable_def
;
137 %token KW_COLUMN_MAJOR
141 %token KW_DEPTHSTENCILSTATE
142 %token KW_DEPTHSTENCILVIEW
150 %token KW_GEOMETRYSHADER
151 %token KW_GROUPSHARED
158 %token KW_NOINTERPOLATION
161 %token KW_PIXELSHADER
163 %token KW_RASTERIZERSTATE
164 %token KW_RENDERTARGETVIEW
172 %token KW_SAMPLERCUBE
173 %token KW_SAMPLER_STATE
174 %token KW_SAMPLERCOMPARISONSTATE
177 %token KW_STATEBLOCK_STATE
184 %token KW_TECHNIQUE10
187 %token KW_TEXTURE1DARRAY
189 %token KW_TEXTURE2DARRAY
190 %token KW_TEXTURE2DMS
191 %token KW_TEXTURE2DMSARRAY
193 %token KW_TEXTURE3DARRAY
194 %token KW_TEXTURECUBE
199 %token KW_VERTEXSHADER
210 %token OP_LEFTSHIFTASSIGN
212 %token OP_RIGHTSHIFTASSIGN
232 %token
<intval
> PRE_LINE
234 %token
<name
> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
235 %type
<name
> any_identifier
237 %token
<floatval
> C_FLOAT
238 %token
<intval
> C_INTEGER
239 %type
<boolval
> boolean
240 %type
<type
> base_type
242 %type
<list
> complex_initializer
243 %type
<list
> initializer_expr_list
244 %type
<instr
> initializer_expr
245 %type
<modifiers
> var_modifiers
249 %type
<name
> semantic
250 %type
<variable_def
> variable_def
251 %type
<list
> variables_def
252 %type
<instr
> primary_expr
253 %type
<instr
> postfix_expr
254 %type
<instr
> unary_expr
255 %type
<instr
> mul_expr
256 %type
<instr
> add_expr
257 %type
<instr
> shift_expr
258 %type
<instr
> relational_expr
259 %type
<instr
> equality_expr
260 %type
<instr
> bitand_expr
261 %type
<instr
> bitxor_expr
262 %type
<instr
> bitor_expr
263 %type
<instr
> logicand_expr
264 %type
<instr
> logicor_expr
265 %type
<instr
> conditional_expr
266 %type
<instr
> assignment_expr
269 hlsl_prog: /* empty */
272 | hlsl_prog declaration_statement
274 TRACE
("Declaration statement parsed.\n");
276 | hlsl_prog preproc_directive
280 preproc_directive: PRE_LINE STRING
282 TRACE
("Updating line information to file %s, line %u\n", debugstr_a
($2), $1);
283 hlsl_ctx.line_no
= $1 - 1;
284 d3dcompiler_free
(hlsl_ctx.source_file
);
285 hlsl_ctx.source_file
= $2;
288 any_identifier: VAR_IDENTIFIER
292 semantic: /* Empty */
308 $$
= new_hlsl_type
("void", HLSL_CLASS_SCALAR
, HLSL_TYPE_VOID
, 1, 1);
312 struct hlsl_type
*type
;
314 TRACE
("Type %s.\n", $1);
315 type
= get_type
(hlsl_ctx.cur_scope
, $1, TRUE
);
317 d3dcompiler_free
($1);
319 | KW_STRUCT TYPE_IDENTIFIER
321 struct hlsl_type
*type
;
323 TRACE
("Struct type %s.\n", $2);
324 type
= get_type
(hlsl_ctx.cur_scope
, $2, TRUE
);
325 if
(type
->type
!= HLSL_CLASS_STRUCT
)
327 hlsl_message
("Line %u: redefining %s as a structure.\n",
328 hlsl_ctx.line_no
, $2);
329 set_parse_status
(&hlsl_ctx.status
, PARSE_ERR
);
335 d3dcompiler_free
($2);
338 declaration_statement: declaration
342 declaration: var_modifiers type variables_def
';'
344 struct parse_variable_def
*v
, *v_next
;
345 struct hlsl_ir_var
*var
;
346 BOOL ret
, local
= TRUE
;
348 LIST_FOR_EACH_ENTRY_SAFE
(v
, v_next
, $3, struct parse_variable_def
, entry
)
350 debug_dump_decl
($2, $1, v
->name
, hlsl_ctx.line_no
);
351 var
= d3dcompiler_alloc
(sizeof
(*var
));
352 var
->node.type
= HLSL_IR_VAR
;
354 var
->node.data_type
= new_array_type
($2, v
->array_size
);
356 var
->node.data_type
= $2;
359 var
->semantic
= v
->semantic
;
360 var
->node.line
= hlsl_ctx.line_no
;
363 FIXME
("Variable with an initializer.\n");
364 free_instr_list
(v
->initializer
);
367 if
(hlsl_ctx.cur_scope
== hlsl_ctx.globals
)
369 var
->modifiers |
= HLSL_STORAGE_UNIFORM
;
373 ret
= declare_variable
(var
, local
);
375 free_declaration
(var
);
377 TRACE
("Declared variable %s.\n", var
->name
);
380 d3dcompiler_free
($3);
383 variables_def: variable_def
385 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
387 list_add_head
($$
, &$1->entry
);
389 | variables_def
',' variable_def
392 list_add_tail
($$
, &$3->entry
);
395 /* FIXME: Local variables can't have semantics. */
396 variable_def: any_identifier array semantic
398 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
403 | any_identifier array semantic
'=' complex_initializer
405 TRACE
("Declaration with initializer.\n");
406 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
410 $$
->initializer
= $5;
424 var_modifiers: /* Empty */
428 | KW_EXTERN var_modifiers
430 $$
= add_modifier
($2, HLSL_STORAGE_EXTERN
);
432 | KW_NOINTERPOLATION var_modifiers
434 $$
= add_modifier
($2, HLSL_STORAGE_NOINTERPOLATION
);
436 | KW_PRECISE var_modifiers
438 $$
= add_modifier
($2, HLSL_MODIFIER_PRECISE
);
440 | KW_SHARED var_modifiers
442 $$
= add_modifier
($2, HLSL_STORAGE_SHARED
);
444 | KW_GROUPSHARED var_modifiers
446 $$
= add_modifier
($2, HLSL_STORAGE_GROUPSHARED
);
448 | KW_STATIC var_modifiers
450 $$
= add_modifier
($2, HLSL_STORAGE_STATIC
);
452 | KW_UNIFORM var_modifiers
454 $$
= add_modifier
($2, HLSL_STORAGE_UNIFORM
);
456 | KW_VOLATILE var_modifiers
458 $$
= add_modifier
($2, HLSL_STORAGE_VOLATILE
);
460 | KW_CONST var_modifiers
462 $$
= add_modifier
($2, HLSL_MODIFIER_CONST
);
464 | KW_ROW_MAJOR var_modifiers
466 $$
= add_modifier
($2, HLSL_MODIFIER_ROW_MAJOR
);
468 | KW_COLUMN_MAJOR var_modifiers
470 $$
= add_modifier
($2, HLSL_MODIFIER_COLUMN_MAJOR
);
473 complex_initializer: initializer_expr
475 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
477 list_add_head
($$
, &$1->entry
);
479 |
'{' initializer_expr_list
'}'
484 initializer_expr: assignment_expr
489 initializer_expr_list: initializer_expr
491 $$
= d3dcompiler_alloc
(sizeof
(*$$
));
493 list_add_head
($$
, &$1->entry
);
495 | initializer_expr_list
',' initializer_expr
498 list_add_tail
($$
, &$3->entry
);
510 primary_expr: C_FLOAT
512 struct hlsl_ir_constant
*c
= d3dcompiler_alloc
(sizeof
(*c
));
515 ERR
("Out of memory.\n");
518 c
->node.type
= HLSL_IR_CONSTANT
;
519 c
->node.data_type
= new_hlsl_type
("float", HLSL_CLASS_SCALAR
, HLSL_TYPE_FLOAT
, 1, 1);
520 c
->v.value.f
[0] = $1;
525 struct hlsl_ir_constant
*c
= d3dcompiler_alloc
(sizeof
(*c
));
528 ERR
("Out of memory.\n");
531 c
->node.type
= HLSL_IR_CONSTANT
;
532 c
->node.data_type
= new_hlsl_type
("int", HLSL_CLASS_SCALAR
, HLSL_TYPE_INT
, 1, 1);
533 c
->v.value.i
[0] = $1;
538 struct hlsl_ir_constant
*c
= d3dcompiler_alloc
(sizeof
(*c
));
541 ERR
("Out of memory.\n");
544 c
->node.type
= HLSL_IR_CONSTANT
;
545 c
->node.data_type
= new_hlsl_type
("bool", HLSL_CLASS_SCALAR
, HLSL_TYPE_BOOL
, 1, 1);
546 c
->v.value.b
[0] = $1;
551 struct hlsl_ir_deref
*deref
= new_var_deref
($1);
552 $$
= deref ?
&deref
->node
: NULL
;
559 variable: VAR_IDENTIFIER
561 struct hlsl_ir_var
*var
;
562 var
= get_variable
(hlsl_ctx.cur_scope
, $1);
565 hlsl_message
("Line %d: variable '%s' not declared\n",
566 hlsl_ctx.line_no
, $1);
567 set_parse_status
(&hlsl_ctx.status
, PARSE_ERR
);
573 postfix_expr: primary_expr
578 unary_expr: postfix_expr
598 relational_expr: shift_expr
603 equality_expr: relational_expr
608 bitand_expr: equality_expr
613 bitxor_expr: bitand_expr
618 bitor_expr: bitxor_expr
623 logicand_expr: bitor_expr
628 logicor_expr: logicand_expr
633 conditional_expr: logicor_expr
638 assignment_expr: conditional_expr
643 expr: assignment_expr
647 | expr
',' assignment_expr
649 FIXME
("Comma expression\n");
654 struct bwriter_shader
*parse_hlsl
(enum shader_type type
, DWORD version
, const char *entrypoint
, char **messages
)
656 struct hlsl_scope
*scope
, *next_scope
;
657 struct hlsl_type
*hlsl_type
, *next_type
;
658 struct hlsl_ir_var
*var
, *next_var
;
660 hlsl_ctx.line_no
= 1;
661 hlsl_ctx.source_file
= d3dcompiler_strdup
("");
662 hlsl_ctx.cur_scope
= NULL
;
663 hlsl_ctx.matrix_majority
= HLSL_COLUMN_MAJOR
;
664 list_init
(&hlsl_ctx.scopes
);
665 list_init
(&hlsl_ctx.types
);
666 list_init
(&hlsl_ctx.functions
);
668 push_scope
(&hlsl_ctx
);
669 hlsl_ctx.globals
= hlsl_ctx.cur_scope
;
673 d3dcompiler_free
(hlsl_ctx.source_file
);
675 TRACE
("Freeing variables.\n");
676 LIST_FOR_EACH_ENTRY_SAFE
(scope
, next_scope
, &hlsl_ctx.scopes
, struct hlsl_scope
, entry
)
678 LIST_FOR_EACH_ENTRY_SAFE
(var
, next_var
, &scope
->vars
, struct hlsl_ir_var
, scope_entry
)
680 free_declaration
(var
);
682 d3dcompiler_free
(scope
);
685 TRACE
("Freeing types.\n");
686 LIST_FOR_EACH_ENTRY_SAFE
(hlsl_type
, next_type
, &hlsl_ctx.types
, struct hlsl_type
, entry
)
688 free_hlsl_type
(hlsl_type
);