1 /* 2 * HLSL parser 3 * 4 * Copyright 2008 Stefan Dösinger 5 * Copyright 2012 Matteo Bruni for CodeWeavers 6 * 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. 11 * 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. 16 * 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 20 */ 21 %{ 22 #include "config.h" 23 #include "wine/debug.h" 24 25 #include <stdio.h> 26 27 #include "d3dcompiler_private.h" 28 29 WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser); 30 31 int hlsl_lex(void); 32 33 struct hlsl_parse_ctx hlsl_ctx; 34 35 struct YYLTYPE; 36 static void set_location(struct source_location *loc, const struct YYLTYPE *l); 37 38 void hlsl_message(const char *fmt, ...) 39 { 40 va_list args; 41 42 va_start(args, fmt); 43 compilation_message(&hlsl_ctx.messages, fmt, args); 44 va_end(args); 45 } 46 47 static const char *hlsl_get_error_level_name(enum hlsl_error_level level) 48 { 49 static const char * const names[] = 50 { 51 "error", 52 "warning", 53 "note", 54 }; 55 return names[level]; 56 } 57 58 void hlsl_report_message(const char *filename, DWORD line, DWORD column, 59 enum hlsl_error_level level, const char *fmt, ...) 60 { 61 va_list args; 62 char *string = NULL; 63 int rc, size = 0; 64 65 while (1) 66 { 67 va_start(args, fmt); 68 rc = vsnprintf(string, size, fmt, args); 69 va_end(args); 70 71 if (rc >= 0 && rc < size) 72 break; 73 74 if (rc >= size) 75 size = rc + 1; 76 else 77 size = size ? size * 2 : 32; 78 79 if (!string) 80 string = d3dcompiler_alloc(size); 81 else 82 string = d3dcompiler_realloc(string, size); 83 if (!string) 84 { 85 ERR("Error reallocating memory for a string.\n"); 86 return; 87 } 88 } 89 90 hlsl_message("%s:%u:%u: %s: %s\n", filename, line, column, hlsl_get_error_level_name(level), string); 91 d3dcompiler_free(string); 92 93 if (level == HLSL_LEVEL_ERROR) 94 set_parse_status(&hlsl_ctx.status, PARSE_ERR); 95 else if (level == HLSL_LEVEL_WARNING) 96 set_parse_status(&hlsl_ctx.status, PARSE_WARN); 97 } 98 99 static void hlsl_error(const char *s) 100 { 101 hlsl_report_message(hlsl_ctx.source_file, hlsl_ctx.line_no, hlsl_ctx.column, HLSL_LEVEL_ERROR, "%s", s); 102 } 103 104 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no) 105 { 106 TRACE("Line %u: ", line_no); 107 if (modifiers) 108 TRACE("%s ", debug_modifiers(modifiers)); 109 TRACE("%s %s;\n", debug_hlsl_type(type), declname); 110 } 111 112 static void check_invalid_matrix_modifiers(DWORD modifiers, struct source_location *loc) 113 { 114 if (modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)) 115 { 116 hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR, 117 "'row_major' or 'column_major' modifiers are only allowed for matrices"); 118 } 119 } 120 121 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local) 122 { 123 BOOL ret; 124 125 TRACE("Declaring variable %s.\n", decl->name); 126 if (decl->node.data_type->type == HLSL_CLASS_MATRIX) 127 { 128 if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))) 129 { 130 decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR 131 ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR; 132 } 133 } 134 else 135 check_invalid_matrix_modifiers(decl->modifiers, &decl->node.loc); 136 137 if (local) 138 { 139 DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED 140 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM); 141 if (invalid) 142 { 143 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR, 144 "modifier '%s' invalid for local variables", debug_modifiers(invalid)); 145 } 146 if (decl->semantic) 147 { 148 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR, 149 "semantics are not allowed on local variables"); 150 return FALSE; 151 } 152 } 153 else 154 { 155 if (find_function(decl->name)) 156 { 157 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR, 158 "redefinition of '%s'", decl->name); 159 return FALSE; 160 } 161 } 162 ret = add_declaration(hlsl_ctx.cur_scope, decl, local); 163 if (!ret) 164 { 165 struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name); 166 167 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR, 168 "\"%s\" already declared", decl->name); 169 hlsl_report_message(old->node.loc.file, old->node.loc.line, old->node.loc.col, HLSL_LEVEL_NOTE, 170 "\"%s\" was previously declared here", old->name); 171 return FALSE; 172 } 173 return TRUE; 174 } 175 176 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc); 177 178 static BOOL check_type_modifiers(DWORD modifiers, struct source_location *loc) 179 { 180 if (modifiers & ~HLSL_TYPE_MODIFIERS_MASK) 181 { 182 hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR, 183 "modifier not allowed on typedefs"); 184 return FALSE; 185 } 186 return TRUE; 187 } 188 189 static BOOL add_type_to_scope(struct hlsl_scope *scope, struct hlsl_type *def) 190 { 191 if (get_type(scope, def->name, FALSE)) 192 return FALSE; 193 194 wine_rb_put(&scope->types, def->name, &def->scope_entry); 195 return TRUE; 196 } 197 198 static void declare_predefined_types(struct hlsl_scope *scope) 199 { 200 struct hlsl_type *type; 201 unsigned int x, y, bt; 202 static const char * const names[] = 203 { 204 "float", 205 "half", 206 "double", 207 "int", 208 "uint", 209 "bool", 210 }; 211 char name[10]; 212 213 for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt) 214 { 215 for (y = 1; y <= 4; ++y) 216 { 217 for (x = 1; x <= 4; ++x) 218 { 219 sprintf(name, "%s%ux%u", names[bt], x, y); 220 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_MATRIX, bt, x, y); 221 add_type_to_scope(scope, type); 222 223 if (y == 1) 224 { 225 sprintf(name, "%s%u", names[bt], x); 226 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_VECTOR, bt, x, y); 227 add_type_to_scope(scope, type); 228 229 if (x == 1) 230 { 231 sprintf(name, "%s", names[bt]); 232 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_SCALAR, bt, x, y); 233 add_type_to_scope(scope, type); 234 } 235 } 236 } 237 } 238 } 239 240 /* DX8 effects predefined types */ 241 type = new_hlsl_type(d3dcompiler_strdup("DWORD"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1); 242 add_type_to_scope(scope, type); 243 type = new_hlsl_type(d3dcompiler_strdup("FLOAT"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1); 244 add_type_to_scope(scope, type); 245 type = new_hlsl_type(d3dcompiler_strdup("VECTOR"), HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1); 246 add_type_to_scope(scope, type); 247 type = new_hlsl_type(d3dcompiler_strdup("MATRIX"), HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4); 248 add_type_to_scope(scope, type); 249 type = new_hlsl_type(d3dcompiler_strdup("STRING"), HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1); 250 add_type_to_scope(scope, type); 251 type = new_hlsl_type(d3dcompiler_strdup("TEXTURE"), HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1); 252 add_type_to_scope(scope, type); 253 type = new_hlsl_type(d3dcompiler_strdup("PIXELSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1); 254 add_type_to_scope(scope, type); 255 type = new_hlsl_type(d3dcompiler_strdup("VERTEXSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1); 256 add_type_to_scope(scope, type); 257 } 258 259 static struct hlsl_ir_if *loop_condition(struct list *cond_list) 260 { 261 struct hlsl_ir_if *out_cond; 262 struct hlsl_ir_expr *not_cond; 263 struct hlsl_ir_node *cond, *operands[3]; 264 struct hlsl_ir_jump *jump; 265 unsigned int count = list_count(cond_list); 266 267 if (!count) 268 return NULL; 269 if (count != 1) 270 ERR("Got multiple expressions in a for condition.\n"); 271 272 cond = LIST_ENTRY(list_head(cond_list), struct hlsl_ir_node, entry); 273 out_cond = d3dcompiler_alloc(sizeof(*out_cond)); 274 if (!out_cond) 275 { 276 ERR("Out of memory.\n"); 277 return NULL; 278 } 279 out_cond->node.type = HLSL_IR_IF; 280 operands[0] = cond; 281 operands[1] = operands[2] = NULL; 282 not_cond = new_expr(HLSL_IR_UNOP_LOGIC_NOT, operands, &cond->loc); 283 if (!not_cond) 284 { 285 ERR("Out of memory.\n"); 286 d3dcompiler_free(out_cond); 287 return NULL; 288 } 289 out_cond->condition = ¬_cond->node; 290 jump = d3dcompiler_alloc(sizeof(*jump)); 291 if (!jump) 292 { 293 ERR("Out of memory.\n"); 294 d3dcompiler_free(out_cond); 295 d3dcompiler_free(not_cond); 296 return NULL; 297 } 298 jump->node.type = HLSL_IR_JUMP; 299 jump->type = HLSL_IR_JUMP_BREAK; 300 out_cond->then_instrs = d3dcompiler_alloc(sizeof(*out_cond->then_instrs)); 301 if (!out_cond->then_instrs) 302 { 303 ERR("Out of memory.\n"); 304 d3dcompiler_free(out_cond); 305 d3dcompiler_free(not_cond); 306 d3dcompiler_free(jump); 307 return NULL; 308 } 309 list_init(out_cond->then_instrs); 310 list_add_head(out_cond->then_instrs, &jump->node.entry); 311 312 return out_cond; 313 } 314 315 enum loop_type 316 { 317 LOOP_FOR, 318 LOOP_WHILE, 319 LOOP_DO_WHILE 320 }; 321 322 static struct list *create_loop(enum loop_type type, struct list *init, struct list *cond, 323 struct hlsl_ir_node *iter, struct list *body, struct source_location *loc) 324 { 325 struct list *list = NULL; 326 struct hlsl_ir_loop *loop = NULL; 327 struct hlsl_ir_if *cond_jump = NULL; 328 329 list = d3dcompiler_alloc(sizeof(*list)); 330 if (!list) 331 goto oom; 332 list_init(list); 333 334 if (init) 335 list_move_head(list, init); 336 337 loop = d3dcompiler_alloc(sizeof(*loop)); 338 if (!loop) 339 goto oom; 340 loop->node.type = HLSL_IR_LOOP; 341 loop->node.loc = *loc; 342 list_add_tail(list, &loop->node.entry); 343 loop->body = d3dcompiler_alloc(sizeof(*loop->body)); 344 if (!loop->body) 345 goto oom; 346 list_init(loop->body); 347 348 cond_jump = loop_condition(cond); 349 if (!cond_jump) 350 goto oom; 351 352 if (type != LOOP_DO_WHILE) 353 list_add_tail(loop->body, &cond_jump->node.entry); 354 355 list_move_tail(loop->body, body); 356 357 if (iter) 358 list_add_tail(loop->body, &iter->entry); 359 360 if (type == LOOP_DO_WHILE) 361 list_add_tail(loop->body, &cond_jump->node.entry); 362 363 d3dcompiler_free(init); 364 d3dcompiler_free(cond); 365 d3dcompiler_free(body); 366 return list; 367 368 oom: 369 ERR("Out of memory.\n"); 370 if (loop) 371 d3dcompiler_free(loop->body); 372 d3dcompiler_free(loop); 373 d3dcompiler_free(cond_jump); 374 d3dcompiler_free(list); 375 free_instr_list(init); 376 free_instr_list(cond); 377 free_instr(iter); 378 free_instr_list(body); 379 return NULL; 380 } 381 382 static unsigned int initializer_size(struct list *initializer) 383 { 384 unsigned int count = 0; 385 struct hlsl_ir_node *node; 386 387 LIST_FOR_EACH_ENTRY(node, initializer, struct hlsl_ir_node, entry) 388 { 389 count += components_count_type(node->data_type); 390 } 391 TRACE("Initializer size = %u\n", count); 392 return count; 393 } 394 395 static unsigned int components_count_expr_list(struct list *list) 396 { 397 struct hlsl_ir_node *node; 398 unsigned int count = 0; 399 400 LIST_FOR_EACH_ENTRY(node, list, struct hlsl_ir_node, entry) 401 { 402 count += components_count_type(node->data_type); 403 } 404 return count; 405 } 406 407 static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components, 408 struct hlsl_ir_node *val, struct source_location *loc) 409 { 410 struct hlsl_ir_swizzle *swizzle = d3dcompiler_alloc(sizeof(*swizzle)); 411 412 if (!swizzle) 413 return NULL; 414 swizzle->node.type = HLSL_IR_SWIZZLE; 415 swizzle->node.loc = *loc; 416 swizzle->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1); 417 swizzle->val = val; 418 swizzle->swizzle = s; 419 return swizzle; 420 } 421 422 static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const char *swizzle, 423 struct source_location *loc) 424 { 425 unsigned int len = strlen(swizzle), component = 0; 426 unsigned int i, set, swiz = 0; 427 BOOL valid; 428 429 if (value->data_type->type == HLSL_CLASS_MATRIX) 430 { 431 /* Matrix swizzle */ 432 BOOL m_swizzle; 433 unsigned int inc, x, y; 434 435 if (len < 3 || swizzle[0] != '_') 436 return NULL; 437 m_swizzle = swizzle[1] == 'm'; 438 inc = m_swizzle ? 4 : 3; 439 440 if (len % inc || len > inc * 4) 441 return NULL; 442 443 for (i = 0; i < len; i += inc) 444 { 445 if (swizzle[i] != '_') 446 return NULL; 447 if (m_swizzle) 448 { 449 if (swizzle[i + 1] != 'm') 450 return NULL; 451 x = swizzle[i + 2] - '0'; 452 y = swizzle[i + 3] - '0'; 453 } 454 else 455 { 456 x = swizzle[i + 1] - '1'; 457 y = swizzle[i + 2] - '1'; 458 } 459 460 if (x >= value->data_type->dimx || y >= value->data_type->dimy) 461 return NULL; 462 swiz |= (y << 4 | x) << component * 8; 463 component++; 464 } 465 return new_swizzle(swiz, component, value, loc); 466 } 467 468 /* Vector swizzle */ 469 if (len > 4) 470 return NULL; 471 472 for (set = 0; set < 2; ++set) 473 { 474 valid = TRUE; 475 component = 0; 476 for (i = 0; i < len; ++i) 477 { 478 char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}}; 479 unsigned int s = 0; 480 481 for (s = 0; s < 4; ++s) 482 { 483 if (swizzle[i] == c[set][s]) 484 break; 485 } 486 if (s == 4) 487 { 488 valid = FALSE; 489 break; 490 } 491 492 if (s >= value->data_type->dimx) 493 return NULL; 494 swiz |= s << component * 2; 495 component++; 496 } 497 if (valid) 498 return new_swizzle(swiz, component, value, loc); 499 } 500 501 return NULL; 502 } 503 504 static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var, struct list *initializer) 505 { 506 struct hlsl_type *type = var->node.data_type; 507 struct hlsl_ir_node *node; 508 struct hlsl_struct_field *field; 509 struct list *cur_node; 510 struct hlsl_ir_node *assignment; 511 struct hlsl_ir_deref *deref; 512 513 if (initializer_size(initializer) != components_count_type(type)) 514 { 515 hlsl_report_message(var->node.loc.file, var->node.loc.line, var->node.loc.col, HLSL_LEVEL_ERROR, 516 "structure initializer mismatch"); 517 free_instr_list(initializer); 518 return; 519 } 520 cur_node = list_head(initializer); 521 assert(cur_node); 522 node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry); 523 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) 524 { 525 if (!cur_node) 526 { 527 d3dcompiler_free(initializer); 528 return; 529 } 530 if (components_count_type(field->type) == components_count_type(node->data_type)) 531 { 532 deref = new_record_deref(&var->node, field); 533 if (!deref) 534 { 535 ERR("Out of memory.\n"); 536 break; 537 } 538 deref->node.loc = node->loc; 539 assignment = make_assignment(&deref->node, ASSIGN_OP_ASSIGN, BWRITERSP_WRITEMASK_ALL, node); 540 list_add_tail(list, &assignment->entry); 541 } 542 else 543 FIXME("Initializing with \"mismatched\" fields is not supported yet.\n"); 544 cur_node = list_next(initializer, cur_node); 545 node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry); 546 } 547 548 /* Free initializer elements in excess. */ 549 while (cur_node) 550 { 551 struct list *next = list_next(initializer, cur_node); 552 free_instr(node); 553 cur_node = next; 554 node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry); 555 } 556 d3dcompiler_free(initializer); 557 } 558 559 static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list) 560 { 561 struct hlsl_type *type; 562 struct parse_variable_def *v, *v_next; 563 struct hlsl_ir_var *var; 564 struct hlsl_ir_node *assignment; 565 BOOL ret, local = TRUE; 566 struct list *statements_list = d3dcompiler_alloc(sizeof(*statements_list)); 567 568 if (!statements_list) 569 { 570 ERR("Out of memory.\n"); 571 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) 572 d3dcompiler_free(v); 573 d3dcompiler_free(var_list); 574 return NULL; 575 } 576 list_init(statements_list); 577 578 if (!var_list) 579 return statements_list; 580 581 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) 582 { 583 var = d3dcompiler_alloc(sizeof(*var)); 584 if (!var) 585 { 586 ERR("Out of memory.\n"); 587 d3dcompiler_free(v); 588 continue; 589 } 590 var->node.type = HLSL_IR_VAR; 591 if (v->array_size) 592 type = new_array_type(basic_type, v->array_size); 593 else 594 type = basic_type; 595 var->node.data_type = type; 596 var->node.loc = v->loc; 597 var->name = v->name; 598 var->modifiers = modifiers; 599 var->semantic = v->semantic; 600 var->reg_reservation = v->reg_reservation; 601 debug_dump_decl(type, modifiers, v->name, v->loc.line); 602 603 if (hlsl_ctx.cur_scope == hlsl_ctx.globals) 604 { 605 var->modifiers |= HLSL_STORAGE_UNIFORM; 606 local = FALSE; 607 } 608 609 if (var->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer) 610 { 611 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, 612 HLSL_LEVEL_ERROR, "const variable without initializer"); 613 free_declaration(var); 614 d3dcompiler_free(v); 615 continue; 616 } 617 618 ret = declare_variable(var, local); 619 if (!ret) 620 { 621 free_declaration(var); 622 d3dcompiler_free(v); 623 continue; 624 } 625 TRACE("Declared variable %s.\n", var->name); 626 627 if (v->initializer) 628 { 629 unsigned int size = initializer_size(v->initializer); 630 struct hlsl_ir_node *node; 631 632 TRACE("Variable with initializer.\n"); 633 if (type->type <= HLSL_CLASS_LAST_NUMERIC 634 && type->dimx * type->dimy != size && size != 1) 635 { 636 if (size < type->dimx * type->dimy) 637 { 638 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR, 639 "'%s' initializer does not match", v->name); 640 free_instr_list(v->initializer); 641 d3dcompiler_free(v); 642 continue; 643 } 644 } 645 if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY) 646 && components_count_type(type) != size) 647 { 648 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR, 649 "'%s' initializer does not match", v->name); 650 free_instr_list(v->initializer); 651 d3dcompiler_free(v); 652 continue; 653 } 654 655 if (type->type == HLSL_CLASS_STRUCT) 656 { 657 struct_var_initializer(statements_list, var, v->initializer); 658 d3dcompiler_free(v); 659 continue; 660 } 661 if (type->type > HLSL_CLASS_LAST_NUMERIC) 662 { 663 FIXME("Initializers for non scalar/struct variables not supported yet.\n"); 664 free_instr_list(v->initializer); 665 d3dcompiler_free(v); 666 continue; 667 } 668 if (v->array_size > 0) 669 { 670 FIXME("Initializing arrays is not supported yet.\n"); 671 free_instr_list(v->initializer); 672 d3dcompiler_free(v); 673 continue; 674 } 675 if (list_count(v->initializer) > 1) 676 { 677 FIXME("Complex initializers are not supported yet.\n"); 678 free_instr_list(v->initializer); 679 d3dcompiler_free(v); 680 continue; 681 } 682 node = LIST_ENTRY(list_head(v->initializer), struct hlsl_ir_node, entry); 683 assignment = make_assignment(&var->node, ASSIGN_OP_ASSIGN, 684 BWRITERSP_WRITEMASK_ALL, node); 685 list_add_tail(statements_list, &assignment->entry); 686 d3dcompiler_free(v->initializer); 687 } 688 d3dcompiler_free(v); 689 } 690 d3dcompiler_free(var_list); 691 return statements_list; 692 } 693 694 static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field) 695 { 696 struct hlsl_struct_field *f; 697 698 LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry) 699 { 700 if (!strcmp(f->name, field->name)) 701 return FALSE; 702 } 703 list_add_tail(fields, &field->entry); 704 return TRUE; 705 } 706 707 static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, struct list *fields) 708 { 709 struct parse_variable_def *v, *v_next; 710 struct hlsl_struct_field *field; 711 struct list *list; 712 713 list = d3dcompiler_alloc(sizeof(*list)); 714 if (!list) 715 { 716 ERR("Out of memory.\n"); 717 return NULL; 718 } 719 list_init(list); 720 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry) 721 { 722 debug_dump_decl(type, 0, v->name, v->loc.line); 723 field = d3dcompiler_alloc(sizeof(*field)); 724 if (!field) 725 { 726 ERR("Out of memory.\n"); 727 d3dcompiler_free(v); 728 return list; 729 } 730 field->type = type; 731 field->name = v->name; 732 field->modifiers = modifiers; 733 field->semantic = v->semantic; 734 if (v->initializer) 735 { 736 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR, 737 "struct field with an initializer.\n"); 738 free_instr_list(v->initializer); 739 } 740 list_add_tail(list, &field->entry); 741 d3dcompiler_free(v); 742 } 743 d3dcompiler_free(fields); 744 return list; 745 } 746 747 static struct hlsl_type *new_struct_type(const char *name, DWORD modifiers, struct list *fields) 748 { 749 struct hlsl_type *type = d3dcompiler_alloc(sizeof(*type)); 750 751 if (!type) 752 { 753 ERR("Out of memory.\n"); 754 return NULL; 755 } 756 type->type = HLSL_CLASS_STRUCT; 757 type->name = name; 758 type->dimx = type->dimy = 1; 759 type->modifiers = modifiers; 760 type->e.elements = fields; 761 762 list_add_tail(&hlsl_ctx.types, &type->entry); 763 764 return type; 765 } 766 767 static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list, 768 struct source_location *loc) 769 { 770 BOOL ret; 771 struct hlsl_type *type; 772 struct parse_variable_def *v, *v_next; 773 774 if (!check_type_modifiers(modifiers, loc)) 775 { 776 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry) 777 d3dcompiler_free(v); 778 d3dcompiler_free(list); 779 return FALSE; 780 } 781 782 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry) 783 { 784 if (v->array_size) 785 type = new_array_type(orig_type, v->array_size); 786 else 787 type = clone_hlsl_type(orig_type); 788 if (!type) 789 { 790 ERR("Out of memory\n"); 791 return FALSE; 792 } 793 d3dcompiler_free((void *)type->name); 794 type->name = v->name; 795 type->modifiers |= modifiers; 796 797 if (type->type != HLSL_CLASS_MATRIX) 798 check_invalid_matrix_modifiers(type->modifiers, &v->loc); 799 800 ret = add_type_to_scope(hlsl_ctx.cur_scope, type); 801 if (!ret) 802 { 803 hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR, 804 "redefinition of custom type '%s'", v->name); 805 } 806 d3dcompiler_free(v); 807 } 808 d3dcompiler_free(list); 809 return TRUE; 810 } 811 812 static BOOL add_func_parameter(struct list *list, struct parse_parameter *param, const struct source_location *loc) 813 { 814 struct hlsl_ir_var *decl = d3dcompiler_alloc(sizeof(*decl)); 815 816 if (!decl) 817 { 818 ERR("Out of memory.\n"); 819 return FALSE; 820 } 821 decl->node.type = HLSL_IR_VAR; 822 decl->node.data_type = param->type; 823 decl->node.loc = *loc; 824 decl->name = param->name; 825 decl->semantic = param->semantic; 826 decl->reg_reservation = param->reg_reservation; 827 decl->modifiers = param->modifiers; 828 829 if (!add_declaration(hlsl_ctx.cur_scope, decl, FALSE)) 830 { 831 free_declaration(decl); 832 return FALSE; 833 } 834 list_add_tail(list, &decl->node.entry); 835 return TRUE; 836 } 837 838 static struct reg_reservation *parse_reg_reservation(const char *reg_string) 839 { 840 struct reg_reservation *reg_res; 841 enum bwritershader_param_register_type type; 842 DWORD regnum = 0; 843 844 switch (reg_string[0]) 845 { 846 case 'c': 847 type = BWRITERSPR_CONST; 848 break; 849 case 'i': 850 type = BWRITERSPR_CONSTINT; 851 break; 852 case 'b': 853 type = BWRITERSPR_CONSTBOOL; 854 break; 855 case 's': 856 type = BWRITERSPR_SAMPLER; 857 break; 858 default: 859 FIXME("Unsupported register type.\n"); 860 return NULL; 861 } 862 863 if (!sscanf(reg_string + 1, "%u", ®num)) 864 { 865 FIXME("Unsupported register reservation syntax.\n"); 866 return NULL; 867 } 868 869 reg_res = d3dcompiler_alloc(sizeof(*reg_res)); 870 if (!reg_res) 871 { 872 ERR("Out of memory.\n"); 873 return NULL; 874 } 875 reg_res->type = type; 876 reg_res->regnum = regnum; 877 return reg_res; 878 } 879 880 static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tree *funcs, char *name, 881 struct list *params, BOOL exact_signature) 882 { 883 struct hlsl_ir_function *func; 884 struct wine_rb_entry *entry; 885 886 entry = wine_rb_get(funcs, name); 887 if (entry) 888 { 889 func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); 890 891 entry = wine_rb_get(&func->overloads, params); 892 if (!entry) 893 { 894 if (!exact_signature) 895 FIXME("No exact match, search for a compatible overloaded function (if any).\n"); 896 return NULL; 897 } 898 return WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); 899 } 900 return NULL; 901 } 902 903 %} 904 905 %locations 906 %error-verbose 907 %expect 1 908 909 %union 910 { 911 struct hlsl_type *type; 912 INT intval; 913 FLOAT floatval; 914 BOOL boolval; 915 char *name; 916 DWORD modifiers; 917 struct hlsl_ir_var *var; 918 struct hlsl_ir_node *instr; 919 struct list *list; 920 struct parse_function function; 921 struct parse_parameter parameter; 922 struct parse_variable_def *variable_def; 923 struct parse_if_body if_body; 924 enum parse_unary_op unary_op; 925 enum parse_assign_op assign_op; 926 struct reg_reservation *reg_reservation; 927 struct parse_colon_attribute colon_attribute; 928 } 929 930 %token KW_BLENDSTATE 931 %token KW_BREAK 932 %token KW_BUFFER 933 %token KW_CBUFFER 934 %token KW_COLUMN_MAJOR 935 %token KW_COMPILE 936 %token KW_CONST 937 %token KW_CONTINUE 938 %token KW_DEPTHSTENCILSTATE 939 %token KW_DEPTHSTENCILVIEW 940 %token KW_DISCARD 941 %token KW_DO 942 %token KW_DOUBLE 943 %token KW_ELSE 944 %token KW_EXTERN 945 %token KW_FALSE 946 %token KW_FOR 947 %token KW_GEOMETRYSHADER 948 %token KW_GROUPSHARED 949 %token KW_IF 950 %token KW_IN 951 %token KW_INLINE 952 %token KW_INOUT 953 %token KW_MATRIX 954 %token KW_NAMESPACE 955 %token KW_NOINTERPOLATION 956 %token KW_OUT 957 %token KW_PASS 958 %token KW_PIXELSHADER 959 %token KW_PRECISE 960 %token KW_RASTERIZERSTATE 961 %token KW_RENDERTARGETVIEW 962 %token KW_RETURN 963 %token KW_REGISTER 964 %token KW_ROW_MAJOR 965 %token KW_SAMPLER 966 %token KW_SAMPLER1D 967 %token KW_SAMPLER2D 968 %token KW_SAMPLER3D 969 %token KW_SAMPLERCUBE 970 %token KW_SAMPLER_STATE 971 %token KW_SAMPLERCOMPARISONSTATE 972 %token KW_SHARED 973 %token KW_STATEBLOCK 974 %token KW_STATEBLOCK_STATE 975 %token KW_STATIC 976 %token KW_STRING 977 %token KW_STRUCT 978 %token KW_SWITCH 979 %token KW_TBUFFER 980 %token KW_TECHNIQUE 981 %token KW_TECHNIQUE10 982 %token KW_TEXTURE 983 %token KW_TEXTURE1D 984 %token KW_TEXTURE1DARRAY 985 %token KW_TEXTURE2D 986 %token KW_TEXTURE2DARRAY 987 %token KW_TEXTURE2DMS 988 %token KW_TEXTURE2DMSARRAY 989 %token KW_TEXTURE3D 990 %token KW_TEXTURE3DARRAY 991 %token KW_TEXTURECUBE 992 %token KW_TRUE 993 %token KW_TYPEDEF 994 %token KW_UNIFORM 995 %token KW_VECTOR 996 %token KW_VERTEXSHADER 997 %token KW_VOID 998 %token KW_VOLATILE 999 %token KW_WHILE 1000 1001 %token OP_INC 1002 %token OP_DEC 1003 %token OP_AND 1004 %token OP_OR 1005 %token OP_EQ 1006 %token OP_LEFTSHIFT 1007 %token OP_LEFTSHIFTASSIGN 1008 %token OP_RIGHTSHIFT 1009 %token OP_RIGHTSHIFTASSIGN 1010 %token OP_ELLIPSIS 1011 %token OP_LE 1012 %token OP_GE 1013 %token OP_NE 1014 %token OP_ADDASSIGN 1015 %token OP_SUBASSIGN 1016 %token OP_MULASSIGN 1017 %token OP_DIVASSIGN 1018 %token OP_MODASSIGN 1019 %token OP_ANDASSIGN 1020 %token OP_ORASSIGN 1021 %token OP_XORASSIGN 1022 %token OP_UNKNOWN1 1023 %token OP_UNKNOWN2 1024 %token OP_UNKNOWN3 1025 %token OP_UNKNOWN4 1026 1027 %token <intval> PRE_LINE 1028 1029 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER 1030 %type <name> any_identifier var_identifier 1031 %token <name> STRING 1032 %token <floatval> C_FLOAT 1033 %token <intval> C_INTEGER 1034 %type <boolval> boolean 1035 %type <type> base_type 1036 %type <type> type 1037 %type <list> declaration_statement 1038 %type <list> declaration 1039 %type <list> struct_declaration 1040 %type <type> struct_spec 1041 %type <type> named_struct_spec 1042 %type <type> unnamed_struct_spec 1043 %type <list> type_specs 1044 %type <variable_def> type_spec 1045 %type <list> complex_initializer 1046 %type <list> initializer_expr_list 1047 %type <instr> initializer_expr 1048 %type <modifiers> var_modifiers 1049 %type <list> field 1050 %type <list> parameters 1051 %type <list> param_list 1052 %type <instr> expr 1053 %type <var> variable 1054 %type <intval> array 1055 %type <list> statement 1056 %type <list> statement_list 1057 %type <list> compound_statement 1058 %type <list> jump_statement 1059 %type <list> selection_statement 1060 %type <list> loop_statement 1061 %type <function> func_declaration 1062 %type <function> func_prototype 1063 %type <list> fields_list 1064 %type <parameter> parameter 1065 %type <colon_attribute> colon_attribute 1066 %type <name> semantic 1067 %type <reg_reservation> register_opt 1068 %type <variable_def> variable_def 1069 %type <list> variables_def 1070 %type <list> variables_def_optional 1071 %type <if_body> if_body 1072 %type <instr> primary_expr 1073 %type <instr> postfix_expr 1074 %type <instr> unary_expr 1075 %type <instr> mul_expr 1076 %type <instr> add_expr 1077 %type <instr> shift_expr 1078 %type <instr> relational_expr 1079 %type <instr> equality_expr 1080 %type <instr> bitand_expr 1081 %type <instr> bitxor_expr 1082 %type <instr> bitor_expr 1083 %type <instr> logicand_expr 1084 %type <instr> logicor_expr 1085 %type <instr> conditional_expr 1086 %type <instr> assignment_expr 1087 %type <list> expr_statement 1088 %type <unary_op> unary_op 1089 %type <assign_op> assign_op 1090 %type <modifiers> input_mods 1091 %type <modifiers> input_mod 1092 %% 1093 1094 hlsl_prog: /* empty */ 1095 { 1096 } 1097 | hlsl_prog func_declaration 1098 { 1099 const struct hlsl_ir_function_decl *decl; 1100 1101 decl = get_overloaded_func(&hlsl_ctx.functions, $2.name, $2.decl->parameters, TRUE); 1102 if (decl && !decl->func->intrinsic) 1103 { 1104 if (decl->body && $2.decl->body) 1105 { 1106 hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line, 1107 $2.decl->node.loc.col, HLSL_LEVEL_ERROR, 1108 "redefinition of function %s", debugstr_a($2.name)); 1109 return 1; 1110 } 1111 else if (!compare_hlsl_types(decl->node.data_type, $2.decl->node.data_type)) 1112 { 1113 hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line, 1114 $2.decl->node.loc.col, HLSL_LEVEL_ERROR, 1115 "redefining function %s with a different return type", 1116 debugstr_a($2.name)); 1117 hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_NOTE, 1118 "%s previously declared here", 1119 debugstr_a($2.name)); 1120 return 1; 1121 } 1122 } 1123 1124 if ($2.decl->node.data_type->base_type == HLSL_TYPE_VOID && $2.decl->semantic) 1125 { 1126 hlsl_report_message($2.decl->node.loc.file, $2.decl->node.loc.line, 1127 $2.decl->node.loc.col, HLSL_LEVEL_ERROR, 1128 "void function with a semantic"); 1129 } 1130 1131 TRACE("Adding function '%s' to the function list.\n", $2.name); 1132 add_function_decl(&hlsl_ctx.functions, $2.name, $2.decl, FALSE); 1133 } 1134 | hlsl_prog declaration_statement 1135 { 1136 TRACE("Declaration statement parsed.\n"); 1137 } 1138 | hlsl_prog preproc_directive 1139 { 1140 } 1141 | hlsl_prog ';' 1142 { 1143 TRACE("Skipping stray semicolon.\n"); 1144 } 1145 1146 preproc_directive: PRE_LINE STRING 1147 { 1148 const char **new_array = NULL; 1149 1150 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1); 1151 hlsl_ctx.line_no = $1; 1152 if (strcmp($2, hlsl_ctx.source_file)) 1153 new_array = d3dcompiler_realloc(hlsl_ctx.source_files, 1154 sizeof(*hlsl_ctx.source_files) * (hlsl_ctx.source_files_count + 1)); 1155 1156 if (new_array) 1157 { 1158 hlsl_ctx.source_files = new_array; 1159 hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2; 1160 hlsl_ctx.source_file = $2; 1161 } 1162 else 1163 { 1164 d3dcompiler_free($2); 1165 } 1166 } 1167 1168 struct_declaration: struct_spec variables_def_optional ';' 1169 { 1170 struct source_location loc; 1171 1172 set_location(&loc, &@3); 1173 if (!$2) 1174 { 1175 if (!$1->name) 1176 { 1177 hlsl_report_message(loc.file, loc.line, loc.col, 1178 HLSL_LEVEL_ERROR, "anonymous struct declaration with no variables"); 1179 } 1180 check_type_modifiers($1->modifiers, &loc); 1181 } 1182 $$ = declare_vars($1, 0, $2); 1183 } 1184 1185 struct_spec: named_struct_spec 1186 | unnamed_struct_spec 1187 1188 named_struct_spec: var_modifiers KW_STRUCT any_identifier '{' fields_list '}' 1189 { 1190 BOOL ret; 1191 struct source_location loc; 1192 1193 TRACE("Structure %s declaration.\n", debugstr_a($3)); 1194 set_location(&loc, &@1); 1195 check_invalid_matrix_modifiers($1, &loc); 1196 $$ = new_struct_type($3, $1, $5); 1197 1198 if (get_variable(hlsl_ctx.cur_scope, $3)) 1199 { 1200 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column, 1201 HLSL_LEVEL_ERROR, "redefinition of '%s'", $3); 1202 return 1; 1203 } 1204 1205 ret = add_type_to_scope(hlsl_ctx.cur_scope, $$); 1206 if (!ret) 1207 { 1208 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column, 1209 HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $3); 1210 return 1; 1211 } 1212 } 1213 1214 unnamed_struct_spec: var_modifiers KW_STRUCT '{' fields_list '}' 1215 { 1216 struct source_location loc; 1217 1218 TRACE("Anonymous structure declaration.\n"); 1219 set_location(&loc, &@1); 1220 check_invalid_matrix_modifiers($1, &loc); 1221 $$ = new_struct_type(NULL, $1, $4); 1222 } 1223 1224 any_identifier: VAR_IDENTIFIER 1225 | TYPE_IDENTIFIER 1226 | NEW_IDENTIFIER 1227 1228 fields_list: /* Empty */ 1229 { 1230 $$ = d3dcompiler_alloc(sizeof(*$$)); 1231 list_init($$); 1232 } 1233 | fields_list field 1234 { 1235 BOOL ret; 1236 struct hlsl_struct_field *field, *next; 1237 1238 $$ = $1; 1239 LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry) 1240 { 1241 ret = add_struct_field($$, field); 1242 if (ret == FALSE) 1243 { 1244 hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column, 1245 HLSL_LEVEL_ERROR, "redefinition of '%s'", field->name); 1246 d3dcompiler_free(field); 1247 } 1248 } 1249 d3dcompiler_free($2); 1250 } 1251 1252 field: var_modifiers type variables_def ';' 1253 { 1254 $$ = gen_struct_fields($2, $1, $3); 1255 } 1256 | unnamed_struct_spec variables_def ';' 1257 { 1258 $$ = gen_struct_fields($1, 0, $2); 1259 } 1260 1261 func_declaration: func_prototype compound_statement 1262 { 1263 TRACE("Function %s parsed.\n", $1.name); 1264 $$ = $1; 1265 $$.decl->body = $2; 1266 pop_scope(&hlsl_ctx); 1267 } 1268 | func_prototype ';' 1269 { 1270 TRACE("Function prototype for %s.\n", $1.name); 1271 $$ = $1; 1272 pop_scope(&hlsl_ctx); 1273 } 1274 1275 func_prototype: var_modifiers type var_identifier '(' parameters ')' colon_attribute 1276 { 1277 if (get_variable(hlsl_ctx.globals, $3)) 1278 { 1279 hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column, 1280 HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3); 1281 return 1; 1282 } 1283 if ($2->base_type == HLSL_TYPE_VOID && $7.semantic) 1284 { 1285 hlsl_report_message(hlsl_ctx.source_file, @7.first_line, @7.first_column, 1286 HLSL_LEVEL_ERROR, "void function with a semantic"); 1287 } 1288 1289 if ($7.reg_reservation) 1290 { 1291 FIXME("Unexpected register reservation for a function.\n"); 1292 d3dcompiler_free($7.reg_reservation); 1293 } 1294 $$.decl = new_func_decl($2, $5); 1295 if (!$$.decl) 1296 { 1297 ERR("Out of memory.\n"); 1298 return -1; 1299 } 1300 $$.name = $3; 1301 $$.decl->semantic = $7.semantic; 1302 set_location(&$$.decl->node.loc, &@3); 1303 } 1304 1305 compound_statement: '{' '}' 1306 { 1307 $$ = d3dcompiler_alloc(sizeof(*$$)); 1308 list_init($$); 1309 } 1310 | '{' scope_start statement_list '}' 1311 { 1312 pop_scope(&hlsl_ctx); 1313 $$ = $3; 1314 } 1315 1316 scope_start: /* Empty */ 1317 { 1318 push_scope(&hlsl_ctx); 1319 } 1320 1321 var_identifier: VAR_IDENTIFIER 1322 | NEW_IDENTIFIER 1323 1324 colon_attribute: /* Empty */ 1325 { 1326 $$.semantic = NULL; 1327 $$.reg_reservation = NULL; 1328 } 1329 | semantic 1330 { 1331 $$.semantic = $1; 1332 $$.reg_reservation = NULL; 1333 } 1334 | register_opt 1335 { 1336 $$.semantic = NULL; 1337 $$.reg_reservation = $1; 1338 } 1339 1340 semantic: ':' any_identifier 1341 { 1342 $$ = $2; 1343 } 1344 1345 /* FIXME: Writemasks */ 1346 register_opt: ':' KW_REGISTER '(' any_identifier ')' 1347 { 1348 $$ = parse_reg_reservation($4); 1349 d3dcompiler_free($4); 1350 } 1351 | ':' KW_REGISTER '(' any_identifier ',' any_identifier ')' 1352 { 1353 FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a($4)); 1354 d3dcompiler_free($4); 1355 1356 $$ = parse_reg_reservation($6); 1357 d3dcompiler_free($6); 1358 } 1359 1360 parameters: scope_start 1361 { 1362 $$ = d3dcompiler_alloc(sizeof(*$$)); 1363 list_init($$); 1364 } 1365 | scope_start param_list 1366 { 1367 $$ = $2; 1368 } 1369 1370 param_list: parameter 1371 { 1372 struct source_location loc; 1373 1374 $$ = d3dcompiler_alloc(sizeof(*$$)); 1375 list_init($$); 1376 set_location(&loc, &@1); 1377 if (!add_func_parameter($$, &$1, &loc)) 1378 { 1379 ERR("Error adding function parameter %s.\n", $1.name); 1380 set_parse_status(&hlsl_ctx.status, PARSE_ERR); 1381 return -1; 1382 } 1383 } 1384 | param_list ',' parameter 1385 { 1386 struct source_location loc; 1387 1388 $$ = $1; 1389 set_location(&loc, &@3); 1390 if (!add_func_parameter($$, &$3, &loc)) 1391 { 1392 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 1393 "duplicate parameter %s", $3.name); 1394 return 1; 1395 } 1396 } 1397 1398 parameter: input_mods var_modifiers type any_identifier colon_attribute 1399 { 1400 $$.modifiers = $1 ? $1 : HLSL_MODIFIER_IN; 1401 $$.modifiers |= $2; 1402 $$.type = $3; 1403 $$.name = $4; 1404 $$.semantic = $5.semantic; 1405 $$.reg_reservation = $5.reg_reservation; 1406 } 1407 1408 input_mods: /* Empty */ 1409 { 1410 $$ = 0; 1411 } 1412 | input_mods input_mod 1413 { 1414 if ($1 & $2) 1415 { 1416 hlsl_report_message(hlsl_ctx.source_file, @2.first_line, @2.first_column, 1417 HLSL_LEVEL_ERROR, "duplicate input-output modifiers"); 1418 return 1; 1419 } 1420 $$ = $1 | $2; 1421 } 1422 1423 input_mod: KW_IN 1424 { 1425 $$ = HLSL_MODIFIER_IN; 1426 } 1427 | KW_OUT 1428 { 1429 $$ = HLSL_MODIFIER_OUT; 1430 } 1431 | KW_INOUT 1432 { 1433 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT; 1434 } 1435 1436 type: base_type 1437 { 1438 $$ = $1; 1439 } 1440 | KW_VECTOR '<' base_type ',' C_INTEGER '>' 1441 { 1442 if ($3->type != HLSL_CLASS_SCALAR) 1443 { 1444 hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n", 1445 hlsl_ctx.line_no); 1446 set_parse_status(&hlsl_ctx.status, PARSE_ERR); 1447 return 1; 1448 } 1449 if ($5 < 1 || $5 > 4) 1450 { 1451 hlsl_message("Line %u: vector size must be between 1 and 4.\n", 1452 hlsl_ctx.line_no); 1453 set_parse_status(&hlsl_ctx.status, PARSE_ERR); 1454 return 1; 1455 } 1456 1457 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1); 1458 } 1459 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>' 1460 { 1461 if ($3->type != HLSL_CLASS_SCALAR) 1462 { 1463 hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n", 1464 hlsl_ctx.line_no); 1465 set_parse_status(&hlsl_ctx.status, PARSE_ERR); 1466 return 1; 1467 } 1468 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4) 1469 { 1470 hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n", 1471 hlsl_ctx.line_no); 1472 set_parse_status(&hlsl_ctx.status, PARSE_ERR); 1473 return 1; 1474 } 1475 1476 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7); 1477 } 1478 1479 base_type: KW_VOID 1480 { 1481 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1); 1482 } 1483 | KW_SAMPLER 1484 { 1485 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); 1486 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC; 1487 } 1488 | KW_SAMPLER1D 1489 { 1490 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); 1491 $$->sampler_dim = HLSL_SAMPLER_DIM_1D; 1492 } 1493 | KW_SAMPLER2D 1494 { 1495 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); 1496 $$->sampler_dim = HLSL_SAMPLER_DIM_2D; 1497 } 1498 | KW_SAMPLER3D 1499 { 1500 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); 1501 $$->sampler_dim = HLSL_SAMPLER_DIM_3D; 1502 } 1503 | KW_SAMPLERCUBE 1504 { 1505 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); 1506 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE; 1507 } 1508 | TYPE_IDENTIFIER 1509 { 1510 struct hlsl_type *type; 1511 1512 type = get_type(hlsl_ctx.cur_scope, $1, TRUE); 1513 $$ = type; 1514 d3dcompiler_free($1); 1515 } 1516 | KW_STRUCT TYPE_IDENTIFIER 1517 { 1518 struct hlsl_type *type; 1519 1520 type = get_type(hlsl_ctx.cur_scope, $2, TRUE); 1521 if (type->type != HLSL_CLASS_STRUCT) 1522 { 1523 hlsl_message("Line %u: redefining %s as a structure.\n", 1524 hlsl_ctx.line_no, $2); 1525 set_parse_status(&hlsl_ctx.status, PARSE_ERR); 1526 } 1527 else 1528 { 1529 $$ = type; 1530 } 1531 d3dcompiler_free($2); 1532 } 1533 1534 declaration_statement: declaration 1535 | struct_declaration 1536 | typedef 1537 { 1538 $$ = d3dcompiler_alloc(sizeof(*$$)); 1539 if (!$$) 1540 { 1541 ERR("Out of memory\n"); 1542 return -1; 1543 } 1544 list_init($$); 1545 } 1546 1547 typedef: KW_TYPEDEF var_modifiers type type_specs ';' 1548 { 1549 struct source_location loc; 1550 1551 set_location(&loc, &@1); 1552 if (!add_typedef($2, $3, $4, &loc)) 1553 return 1; 1554 } 1555 | KW_TYPEDEF struct_spec type_specs ';' 1556 { 1557 struct source_location loc; 1558 1559 set_location(&loc, &@1); 1560 if (!add_typedef(0, $2, $3, &loc)) 1561 return 1; 1562 } 1563 1564 type_specs: type_spec 1565 { 1566 $$ = d3dcompiler_alloc(sizeof(*$$)); 1567 list_init($$); 1568 list_add_head($$, &$1->entry); 1569 } 1570 | type_specs ',' type_spec 1571 { 1572 $$ = $1; 1573 list_add_tail($$, &$3->entry); 1574 } 1575 1576 type_spec: any_identifier array 1577 { 1578 $$ = d3dcompiler_alloc(sizeof(*$$)); 1579 set_location(&$$->loc, &@1); 1580 $$->name = $1; 1581 $$->array_size = $2; 1582 } 1583 1584 declaration: var_modifiers type variables_def ';' 1585 { 1586 $$ = declare_vars($2, $1, $3); 1587 } 1588 1589 variables_def_optional: /* Empty */ 1590 { 1591 $$ = NULL; 1592 } 1593 | variables_def 1594 { 1595 $$ = $1; 1596 } 1597 1598 variables_def: variable_def 1599 { 1600 $$ = d3dcompiler_alloc(sizeof(*$$)); 1601 list_init($$); 1602 list_add_head($$, &$1->entry); 1603 } 1604 | variables_def ',' variable_def 1605 { 1606 $$ = $1; 1607 list_add_tail($$, &$3->entry); 1608 } 1609 1610 variable_def: any_identifier array colon_attribute 1611 { 1612 $$ = d3dcompiler_alloc(sizeof(*$$)); 1613 set_location(&$$->loc, &@1); 1614 $$->name = $1; 1615 $$->array_size = $2; 1616 $$->semantic = $3.semantic; 1617 $$->reg_reservation = $3.reg_reservation; 1618 } 1619 | any_identifier array colon_attribute '=' complex_initializer 1620 { 1621 TRACE("Declaration with initializer.\n"); 1622 $$ = d3dcompiler_alloc(sizeof(*$$)); 1623 set_location(&$$->loc, &@1); 1624 $$->name = $1; 1625 $$->array_size = $2; 1626 $$->semantic = $3.semantic; 1627 $$->reg_reservation = $3.reg_reservation; 1628 $$->initializer = $5; 1629 } 1630 1631 array: /* Empty */ 1632 { 1633 $$ = 0; 1634 } 1635 | '[' expr ']' 1636 { 1637 FIXME("Array.\n"); 1638 $$ = 0; 1639 free_instr($2); 1640 } 1641 1642 var_modifiers: /* Empty */ 1643 { 1644 $$ = 0; 1645 } 1646 | KW_EXTERN var_modifiers 1647 { 1648 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1); 1649 } 1650 | KW_NOINTERPOLATION var_modifiers 1651 { 1652 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1); 1653 } 1654 | KW_PRECISE var_modifiers 1655 { 1656 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1); 1657 } 1658 | KW_SHARED var_modifiers 1659 { 1660 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1); 1661 } 1662 | KW_GROUPSHARED var_modifiers 1663 { 1664 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1); 1665 } 1666 | KW_STATIC var_modifiers 1667 { 1668 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1); 1669 } 1670 | KW_UNIFORM var_modifiers 1671 { 1672 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1); 1673 } 1674 | KW_VOLATILE var_modifiers 1675 { 1676 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1); 1677 } 1678 | KW_CONST var_modifiers 1679 { 1680 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1); 1681 } 1682 | KW_ROW_MAJOR var_modifiers 1683 { 1684 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1); 1685 } 1686 | KW_COLUMN_MAJOR var_modifiers 1687 { 1688 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1); 1689 } 1690 1691 complex_initializer: initializer_expr 1692 { 1693 $$ = d3dcompiler_alloc(sizeof(*$$)); 1694 list_init($$); 1695 list_add_head($$, &$1->entry); 1696 } 1697 | '{' initializer_expr_list '}' 1698 { 1699 $$ = $2; 1700 } 1701 | '{' initializer_expr_list ',' '}' 1702 { 1703 $$ = $2; 1704 } 1705 1706 initializer_expr: assignment_expr 1707 { 1708 $$ = $1; 1709 } 1710 1711 initializer_expr_list: initializer_expr 1712 { 1713 $$ = d3dcompiler_alloc(sizeof(*$$)); 1714 list_init($$); 1715 list_add_head($$, &$1->entry); 1716 } 1717 | initializer_expr_list ',' initializer_expr 1718 { 1719 $$ = $1; 1720 list_add_tail($$, &$3->entry); 1721 } 1722 1723 boolean: KW_TRUE 1724 { 1725 $$ = TRUE; 1726 } 1727 | KW_FALSE 1728 { 1729 $$ = FALSE; 1730 } 1731 1732 statement_list: statement 1733 { 1734 $$ = $1; 1735 } 1736 | statement_list statement 1737 { 1738 $$ = $1; 1739 list_move_tail($$, $2); 1740 d3dcompiler_free($2); 1741 } 1742 1743 statement: declaration_statement 1744 | expr_statement 1745 | compound_statement 1746 | jump_statement 1747 | selection_statement 1748 | loop_statement 1749 1750 /* FIXME: add rule for return with no value */ 1751 jump_statement: KW_RETURN expr ';' 1752 { 1753 struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump)); 1754 if (!jump) 1755 { 1756 ERR("Out of memory\n"); 1757 return -1; 1758 } 1759 jump->node.type = HLSL_IR_JUMP; 1760 set_location(&jump->node.loc, &@1); 1761 jump->type = HLSL_IR_JUMP_RETURN; 1762 jump->node.data_type = $2->data_type; 1763 jump->return_value = $2; 1764 1765 FIXME("Check for valued return on void function.\n"); 1766 FIXME("Implicit conversion to the return type if needed, " 1767 "error out if conversion not possible.\n"); 1768 1769 $$ = d3dcompiler_alloc(sizeof(*$$)); 1770 list_init($$); 1771 list_add_tail($$, &jump->node.entry); 1772 } 1773 1774 selection_statement: KW_IF '(' expr ')' if_body 1775 { 1776 struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr)); 1777 if (!instr) 1778 { 1779 ERR("Out of memory\n"); 1780 return -1; 1781 } 1782 instr->node.type = HLSL_IR_IF; 1783 set_location(&instr->node.loc, &@1); 1784 instr->condition = $3; 1785 instr->then_instrs = $5.then_instrs; 1786 instr->else_instrs = $5.else_instrs; 1787 if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1) 1788 { 1789 hlsl_report_message(instr->node.loc.file, instr->node.loc.line, 1790 instr->node.loc.col, HLSL_LEVEL_ERROR, 1791 "if condition requires a scalar"); 1792 } 1793 $$ = d3dcompiler_alloc(sizeof(*$$)); 1794 list_init($$); 1795 list_add_head($$, &instr->node.entry); 1796 } 1797 1798 if_body: statement 1799 { 1800 $$.then_instrs = $1; 1801 $$.else_instrs = NULL; 1802 } 1803 | statement KW_ELSE statement 1804 { 1805 $$.then_instrs = $1; 1806 $$.else_instrs = $3; 1807 } 1808 1809 loop_statement: KW_WHILE '(' expr ')' statement 1810 { 1811 struct source_location loc; 1812 struct list *cond = d3dcompiler_alloc(sizeof(*cond)); 1813 1814 if (!cond) 1815 { 1816 ERR("Out of memory.\n"); 1817 return -1; 1818 } 1819 list_init(cond); 1820 list_add_head(cond, &$3->entry); 1821 set_location(&loc, &@1); 1822 $$ = create_loop(LOOP_WHILE, NULL, cond, NULL, $5, &loc); 1823 } 1824 | KW_DO statement KW_WHILE '(' expr ')' ';' 1825 { 1826 struct source_location loc; 1827 struct list *cond = d3dcompiler_alloc(sizeof(*cond)); 1828 1829 if (!cond) 1830 { 1831 ERR("Out of memory.\n"); 1832 return -1; 1833 } 1834 list_init(cond); 1835 list_add_head(cond, &$5->entry); 1836 set_location(&loc, &@1); 1837 $$ = create_loop(LOOP_DO_WHILE, NULL, cond, NULL, $2, &loc); 1838 } 1839 | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement 1840 { 1841 struct source_location loc; 1842 1843 set_location(&loc, &@1); 1844 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc); 1845 pop_scope(&hlsl_ctx); 1846 } 1847 | KW_FOR '(' scope_start declaration expr_statement expr ')' statement 1848 { 1849 struct source_location loc; 1850 1851 set_location(&loc, &@1); 1852 if (!$4) 1853 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_WARNING, 1854 "no expressions in for loop initializer"); 1855 $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, &loc); 1856 pop_scope(&hlsl_ctx); 1857 } 1858 1859 expr_statement: ';' 1860 { 1861 $$ = d3dcompiler_alloc(sizeof(*$$)); 1862 list_init($$); 1863 } 1864 | expr ';' 1865 { 1866 $$ = d3dcompiler_alloc(sizeof(*$$)); 1867 list_init($$); 1868 if ($1) 1869 list_add_head($$, &$1->entry); 1870 } 1871 1872 primary_expr: C_FLOAT 1873 { 1874 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c)); 1875 if (!c) 1876 { 1877 ERR("Out of memory.\n"); 1878 return -1; 1879 } 1880 c->node.type = HLSL_IR_CONSTANT; 1881 set_location(&c->node.loc, &yylloc); 1882 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("float"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1); 1883 c->v.value.f[0] = $1; 1884 $$ = &c->node; 1885 } 1886 | C_INTEGER 1887 { 1888 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c)); 1889 if (!c) 1890 { 1891 ERR("Out of memory.\n"); 1892 return -1; 1893 } 1894 c->node.type = HLSL_IR_CONSTANT; 1895 set_location(&c->node.loc, &yylloc); 1896 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("int"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1); 1897 c->v.value.i[0] = $1; 1898 $$ = &c->node; 1899 } 1900 | boolean 1901 { 1902 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c)); 1903 if (!c) 1904 { 1905 ERR("Out of memory.\n"); 1906 return -1; 1907 } 1908 c->node.type = HLSL_IR_CONSTANT; 1909 set_location(&c->node.loc, &yylloc); 1910 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("bool"), HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1); 1911 c->v.value.b[0] = $1; 1912 $$ = &c->node; 1913 } 1914 | variable 1915 { 1916 struct hlsl_ir_deref *deref = new_var_deref($1); 1917 if (deref) 1918 { 1919 $$ = &deref->node; 1920 set_location(&$$->loc, &@1); 1921 } 1922 else 1923 $$ = NULL; 1924 } 1925 | '(' expr ')' 1926 { 1927 $$ = $2; 1928 } 1929 1930 variable: VAR_IDENTIFIER 1931 { 1932 struct hlsl_ir_var *var; 1933 var = get_variable(hlsl_ctx.cur_scope, $1); 1934 if (!var) 1935 { 1936 hlsl_message("Line %d: variable '%s' not declared\n", 1937 hlsl_ctx.line_no, $1); 1938 set_parse_status(&hlsl_ctx.status, PARSE_ERR); 1939 return 1; 1940 } 1941 $$ = var; 1942 } 1943 1944 postfix_expr: primary_expr 1945 { 1946 $$ = $1; 1947 } 1948 | postfix_expr OP_INC 1949 { 1950 struct hlsl_ir_node *operands[3]; 1951 struct source_location loc; 1952 1953 set_location(&loc, &@2); 1954 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST) 1955 { 1956 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 1957 "modifying a const expression"); 1958 return 1; 1959 } 1960 operands[0] = $1; 1961 operands[1] = operands[2] = NULL; 1962 $$ = &new_expr(HLSL_IR_UNOP_POSTINC, operands, &loc)->node; 1963 /* Post increment/decrement expressions are considered const */ 1964 $$->data_type = clone_hlsl_type($$->data_type); 1965 $$->data_type->modifiers |= HLSL_MODIFIER_CONST; 1966 } 1967 | postfix_expr OP_DEC 1968 { 1969 struct hlsl_ir_node *operands[3]; 1970 struct source_location loc; 1971 1972 set_location(&loc, &@2); 1973 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST) 1974 { 1975 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 1976 "modifying a const expression"); 1977 return 1; 1978 } 1979 operands[0] = $1; 1980 operands[1] = operands[2] = NULL; 1981 $$ = &new_expr(HLSL_IR_UNOP_POSTDEC, operands, &loc)->node; 1982 /* Post increment/decrement expressions are considered const */ 1983 $$->data_type = clone_hlsl_type($$->data_type); 1984 $$->data_type->modifiers |= HLSL_MODIFIER_CONST; 1985 } 1986 | postfix_expr '.' any_identifier 1987 { 1988 struct source_location loc; 1989 1990 set_location(&loc, &@2); 1991 if ($1->data_type->type == HLSL_CLASS_STRUCT) 1992 { 1993 struct hlsl_type *type = $1->data_type; 1994 struct hlsl_struct_field *field; 1995 1996 $$ = NULL; 1997 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) 1998 { 1999 if (!strcmp($3, field->name)) 2000 { 2001 struct hlsl_ir_deref *deref = new_record_deref($1, field); 2002 2003 if (!deref) 2004 { 2005 ERR("Out of memory\n"); 2006 return -1; 2007 } 2008 deref->node.loc = loc; 2009 $$ = &deref->node; 2010 break; 2011 } 2012 } 2013 if (!$$) 2014 { 2015 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 2016 "invalid subscript %s", debugstr_a($3)); 2017 return 1; 2018 } 2019 } 2020 else if ($1->data_type->type <= HLSL_CLASS_LAST_NUMERIC) 2021 { 2022 struct hlsl_ir_swizzle *swizzle; 2023 2024 swizzle = get_swizzle($1, $3, &loc); 2025 if (!swizzle) 2026 { 2027 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 2028 "invalid swizzle %s", debugstr_a($3)); 2029 return 1; 2030 } 2031 $$ = &swizzle->node; 2032 } 2033 else 2034 { 2035 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 2036 "invalid subscript %s", debugstr_a($3)); 2037 return 1; 2038 } 2039 } 2040 | postfix_expr '[' expr ']' 2041 { 2042 /* This may be an array dereference or a vector/matrix 2043 * subcomponent access. 2044 * We store it as an array dereference in any case. */ 2045 struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref)); 2046 struct hlsl_type *expr_type = $1->data_type; 2047 struct source_location loc; 2048 2049 TRACE("Array dereference from type %s\n", debug_hlsl_type(expr_type)); 2050 if (!deref) 2051 { 2052 ERR("Out of memory\n"); 2053 return -1; 2054 } 2055 deref->node.type = HLSL_IR_DEREF; 2056 set_location(&loc, &@2); 2057 deref->node.loc = loc; 2058 if (expr_type->type == HLSL_CLASS_ARRAY) 2059 { 2060 deref->node.data_type = expr_type->e.array.type; 2061 } 2062 else if (expr_type->type == HLSL_CLASS_MATRIX) 2063 { 2064 deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, expr_type->base_type, expr_type->dimx, 1); 2065 } 2066 else if (expr_type->type == HLSL_CLASS_VECTOR) 2067 { 2068 deref->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_SCALAR, expr_type->base_type, 1, 1); 2069 } 2070 else 2071 { 2072 if (expr_type->type == HLSL_CLASS_SCALAR) 2073 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 2074 "array-indexed expression is scalar"); 2075 else 2076 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 2077 "expression is not array-indexable"); 2078 d3dcompiler_free(deref); 2079 free_instr($1); 2080 free_instr($3); 2081 return 1; 2082 } 2083 if ($3->data_type->type != HLSL_CLASS_SCALAR) 2084 { 2085 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 2086 "array index is not scalar"); 2087 d3dcompiler_free(deref); 2088 free_instr($1); 2089 free_instr($3); 2090 return 1; 2091 } 2092 deref->type = HLSL_IR_DEREF_ARRAY; 2093 deref->v.array.array = $1; 2094 deref->v.array.index = $3; 2095 2096 $$ = &deref->node; 2097 } 2098 /* "var_modifiers" doesn't make sense in this case, but it's needed 2099 in the grammar to avoid shift/reduce conflicts. */ 2100 | var_modifiers type '(' initializer_expr_list ')' 2101 { 2102 struct hlsl_ir_constructor *constructor; 2103 2104 TRACE("%s constructor.\n", debug_hlsl_type($2)); 2105 if ($1) 2106 { 2107 hlsl_message("Line %u: unexpected modifier in a constructor.\n", 2108 hlsl_ctx.line_no); 2109 set_parse_status(&hlsl_ctx.status, PARSE_ERR); 2110 return -1; 2111 } 2112 if ($2->type > HLSL_CLASS_LAST_NUMERIC) 2113 { 2114 hlsl_message("Line %u: constructors are allowed only for numeric data types.\n", 2115 hlsl_ctx.line_no); 2116 set_parse_status(&hlsl_ctx.status, PARSE_ERR); 2117 return -1; 2118 } 2119 if ($2->dimx * $2->dimy != components_count_expr_list($4)) 2120 { 2121 hlsl_message("Line %u: wrong number of components in constructor.\n", 2122 hlsl_ctx.line_no); 2123 set_parse_status(&hlsl_ctx.status, PARSE_ERR); 2124 return -1; 2125 } 2126 2127 constructor = d3dcompiler_alloc(sizeof(*constructor)); 2128 constructor->node.type = HLSL_IR_CONSTRUCTOR; 2129 set_location(&constructor->node.loc, &@3); 2130 constructor->node.data_type = $2; 2131 constructor->arguments = $4; 2132 2133 $$ = &constructor->node; 2134 } 2135 2136 unary_expr: postfix_expr 2137 { 2138 $$ = $1; 2139 } 2140 | OP_INC unary_expr 2141 { 2142 struct hlsl_ir_node *operands[3]; 2143 struct source_location loc; 2144 2145 set_location(&loc, &@1); 2146 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST) 2147 { 2148 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 2149 "modifying a const expression"); 2150 return 1; 2151 } 2152 operands[0] = $2; 2153 operands[1] = operands[2] = NULL; 2154 $$ = &new_expr(HLSL_IR_UNOP_PREINC, operands, &loc)->node; 2155 } 2156 | OP_DEC unary_expr 2157 { 2158 struct hlsl_ir_node *operands[3]; 2159 struct source_location loc; 2160 2161 set_location(&loc, &@1); 2162 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST) 2163 { 2164 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 2165 "modifying a const expression"); 2166 return 1; 2167 } 2168 operands[0] = $2; 2169 operands[1] = operands[2] = NULL; 2170 $$ = &new_expr(HLSL_IR_UNOP_PREDEC, operands, &loc)->node; 2171 } 2172 | unary_op unary_expr 2173 { 2174 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG, 2175 HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT}; 2176 struct hlsl_ir_node *operands[3]; 2177 struct source_location loc; 2178 2179 if ($1 == UNARY_OP_PLUS) 2180 { 2181 $$ = $2; 2182 } 2183 else 2184 { 2185 operands[0] = $2; 2186 operands[1] = operands[2] = NULL; 2187 set_location(&loc, &@1); 2188 $$ = &new_expr(ops[$1], operands, &loc)->node; 2189 } 2190 } 2191 /* var_modifiers just to avoid shift/reduce conflicts */ 2192 | '(' var_modifiers type array ')' unary_expr 2193 { 2194 struct hlsl_ir_expr *expr; 2195 struct hlsl_type *src_type = $6->data_type; 2196 struct hlsl_type *dst_type; 2197 struct source_location loc; 2198 2199 set_location(&loc, &@3); 2200 if ($2) 2201 { 2202 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 2203 "unexpected modifier in a cast"); 2204 return 1; 2205 } 2206 2207 if ($4) 2208 dst_type = new_array_type($3, $4); 2209 else 2210 dst_type = $3; 2211 2212 if (!compatible_data_types(src_type, dst_type)) 2213 { 2214 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 2215 "can't cast from %s to %s", 2216 debug_hlsl_type(src_type), debug_hlsl_type(dst_type)); 2217 return 1; 2218 } 2219 2220 expr = new_cast($6, dst_type, &loc); 2221 $$ = expr ? &expr->node : NULL; 2222 } 2223 2224 unary_op: '+' 2225 { 2226 $$ = UNARY_OP_PLUS; 2227 } 2228 | '-' 2229 { 2230 $$ = UNARY_OP_MINUS; 2231 } 2232 | '!' 2233 { 2234 $$ = UNARY_OP_LOGICNOT; 2235 } 2236 | '~' 2237 { 2238 $$ = UNARY_OP_BITNOT; 2239 } 2240 2241 mul_expr: unary_expr 2242 { 2243 $$ = $1; 2244 } 2245 | mul_expr '*' unary_expr 2246 { 2247 struct source_location loc; 2248 2249 set_location(&loc, &@2); 2250 $$ = &hlsl_mul($1, $3, &loc)->node; 2251 } 2252 | mul_expr '/' unary_expr 2253 { 2254 struct source_location loc; 2255 2256 set_location(&loc, &@2); 2257 $$ = &hlsl_div($1, $3, &loc)->node; 2258 } 2259 | mul_expr '%' unary_expr 2260 { 2261 struct source_location loc; 2262 2263 set_location(&loc, &@2); 2264 $$ = &hlsl_mod($1, $3, &loc)->node; 2265 } 2266 2267 add_expr: mul_expr 2268 { 2269 $$ = $1; 2270 } 2271 | add_expr '+' mul_expr 2272 { 2273 struct source_location loc; 2274 2275 set_location(&loc, &@2); 2276 $$ = &hlsl_add($1, $3, &loc)->node; 2277 } 2278 | add_expr '-' mul_expr 2279 { 2280 struct source_location loc; 2281 2282 set_location(&loc, &@2); 2283 $$ = &hlsl_sub($1, $3, &loc)->node; 2284 } 2285 2286 shift_expr: add_expr 2287 { 2288 $$ = $1; 2289 } 2290 | shift_expr OP_LEFTSHIFT add_expr 2291 { 2292 FIXME("Left shift\n"); 2293 } 2294 | shift_expr OP_RIGHTSHIFT add_expr 2295 { 2296 FIXME("Right shift\n"); 2297 } 2298 2299 relational_expr: shift_expr 2300 { 2301 $$ = $1; 2302 } 2303 | relational_expr '<' shift_expr 2304 { 2305 struct source_location loc; 2306 2307 set_location(&loc, &@2); 2308 $$ = &hlsl_lt($1, $3, &loc)->node; 2309 } 2310 | relational_expr '>' shift_expr 2311 { 2312 struct source_location loc; 2313 2314 set_location(&loc, &@2); 2315 $$ = &hlsl_gt($1, $3, &loc)->node; 2316 } 2317 | relational_expr OP_LE shift_expr 2318 { 2319 struct source_location loc; 2320 2321 set_location(&loc, &@2); 2322 $$ = &hlsl_le($1, $3, &loc)->node; 2323 } 2324 | relational_expr OP_GE shift_expr 2325 { 2326 struct source_location loc; 2327 2328 set_location(&loc, &@2); 2329 $$ = &hlsl_ge($1, $3, &loc)->node; 2330 } 2331 2332 equality_expr: relational_expr 2333 { 2334 $$ = $1; 2335 } 2336 | equality_expr OP_EQ relational_expr 2337 { 2338 struct source_location loc; 2339 2340 set_location(&loc, &@2); 2341 $$ = &hlsl_eq($1, $3, &loc)->node; 2342 } 2343 | equality_expr OP_NE relational_expr 2344 { 2345 struct source_location loc; 2346 2347 set_location(&loc, &@2); 2348 $$ = &hlsl_ne($1, $3, &loc)->node; 2349 } 2350 2351 bitand_expr: equality_expr 2352 { 2353 $$ = $1; 2354 } 2355 | bitand_expr '&' equality_expr 2356 { 2357 FIXME("bitwise AND\n"); 2358 } 2359 2360 bitxor_expr: bitand_expr 2361 { 2362 $$ = $1; 2363 } 2364 | bitxor_expr '^' bitand_expr 2365 { 2366 FIXME("bitwise XOR\n"); 2367 } 2368 2369 bitor_expr: bitxor_expr 2370 { 2371 $$ = $1; 2372 } 2373 | bitor_expr '|' bitxor_expr 2374 { 2375 FIXME("bitwise OR\n"); 2376 } 2377 2378 logicand_expr: bitor_expr 2379 { 2380 $$ = $1; 2381 } 2382 | logicand_expr OP_AND bitor_expr 2383 { 2384 FIXME("logic AND\n"); 2385 } 2386 2387 logicor_expr: logicand_expr 2388 { 2389 $$ = $1; 2390 } 2391 | logicor_expr OP_OR logicand_expr 2392 { 2393 FIXME("logic OR\n"); 2394 } 2395 2396 conditional_expr: logicor_expr 2397 { 2398 $$ = $1; 2399 } 2400 | logicor_expr '?' expr ':' assignment_expr 2401 { 2402 FIXME("ternary operator\n"); 2403 } 2404 2405 assignment_expr: conditional_expr 2406 { 2407 $$ = $1; 2408 } 2409 | unary_expr assign_op assignment_expr 2410 { 2411 struct source_location loc; 2412 2413 set_location(&loc, &@2); 2414 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST) 2415 { 2416 hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR, 2417 "l-value is const"); 2418 return 1; 2419 } 2420 $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3); 2421 if (!$$) 2422 return 1; 2423 $$->loc = loc; 2424 } 2425 2426 assign_op: '=' 2427 { 2428 $$ = ASSIGN_OP_ASSIGN; 2429 } 2430 | OP_ADDASSIGN 2431 { 2432 $$ = ASSIGN_OP_ADD; 2433 } 2434 | OP_SUBASSIGN 2435 { 2436 $$ = ASSIGN_OP_SUB; 2437 } 2438 | OP_MULASSIGN 2439 { 2440 $$ = ASSIGN_OP_MUL; 2441 } 2442 | OP_DIVASSIGN 2443 { 2444 $$ = ASSIGN_OP_DIV; 2445 } 2446 | OP_MODASSIGN 2447 { 2448 $$ = ASSIGN_OP_MOD; 2449 } 2450 | OP_LEFTSHIFTASSIGN 2451 { 2452 $$ = ASSIGN_OP_LSHIFT; 2453 } 2454 | OP_RIGHTSHIFTASSIGN 2455 { 2456 $$ = ASSIGN_OP_RSHIFT; 2457 } 2458 | OP_ANDASSIGN 2459 { 2460 $$ = ASSIGN_OP_AND; 2461 } 2462 | OP_ORASSIGN 2463 { 2464 $$ = ASSIGN_OP_OR; 2465 } 2466 | OP_XORASSIGN 2467 { 2468 $$ = ASSIGN_OP_XOR; 2469 } 2470 2471 expr: assignment_expr 2472 { 2473 $$ = $1; 2474 } 2475 | expr ',' assignment_expr 2476 { 2477 FIXME("Comma expression\n"); 2478 } 2479 2480 %% 2481 2482 static void set_location(struct source_location *loc, const struct YYLTYPE *l) 2483 { 2484 loc->file = hlsl_ctx.source_file; 2485 loc->line = l->first_line; 2486 loc->col = l->first_column; 2487 } 2488 2489 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc) 2490 { 2491 if (modifiers & mod) 2492 { 2493 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR, 2494 "modifier '%s' already specified", debug_modifiers(mod)); 2495 return modifiers; 2496 } 2497 if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR) 2498 && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)) 2499 { 2500 hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR, 2501 "more than one matrix majority keyword"); 2502 return modifiers; 2503 } 2504 return modifiers | mod; 2505 } 2506 2507 static void dump_function_decl(struct wine_rb_entry *entry, void *context) 2508 { 2509 struct hlsl_ir_function_decl *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); 2510 if (func->body) 2511 debug_dump_ir_function_decl(func); 2512 } 2513 2514 static void dump_function(struct wine_rb_entry *entry, void *context) 2515 { 2516 struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); 2517 wine_rb_for_each_entry(&func->overloads, dump_function_decl, NULL); 2518 } 2519 2520 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor, 2521 const char *entrypoint, char **messages) 2522 { 2523 struct hlsl_scope *scope, *next_scope; 2524 struct hlsl_type *hlsl_type, *next_type; 2525 struct hlsl_ir_var *var, *next_var; 2526 unsigned int i; 2527 2528 hlsl_ctx.status = PARSE_SUCCESS; 2529 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0; 2530 hlsl_ctx.line_no = hlsl_ctx.column = 1; 2531 hlsl_ctx.source_file = d3dcompiler_strdup(""); 2532 hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files)); 2533 if (hlsl_ctx.source_files) 2534 hlsl_ctx.source_files[0] = hlsl_ctx.source_file; 2535 hlsl_ctx.source_files_count = 1; 2536 hlsl_ctx.cur_scope = NULL; 2537 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR; 2538 list_init(&hlsl_ctx.scopes); 2539 list_init(&hlsl_ctx.types); 2540 init_functions_tree(&hlsl_ctx.functions); 2541 2542 push_scope(&hlsl_ctx); 2543 hlsl_ctx.globals = hlsl_ctx.cur_scope; 2544 declare_predefined_types(hlsl_ctx.globals); 2545 2546 hlsl_parse(); 2547 2548 if (TRACE_ON(hlsl_parser)) 2549 { 2550 TRACE("IR dump.\n"); 2551 wine_rb_for_each_entry(&hlsl_ctx.functions, dump_function, NULL); 2552 } 2553 2554 TRACE("Compilation status = %d\n", hlsl_ctx.status); 2555 if (messages) 2556 { 2557 if (hlsl_ctx.messages.size) 2558 *messages = hlsl_ctx.messages.string; 2559 else 2560 *messages = NULL; 2561 } 2562 else 2563 { 2564 if (hlsl_ctx.messages.capacity) 2565 d3dcompiler_free(hlsl_ctx.messages.string); 2566 } 2567 2568 for (i = 0; i < hlsl_ctx.source_files_count; ++i) 2569 d3dcompiler_free((void *)hlsl_ctx.source_files[i]); 2570 d3dcompiler_free(hlsl_ctx.source_files); 2571 2572 TRACE("Freeing functions IR.\n"); 2573 wine_rb_destroy(&hlsl_ctx.functions, free_function_rb, NULL); 2574 2575 TRACE("Freeing variables.\n"); 2576 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry) 2577 { 2578 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry) 2579 { 2580 free_declaration(var); 2581 } 2582 wine_rb_destroy(&scope->types, NULL, NULL); 2583 d3dcompiler_free(scope); 2584 } 2585 2586 TRACE("Freeing types.\n"); 2587 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry) 2588 { 2589 free_hlsl_type(hlsl_type); 2590 } 2591 2592 return NULL; 2593 } 2594