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