d3drm: Improve IDirect3DRMViewportX_Render stub.
[wine/multimedia.git] / dlls / d3dcompiler_43 / hlsl.y
blobae1599f24570e27e9ef05d1506a6d98268344dbf
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 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);
53 if (modifiers)
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)
60 BOOL ret;
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;
71 if (local)
73 DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
74 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
75 if (invalid)
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);
83 if (ret == FALSE)
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);
90 return FALSE;
92 return TRUE;
95 static DWORD add_modifier(DWORD modifiers, DWORD mod)
97 if (modifiers & 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);
102 return modifiers;
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",
108 hlsl_ctx.line_no);
109 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
110 return modifiers;
112 return modifiers | mod;
117 %error-verbose
119 %union
121 struct hlsl_type *type;
122 INT intval;
123 FLOAT floatval;
124 BOOL boolval;
125 char *name;
126 DWORD modifiers;
127 struct hlsl_ir_var *var;
128 struct hlsl_ir_node *instr;
129 struct list *list;
130 struct parse_variable_def *variable_def;
133 %token KW_BLENDSTATE
134 %token KW_BREAK
135 %token KW_BUFFER
136 %token KW_CBUFFER
137 %token KW_COLUMN_MAJOR
138 %token KW_COMPILE
139 %token KW_CONST
140 %token KW_CONTINUE
141 %token KW_DEPTHSTENCILSTATE
142 %token KW_DEPTHSTENCILVIEW
143 %token KW_DISCARD
144 %token KW_DO
145 %token KW_DOUBLE
146 %token KW_ELSE
147 %token KW_EXTERN
148 %token KW_FALSE
149 %token KW_FOR
150 %token KW_GEOMETRYSHADER
151 %token KW_GROUPSHARED
152 %token KW_IF
153 %token KW_IN
154 %token KW_INLINE
155 %token KW_INOUT
156 %token KW_MATRIX
157 %token KW_NAMESPACE
158 %token KW_NOINTERPOLATION
159 %token KW_OUT
160 %token KW_PASS
161 %token KW_PIXELSHADER
162 %token KW_PRECISE
163 %token KW_RASTERIZERSTATE
164 %token KW_RENDERTARGETVIEW
165 %token KW_RETURN
166 %token KW_REGISTER
167 %token KW_ROW_MAJOR
168 %token KW_SAMPLER
169 %token KW_SAMPLER1D
170 %token KW_SAMPLER2D
171 %token KW_SAMPLER3D
172 %token KW_SAMPLERCUBE
173 %token KW_SAMPLER_STATE
174 %token KW_SAMPLERCOMPARISONSTATE
175 %token KW_SHARED
176 %token KW_STATEBLOCK
177 %token KW_STATEBLOCK_STATE
178 %token KW_STATIC
179 %token KW_STRING
180 %token KW_STRUCT
181 %token KW_SWITCH
182 %token KW_TBUFFER
183 %token KW_TECHNIQUE
184 %token KW_TECHNIQUE10
185 %token KW_TEXTURE
186 %token KW_TEXTURE1D
187 %token KW_TEXTURE1DARRAY
188 %token KW_TEXTURE2D
189 %token KW_TEXTURE2DARRAY
190 %token KW_TEXTURE2DMS
191 %token KW_TEXTURE2DMSARRAY
192 %token KW_TEXTURE3D
193 %token KW_TEXTURE3DARRAY
194 %token KW_TEXTURECUBE
195 %token KW_TRUE
196 %token KW_TYPEDEF
197 %token KW_UNIFORM
198 %token KW_VECTOR
199 %token KW_VERTEXSHADER
200 %token KW_VOID
201 %token KW_VOLATILE
202 %token KW_WHILE
204 %token OP_INC
205 %token OP_DEC
206 %token OP_AND
207 %token OP_OR
208 %token OP_EQ
209 %token OP_LEFTSHIFT
210 %token OP_LEFTSHIFTASSIGN
211 %token OP_RIGHTSHIFT
212 %token OP_RIGHTSHIFTASSIGN
213 %token OP_ELLIPSIS
214 %token OP_LE
215 %token OP_GE
216 %token OP_LT
217 %token OP_GT
218 %token OP_NE
219 %token OP_ADDASSIGN
220 %token OP_SUBASSIGN
221 %token OP_MULASSIGN
222 %token OP_DIVASSIGN
223 %token OP_MODASSIGN
224 %token OP_ANDASSIGN
225 %token OP_ORASSIGN
226 %token OP_XORASSIGN
227 %token OP_UNKNOWN1
228 %token OP_UNKNOWN2
229 %token OP_UNKNOWN3
230 %token OP_UNKNOWN4
232 %token <intval> PRE_LINE
234 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
235 %type <name> any_identifier
236 %token <name> STRING
237 %token <floatval> C_FLOAT
238 %token <intval> C_INTEGER
239 %type <boolval> boolean
240 %type <type> base_type
241 %type <type> type
242 %type <list> complex_initializer
243 %type <list> initializer_expr_list
244 %type <instr> initializer_expr
245 %type <modifiers> var_modifiers
246 %type <instr> expr
247 %type <var> variable
248 %type <intval> array
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
289 | TYPE_IDENTIFIER
290 | NEW_IDENTIFIER
292 semantic: /* Empty */
294 $$ = NULL;
296 | ':' any_identifier
298 $$ = $2;
301 type: base_type
303 $$ = $1;
306 base_type: KW_VOID
308 $$ = new_hlsl_type("void", HLSL_CLASS_SCALAR, HLSL_TYPE_VOID, 1, 1);
310 | TYPE_IDENTIFIER
312 struct hlsl_type *type;
314 TRACE("Type %s.\n", $1);
315 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
316 $$ = type;
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);
331 else
333 $$ = type;
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;
353 if (v->array_size)
354 var->node.data_type = new_array_type($2, v->array_size);
355 else
356 var->node.data_type = $2;
357 var->name = v->name;
358 var->modifiers = $1;
359 var->semantic = v->semantic;
360 var->node.line = hlsl_ctx.line_no;
361 if (v->initializer)
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;
370 local = FALSE;
373 ret = declare_variable(var, local);
374 if (ret == FALSE)
375 free_declaration(var);
376 else
377 TRACE("Declared variable %s.\n", var->name);
378 d3dcompiler_free(v);
380 d3dcompiler_free($3);
383 variables_def: variable_def
385 $$ = d3dcompiler_alloc(sizeof(*$$));
386 list_init($$);
387 list_add_head($$, &$1->entry);
389 | variables_def ',' variable_def
391 $$ = $1;
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(*$$));
399 $$->name = $1;
400 $$->array_size = $2;
401 $$->semantic = $3;
403 | any_identifier array semantic '=' complex_initializer
405 TRACE("Declaration with initializer.\n");
406 $$ = d3dcompiler_alloc(sizeof(*$$));
407 $$->name = $1;
408 $$->array_size = $2;
409 $$->semantic = $3;
410 $$->initializer = $5;
413 array: /* Empty */
415 $$ = 0;
417 | '[' expr ']'
419 FIXME("Array.\n");
420 $$ = 0;
421 free_instr($2);
424 var_modifiers: /* Empty */
426 $$ = 0;
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(*$$));
476 list_init($$);
477 list_add_head($$, &$1->entry);
479 | '{' initializer_expr_list '}'
481 $$ = $2;
484 initializer_expr: assignment_expr
486 $$ = $1;
489 initializer_expr_list: initializer_expr
491 $$ = d3dcompiler_alloc(sizeof(*$$));
492 list_init($$);
493 list_add_head($$, &$1->entry);
495 | initializer_expr_list ',' initializer_expr
497 $$ = $1;
498 list_add_tail($$, &$3->entry);
501 boolean: KW_TRUE
503 $$ = TRUE;
505 | KW_FALSE
507 $$ = FALSE;
510 primary_expr: C_FLOAT
512 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
513 if (!c)
515 ERR("Out of memory.\n");
516 return -1;
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;
521 $$ = &c->node;
523 | C_INTEGER
525 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
526 if (!c)
528 ERR("Out of memory.\n");
529 return -1;
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;
534 $$ = &c->node;
536 | boolean
538 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
539 if (!c)
541 ERR("Out of memory.\n");
542 return -1;
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;
547 $$ = &c->node;
549 | variable
551 struct hlsl_ir_deref *deref = new_var_deref($1);
552 $$ = deref ? &deref->node : NULL;
554 | '(' expr ')'
556 $$ = $2;
559 variable: VAR_IDENTIFIER
561 struct hlsl_ir_var *var;
562 var = get_variable(hlsl_ctx.cur_scope, $1);
563 if (!var)
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);
568 return 1;
570 $$ = var;
573 postfix_expr: primary_expr
575 $$ = $1;
578 unary_expr: postfix_expr
580 $$ = $1;
583 mul_expr: unary_expr
585 $$ = $1;
588 add_expr: mul_expr
590 $$ = $1;
593 shift_expr: add_expr
595 $$ = $1;
598 relational_expr: shift_expr
600 $$ = $1;
603 equality_expr: relational_expr
605 $$ = $1;
608 bitand_expr: equality_expr
610 $$ = $1;
613 bitxor_expr: bitand_expr
615 $$ = $1;
618 bitor_expr: bitxor_expr
620 $$ = $1;
623 logicand_expr: bitor_expr
625 $$ = $1;
628 logicor_expr: logicand_expr
630 $$ = $1;
633 conditional_expr: logicor_expr
635 $$ = $1;
638 assignment_expr: conditional_expr
640 $$ = $1;
643 expr: assignment_expr
645 $$ = $1;
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;
671 hlsl_parse();
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);
691 return NULL;