blob 4e9c8d2b (998536B) - Raw
1 /* 2 * Copyright (c) 2016 Andrew Kelley 3 * 4 * This file is part of zig, which is MIT licensed. 5 * See http://opensource.org/licenses/MIT 6 */ 7 8 #include "analyze.hpp" 9 #include "ast_render.hpp" 10 #include "error.hpp" 11 #include "ir.hpp" 12 #include "ir_print.hpp" 13 #include "os.hpp" 14 #include "range_set.hpp" 15 #include "softfloat.hpp" 16 #include "translate_c.hpp" 17 #include "util.hpp" 18 19 struct IrExecContext { 20 ZigList<ConstExprValue *> mem_slot_list; 21 }; 22 23 struct IrBuilder { 24 CodeGen *codegen; 25 IrExecutable *exec; 26 IrBasicBlock *current_basic_block; 27 }; 28 29 struct IrAnalyze { 30 CodeGen *codegen; 31 IrBuilder old_irb; 32 IrBuilder new_irb; 33 IrExecContext exec_context; 34 size_t old_bb_index; 35 size_t instruction_index; 36 ZigType *explicit_return_type; 37 ZigList<IrInstruction *> src_implicit_return_type_list; 38 IrBasicBlock *const_predecessor_bb; 39 }; 40 41 enum ConstCastResultId { 42 ConstCastResultIdOk, 43 ConstCastResultIdErrSet, 44 ConstCastResultIdErrSetGlobal, 45 ConstCastResultIdPointerChild, 46 ConstCastResultIdSliceChild, 47 ConstCastResultIdOptionalChild, 48 ConstCastResultIdErrorUnionPayload, 49 ConstCastResultIdErrorUnionErrorSet, 50 ConstCastResultIdFnAlign, 51 ConstCastResultIdFnCC, 52 ConstCastResultIdFnVarArgs, 53 ConstCastResultIdFnIsGeneric, 54 ConstCastResultIdFnReturnType, 55 ConstCastResultIdFnArgCount, 56 ConstCastResultIdFnGenericArgCount, 57 ConstCastResultIdFnArg, 58 ConstCastResultIdFnArgNoAlias, 59 ConstCastResultIdType, 60 ConstCastResultIdUnresolvedInferredErrSet, 61 ConstCastResultIdAsyncAllocatorType, 62 ConstCastResultIdNullWrapPtr 63 }; 64 65 struct ConstCastOnly; 66 struct ConstCastArg { 67 size_t arg_index; 68 ConstCastOnly *child; 69 }; 70 71 struct ConstCastArgNoAlias { 72 size_t arg_index; 73 }; 74 75 struct ConstCastOptionalMismatch; 76 struct ConstCastPointerMismatch; 77 struct ConstCastSliceMismatch; 78 struct ConstCastErrUnionErrSetMismatch; 79 struct ConstCastErrUnionPayloadMismatch; 80 struct ConstCastErrSetMismatch; 81 struct ConstCastTypeMismatch; 82 83 struct ConstCastOnly { 84 ConstCastResultId id; 85 union { 86 ConstCastErrSetMismatch *error_set_mismatch; 87 ConstCastPointerMismatch *pointer_mismatch; 88 ConstCastSliceMismatch *slice_mismatch; 89 ConstCastOptionalMismatch *optional; 90 ConstCastErrUnionPayloadMismatch *error_union_payload; 91 ConstCastErrUnionErrSetMismatch *error_union_error_set; 92 ConstCastTypeMismatch *type_mismatch; 93 ConstCastOnly *return_type; 94 ConstCastOnly *async_allocator_type; 95 ConstCastOnly *null_wrap_ptr_child; 96 ConstCastArg fn_arg; 97 ConstCastArgNoAlias arg_no_alias; 98 } data; 99 }; 100 101 struct ConstCastTypeMismatch { 102 ZigType *wanted_type; 103 ZigType *actual_type; 104 }; 105 106 struct ConstCastOptionalMismatch { 107 ConstCastOnly child; 108 ZigType *wanted_child; 109 ZigType *actual_child; 110 }; 111 112 struct ConstCastPointerMismatch { 113 ConstCastOnly child; 114 ZigType *wanted_child; 115 ZigType *actual_child; 116 }; 117 118 struct ConstCastSliceMismatch { 119 ConstCastOnly child; 120 ZigType *wanted_child; 121 ZigType *actual_child; 122 }; 123 124 struct ConstCastErrUnionErrSetMismatch { 125 ConstCastOnly child; 126 ZigType *wanted_err_set; 127 ZigType *actual_err_set; 128 }; 129 130 struct ConstCastErrUnionPayloadMismatch { 131 ConstCastOnly child; 132 ZigType *wanted_payload; 133 ZigType *actual_payload; 134 }; 135 136 struct ConstCastErrSetMismatch { 137 ZigList<ErrorTableEntry *> missing_errors; 138 }; 139 140 static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); 141 static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval); 142 static ZigType *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); 143 static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type); 144 static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr); 145 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg); 146 static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 147 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type); 148 static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var); 149 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); 150 static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval); 151 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); 152 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); 153 static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); 154 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); 155 156 static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { 157 assert(get_codegen_ptr_type(const_val->type) != nullptr); 158 assert(const_val->special == ConstValSpecialStatic); 159 ConstExprValue *result; 160 switch (const_val->data.x_ptr.special) { 161 case ConstPtrSpecialInvalid: 162 zig_unreachable(); 163 case ConstPtrSpecialRef: 164 result = const_val->data.x_ptr.data.ref.pointee; 165 break; 166 case ConstPtrSpecialBaseArray: 167 expand_undef_array(g, const_val->data.x_ptr.data.base_array.array_val); 168 result = &const_val->data.x_ptr.data.base_array.array_val->data.x_array.s_none.elements[ 169 const_val->data.x_ptr.data.base_array.elem_index]; 170 break; 171 case ConstPtrSpecialBaseStruct: 172 result = &const_val->data.x_ptr.data.base_struct.struct_val->data.x_struct.fields[ 173 const_val->data.x_ptr.data.base_struct.field_index]; 174 break; 175 case ConstPtrSpecialHardCodedAddr: 176 zig_unreachable(); 177 case ConstPtrSpecialDiscard: 178 zig_unreachable(); 179 case ConstPtrSpecialFunction: 180 zig_unreachable(); 181 } 182 assert(result != nullptr); 183 return result; 184 } 185 186 static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { 187 if (a == b) 188 return true; 189 190 if (a->id == b->id) 191 return true; 192 193 if (get_codegen_ptr_type(a) != nullptr && get_codegen_ptr_type(b) != nullptr) 194 return true; 195 196 return false; 197 } 198 199 ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { 200 ConstExprValue *result = const_ptr_pointee_unchecked(g, const_val); 201 if (const_val->type->id == ZigTypeIdPointer) { 202 assert(types_have_same_zig_comptime_repr(const_val->type->data.pointer.child_type, result->type)); 203 } 204 return result; 205 } 206 207 static bool ir_should_inline(IrExecutable *exec, Scope *scope) { 208 if (exec->is_inline) 209 return true; 210 211 while (scope != nullptr) { 212 if (scope->id == ScopeIdCompTime) 213 return true; 214 if (scope->id == ScopeIdFnDef) 215 break; 216 scope = scope->parent; 217 } 218 return false; 219 } 220 221 static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) { 222 assert(basic_block); 223 assert(instruction); 224 basic_block->instruction_list.append(instruction); 225 } 226 227 static size_t exec_next_debug_id(IrExecutable *exec) { 228 size_t result = exec->next_debug_id; 229 exec->next_debug_id += 1; 230 return result; 231 } 232 233 static size_t exec_next_mem_slot(IrExecutable *exec) { 234 size_t result = exec->mem_slot_count; 235 exec->mem_slot_count += 1; 236 return result; 237 } 238 239 static ZigFn *exec_fn_entry(IrExecutable *exec) { 240 return exec->fn_entry; 241 } 242 243 static Buf *exec_c_import_buf(IrExecutable *exec) { 244 return exec->c_import_buf; 245 } 246 247 static bool value_is_comptime(ConstExprValue *const_val) { 248 return const_val->special != ConstValSpecialRuntime; 249 } 250 251 static bool instr_is_comptime(IrInstruction *instruction) { 252 return value_is_comptime(&instruction->value); 253 } 254 255 static bool instr_is_unreachable(IrInstruction *instruction) { 256 return instruction->value.type && instruction->value.type->id == ZigTypeIdUnreachable; 257 } 258 259 static void ir_link_new_instruction(IrInstruction *new_instruction, IrInstruction *old_instruction) { 260 new_instruction->other = old_instruction; 261 old_instruction->other = new_instruction; 262 } 263 264 static void ir_link_new_bb(IrBasicBlock *new_bb, IrBasicBlock *old_bb) { 265 new_bb->other = old_bb; 266 old_bb->other = new_bb; 267 } 268 269 static void ir_ref_bb(IrBasicBlock *bb) { 270 bb->ref_count += 1; 271 } 272 273 static void ir_ref_instruction(IrInstruction *instruction, IrBasicBlock *cur_bb) { 274 assert(instruction->id != IrInstructionIdInvalid); 275 instruction->ref_count += 1; 276 if (instruction->owner_bb != cur_bb && !instr_is_comptime(instruction)) 277 ir_ref_bb(instruction->owner_bb); 278 } 279 280 static void ir_ref_var(ZigVar *var) { 281 var->ref_count += 1; 282 } 283 284 static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const char *name_hint) { 285 IrBasicBlock *result = allocate<IrBasicBlock>(1); 286 result->scope = scope; 287 result->name_hint = name_hint; 288 result->debug_id = exec_next_debug_id(irb->exec); 289 return result; 290 } 291 292 static IrBasicBlock *ir_build_bb_from(IrBuilder *irb, IrBasicBlock *other_bb) { 293 IrBasicBlock *new_bb = ir_create_basic_block(irb, other_bb->scope, other_bb->name_hint); 294 ir_link_new_bb(new_bb, other_bb); 295 return new_bb; 296 } 297 298 static constexpr IrInstructionId ir_instruction_id(IrInstructionCondBr *) { 299 return IrInstructionIdCondBr; 300 } 301 302 static constexpr IrInstructionId ir_instruction_id(IrInstructionBr *) { 303 return IrInstructionIdBr; 304 } 305 306 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchBr *) { 307 return IrInstructionIdSwitchBr; 308 } 309 310 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchVar *) { 311 return IrInstructionIdSwitchVar; 312 } 313 314 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchTarget *) { 315 return IrInstructionIdSwitchTarget; 316 } 317 318 static constexpr IrInstructionId ir_instruction_id(IrInstructionPhi *) { 319 return IrInstructionIdPhi; 320 } 321 322 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnOp *) { 323 return IrInstructionIdUnOp; 324 } 325 326 static constexpr IrInstructionId ir_instruction_id(IrInstructionBinOp *) { 327 return IrInstructionIdBinOp; 328 } 329 330 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVar *) { 331 return IrInstructionIdDeclVar; 332 } 333 334 static constexpr IrInstructionId ir_instruction_id(IrInstructionExport *) { 335 return IrInstructionIdExport; 336 } 337 338 static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) { 339 return IrInstructionIdLoadPtr; 340 } 341 342 static constexpr IrInstructionId ir_instruction_id(IrInstructionStorePtr *) { 343 return IrInstructionIdStorePtr; 344 } 345 346 static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldPtr *) { 347 return IrInstructionIdFieldPtr; 348 } 349 350 static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *) { 351 return IrInstructionIdStructFieldPtr; 352 } 353 354 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionFieldPtr *) { 355 return IrInstructionIdUnionFieldPtr; 356 } 357 358 static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) { 359 return IrInstructionIdElemPtr; 360 } 361 362 static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) { 363 return IrInstructionIdVarPtr; 364 } 365 366 static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) { 367 return IrInstructionIdCall; 368 } 369 370 static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) { 371 return IrInstructionIdConst; 372 } 373 374 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturn *) { 375 return IrInstructionIdReturn; 376 } 377 378 static constexpr IrInstructionId ir_instruction_id(IrInstructionCast *) { 379 return IrInstructionIdCast; 380 } 381 382 static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitList *) { 383 return IrInstructionIdContainerInitList; 384 } 385 386 static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitFields *) { 387 return IrInstructionIdContainerInitFields; 388 } 389 390 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnreachable *) { 391 return IrInstructionIdUnreachable; 392 } 393 394 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) { 395 return IrInstructionIdTypeOf; 396 } 397 398 static constexpr IrInstructionId ir_instruction_id(IrInstructionToPtrType *) { 399 return IrInstructionIdToPtrType; 400 } 401 402 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *) { 403 return IrInstructionIdPtrTypeChild; 404 } 405 406 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) { 407 return IrInstructionIdSetCold; 408 } 409 410 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetRuntimeSafety *) { 411 return IrInstructionIdSetRuntimeSafety; 412 } 413 414 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFloatMode *) { 415 return IrInstructionIdSetFloatMode; 416 } 417 418 static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) { 419 return IrInstructionIdArrayType; 420 } 421 422 static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseType *) { 423 return IrInstructionIdPromiseType; 424 } 425 426 static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { 427 return IrInstructionIdSliceType; 428 } 429 430 static constexpr IrInstructionId ir_instruction_id(IrInstructionAsm *) { 431 return IrInstructionIdAsm; 432 } 433 434 static constexpr IrInstructionId ir_instruction_id(IrInstructionSizeOf *) { 435 return IrInstructionIdSizeOf; 436 } 437 438 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestNonNull *) { 439 return IrInstructionIdTestNonNull; 440 } 441 442 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapOptional *) { 443 return IrInstructionIdUnwrapOptional; 444 } 445 446 static constexpr IrInstructionId ir_instruction_id(IrInstructionClz *) { 447 return IrInstructionIdClz; 448 } 449 450 static constexpr IrInstructionId ir_instruction_id(IrInstructionCtz *) { 451 return IrInstructionIdCtz; 452 } 453 454 static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) { 455 return IrInstructionIdPopCount; 456 } 457 458 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) { 459 return IrInstructionIdUnionTag; 460 } 461 462 static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) { 463 return IrInstructionIdImport; 464 } 465 466 static constexpr IrInstructionId ir_instruction_id(IrInstructionCImport *) { 467 return IrInstructionIdCImport; 468 } 469 470 static constexpr IrInstructionId ir_instruction_id(IrInstructionCInclude *) { 471 return IrInstructionIdCInclude; 472 } 473 474 static constexpr IrInstructionId ir_instruction_id(IrInstructionCDefine *) { 475 return IrInstructionIdCDefine; 476 } 477 478 static constexpr IrInstructionId ir_instruction_id(IrInstructionCUndef *) { 479 return IrInstructionIdCUndef; 480 } 481 482 static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayLen *) { 483 return IrInstructionIdArrayLen; 484 } 485 486 static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) { 487 return IrInstructionIdRef; 488 } 489 490 static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) { 491 return IrInstructionIdStructInit; 492 } 493 494 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInit *) { 495 return IrInstructionIdUnionInit; 496 } 497 498 static constexpr IrInstructionId ir_instruction_id(IrInstructionMinValue *) { 499 return IrInstructionIdMinValue; 500 } 501 502 static constexpr IrInstructionId ir_instruction_id(IrInstructionMaxValue *) { 503 return IrInstructionIdMaxValue; 504 } 505 506 static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { 507 return IrInstructionIdCompileErr; 508 } 509 510 static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileLog *) { 511 return IrInstructionIdCompileLog; 512 } 513 514 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrName *) { 515 return IrInstructionIdErrName; 516 } 517 518 static constexpr IrInstructionId ir_instruction_id(IrInstructionEmbedFile *) { 519 return IrInstructionIdEmbedFile; 520 } 521 522 static constexpr IrInstructionId ir_instruction_id(IrInstructionCmpxchg *) { 523 return IrInstructionIdCmpxchg; 524 } 525 526 static constexpr IrInstructionId ir_instruction_id(IrInstructionFence *) { 527 return IrInstructionIdFence; 528 } 529 530 static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) { 531 return IrInstructionIdTruncate; 532 } 533 534 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntCast *) { 535 return IrInstructionIdIntCast; 536 } 537 538 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) { 539 return IrInstructionIdFloatCast; 540 } 541 542 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrSetCast *) { 543 return IrInstructionIdErrSetCast; 544 } 545 546 static constexpr IrInstructionId ir_instruction_id(IrInstructionToBytes *) { 547 return IrInstructionIdToBytes; 548 } 549 550 static constexpr IrInstructionId ir_instruction_id(IrInstructionFromBytes *) { 551 return IrInstructionIdFromBytes; 552 } 553 554 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) { 555 return IrInstructionIdIntToFloat; 556 } 557 558 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) { 559 return IrInstructionIdFloatToInt; 560 } 561 562 static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) { 563 return IrInstructionIdBoolToInt; 564 } 565 566 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { 567 return IrInstructionIdIntType; 568 } 569 570 static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { 571 return IrInstructionIdBoolNot; 572 } 573 574 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemset *) { 575 return IrInstructionIdMemset; 576 } 577 578 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) { 579 return IrInstructionIdMemcpy; 580 } 581 582 static constexpr IrInstructionId ir_instruction_id(IrInstructionSlice *) { 583 return IrInstructionIdSlice; 584 } 585 586 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) { 587 return IrInstructionIdMemberCount; 588 } 589 590 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberType *) { 591 return IrInstructionIdMemberType; 592 } 593 594 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberName *) { 595 return IrInstructionIdMemberName; 596 } 597 598 static constexpr IrInstructionId ir_instruction_id(IrInstructionBreakpoint *) { 599 return IrInstructionIdBreakpoint; 600 } 601 602 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnAddress *) { 603 return IrInstructionIdReturnAddress; 604 } 605 606 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *) { 607 return IrInstructionIdFrameAddress; 608 } 609 610 static constexpr IrInstructionId ir_instruction_id(IrInstructionHandle *) { 611 return IrInstructionIdHandle; 612 } 613 614 static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignOf *) { 615 return IrInstructionIdAlignOf; 616 } 617 618 static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { 619 return IrInstructionIdOverflowOp; 620 } 621 622 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErr *) { 623 return IrInstructionIdTestErr; 624 } 625 626 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrCode *) { 627 return IrInstructionIdUnwrapErrCode; 628 } 629 630 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrPayload *) { 631 return IrInstructionIdUnwrapErrPayload; 632 } 633 634 static constexpr IrInstructionId ir_instruction_id(IrInstructionOptionalWrap *) { 635 return IrInstructionIdOptionalWrap; 636 } 637 638 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapPayload *) { 639 return IrInstructionIdErrWrapPayload; 640 } 641 642 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapCode *) { 643 return IrInstructionIdErrWrapCode; 644 } 645 646 static constexpr IrInstructionId ir_instruction_id(IrInstructionFnProto *) { 647 return IrInstructionIdFnProto; 648 } 649 650 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestComptime *) { 651 return IrInstructionIdTestComptime; 652 } 653 654 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCast *) { 655 return IrInstructionIdPtrCast; 656 } 657 658 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) { 659 return IrInstructionIdBitCast; 660 } 661 662 static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) { 663 return IrInstructionIdWidenOrShorten; 664 } 665 666 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrToInt *) { 667 return IrInstructionIdPtrToInt; 668 } 669 670 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToPtr *) { 671 return IrInstructionIdIntToPtr; 672 } 673 674 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToEnum *) { 675 return IrInstructionIdIntToEnum; 676 } 677 678 static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumToInt *) { 679 return IrInstructionIdEnumToInt; 680 } 681 682 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToErr *) { 683 return IrInstructionIdIntToErr; 684 } 685 686 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrToInt *) { 687 return IrInstructionIdErrToInt; 688 } 689 690 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckSwitchProngs *) { 691 return IrInstructionIdCheckSwitchProngs; 692 } 693 694 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckStatementIsVoid *) { 695 return IrInstructionIdCheckStatementIsVoid; 696 } 697 698 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeName *) { 699 return IrInstructionIdTypeName; 700 } 701 702 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) { 703 return IrInstructionIdDeclRef; 704 } 705 706 static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) { 707 return IrInstructionIdPanic; 708 } 709 710 static constexpr IrInstructionId ir_instruction_id(IrInstructionTagName *) { 711 return IrInstructionIdTagName; 712 } 713 714 static constexpr IrInstructionId ir_instruction_id(IrInstructionTagType *) { 715 return IrInstructionIdTagType; 716 } 717 718 static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) { 719 return IrInstructionIdFieldParentPtr; 720 } 721 722 static constexpr IrInstructionId ir_instruction_id(IrInstructionOffsetOf *) { 723 return IrInstructionIdOffsetOf; 724 } 725 726 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { 727 return IrInstructionIdTypeInfo; 728 } 729 730 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { 731 return IrInstructionIdTypeId; 732 } 733 734 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetEvalBranchQuota *) { 735 return IrInstructionIdSetEvalBranchQuota; 736 } 737 738 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrType *) { 739 return IrInstructionIdPtrType; 740 } 741 742 static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { 743 return IrInstructionIdAlignCast; 744 } 745 746 static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { 747 return IrInstructionIdOpaqueType; 748 } 749 750 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetAlignStack *) { 751 return IrInstructionIdSetAlignStack; 752 } 753 754 static constexpr IrInstructionId ir_instruction_id(IrInstructionArgType *) { 755 return IrInstructionIdArgType; 756 } 757 758 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorReturnTrace *) { 759 return IrInstructionIdErrorReturnTrace; 760 } 761 762 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorUnion *) { 763 return IrInstructionIdErrorUnion; 764 } 765 766 static constexpr IrInstructionId ir_instruction_id(IrInstructionCancel *) { 767 return IrInstructionIdCancel; 768 } 769 770 static constexpr IrInstructionId ir_instruction_id(IrInstructionGetImplicitAllocator *) { 771 return IrInstructionIdGetImplicitAllocator; 772 } 773 774 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroId *) { 775 return IrInstructionIdCoroId; 776 } 777 778 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAlloc *) { 779 return IrInstructionIdCoroAlloc; 780 } 781 782 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSize *) { 783 return IrInstructionIdCoroSize; 784 } 785 786 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroBegin *) { 787 return IrInstructionIdCoroBegin; 788 } 789 790 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocFail *) { 791 return IrInstructionIdCoroAllocFail; 792 } 793 794 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSuspend *) { 795 return IrInstructionIdCoroSuspend; 796 } 797 798 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroEnd *) { 799 return IrInstructionIdCoroEnd; 800 } 801 802 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroFree *) { 803 return IrInstructionIdCoroFree; 804 } 805 806 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroResume *) { 807 return IrInstructionIdCoroResume; 808 } 809 810 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSave *) { 811 return IrInstructionIdCoroSave; 812 } 813 814 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroPromise *) { 815 return IrInstructionIdCoroPromise; 816 } 817 818 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocHelper *) { 819 return IrInstructionIdCoroAllocHelper; 820 } 821 822 static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicRmw *) { 823 return IrInstructionIdAtomicRmw; 824 } 825 826 static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) { 827 return IrInstructionIdAtomicLoad; 828 } 829 830 static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseResultType *) { 831 return IrInstructionIdPromiseResultType; 832 } 833 834 static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitBookkeeping *) { 835 return IrInstructionIdAwaitBookkeeping; 836 } 837 838 static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) { 839 return IrInstructionIdSaveErrRetAddr; 840 } 841 842 static constexpr IrInstructionId ir_instruction_id(IrInstructionAddImplicitReturnType *) { 843 return IrInstructionIdAddImplicitReturnType; 844 } 845 846 static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrRetTraces *) { 847 return IrInstructionIdMergeErrRetTraces; 848 } 849 850 static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTracePtr *) { 851 return IrInstructionIdMarkErrRetTracePtr; 852 } 853 854 static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) { 855 return IrInstructionIdSqrt; 856 } 857 858 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { 859 return IrInstructionIdCheckRuntimeScope; 860 } 861 862 template<typename T> 863 static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { 864 T *special_instruction = allocate<T>(1); 865 special_instruction->base.id = ir_instruction_id(special_instruction); 866 special_instruction->base.scope = scope; 867 special_instruction->base.source_node = source_node; 868 special_instruction->base.debug_id = exec_next_debug_id(irb->exec); 869 special_instruction->base.owner_bb = irb->current_basic_block; 870 special_instruction->base.value.global_refs = allocate<ConstGlobalRefs>(1); 871 return special_instruction; 872 } 873 874 template<typename T> 875 static T *ir_build_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { 876 T *special_instruction = ir_create_instruction<T>(irb, scope, source_node); 877 ir_instruction_append(irb->current_basic_block, &special_instruction->base); 878 return special_instruction; 879 } 880 881 static IrInstruction *ir_build_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *dest_type, 882 IrInstruction *value, CastOp cast_op) 883 { 884 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, scope, source_node); 885 cast_instruction->dest_type = dest_type; 886 cast_instruction->value = value; 887 cast_instruction->cast_op = cast_op; 888 889 ir_ref_instruction(value, irb->current_basic_block); 890 891 return &cast_instruction->base; 892 } 893 894 static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *condition, 895 IrBasicBlock *then_block, IrBasicBlock *else_block, IrInstruction *is_comptime) 896 { 897 IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, scope, source_node); 898 cond_br_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 899 cond_br_instruction->base.value.special = ConstValSpecialStatic; 900 cond_br_instruction->condition = condition; 901 cond_br_instruction->then_block = then_block; 902 cond_br_instruction->else_block = else_block; 903 cond_br_instruction->is_comptime = is_comptime; 904 905 ir_ref_instruction(condition, irb->current_basic_block); 906 ir_ref_bb(then_block); 907 ir_ref_bb(else_block); 908 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 909 910 return &cond_br_instruction->base; 911 } 912 913 static IrInstruction *ir_build_cond_br_from(IrBuilder *irb, IrInstruction *old_instruction, 914 IrInstruction *condition, IrBasicBlock *then_block, IrBasicBlock *else_block, IrInstruction *is_comptime) 915 { 916 IrInstruction *new_instruction = ir_build_cond_br(irb, old_instruction->scope, old_instruction->source_node, 917 condition, then_block, else_block, is_comptime); 918 ir_link_new_instruction(new_instruction, old_instruction); 919 return new_instruction; 920 } 921 922 static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *return_value) { 923 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); 924 return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 925 return_instruction->base.value.special = ConstValSpecialStatic; 926 return_instruction->value = return_value; 927 928 ir_ref_instruction(return_value, irb->current_basic_block); 929 930 return &return_instruction->base; 931 } 932 933 static IrInstruction *ir_create_const(IrBuilder *irb, Scope *scope, AstNode *source_node, 934 ZigType *type_entry) 935 { 936 assert(type_entry); 937 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 938 const_instruction->base.value.type = type_entry; 939 const_instruction->base.value.special = ConstValSpecialStatic; 940 return &const_instruction->base; 941 } 942 943 static IrInstruction *ir_build_const_void(IrBuilder *irb, Scope *scope, AstNode *source_node) { 944 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 945 const_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 946 const_instruction->base.value.special = ConstValSpecialStatic; 947 return &const_instruction->base; 948 } 949 950 static IrInstruction *ir_build_const_undefined(IrBuilder *irb, Scope *scope, AstNode *source_node) { 951 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 952 const_instruction->base.value.special = ConstValSpecialUndef; 953 const_instruction->base.value.type = irb->codegen->builtin_types.entry_undef; 954 return &const_instruction->base; 955 } 956 957 static IrInstruction *ir_build_const_uint(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { 958 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 959 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_int; 960 const_instruction->base.value.special = ConstValSpecialStatic; 961 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); 962 return &const_instruction->base; 963 } 964 965 static IrInstruction *ir_build_const_bigint(IrBuilder *irb, Scope *scope, AstNode *source_node, BigInt *bigint) { 966 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 967 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_int; 968 const_instruction->base.value.special = ConstValSpecialStatic; 969 bigint_init_bigint(&const_instruction->base.value.data.x_bigint, bigint); 970 return &const_instruction->base; 971 } 972 973 static IrInstruction *ir_build_const_bigfloat(IrBuilder *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) { 974 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 975 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_float; 976 const_instruction->base.value.special = ConstValSpecialStatic; 977 bigfloat_init_bigfloat(&const_instruction->base.value.data.x_bigfloat, bigfloat); 978 return &const_instruction->base; 979 } 980 981 static IrInstruction *ir_build_const_null(IrBuilder *irb, Scope *scope, AstNode *source_node) { 982 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 983 const_instruction->base.value.type = irb->codegen->builtin_types.entry_null; 984 const_instruction->base.value.special = ConstValSpecialStatic; 985 return &const_instruction->base; 986 } 987 988 static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { 989 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 990 const_instruction->base.value.type = irb->codegen->builtin_types.entry_usize; 991 const_instruction->base.value.special = ConstValSpecialStatic; 992 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); 993 return &const_instruction->base; 994 } 995 996 static IrInstruction *ir_build_const_u8(IrBuilder *irb, Scope *scope, AstNode *source_node, uint8_t value) { 997 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 998 const_instruction->base.value.type = irb->codegen->builtin_types.entry_u8; 999 const_instruction->base.value.special = ConstValSpecialStatic; 1000 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); 1001 return &const_instruction->base; 1002 } 1003 1004 static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1005 ZigType *type_entry) 1006 { 1007 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1008 const_instruction->base.value.type = irb->codegen->builtin_types.entry_type; 1009 const_instruction->base.value.special = ConstValSpecialStatic; 1010 const_instruction->base.value.data.x_type = type_entry; 1011 return &const_instruction->base; 1012 } 1013 1014 static IrInstruction *ir_build_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1015 ZigType *type_entry) 1016 { 1017 IrInstruction *instruction = ir_create_const_type(irb, scope, source_node, type_entry); 1018 ir_instruction_append(irb->current_basic_block, instruction); 1019 return instruction; 1020 } 1021 1022 static IrInstruction *ir_create_const_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigFn *fn_entry) { 1023 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1024 const_instruction->base.value.type = fn_entry->type_entry; 1025 const_instruction->base.value.special = ConstValSpecialStatic; 1026 const_instruction->base.value.data.x_ptr.data.fn.fn_entry = fn_entry; 1027 const_instruction->base.value.data.x_ptr.mut = ConstPtrMutComptimeConst; 1028 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialFunction; 1029 return &const_instruction->base; 1030 } 1031 1032 static IrInstruction *ir_build_const_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigFn *fn_entry) { 1033 IrInstruction *instruction = ir_create_const_fn(irb, scope, source_node, fn_entry); 1034 ir_instruction_append(irb->current_basic_block, instruction); 1035 return instruction; 1036 } 1037 1038 static IrInstruction *ir_build_const_import(IrBuilder *irb, Scope *scope, AstNode *source_node, ImportTableEntry *import) { 1039 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1040 const_instruction->base.value.type = irb->codegen->builtin_types.entry_namespace; 1041 const_instruction->base.value.special = ConstValSpecialStatic; 1042 const_instruction->base.value.data.x_import = import; 1043 return &const_instruction->base; 1044 } 1045 1046 static IrInstruction *ir_build_const_scope(IrBuilder *irb, Scope *parent_scope, AstNode *source_node, 1047 Scope *target_scope) 1048 { 1049 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, parent_scope, source_node); 1050 const_instruction->base.value.type = irb->codegen->builtin_types.entry_block; 1051 const_instruction->base.value.special = ConstValSpecialStatic; 1052 const_instruction->base.value.data.x_block = target_scope; 1053 return &const_instruction->base; 1054 } 1055 1056 static IrInstruction *ir_build_const_bool(IrBuilder *irb, Scope *scope, AstNode *source_node, bool value) { 1057 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1058 const_instruction->base.value.type = irb->codegen->builtin_types.entry_bool; 1059 const_instruction->base.value.special = ConstValSpecialStatic; 1060 const_instruction->base.value.data.x_bool = value; 1061 return &const_instruction->base; 1062 } 1063 1064 static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, 1065 ZigFn *fn_entry, IrInstruction *first_arg) 1066 { 1067 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1068 const_instruction->base.value.type = get_bound_fn_type(irb->codegen, fn_entry); 1069 const_instruction->base.value.special = ConstValSpecialStatic; 1070 const_instruction->base.value.data.x_bound_fn.fn = fn_entry; 1071 const_instruction->base.value.data.x_bound_fn.first_arg = first_arg; 1072 return &const_instruction->base; 1073 } 1074 1075 static IrInstruction *ir_create_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1076 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1077 init_const_str_lit(irb->codegen, &const_instruction->base.value, str); 1078 1079 return &const_instruction->base; 1080 } 1081 static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1082 IrInstruction *instruction = ir_create_const_str_lit(irb, scope, source_node, str); 1083 ir_instruction_append(irb->current_basic_block, instruction); 1084 return instruction; 1085 } 1086 1087 static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1088 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1089 init_const_c_str_lit(irb->codegen, &const_instruction->base.value, str); 1090 return &const_instruction->base; 1091 } 1092 1093 static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, 1094 IrInstruction *op1, IrInstruction *op2, bool safety_check_on) 1095 { 1096 IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irb, scope, source_node); 1097 bin_op_instruction->op_id = op_id; 1098 bin_op_instruction->op1 = op1; 1099 bin_op_instruction->op2 = op2; 1100 bin_op_instruction->safety_check_on = safety_check_on; 1101 1102 ir_ref_instruction(op1, irb->current_basic_block); 1103 ir_ref_instruction(op2, irb->current_basic_block); 1104 1105 return &bin_op_instruction->base; 1106 } 1107 1108 static IrInstruction *ir_build_bin_op_from(IrBuilder *irb, IrInstruction *old_instruction, IrBinOp op_id, 1109 IrInstruction *op1, IrInstruction *op2, bool safety_check_on) 1110 { 1111 IrInstruction *new_instruction = ir_build_bin_op(irb, old_instruction->scope, 1112 old_instruction->source_node, op_id, op1, op2, safety_check_on); 1113 ir_link_new_instruction(new_instruction, old_instruction); 1114 return new_instruction; 1115 } 1116 1117 static IrInstruction *ir_build_var_ptr_x(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, 1118 ScopeFnDef *crossed_fndef_scope) 1119 { 1120 IrInstructionVarPtr *instruction = ir_build_instruction<IrInstructionVarPtr>(irb, scope, source_node); 1121 instruction->var = var; 1122 instruction->crossed_fndef_scope = crossed_fndef_scope; 1123 1124 ir_ref_var(var); 1125 1126 return &instruction->base; 1127 } 1128 1129 static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var) { 1130 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); 1131 } 1132 1133 static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr, 1134 IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len) 1135 { 1136 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); 1137 instruction->array_ptr = array_ptr; 1138 instruction->elem_index = elem_index; 1139 instruction->safety_check_on = safety_check_on; 1140 instruction->ptr_len = ptr_len; 1141 1142 ir_ref_instruction(array_ptr, irb->current_basic_block); 1143 ir_ref_instruction(elem_index, irb->current_basic_block); 1144 1145 return &instruction->base; 1146 } 1147 1148 static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node, 1149 IrInstruction *container_ptr, IrInstruction *field_name_expr) 1150 { 1151 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); 1152 instruction->container_ptr = container_ptr; 1153 instruction->field_name_buffer = nullptr; 1154 instruction->field_name_expr = field_name_expr; 1155 1156 ir_ref_instruction(container_ptr, irb->current_basic_block); 1157 ir_ref_instruction(field_name_expr, irb->current_basic_block); 1158 1159 return &instruction->base; 1160 } 1161 1162 static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1163 IrInstruction *container_ptr, Buf *field_name) 1164 { 1165 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); 1166 instruction->container_ptr = container_ptr; 1167 instruction->field_name_buffer = field_name; 1168 instruction->field_name_expr = nullptr; 1169 1170 ir_ref_instruction(container_ptr, irb->current_basic_block); 1171 1172 return &instruction->base; 1173 } 1174 1175 static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1176 IrInstruction *struct_ptr, TypeStructField *field) 1177 { 1178 IrInstructionStructFieldPtr *instruction = ir_build_instruction<IrInstructionStructFieldPtr>(irb, scope, source_node); 1179 instruction->struct_ptr = struct_ptr; 1180 instruction->field = field; 1181 1182 ir_ref_instruction(struct_ptr, irb->current_basic_block); 1183 1184 return &instruction->base; 1185 } 1186 1187 static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1188 IrInstruction *union_ptr, TypeUnionField *field) 1189 { 1190 IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node); 1191 instruction->union_ptr = union_ptr; 1192 instruction->field = field; 1193 1194 ir_ref_instruction(union_ptr, irb->current_basic_block); 1195 1196 return &instruction->base; 1197 } 1198 1199 static IrInstruction *ir_build_union_field_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, 1200 IrInstruction *union_ptr, TypeUnionField *type_union_field) 1201 { 1202 IrInstruction *new_instruction = ir_build_union_field_ptr(irb, old_instruction->scope, 1203 old_instruction->source_node, union_ptr, type_union_field); 1204 ir_link_new_instruction(new_instruction, old_instruction); 1205 return new_instruction; 1206 } 1207 1208 static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node, 1209 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, 1210 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, 1211 IrInstruction *new_stack) 1212 { 1213 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node); 1214 call_instruction->fn_entry = fn_entry; 1215 call_instruction->fn_ref = fn_ref; 1216 call_instruction->is_comptime = is_comptime; 1217 call_instruction->fn_inline = fn_inline; 1218 call_instruction->args = args; 1219 call_instruction->arg_count = arg_count; 1220 call_instruction->is_async = is_async; 1221 call_instruction->async_allocator = async_allocator; 1222 call_instruction->new_stack = new_stack; 1223 1224 if (fn_ref) 1225 ir_ref_instruction(fn_ref, irb->current_basic_block); 1226 for (size_t i = 0; i < arg_count; i += 1) 1227 ir_ref_instruction(args[i], irb->current_basic_block); 1228 if (async_allocator) 1229 ir_ref_instruction(async_allocator, irb->current_basic_block); 1230 if (new_stack != nullptr) 1231 ir_ref_instruction(new_stack, irb->current_basic_block); 1232 1233 return &call_instruction->base; 1234 } 1235 1236 static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction, 1237 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, 1238 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, 1239 IrInstruction *new_stack) 1240 { 1241 IrInstruction *new_instruction = ir_build_call(irb, old_instruction->scope, 1242 old_instruction->source_node, fn_entry, fn_ref, arg_count, args, is_comptime, fn_inline, is_async, async_allocator, new_stack); 1243 ir_link_new_instruction(new_instruction, old_instruction); 1244 return new_instruction; 1245 } 1246 1247 static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, 1248 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values) 1249 { 1250 assert(incoming_count != 0); 1251 assert(incoming_count != SIZE_MAX); 1252 1253 IrInstructionPhi *phi_instruction = ir_build_instruction<IrInstructionPhi>(irb, scope, source_node); 1254 phi_instruction->incoming_count = incoming_count; 1255 phi_instruction->incoming_blocks = incoming_blocks; 1256 phi_instruction->incoming_values = incoming_values; 1257 1258 for (size_t i = 0; i < incoming_count; i += 1) { 1259 ir_ref_bb(incoming_blocks[i]); 1260 ir_ref_instruction(incoming_values[i], irb->current_basic_block); 1261 } 1262 1263 return &phi_instruction->base; 1264 } 1265 1266 static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instruction, 1267 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values) 1268 { 1269 IrInstruction *new_instruction = ir_build_phi(irb, old_instruction->scope, old_instruction->source_node, 1270 incoming_count, incoming_blocks, incoming_values); 1271 ir_link_new_instruction(new_instruction, old_instruction); 1272 return new_instruction; 1273 } 1274 1275 static IrInstruction *ir_create_br(IrBuilder *irb, Scope *scope, AstNode *source_node, 1276 IrBasicBlock *dest_block, IrInstruction *is_comptime) 1277 { 1278 IrInstructionBr *br_instruction = ir_create_instruction<IrInstructionBr>(irb, scope, source_node); 1279 br_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1280 br_instruction->base.value.special = ConstValSpecialStatic; 1281 br_instruction->dest_block = dest_block; 1282 br_instruction->is_comptime = is_comptime; 1283 1284 ir_ref_bb(dest_block); 1285 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 1286 1287 return &br_instruction->base; 1288 } 1289 1290 static IrInstruction *ir_build_br(IrBuilder *irb, Scope *scope, AstNode *source_node, 1291 IrBasicBlock *dest_block, IrInstruction *is_comptime) 1292 { 1293 IrInstruction *instruction = ir_create_br(irb, scope, source_node, dest_block, is_comptime); 1294 ir_instruction_append(irb->current_basic_block, instruction); 1295 return instruction; 1296 } 1297 1298 static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instruction, IrBasicBlock *dest_block) { 1299 IrInstruction *new_instruction = ir_build_br(irb, old_instruction->scope, old_instruction->source_node, dest_block, nullptr); 1300 ir_link_new_instruction(new_instruction, old_instruction); 1301 return new_instruction; 1302 } 1303 1304 static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1305 IrInstruction *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, 1306 IrInstruction *align_value, uint32_t bit_offset_start, uint32_t bit_offset_end) 1307 { 1308 IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node); 1309 ptr_type_of_instruction->align_value = align_value; 1310 ptr_type_of_instruction->child_type = child_type; 1311 ptr_type_of_instruction->is_const = is_const; 1312 ptr_type_of_instruction->is_volatile = is_volatile; 1313 ptr_type_of_instruction->ptr_len = ptr_len; 1314 ptr_type_of_instruction->bit_offset_start = bit_offset_start; 1315 ptr_type_of_instruction->bit_offset_end = bit_offset_end; 1316 1317 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 1318 ir_ref_instruction(child_type, irb->current_basic_block); 1319 1320 return &ptr_type_of_instruction->base; 1321 } 1322 1323 static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, IrInstruction *value) { 1324 IrInstructionUnOp *br_instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); 1325 br_instruction->op_id = op_id; 1326 br_instruction->value = value; 1327 1328 ir_ref_instruction(value, irb->current_basic_block); 1329 1330 return &br_instruction->base; 1331 } 1332 1333 static IrInstruction *ir_build_un_op_from(IrBuilder *irb, IrInstruction *old_instruction, 1334 IrUnOp op_id, IrInstruction *value) 1335 { 1336 IrInstruction *new_instruction = ir_build_un_op(irb, old_instruction->scope, 1337 old_instruction->source_node, op_id, value); 1338 ir_link_new_instruction(new_instruction, old_instruction); 1339 return new_instruction; 1340 } 1341 1342 static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node, 1343 IrInstruction *container_type, size_t item_count, IrInstruction **items) 1344 { 1345 IrInstructionContainerInitList *container_init_list_instruction = 1346 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); 1347 container_init_list_instruction->container_type = container_type; 1348 container_init_list_instruction->item_count = item_count; 1349 container_init_list_instruction->items = items; 1350 1351 ir_ref_instruction(container_type, irb->current_basic_block); 1352 for (size_t i = 0; i < item_count; i += 1) { 1353 ir_ref_instruction(items[i], irb->current_basic_block); 1354 } 1355 1356 return &container_init_list_instruction->base; 1357 } 1358 1359 static IrInstruction *ir_build_container_init_list_from(IrBuilder *irb, IrInstruction *old_instruction, 1360 IrInstruction *container_type, size_t item_count, IrInstruction **items) 1361 { 1362 IrInstruction *new_instruction = ir_build_container_init_list(irb, old_instruction->scope, 1363 old_instruction->source_node, container_type, item_count, items); 1364 ir_link_new_instruction(new_instruction, old_instruction); 1365 return new_instruction; 1366 } 1367 1368 static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node, 1369 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields) 1370 { 1371 IrInstructionContainerInitFields *container_init_fields_instruction = 1372 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); 1373 container_init_fields_instruction->container_type = container_type; 1374 container_init_fields_instruction->field_count = field_count; 1375 container_init_fields_instruction->fields = fields; 1376 1377 ir_ref_instruction(container_type, irb->current_basic_block); 1378 for (size_t i = 0; i < field_count; i += 1) { 1379 ir_ref_instruction(fields[i].value, irb->current_basic_block); 1380 } 1381 1382 return &container_init_fields_instruction->base; 1383 } 1384 1385 static IrInstruction *ir_build_struct_init(IrBuilder *irb, Scope *scope, AstNode *source_node, 1386 ZigType *struct_type, size_t field_count, IrInstructionStructInitField *fields) 1387 { 1388 IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, scope, source_node); 1389 struct_init_instruction->struct_type = struct_type; 1390 struct_init_instruction->field_count = field_count; 1391 struct_init_instruction->fields = fields; 1392 1393 for (size_t i = 0; i < field_count; i += 1) 1394 ir_ref_instruction(fields[i].value, irb->current_basic_block); 1395 1396 return &struct_init_instruction->base; 1397 } 1398 1399 static IrInstruction *ir_build_struct_init_from(IrBuilder *irb, IrInstruction *old_instruction, 1400 ZigType *struct_type, size_t field_count, IrInstructionStructInitField *fields) 1401 { 1402 IrInstruction *new_instruction = ir_build_struct_init(irb, old_instruction->scope, 1403 old_instruction->source_node, struct_type, field_count, fields); 1404 ir_link_new_instruction(new_instruction, old_instruction); 1405 return new_instruction; 1406 } 1407 1408 static IrInstruction *ir_build_union_init(IrBuilder *irb, Scope *scope, AstNode *source_node, 1409 ZigType *union_type, TypeUnionField *field, IrInstruction *init_value) 1410 { 1411 IrInstructionUnionInit *union_init_instruction = ir_build_instruction<IrInstructionUnionInit>(irb, scope, source_node); 1412 union_init_instruction->union_type = union_type; 1413 union_init_instruction->field = field; 1414 union_init_instruction->init_value = init_value; 1415 1416 ir_ref_instruction(init_value, irb->current_basic_block); 1417 1418 return &union_init_instruction->base; 1419 } 1420 1421 static IrInstruction *ir_build_union_init_from(IrBuilder *irb, IrInstruction *old_instruction, 1422 ZigType *union_type, TypeUnionField *field, IrInstruction *init_value) 1423 { 1424 IrInstruction *new_instruction = ir_build_union_init(irb, old_instruction->scope, 1425 old_instruction->source_node, union_type, field, init_value); 1426 ir_link_new_instruction(new_instruction, old_instruction); 1427 return new_instruction; 1428 } 1429 1430 static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1431 IrInstructionUnreachable *unreachable_instruction = 1432 ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); 1433 unreachable_instruction->base.value.special = ConstValSpecialStatic; 1434 unreachable_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1435 return &unreachable_instruction->base; 1436 } 1437 1438 static IrInstruction *ir_build_unreachable_from(IrBuilder *irb, IrInstruction *old_instruction) { 1439 IrInstruction *new_instruction = ir_build_unreachable(irb, old_instruction->scope, old_instruction->source_node); 1440 ir_link_new_instruction(new_instruction, old_instruction); 1441 return new_instruction; 1442 } 1443 1444 static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1445 IrInstruction *ptr, IrInstruction *value) 1446 { 1447 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node); 1448 instruction->base.value.special = ConstValSpecialStatic; 1449 instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1450 instruction->ptr = ptr; 1451 instruction->value = value; 1452 1453 ir_ref_instruction(ptr, irb->current_basic_block); 1454 ir_ref_instruction(value, irb->current_basic_block); 1455 1456 return &instruction->base; 1457 } 1458 1459 static IrInstruction *ir_build_store_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, 1460 IrInstruction *ptr, IrInstruction *value) 1461 { 1462 IrInstruction *new_instruction = ir_build_store_ptr(irb, old_instruction->scope, 1463 old_instruction->source_node, ptr, value); 1464 ir_link_new_instruction(new_instruction, old_instruction); 1465 return new_instruction; 1466 } 1467 1468 static IrInstruction *ir_build_var_decl(IrBuilder *irb, Scope *scope, AstNode *source_node, 1469 ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value) 1470 { 1471 IrInstructionDeclVar *decl_var_instruction = ir_build_instruction<IrInstructionDeclVar>(irb, scope, source_node); 1472 decl_var_instruction->base.value.special = ConstValSpecialStatic; 1473 decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1474 decl_var_instruction->var = var; 1475 decl_var_instruction->var_type = var_type; 1476 decl_var_instruction->align_value = align_value; 1477 decl_var_instruction->init_value = init_value; 1478 1479 if (var_type) ir_ref_instruction(var_type, irb->current_basic_block); 1480 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 1481 ir_ref_instruction(init_value, irb->current_basic_block); 1482 1483 return &decl_var_instruction->base; 1484 } 1485 1486 static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_instruction, 1487 ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value) 1488 { 1489 IrInstruction *new_instruction = ir_build_var_decl(irb, old_instruction->scope, 1490 old_instruction->source_node, var, var_type, align_value, init_value); 1491 ir_link_new_instruction(new_instruction, old_instruction); 1492 return new_instruction; 1493 } 1494 1495 static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node, 1496 IrInstruction *name, IrInstruction *target, IrInstruction *linkage) 1497 { 1498 IrInstructionExport *export_instruction = ir_build_instruction<IrInstructionExport>( 1499 irb, scope, source_node); 1500 export_instruction->base.value.special = ConstValSpecialStatic; 1501 export_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1502 export_instruction->name = name; 1503 export_instruction->target = target; 1504 export_instruction->linkage = linkage; 1505 1506 ir_ref_instruction(name, irb->current_basic_block); 1507 ir_ref_instruction(target, irb->current_basic_block); 1508 if (linkage) ir_ref_instruction(linkage, irb->current_basic_block); 1509 1510 return &export_instruction->base; 1511 } 1512 1513 static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { 1514 IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node); 1515 instruction->ptr = ptr; 1516 1517 ir_ref_instruction(ptr, irb->current_basic_block); 1518 1519 return &instruction->base; 1520 } 1521 1522 static IrInstruction *ir_build_load_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *ptr) { 1523 IrInstruction *new_instruction = ir_build_load_ptr(irb, old_instruction->scope, 1524 old_instruction->source_node, ptr); 1525 ir_link_new_instruction(new_instruction, old_instruction); 1526 return new_instruction; 1527 } 1528 1529 static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1530 IrInstructionTypeOf *instruction = ir_build_instruction<IrInstructionTypeOf>(irb, scope, source_node); 1531 instruction->value = value; 1532 1533 ir_ref_instruction(value, irb->current_basic_block); 1534 1535 return &instruction->base; 1536 } 1537 1538 static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1539 IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, scope, source_node); 1540 instruction->value = value; 1541 1542 ir_ref_instruction(value, irb->current_basic_block); 1543 1544 return &instruction->base; 1545 } 1546 1547 static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstNode *source_node, 1548 IrInstruction *value) 1549 { 1550 IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>( 1551 irb, scope, source_node); 1552 instruction->value = value; 1553 1554 ir_ref_instruction(value, irb->current_basic_block); 1555 1556 return &instruction->base; 1557 } 1558 1559 static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) { 1560 IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); 1561 instruction->is_cold = is_cold; 1562 1563 ir_ref_instruction(is_cold, irb->current_basic_block); 1564 1565 return &instruction->base; 1566 } 1567 1568 static IrInstruction *ir_build_set_runtime_safety(IrBuilder *irb, Scope *scope, AstNode *source_node, 1569 IrInstruction *safety_on) 1570 { 1571 IrInstructionSetRuntimeSafety *instruction = ir_build_instruction<IrInstructionSetRuntimeSafety>(irb, scope, source_node); 1572 instruction->safety_on = safety_on; 1573 1574 ir_ref_instruction(safety_on, irb->current_basic_block); 1575 1576 return &instruction->base; 1577 } 1578 1579 static IrInstruction *ir_build_set_float_mode(IrBuilder *irb, Scope *scope, AstNode *source_node, 1580 IrInstruction *scope_value, IrInstruction *mode_value) 1581 { 1582 IrInstructionSetFloatMode *instruction = ir_build_instruction<IrInstructionSetFloatMode>(irb, scope, source_node); 1583 instruction->scope_value = scope_value; 1584 instruction->mode_value = mode_value; 1585 1586 ir_ref_instruction(scope_value, irb->current_basic_block); 1587 ir_ref_instruction(mode_value, irb->current_basic_block); 1588 1589 return &instruction->base; 1590 } 1591 1592 static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *size, 1593 IrInstruction *child_type) 1594 { 1595 IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, scope, source_node); 1596 instruction->size = size; 1597 instruction->child_type = child_type; 1598 1599 ir_ref_instruction(size, irb->current_basic_block); 1600 ir_ref_instruction(child_type, irb->current_basic_block); 1601 1602 return &instruction->base; 1603 } 1604 1605 static IrInstruction *ir_build_promise_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1606 IrInstruction *payload_type) 1607 { 1608 IrInstructionPromiseType *instruction = ir_build_instruction<IrInstructionPromiseType>(irb, scope, source_node); 1609 instruction->payload_type = payload_type; 1610 1611 if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); 1612 1613 return &instruction->base; 1614 } 1615 1616 static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1617 IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value) 1618 { 1619 IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, scope, source_node); 1620 instruction->is_const = is_const; 1621 instruction->is_volatile = is_volatile; 1622 instruction->child_type = child_type; 1623 instruction->align_value = align_value; 1624 1625 ir_ref_instruction(child_type, irb->current_basic_block); 1626 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 1627 1628 return &instruction->base; 1629 } 1630 1631 static IrInstruction *ir_build_asm(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction **input_list, 1632 IrInstruction **output_types, ZigVar **output_vars, size_t return_count, bool has_side_effects) 1633 { 1634 IrInstructionAsm *instruction = ir_build_instruction<IrInstructionAsm>(irb, scope, source_node); 1635 instruction->input_list = input_list; 1636 instruction->output_types = output_types; 1637 instruction->output_vars = output_vars; 1638 instruction->return_count = return_count; 1639 instruction->has_side_effects = has_side_effects; 1640 1641 assert(source_node->type == NodeTypeAsmExpr); 1642 for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) { 1643 IrInstruction *output_type = output_types[i]; 1644 if (output_type) ir_ref_instruction(output_type, irb->current_basic_block); 1645 } 1646 1647 for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) { 1648 IrInstruction *input_value = input_list[i]; 1649 ir_ref_instruction(input_value, irb->current_basic_block); 1650 } 1651 1652 return &instruction->base; 1653 } 1654 1655 static IrInstruction *ir_build_asm_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction **input_list, 1656 IrInstruction **output_types, ZigVar **output_vars, size_t return_count, bool has_side_effects) 1657 { 1658 IrInstruction *new_instruction = ir_build_asm(irb, old_instruction->scope, 1659 old_instruction->source_node, input_list, output_types, output_vars, return_count, has_side_effects); 1660 ir_link_new_instruction(new_instruction, old_instruction); 1661 return new_instruction; 1662 } 1663 1664 static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { 1665 IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, scope, source_node); 1666 instruction->type_value = type_value; 1667 1668 ir_ref_instruction(type_value, irb->current_basic_block); 1669 1670 return &instruction->base; 1671 } 1672 1673 static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1674 IrInstructionTestNonNull *instruction = ir_build_instruction<IrInstructionTestNonNull>(irb, scope, source_node); 1675 instruction->value = value; 1676 1677 ir_ref_instruction(value, irb->current_basic_block); 1678 1679 return &instruction->base; 1680 } 1681 1682 static IrInstruction *ir_build_test_nonnull_from(IrBuilder *irb, IrInstruction *old_instruction, 1683 IrInstruction *value) 1684 { 1685 IrInstruction *new_instruction = ir_build_test_nonnull(irb, old_instruction->scope, 1686 old_instruction->source_node, value); 1687 ir_link_new_instruction(new_instruction, old_instruction); 1688 return new_instruction; 1689 } 1690 1691 static IrInstruction *ir_build_unwrap_maybe(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value, 1692 bool safety_check_on) 1693 { 1694 IrInstructionUnwrapOptional *instruction = ir_build_instruction<IrInstructionUnwrapOptional>(irb, scope, source_node); 1695 instruction->value = value; 1696 instruction->safety_check_on = safety_check_on; 1697 1698 ir_ref_instruction(value, irb->current_basic_block); 1699 1700 return &instruction->base; 1701 } 1702 1703 static IrInstruction *ir_build_unwrap_maybe_from(IrBuilder *irb, IrInstruction *old_instruction, 1704 IrInstruction *value, bool safety_check_on) 1705 { 1706 IrInstruction *new_instruction = ir_build_unwrap_maybe(irb, old_instruction->scope, old_instruction->source_node, 1707 value, safety_check_on); 1708 ir_link_new_instruction(new_instruction, old_instruction); 1709 return new_instruction; 1710 } 1711 1712 static IrInstruction *ir_build_maybe_wrap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1713 IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>(irb, scope, source_node); 1714 instruction->value = value; 1715 1716 ir_ref_instruction(value, irb->current_basic_block); 1717 1718 return &instruction->base; 1719 } 1720 1721 static IrInstruction *ir_build_err_wrap_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1722 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(irb, scope, source_node); 1723 instruction->value = value; 1724 1725 ir_ref_instruction(value, irb->current_basic_block); 1726 1727 return &instruction->base; 1728 } 1729 1730 static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1731 IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node); 1732 instruction->value = value; 1733 1734 ir_ref_instruction(value, irb->current_basic_block); 1735 1736 return &instruction->base; 1737 } 1738 1739 static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1740 IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node); 1741 instruction->value = value; 1742 1743 ir_ref_instruction(value, irb->current_basic_block); 1744 1745 return &instruction->base; 1746 } 1747 1748 static IrInstruction *ir_build_clz_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) { 1749 IrInstruction *new_instruction = ir_build_clz(irb, old_instruction->scope, old_instruction->source_node, value); 1750 ir_link_new_instruction(new_instruction, old_instruction); 1751 return new_instruction; 1752 } 1753 1754 static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1755 IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node); 1756 instruction->value = value; 1757 1758 ir_ref_instruction(value, irb->current_basic_block); 1759 1760 return &instruction->base; 1761 } 1762 1763 static IrInstruction *ir_build_ctz_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) { 1764 IrInstruction *new_instruction = ir_build_ctz(irb, old_instruction->scope, old_instruction->source_node, value); 1765 ir_link_new_instruction(new_instruction, old_instruction); 1766 return new_instruction; 1767 } 1768 1769 static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1770 IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node); 1771 instruction->value = value; 1772 1773 ir_ref_instruction(value, irb->current_basic_block); 1774 1775 return &instruction->base; 1776 } 1777 1778 static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value, 1779 IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, 1780 IrInstruction *switch_prongs_void) 1781 { 1782 IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node); 1783 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1784 instruction->base.value.special = ConstValSpecialStatic; 1785 instruction->target_value = target_value; 1786 instruction->else_block = else_block; 1787 instruction->case_count = case_count; 1788 instruction->cases = cases; 1789 instruction->is_comptime = is_comptime; 1790 instruction->switch_prongs_void = switch_prongs_void; 1791 1792 ir_ref_instruction(target_value, irb->current_basic_block); 1793 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 1794 ir_ref_bb(else_block); 1795 if (switch_prongs_void) ir_ref_instruction(switch_prongs_void, irb->current_basic_block); 1796 1797 for (size_t i = 0; i < case_count; i += 1) { 1798 ir_ref_instruction(cases[i].value, irb->current_basic_block); 1799 ir_ref_bb(cases[i].block); 1800 } 1801 1802 return &instruction->base; 1803 } 1804 1805 static IrInstruction *ir_build_switch_br_from(IrBuilder *irb, IrInstruction *old_instruction, 1806 IrInstruction *target_value, IrBasicBlock *else_block, size_t case_count, 1807 IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, IrInstruction *switch_prongs_void) 1808 { 1809 IrInstruction *new_instruction = ir_build_switch_br(irb, old_instruction->scope, old_instruction->source_node, 1810 target_value, else_block, case_count, cases, is_comptime, switch_prongs_void); 1811 ir_link_new_instruction(new_instruction, old_instruction); 1812 return new_instruction; 1813 } 1814 1815 static IrInstruction *ir_build_switch_target(IrBuilder *irb, Scope *scope, AstNode *source_node, 1816 IrInstruction *target_value_ptr) 1817 { 1818 IrInstructionSwitchTarget *instruction = ir_build_instruction<IrInstructionSwitchTarget>(irb, scope, source_node); 1819 instruction->target_value_ptr = target_value_ptr; 1820 1821 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 1822 1823 return &instruction->base; 1824 } 1825 1826 static IrInstruction *ir_build_switch_var(IrBuilder *irb, Scope *scope, AstNode *source_node, 1827 IrInstruction *target_value_ptr, IrInstruction *prong_value) 1828 { 1829 IrInstructionSwitchVar *instruction = ir_build_instruction<IrInstructionSwitchVar>(irb, scope, source_node); 1830 instruction->target_value_ptr = target_value_ptr; 1831 instruction->prong_value = prong_value; 1832 1833 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 1834 ir_ref_instruction(prong_value, irb->current_basic_block); 1835 1836 return &instruction->base; 1837 } 1838 1839 static IrInstruction *ir_build_union_tag(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1840 IrInstructionUnionTag *instruction = ir_build_instruction<IrInstructionUnionTag>(irb, scope, source_node); 1841 instruction->value = value; 1842 1843 ir_ref_instruction(value, irb->current_basic_block); 1844 1845 return &instruction->base; 1846 } 1847 1848 static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1849 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, scope, source_node); 1850 instruction->name = name; 1851 1852 ir_ref_instruction(name, irb->current_basic_block); 1853 1854 return &instruction->base; 1855 } 1856 1857 static IrInstruction *ir_build_array_len(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_value) { 1858 IrInstructionArrayLen *instruction = ir_build_instruction<IrInstructionArrayLen>(irb, scope, source_node); 1859 instruction->array_value = array_value; 1860 1861 ir_ref_instruction(array_value, irb->current_basic_block); 1862 1863 return &instruction->base; 1864 } 1865 1866 static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value, 1867 bool is_const, bool is_volatile) 1868 { 1869 IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, scope, source_node); 1870 instruction->value = value; 1871 instruction->is_const = is_const; 1872 instruction->is_volatile = is_volatile; 1873 1874 ir_ref_instruction(value, irb->current_basic_block); 1875 1876 return &instruction->base; 1877 } 1878 1879 static IrInstruction *ir_build_min_value(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1880 IrInstructionMinValue *instruction = ir_build_instruction<IrInstructionMinValue>(irb, scope, source_node); 1881 instruction->value = value; 1882 1883 ir_ref_instruction(value, irb->current_basic_block); 1884 1885 return &instruction->base; 1886 } 1887 1888 static IrInstruction *ir_build_max_value(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1889 IrInstructionMaxValue *instruction = ir_build_instruction<IrInstructionMaxValue>(irb, scope, source_node); 1890 instruction->value = value; 1891 1892 ir_ref_instruction(value, irb->current_basic_block); 1893 1894 return &instruction->base; 1895 } 1896 1897 static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { 1898 IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); 1899 instruction->msg = msg; 1900 1901 ir_ref_instruction(msg, irb->current_basic_block); 1902 1903 return &instruction->base; 1904 } 1905 1906 static IrInstruction *ir_build_compile_log(IrBuilder *irb, Scope *scope, AstNode *source_node, 1907 size_t msg_count, IrInstruction **msg_list) 1908 { 1909 IrInstructionCompileLog *instruction = ir_build_instruction<IrInstructionCompileLog>(irb, scope, source_node); 1910 instruction->msg_count = msg_count; 1911 instruction->msg_list = msg_list; 1912 1913 for (size_t i = 0; i < msg_count; i += 1) { 1914 ir_ref_instruction(msg_list[i], irb->current_basic_block); 1915 } 1916 1917 return &instruction->base; 1918 } 1919 1920 static IrInstruction *ir_build_err_name(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1921 IrInstructionErrName *instruction = ir_build_instruction<IrInstructionErrName>(irb, scope, source_node); 1922 instruction->value = value; 1923 1924 ir_ref_instruction(value, irb->current_basic_block); 1925 1926 return &instruction->base; 1927 } 1928 1929 static IrInstruction *ir_build_err_name_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) { 1930 IrInstruction *new_instruction = ir_build_err_name(irb, old_instruction->scope, 1931 old_instruction->source_node, value); 1932 ir_link_new_instruction(new_instruction, old_instruction); 1933 return new_instruction; 1934 } 1935 1936 static IrInstruction *ir_build_c_import(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1937 IrInstructionCImport *instruction = ir_build_instruction<IrInstructionCImport>(irb, scope, source_node); 1938 return &instruction->base; 1939 } 1940 1941 static IrInstruction *ir_build_c_include(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1942 IrInstructionCInclude *instruction = ir_build_instruction<IrInstructionCInclude>(irb, scope, source_node); 1943 instruction->name = name; 1944 1945 ir_ref_instruction(name, irb->current_basic_block); 1946 1947 return &instruction->base; 1948 } 1949 1950 static IrInstruction *ir_build_c_define(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name, IrInstruction *value) { 1951 IrInstructionCDefine *instruction = ir_build_instruction<IrInstructionCDefine>(irb, scope, source_node); 1952 instruction->name = name; 1953 instruction->value = value; 1954 1955 ir_ref_instruction(name, irb->current_basic_block); 1956 ir_ref_instruction(value, irb->current_basic_block); 1957 1958 return &instruction->base; 1959 } 1960 1961 static IrInstruction *ir_build_c_undef(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1962 IrInstructionCUndef *instruction = ir_build_instruction<IrInstructionCUndef>(irb, scope, source_node); 1963 instruction->name = name; 1964 1965 ir_ref_instruction(name, irb->current_basic_block); 1966 1967 return &instruction->base; 1968 } 1969 1970 static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1971 IrInstructionEmbedFile *instruction = ir_build_instruction<IrInstructionEmbedFile>(irb, scope, source_node); 1972 instruction->name = name; 1973 1974 ir_ref_instruction(name, irb->current_basic_block); 1975 1976 return &instruction->base; 1977 } 1978 1979 static IrInstruction *ir_build_cmpxchg(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value, 1980 IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, 1981 IrInstruction *success_order_value, IrInstruction *failure_order_value, 1982 bool is_weak, 1983 ZigType *type, AtomicOrder success_order, AtomicOrder failure_order) 1984 { 1985 IrInstructionCmpxchg *instruction = ir_build_instruction<IrInstructionCmpxchg>(irb, scope, source_node); 1986 instruction->type_value = type_value; 1987 instruction->ptr = ptr; 1988 instruction->cmp_value = cmp_value; 1989 instruction->new_value = new_value; 1990 instruction->success_order_value = success_order_value; 1991 instruction->failure_order_value = failure_order_value; 1992 instruction->is_weak = is_weak; 1993 instruction->type = type; 1994 instruction->success_order = success_order; 1995 instruction->failure_order = failure_order; 1996 1997 if (type_value != nullptr) ir_ref_instruction(type_value, irb->current_basic_block); 1998 ir_ref_instruction(ptr, irb->current_basic_block); 1999 ir_ref_instruction(cmp_value, irb->current_basic_block); 2000 ir_ref_instruction(new_value, irb->current_basic_block); 2001 if (type_value != nullptr) ir_ref_instruction(success_order_value, irb->current_basic_block); 2002 if (type_value != nullptr) ir_ref_instruction(failure_order_value, irb->current_basic_block); 2003 2004 return &instruction->base; 2005 } 2006 2007 static IrInstruction *ir_build_fence(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *order_value, AtomicOrder order) { 2008 IrInstructionFence *instruction = ir_build_instruction<IrInstructionFence>(irb, scope, source_node); 2009 instruction->order_value = order_value; 2010 instruction->order = order; 2011 2012 ir_ref_instruction(order_value, irb->current_basic_block); 2013 2014 return &instruction->base; 2015 } 2016 2017 static IrInstruction *ir_build_fence_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *order_value, AtomicOrder order) { 2018 IrInstruction *new_instruction = ir_build_fence(irb, old_instruction->scope, old_instruction->source_node, order_value, order); 2019 ir_link_new_instruction(new_instruction, old_instruction); 2020 return new_instruction; 2021 } 2022 2023 static IrInstruction *ir_build_truncate(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2024 IrInstructionTruncate *instruction = ir_build_instruction<IrInstructionTruncate>(irb, scope, source_node); 2025 instruction->dest_type = dest_type; 2026 instruction->target = target; 2027 2028 ir_ref_instruction(dest_type, irb->current_basic_block); 2029 ir_ref_instruction(target, irb->current_basic_block); 2030 2031 return &instruction->base; 2032 } 2033 2034 static IrInstruction *ir_build_int_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2035 IrInstructionIntCast *instruction = ir_build_instruction<IrInstructionIntCast>(irb, scope, source_node); 2036 instruction->dest_type = dest_type; 2037 instruction->target = target; 2038 2039 ir_ref_instruction(dest_type, irb->current_basic_block); 2040 ir_ref_instruction(target, irb->current_basic_block); 2041 2042 return &instruction->base; 2043 } 2044 2045 static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2046 IrInstructionFloatCast *instruction = ir_build_instruction<IrInstructionFloatCast>(irb, scope, source_node); 2047 instruction->dest_type = dest_type; 2048 instruction->target = target; 2049 2050 ir_ref_instruction(dest_type, irb->current_basic_block); 2051 ir_ref_instruction(target, irb->current_basic_block); 2052 2053 return &instruction->base; 2054 } 2055 2056 static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2057 IrInstructionErrSetCast *instruction = ir_build_instruction<IrInstructionErrSetCast>(irb, scope, source_node); 2058 instruction->dest_type = dest_type; 2059 instruction->target = target; 2060 2061 ir_ref_instruction(dest_type, irb->current_basic_block); 2062 ir_ref_instruction(target, irb->current_basic_block); 2063 2064 return &instruction->base; 2065 } 2066 2067 static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { 2068 IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); 2069 instruction->target = target; 2070 2071 ir_ref_instruction(target, irb->current_basic_block); 2072 2073 return &instruction->base; 2074 } 2075 2076 static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_child_type, IrInstruction *target) { 2077 IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); 2078 instruction->dest_child_type = dest_child_type; 2079 instruction->target = target; 2080 2081 ir_ref_instruction(dest_child_type, irb->current_basic_block); 2082 ir_ref_instruction(target, irb->current_basic_block); 2083 2084 return &instruction->base; 2085 } 2086 2087 static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2088 IrInstructionIntToFloat *instruction = ir_build_instruction<IrInstructionIntToFloat>(irb, scope, source_node); 2089 instruction->dest_type = dest_type; 2090 instruction->target = target; 2091 2092 ir_ref_instruction(dest_type, irb->current_basic_block); 2093 ir_ref_instruction(target, irb->current_basic_block); 2094 2095 return &instruction->base; 2096 } 2097 2098 static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2099 IrInstructionFloatToInt *instruction = ir_build_instruction<IrInstructionFloatToInt>(irb, scope, source_node); 2100 instruction->dest_type = dest_type; 2101 instruction->target = target; 2102 2103 ir_ref_instruction(dest_type, irb->current_basic_block); 2104 ir_ref_instruction(target, irb->current_basic_block); 2105 2106 return &instruction->base; 2107 } 2108 2109 static IrInstruction *ir_build_bool_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { 2110 IrInstructionBoolToInt *instruction = ir_build_instruction<IrInstructionBoolToInt>(irb, scope, source_node); 2111 instruction->target = target; 2112 2113 ir_ref_instruction(target, irb->current_basic_block); 2114 2115 return &instruction->base; 2116 } 2117 2118 static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) { 2119 IrInstructionIntType *instruction = ir_build_instruction<IrInstructionIntType>(irb, scope, source_node); 2120 instruction->is_signed = is_signed; 2121 instruction->bit_count = bit_count; 2122 2123 ir_ref_instruction(is_signed, irb->current_basic_block); 2124 ir_ref_instruction(bit_count, irb->current_basic_block); 2125 2126 return &instruction->base; 2127 } 2128 2129 static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2130 IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node); 2131 instruction->value = value; 2132 2133 ir_ref_instruction(value, irb->current_basic_block); 2134 2135 return &instruction->base; 2136 } 2137 2138 static IrInstruction *ir_build_bool_not_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) { 2139 IrInstruction *new_instruction = ir_build_bool_not(irb, old_instruction->scope, old_instruction->source_node, value); 2140 ir_link_new_instruction(new_instruction, old_instruction); 2141 return new_instruction; 2142 } 2143 2144 static IrInstruction *ir_build_memset(IrBuilder *irb, Scope *scope, AstNode *source_node, 2145 IrInstruction *dest_ptr, IrInstruction *byte, IrInstruction *count) 2146 { 2147 IrInstructionMemset *instruction = ir_build_instruction<IrInstructionMemset>(irb, scope, source_node); 2148 instruction->dest_ptr = dest_ptr; 2149 instruction->byte = byte; 2150 instruction->count = count; 2151 2152 ir_ref_instruction(dest_ptr, irb->current_basic_block); 2153 ir_ref_instruction(byte, irb->current_basic_block); 2154 ir_ref_instruction(count, irb->current_basic_block); 2155 2156 return &instruction->base; 2157 } 2158 2159 static IrInstruction *ir_build_memset_from(IrBuilder *irb, IrInstruction *old_instruction, 2160 IrInstruction *dest_ptr, IrInstruction *byte, IrInstruction *count) 2161 { 2162 IrInstruction *new_instruction = ir_build_memset(irb, old_instruction->scope, old_instruction->source_node, dest_ptr, byte, count); 2163 ir_link_new_instruction(new_instruction, old_instruction); 2164 return new_instruction; 2165 } 2166 2167 static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *source_node, 2168 IrInstruction *dest_ptr, IrInstruction *src_ptr, IrInstruction *count) 2169 { 2170 IrInstructionMemcpy *instruction = ir_build_instruction<IrInstructionMemcpy>(irb, scope, source_node); 2171 instruction->dest_ptr = dest_ptr; 2172 instruction->src_ptr = src_ptr; 2173 instruction->count = count; 2174 2175 ir_ref_instruction(dest_ptr, irb->current_basic_block); 2176 ir_ref_instruction(src_ptr, irb->current_basic_block); 2177 ir_ref_instruction(count, irb->current_basic_block); 2178 2179 return &instruction->base; 2180 } 2181 2182 static IrInstruction *ir_build_memcpy_from(IrBuilder *irb, IrInstruction *old_instruction, 2183 IrInstruction *dest_ptr, IrInstruction *src_ptr, IrInstruction *count) 2184 { 2185 IrInstruction *new_instruction = ir_build_memcpy(irb, old_instruction->scope, old_instruction->source_node, dest_ptr, src_ptr, count); 2186 ir_link_new_instruction(new_instruction, old_instruction); 2187 return new_instruction; 2188 } 2189 2190 static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *source_node, 2191 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on) 2192 { 2193 IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node); 2194 instruction->ptr = ptr; 2195 instruction->start = start; 2196 instruction->end = end; 2197 instruction->safety_check_on = safety_check_on; 2198 2199 ir_ref_instruction(ptr, irb->current_basic_block); 2200 ir_ref_instruction(start, irb->current_basic_block); 2201 if (end) ir_ref_instruction(end, irb->current_basic_block); 2202 2203 return &instruction->base; 2204 } 2205 2206 static IrInstruction *ir_build_slice_from(IrBuilder *irb, IrInstruction *old_instruction, 2207 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on) 2208 { 2209 IrInstruction *new_instruction = ir_build_slice(irb, old_instruction->scope, 2210 old_instruction->source_node, ptr, start, end, safety_check_on); 2211 ir_link_new_instruction(new_instruction, old_instruction); 2212 return new_instruction; 2213 } 2214 2215 static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) { 2216 IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); 2217 instruction->container = container; 2218 2219 ir_ref_instruction(container, irb->current_basic_block); 2220 2221 return &instruction->base; 2222 } 2223 2224 static IrInstruction *ir_build_member_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2225 IrInstruction *container_type, IrInstruction *member_index) 2226 { 2227 IrInstructionMemberType *instruction = ir_build_instruction<IrInstructionMemberType>(irb, scope, source_node); 2228 instruction->container_type = container_type; 2229 instruction->member_index = member_index; 2230 2231 ir_ref_instruction(container_type, irb->current_basic_block); 2232 ir_ref_instruction(member_index, irb->current_basic_block); 2233 2234 return &instruction->base; 2235 } 2236 2237 static IrInstruction *ir_build_member_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2238 IrInstruction *container_type, IrInstruction *member_index) 2239 { 2240 IrInstructionMemberName *instruction = ir_build_instruction<IrInstructionMemberName>(irb, scope, source_node); 2241 instruction->container_type = container_type; 2242 instruction->member_index = member_index; 2243 2244 ir_ref_instruction(container_type, irb->current_basic_block); 2245 ir_ref_instruction(member_index, irb->current_basic_block); 2246 2247 return &instruction->base; 2248 } 2249 2250 static IrInstruction *ir_build_breakpoint(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2251 IrInstructionBreakpoint *instruction = ir_build_instruction<IrInstructionBreakpoint>(irb, scope, source_node); 2252 return &instruction->base; 2253 } 2254 2255 static IrInstruction *ir_build_breakpoint_from(IrBuilder *irb, IrInstruction *old_instruction) { 2256 IrInstruction *new_instruction = ir_build_breakpoint(irb, old_instruction->scope, old_instruction->source_node); 2257 ir_link_new_instruction(new_instruction, old_instruction); 2258 return new_instruction; 2259 } 2260 2261 static IrInstruction *ir_build_return_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2262 IrInstructionReturnAddress *instruction = ir_build_instruction<IrInstructionReturnAddress>(irb, scope, source_node); 2263 return &instruction->base; 2264 } 2265 2266 static IrInstruction *ir_build_return_address_from(IrBuilder *irb, IrInstruction *old_instruction) { 2267 IrInstruction *new_instruction = ir_build_return_address(irb, old_instruction->scope, old_instruction->source_node); 2268 ir_link_new_instruction(new_instruction, old_instruction); 2269 return new_instruction; 2270 } 2271 2272 static IrInstruction *ir_build_frame_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2273 IrInstructionFrameAddress *instruction = ir_build_instruction<IrInstructionFrameAddress>(irb, scope, source_node); 2274 return &instruction->base; 2275 } 2276 2277 static IrInstruction *ir_build_frame_address_from(IrBuilder *irb, IrInstruction *old_instruction) { 2278 IrInstruction *new_instruction = ir_build_frame_address(irb, old_instruction->scope, old_instruction->source_node); 2279 ir_link_new_instruction(new_instruction, old_instruction); 2280 return new_instruction; 2281 } 2282 2283 static IrInstruction *ir_build_handle(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2284 IrInstructionHandle *instruction = ir_build_instruction<IrInstructionHandle>(irb, scope, source_node); 2285 return &instruction->base; 2286 } 2287 2288 static IrInstruction *ir_build_handle_from(IrBuilder *irb, IrInstruction *old_instruction) { 2289 IrInstruction *new_instruction = ir_build_handle(irb, old_instruction->scope, old_instruction->source_node); 2290 ir_link_new_instruction(new_instruction, old_instruction); 2291 return new_instruction; 2292 } 2293 2294 static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode *source_node, 2295 IrOverflowOp op, IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, 2296 IrInstruction *result_ptr, ZigType *result_ptr_type) 2297 { 2298 IrInstructionOverflowOp *instruction = ir_build_instruction<IrInstructionOverflowOp>(irb, scope, source_node); 2299 instruction->op = op; 2300 instruction->type_value = type_value; 2301 instruction->op1 = op1; 2302 instruction->op2 = op2; 2303 instruction->result_ptr = result_ptr; 2304 instruction->result_ptr_type = result_ptr_type; 2305 2306 ir_ref_instruction(type_value, irb->current_basic_block); 2307 ir_ref_instruction(op1, irb->current_basic_block); 2308 ir_ref_instruction(op2, irb->current_basic_block); 2309 ir_ref_instruction(result_ptr, irb->current_basic_block); 2310 2311 return &instruction->base; 2312 } 2313 2314 static IrInstruction *ir_build_overflow_op_from(IrBuilder *irb, IrInstruction *old_instruction, 2315 IrOverflowOp op, IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, 2316 IrInstruction *result_ptr, ZigType *result_ptr_type) 2317 { 2318 IrInstruction *new_instruction = ir_build_overflow_op(irb, old_instruction->scope, old_instruction->source_node, 2319 op, type_value, op1, op2, result_ptr, result_ptr_type); 2320 ir_link_new_instruction(new_instruction, old_instruction); 2321 return new_instruction; 2322 } 2323 2324 static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { 2325 IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node); 2326 instruction->type_value = type_value; 2327 2328 ir_ref_instruction(type_value, irb->current_basic_block); 2329 2330 return &instruction->base; 2331 } 2332 2333 static IrInstruction *ir_build_test_err(IrBuilder *irb, Scope *scope, AstNode *source_node, 2334 IrInstruction *value) 2335 { 2336 IrInstructionTestErr *instruction = ir_build_instruction<IrInstructionTestErr>(irb, scope, source_node); 2337 instruction->value = value; 2338 2339 ir_ref_instruction(value, irb->current_basic_block); 2340 2341 return &instruction->base; 2342 } 2343 2344 static IrInstruction *ir_build_test_err_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) { 2345 IrInstruction *new_instruction = ir_build_test_err(irb, old_instruction->scope, old_instruction->source_node, 2346 value); 2347 ir_link_new_instruction(new_instruction, old_instruction); 2348 return new_instruction; 2349 } 2350 2351 static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, 2352 IrInstruction *value) 2353 { 2354 IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); 2355 instruction->value = value; 2356 2357 ir_ref_instruction(value, irb->current_basic_block); 2358 2359 return &instruction->base; 2360 } 2361 2362 static IrInstruction *ir_build_unwrap_err_code_from(IrBuilder *irb, IrInstruction *old_instruction, 2363 IrInstruction *value) 2364 { 2365 IrInstruction *new_instruction = ir_build_unwrap_err_code(irb, old_instruction->scope, 2366 old_instruction->source_node, value); 2367 ir_link_new_instruction(new_instruction, old_instruction); 2368 return new_instruction; 2369 } 2370 2371 static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, 2372 IrInstruction *value, bool safety_check_on) 2373 { 2374 IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); 2375 instruction->value = value; 2376 instruction->safety_check_on = safety_check_on; 2377 2378 ir_ref_instruction(value, irb->current_basic_block); 2379 2380 return &instruction->base; 2381 } 2382 2383 static IrInstruction *ir_build_unwrap_err_payload_from(IrBuilder *irb, IrInstruction *old_instruction, 2384 IrInstruction *value, bool safety_check_on) 2385 { 2386 IrInstruction *new_instruction = ir_build_unwrap_err_payload(irb, old_instruction->scope, 2387 old_instruction->source_node, value, safety_check_on); 2388 ir_link_new_instruction(new_instruction, old_instruction); 2389 return new_instruction; 2390 } 2391 2392 static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node, 2393 IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type, 2394 IrInstruction *async_allocator_type_value, bool is_var_args) 2395 { 2396 IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node); 2397 instruction->param_types = param_types; 2398 instruction->align_value = align_value; 2399 instruction->return_type = return_type; 2400 instruction->async_allocator_type_value = async_allocator_type_value; 2401 instruction->is_var_args = is_var_args; 2402 2403 assert(source_node->type == NodeTypeFnProto); 2404 size_t param_count = source_node->data.fn_proto.params.length; 2405 if (is_var_args) param_count -= 1; 2406 for (size_t i = 0; i < param_count; i += 1) { 2407 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); 2408 } 2409 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 2410 if (async_allocator_type_value != nullptr) ir_ref_instruction(async_allocator_type_value, irb->current_basic_block); 2411 ir_ref_instruction(return_type, irb->current_basic_block); 2412 2413 return &instruction->base; 2414 } 2415 2416 static IrInstruction *ir_build_test_comptime(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2417 IrInstructionTestComptime *instruction = ir_build_instruction<IrInstructionTestComptime>(irb, scope, source_node); 2418 instruction->value = value; 2419 2420 ir_ref_instruction(value, irb->current_basic_block); 2421 2422 return &instruction->base; 2423 } 2424 2425 static IrInstruction *ir_build_ptr_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 2426 IrInstruction *dest_type, IrInstruction *ptr) 2427 { 2428 IrInstructionPtrCast *instruction = ir_build_instruction<IrInstructionPtrCast>( 2429 irb, scope, source_node); 2430 instruction->dest_type = dest_type; 2431 instruction->ptr = ptr; 2432 2433 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2434 ir_ref_instruction(ptr, irb->current_basic_block); 2435 2436 return &instruction->base; 2437 } 2438 2439 static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 2440 IrInstruction *dest_type, IrInstruction *value) 2441 { 2442 IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>( 2443 irb, scope, source_node); 2444 instruction->dest_type = dest_type; 2445 instruction->value = value; 2446 2447 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2448 ir_ref_instruction(value, irb->current_basic_block); 2449 2450 return &instruction->base; 2451 } 2452 2453 static IrInstruction *ir_build_widen_or_shorten(IrBuilder *irb, Scope *scope, AstNode *source_node, 2454 IrInstruction *target) 2455 { 2456 IrInstructionWidenOrShorten *instruction = ir_build_instruction<IrInstructionWidenOrShorten>( 2457 irb, scope, source_node); 2458 instruction->target = target; 2459 2460 ir_ref_instruction(target, irb->current_basic_block); 2461 2462 return &instruction->base; 2463 } 2464 2465 static IrInstruction *ir_build_int_to_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 2466 IrInstruction *dest_type, IrInstruction *target) 2467 { 2468 IrInstructionIntToPtr *instruction = ir_build_instruction<IrInstructionIntToPtr>( 2469 irb, scope, source_node); 2470 instruction->dest_type = dest_type; 2471 instruction->target = target; 2472 2473 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2474 ir_ref_instruction(target, irb->current_basic_block); 2475 2476 return &instruction->base; 2477 } 2478 2479 static IrInstruction *ir_build_ptr_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2480 IrInstruction *target) 2481 { 2482 IrInstructionPtrToInt *instruction = ir_build_instruction<IrInstructionPtrToInt>( 2483 irb, scope, source_node); 2484 instruction->target = target; 2485 2486 ir_ref_instruction(target, irb->current_basic_block); 2487 2488 return &instruction->base; 2489 } 2490 2491 static IrInstruction *ir_build_int_to_enum(IrBuilder *irb, Scope *scope, AstNode *source_node, 2492 IrInstruction *dest_type, IrInstruction *target) 2493 { 2494 IrInstructionIntToEnum *instruction = ir_build_instruction<IrInstructionIntToEnum>( 2495 irb, scope, source_node); 2496 instruction->dest_type = dest_type; 2497 instruction->target = target; 2498 2499 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2500 ir_ref_instruction(target, irb->current_basic_block); 2501 2502 return &instruction->base; 2503 } 2504 2505 2506 2507 static IrInstruction *ir_build_enum_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2508 IrInstruction *target) 2509 { 2510 IrInstructionEnumToInt *instruction = ir_build_instruction<IrInstructionEnumToInt>( 2511 irb, scope, source_node); 2512 instruction->target = target; 2513 2514 ir_ref_instruction(target, irb->current_basic_block); 2515 2516 return &instruction->base; 2517 } 2518 2519 static IrInstruction *ir_build_int_to_err(IrBuilder *irb, Scope *scope, AstNode *source_node, 2520 IrInstruction *target) 2521 { 2522 IrInstructionIntToErr *instruction = ir_build_instruction<IrInstructionIntToErr>( 2523 irb, scope, source_node); 2524 instruction->target = target; 2525 2526 ir_ref_instruction(target, irb->current_basic_block); 2527 2528 return &instruction->base; 2529 } 2530 2531 static IrInstruction *ir_build_err_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2532 IrInstruction *target) 2533 { 2534 IrInstructionErrToInt *instruction = ir_build_instruction<IrInstructionErrToInt>( 2535 irb, scope, source_node); 2536 instruction->target = target; 2537 2538 ir_ref_instruction(target, irb->current_basic_block); 2539 2540 return &instruction->base; 2541 } 2542 2543 static IrInstruction *ir_build_check_switch_prongs(IrBuilder *irb, Scope *scope, AstNode *source_node, 2544 IrInstruction *target_value, IrInstructionCheckSwitchProngsRange *ranges, size_t range_count, 2545 bool have_else_prong) 2546 { 2547 IrInstructionCheckSwitchProngs *instruction = ir_build_instruction<IrInstructionCheckSwitchProngs>( 2548 irb, scope, source_node); 2549 instruction->target_value = target_value; 2550 instruction->ranges = ranges; 2551 instruction->range_count = range_count; 2552 instruction->have_else_prong = have_else_prong; 2553 2554 ir_ref_instruction(target_value, irb->current_basic_block); 2555 for (size_t i = 0; i < range_count; i += 1) { 2556 ir_ref_instruction(ranges[i].start, irb->current_basic_block); 2557 ir_ref_instruction(ranges[i].end, irb->current_basic_block); 2558 } 2559 2560 return &instruction->base; 2561 } 2562 2563 static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *scope, AstNode *source_node, 2564 IrInstruction* statement_value) 2565 { 2566 IrInstructionCheckStatementIsVoid *instruction = ir_build_instruction<IrInstructionCheckStatementIsVoid>( 2567 irb, scope, source_node); 2568 instruction->statement_value = statement_value; 2569 2570 ir_ref_instruction(statement_value, irb->current_basic_block); 2571 2572 return &instruction->base; 2573 } 2574 2575 static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2576 IrInstruction *type_value) 2577 { 2578 IrInstructionTypeName *instruction = ir_build_instruction<IrInstructionTypeName>( 2579 irb, scope, source_node); 2580 instruction->type_value = type_value; 2581 2582 ir_ref_instruction(type_value, irb->current_basic_block); 2583 2584 return &instruction->base; 2585 } 2586 2587 static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, 2588 Tld *tld, LVal lval) 2589 { 2590 IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>( 2591 irb, scope, source_node); 2592 instruction->tld = tld; 2593 instruction->lval = lval; 2594 2595 return &instruction->base; 2596 } 2597 2598 static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { 2599 IrInstructionPanic *instruction = ir_build_instruction<IrInstructionPanic>(irb, scope, source_node); 2600 instruction->base.value.special = ConstValSpecialStatic; 2601 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 2602 instruction->msg = msg; 2603 2604 ir_ref_instruction(msg, irb->current_basic_block); 2605 2606 return &instruction->base; 2607 } 2608 2609 static IrInstruction *ir_build_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2610 IrInstruction *target) 2611 { 2612 IrInstructionTagName *instruction = ir_build_instruction<IrInstructionTagName>(irb, scope, source_node); 2613 instruction->target = target; 2614 2615 ir_ref_instruction(target, irb->current_basic_block); 2616 2617 return &instruction->base; 2618 } 2619 2620 static IrInstruction *ir_build_tag_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2621 IrInstruction *target) 2622 { 2623 IrInstructionTagType *instruction = ir_build_instruction<IrInstructionTagType>(irb, scope, source_node); 2624 instruction->target = target; 2625 2626 ir_ref_instruction(target, irb->current_basic_block); 2627 2628 return &instruction->base; 2629 } 2630 2631 static IrInstruction *ir_build_field_parent_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 2632 IrInstruction *type_value, IrInstruction *field_name, IrInstruction *field_ptr, TypeStructField *field) 2633 { 2634 IrInstructionFieldParentPtr *instruction = ir_build_instruction<IrInstructionFieldParentPtr>( 2635 irb, scope, source_node); 2636 instruction->type_value = type_value; 2637 instruction->field_name = field_name; 2638 instruction->field_ptr = field_ptr; 2639 instruction->field = field; 2640 2641 ir_ref_instruction(type_value, irb->current_basic_block); 2642 ir_ref_instruction(field_name, irb->current_basic_block); 2643 ir_ref_instruction(field_ptr, irb->current_basic_block); 2644 2645 return &instruction->base; 2646 } 2647 2648 static IrInstruction *ir_build_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node, 2649 IrInstruction *type_value, IrInstruction *field_name) 2650 { 2651 IrInstructionOffsetOf *instruction = ir_build_instruction<IrInstructionOffsetOf>(irb, scope, source_node); 2652 instruction->type_value = type_value; 2653 instruction->field_name = field_name; 2654 2655 ir_ref_instruction(type_value, irb->current_basic_block); 2656 ir_ref_instruction(field_name, irb->current_basic_block); 2657 2658 return &instruction->base; 2659 } 2660 2661 static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *source_node, 2662 IrInstruction *type_value) { 2663 IrInstructionTypeInfo *instruction = ir_build_instruction<IrInstructionTypeInfo>(irb, scope, source_node); 2664 instruction->type_value = type_value; 2665 2666 ir_ref_instruction(type_value, irb->current_basic_block); 2667 2668 return &instruction->base; 2669 } 2670 2671 static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node, 2672 IrInstruction *type_value) 2673 { 2674 IrInstructionTypeId *instruction = ir_build_instruction<IrInstructionTypeId>(irb, scope, source_node); 2675 instruction->type_value = type_value; 2676 2677 ir_ref_instruction(type_value, irb->current_basic_block); 2678 2679 return &instruction->base; 2680 } 2681 2682 static IrInstruction *ir_build_set_eval_branch_quota(IrBuilder *irb, Scope *scope, AstNode *source_node, 2683 IrInstruction *new_quota) 2684 { 2685 IrInstructionSetEvalBranchQuota *instruction = ir_build_instruction<IrInstructionSetEvalBranchQuota>(irb, scope, source_node); 2686 instruction->new_quota = new_quota; 2687 2688 ir_ref_instruction(new_quota, irb->current_basic_block); 2689 2690 return &instruction->base; 2691 } 2692 2693 static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 2694 IrInstruction *align_bytes, IrInstruction *target) 2695 { 2696 IrInstructionAlignCast *instruction = ir_build_instruction<IrInstructionAlignCast>(irb, scope, source_node); 2697 instruction->align_bytes = align_bytes; 2698 instruction->target = target; 2699 2700 if (align_bytes) ir_ref_instruction(align_bytes, irb->current_basic_block); 2701 ir_ref_instruction(target, irb->current_basic_block); 2702 2703 return &instruction->base; 2704 } 2705 2706 static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2707 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); 2708 2709 return &instruction->base; 2710 } 2711 2712 static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, AstNode *source_node, 2713 IrInstruction *align_bytes) 2714 { 2715 IrInstructionSetAlignStack *instruction = ir_build_instruction<IrInstructionSetAlignStack>(irb, scope, source_node); 2716 instruction->align_bytes = align_bytes; 2717 2718 ir_ref_instruction(align_bytes, irb->current_basic_block); 2719 2720 return &instruction->base; 2721 } 2722 2723 static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2724 IrInstruction *fn_type, IrInstruction *arg_index) 2725 { 2726 IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node); 2727 instruction->fn_type = fn_type; 2728 instruction->arg_index = arg_index; 2729 2730 ir_ref_instruction(fn_type, irb->current_basic_block); 2731 ir_ref_instruction(arg_index, irb->current_basic_block); 2732 2733 return &instruction->base; 2734 } 2735 2736 static IrInstruction *ir_build_error_return_trace(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstructionErrorReturnTrace::Optional optional) { 2737 IrInstructionErrorReturnTrace *instruction = ir_build_instruction<IrInstructionErrorReturnTrace>(irb, scope, source_node); 2738 instruction->optional = optional; 2739 2740 return &instruction->base; 2741 } 2742 2743 static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode *source_node, 2744 IrInstruction *err_set, IrInstruction *payload) 2745 { 2746 IrInstructionErrorUnion *instruction = ir_build_instruction<IrInstructionErrorUnion>(irb, scope, source_node); 2747 instruction->err_set = err_set; 2748 instruction->payload = payload; 2749 2750 ir_ref_instruction(err_set, irb->current_basic_block); 2751 ir_ref_instruction(payload, irb->current_basic_block); 2752 2753 return &instruction->base; 2754 } 2755 2756 static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *source_node, 2757 IrInstruction *target) 2758 { 2759 IrInstructionCancel *instruction = ir_build_instruction<IrInstructionCancel>(irb, scope, source_node); 2760 instruction->target = target; 2761 2762 ir_ref_instruction(target, irb->current_basic_block); 2763 2764 return &instruction->base; 2765 } 2766 2767 static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *scope, AstNode *source_node, 2768 ImplicitAllocatorId id) 2769 { 2770 IrInstructionGetImplicitAllocator *instruction = ir_build_instruction<IrInstructionGetImplicitAllocator>(irb, scope, source_node); 2771 instruction->id = id; 2772 2773 return &instruction->base; 2774 } 2775 2776 static IrInstruction *ir_build_coro_id(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *promise_ptr) { 2777 IrInstructionCoroId *instruction = ir_build_instruction<IrInstructionCoroId>(irb, scope, source_node); 2778 instruction->promise_ptr = promise_ptr; 2779 2780 ir_ref_instruction(promise_ptr, irb->current_basic_block); 2781 2782 return &instruction->base; 2783 } 2784 2785 static IrInstruction *ir_build_coro_alloc(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id) { 2786 IrInstructionCoroAlloc *instruction = ir_build_instruction<IrInstructionCoroAlloc>(irb, scope, source_node); 2787 instruction->coro_id = coro_id; 2788 2789 ir_ref_instruction(coro_id, irb->current_basic_block); 2790 2791 return &instruction->base; 2792 } 2793 2794 static IrInstruction *ir_build_coro_size(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2795 IrInstructionCoroSize *instruction = ir_build_instruction<IrInstructionCoroSize>(irb, scope, source_node); 2796 2797 return &instruction->base; 2798 } 2799 2800 static IrInstruction *ir_build_coro_begin(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id, IrInstruction *coro_mem_ptr) { 2801 IrInstructionCoroBegin *instruction = ir_build_instruction<IrInstructionCoroBegin>(irb, scope, source_node); 2802 instruction->coro_id = coro_id; 2803 instruction->coro_mem_ptr = coro_mem_ptr; 2804 2805 ir_ref_instruction(coro_id, irb->current_basic_block); 2806 ir_ref_instruction(coro_mem_ptr, irb->current_basic_block); 2807 2808 return &instruction->base; 2809 } 2810 2811 static IrInstruction *ir_build_coro_alloc_fail(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_val) { 2812 IrInstructionCoroAllocFail *instruction = ir_build_instruction<IrInstructionCoroAllocFail>(irb, scope, source_node); 2813 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 2814 instruction->base.value.special = ConstValSpecialStatic; 2815 instruction->err_val = err_val; 2816 2817 ir_ref_instruction(err_val, irb->current_basic_block); 2818 2819 return &instruction->base; 2820 } 2821 2822 static IrInstruction *ir_build_coro_suspend(IrBuilder *irb, Scope *scope, AstNode *source_node, 2823 IrInstruction *save_point, IrInstruction *is_final) 2824 { 2825 IrInstructionCoroSuspend *instruction = ir_build_instruction<IrInstructionCoroSuspend>(irb, scope, source_node); 2826 instruction->save_point = save_point; 2827 instruction->is_final = is_final; 2828 2829 if (save_point != nullptr) ir_ref_instruction(save_point, irb->current_basic_block); 2830 ir_ref_instruction(is_final, irb->current_basic_block); 2831 2832 return &instruction->base; 2833 } 2834 2835 static IrInstruction *ir_build_coro_end(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2836 IrInstructionCoroEnd *instruction = ir_build_instruction<IrInstructionCoroEnd>(irb, scope, source_node); 2837 return &instruction->base; 2838 } 2839 2840 static IrInstruction *ir_build_coro_free(IrBuilder *irb, Scope *scope, AstNode *source_node, 2841 IrInstruction *coro_id, IrInstruction *coro_handle) 2842 { 2843 IrInstructionCoroFree *instruction = ir_build_instruction<IrInstructionCoroFree>(irb, scope, source_node); 2844 instruction->coro_id = coro_id; 2845 instruction->coro_handle = coro_handle; 2846 2847 ir_ref_instruction(coro_id, irb->current_basic_block); 2848 ir_ref_instruction(coro_handle, irb->current_basic_block); 2849 2850 return &instruction->base; 2851 } 2852 2853 static IrInstruction *ir_build_coro_resume(IrBuilder *irb, Scope *scope, AstNode *source_node, 2854 IrInstruction *awaiter_handle) 2855 { 2856 IrInstructionCoroResume *instruction = ir_build_instruction<IrInstructionCoroResume>(irb, scope, source_node); 2857 instruction->awaiter_handle = awaiter_handle; 2858 2859 ir_ref_instruction(awaiter_handle, irb->current_basic_block); 2860 2861 return &instruction->base; 2862 } 2863 2864 static IrInstruction *ir_build_coro_save(IrBuilder *irb, Scope *scope, AstNode *source_node, 2865 IrInstruction *coro_handle) 2866 { 2867 IrInstructionCoroSave *instruction = ir_build_instruction<IrInstructionCoroSave>(irb, scope, source_node); 2868 instruction->coro_handle = coro_handle; 2869 2870 ir_ref_instruction(coro_handle, irb->current_basic_block); 2871 2872 return &instruction->base; 2873 } 2874 2875 static IrInstruction *ir_build_coro_promise(IrBuilder *irb, Scope *scope, AstNode *source_node, 2876 IrInstruction *coro_handle) 2877 { 2878 IrInstructionCoroPromise *instruction = ir_build_instruction<IrInstructionCoroPromise>(irb, scope, source_node); 2879 instruction->coro_handle = coro_handle; 2880 2881 ir_ref_instruction(coro_handle, irb->current_basic_block); 2882 2883 return &instruction->base; 2884 } 2885 2886 static IrInstruction *ir_build_coro_alloc_helper(IrBuilder *irb, Scope *scope, AstNode *source_node, 2887 IrInstruction *alloc_fn, IrInstruction *coro_size) 2888 { 2889 IrInstructionCoroAllocHelper *instruction = ir_build_instruction<IrInstructionCoroAllocHelper>(irb, scope, source_node); 2890 instruction->alloc_fn = alloc_fn; 2891 instruction->coro_size = coro_size; 2892 2893 ir_ref_instruction(alloc_fn, irb->current_basic_block); 2894 ir_ref_instruction(coro_size, irb->current_basic_block); 2895 2896 return &instruction->base; 2897 } 2898 2899 static IrInstruction *ir_build_atomic_rmw(IrBuilder *irb, Scope *scope, AstNode *source_node, 2900 IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *op, IrInstruction *operand, 2901 IrInstruction *ordering, AtomicRmwOp resolved_op, AtomicOrder resolved_ordering) 2902 { 2903 IrInstructionAtomicRmw *instruction = ir_build_instruction<IrInstructionAtomicRmw>(irb, scope, source_node); 2904 instruction->operand_type = operand_type; 2905 instruction->ptr = ptr; 2906 instruction->op = op; 2907 instruction->operand = operand; 2908 instruction->ordering = ordering; 2909 instruction->resolved_op = resolved_op; 2910 instruction->resolved_ordering = resolved_ordering; 2911 2912 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); 2913 ir_ref_instruction(ptr, irb->current_basic_block); 2914 if (op != nullptr) ir_ref_instruction(op, irb->current_basic_block); 2915 ir_ref_instruction(operand, irb->current_basic_block); 2916 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); 2917 2918 return &instruction->base; 2919 } 2920 2921 static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode *source_node, 2922 IrInstruction *operand_type, IrInstruction *ptr, 2923 IrInstruction *ordering, AtomicOrder resolved_ordering) 2924 { 2925 IrInstructionAtomicLoad *instruction = ir_build_instruction<IrInstructionAtomicLoad>(irb, scope, source_node); 2926 instruction->operand_type = operand_type; 2927 instruction->ptr = ptr; 2928 instruction->ordering = ordering; 2929 instruction->resolved_ordering = resolved_ordering; 2930 2931 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); 2932 ir_ref_instruction(ptr, irb->current_basic_block); 2933 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); 2934 2935 return &instruction->base; 2936 } 2937 2938 static IrInstruction *ir_build_promise_result_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2939 IrInstruction *promise_type) 2940 { 2941 IrInstructionPromiseResultType *instruction = ir_build_instruction<IrInstructionPromiseResultType>(irb, scope, source_node); 2942 instruction->promise_type = promise_type; 2943 2944 ir_ref_instruction(promise_type, irb->current_basic_block); 2945 2946 return &instruction->base; 2947 } 2948 2949 static IrInstruction *ir_build_await_bookkeeping(IrBuilder *irb, Scope *scope, AstNode *source_node, 2950 IrInstruction *promise_result_type) 2951 { 2952 IrInstructionAwaitBookkeeping *instruction = ir_build_instruction<IrInstructionAwaitBookkeeping>(irb, scope, source_node); 2953 instruction->promise_result_type = promise_result_type; 2954 2955 ir_ref_instruction(promise_result_type, irb->current_basic_block); 2956 2957 return &instruction->base; 2958 } 2959 2960 static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2961 IrInstructionSaveErrRetAddr *instruction = ir_build_instruction<IrInstructionSaveErrRetAddr>(irb, scope, source_node); 2962 return &instruction->base; 2963 } 2964 2965 static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2966 IrInstruction *value) 2967 { 2968 IrInstructionAddImplicitReturnType *instruction = ir_build_instruction<IrInstructionAddImplicitReturnType>(irb, scope, source_node); 2969 instruction->value = value; 2970 2971 ir_ref_instruction(value, irb->current_basic_block); 2972 2973 return &instruction->base; 2974 } 2975 2976 static IrInstruction *ir_build_merge_err_ret_traces(IrBuilder *irb, Scope *scope, AstNode *source_node, 2977 IrInstruction *coro_promise_ptr, IrInstruction *src_err_ret_trace_ptr, IrInstruction *dest_err_ret_trace_ptr) 2978 { 2979 IrInstructionMergeErrRetTraces *instruction = ir_build_instruction<IrInstructionMergeErrRetTraces>(irb, scope, source_node); 2980 instruction->coro_promise_ptr = coro_promise_ptr; 2981 instruction->src_err_ret_trace_ptr = src_err_ret_trace_ptr; 2982 instruction->dest_err_ret_trace_ptr = dest_err_ret_trace_ptr; 2983 2984 ir_ref_instruction(coro_promise_ptr, irb->current_basic_block); 2985 ir_ref_instruction(src_err_ret_trace_ptr, irb->current_basic_block); 2986 ir_ref_instruction(dest_err_ret_trace_ptr, irb->current_basic_block); 2987 2988 return &instruction->base; 2989 } 2990 2991 static IrInstruction *ir_build_mark_err_ret_trace_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_ret_trace_ptr) { 2992 IrInstructionMarkErrRetTracePtr *instruction = ir_build_instruction<IrInstructionMarkErrRetTracePtr>(irb, scope, source_node); 2993 instruction->err_ret_trace_ptr = err_ret_trace_ptr; 2994 2995 ir_ref_instruction(err_ret_trace_ptr, irb->current_basic_block); 2996 2997 return &instruction->base; 2998 } 2999 3000 static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 3001 IrInstructionSqrt *instruction = ir_build_instruction<IrInstructionSqrt>(irb, scope, source_node); 3002 instruction->type = type; 3003 instruction->op = op; 3004 3005 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 3006 ir_ref_instruction(op, irb->current_basic_block); 3007 3008 return &instruction->base; 3009 } 3010 3011 static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { 3012 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node); 3013 instruction->scope_is_comptime = scope_is_comptime; 3014 instruction->is_comptime = is_comptime; 3015 3016 ir_ref_instruction(scope_is_comptime, irb->current_basic_block); 3017 ir_ref_instruction(is_comptime, irb->current_basic_block); 3018 3019 return &instruction->base; 3020 } 3021 3022 static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { 3023 results[ReturnKindUnconditional] = 0; 3024 results[ReturnKindError] = 0; 3025 3026 Scope *scope = inner_scope; 3027 3028 while (scope != outer_scope) { 3029 assert(scope); 3030 switch (scope->id) { 3031 case ScopeIdDefer: { 3032 AstNode *defer_node = scope->source_node; 3033 assert(defer_node->type == NodeTypeDefer); 3034 ReturnKind defer_kind = defer_node->data.defer.kind; 3035 results[defer_kind] += 1; 3036 scope = scope->parent; 3037 continue; 3038 } 3039 case ScopeIdDecls: 3040 case ScopeIdFnDef: 3041 return; 3042 case ScopeIdBlock: 3043 case ScopeIdVarDecl: 3044 case ScopeIdLoop: 3045 case ScopeIdSuspend: 3046 case ScopeIdCompTime: 3047 case ScopeIdRuntime: 3048 scope = scope->parent; 3049 continue; 3050 case ScopeIdDeferExpr: 3051 case ScopeIdCImport: 3052 case ScopeIdCoroPrelude: 3053 zig_unreachable(); 3054 } 3055 } 3056 } 3057 3058 static IrInstruction *ir_mark_gen(IrInstruction *instruction) { 3059 instruction->is_gen = true; 3060 return instruction; 3061 } 3062 3063 static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers) { 3064 Scope *scope = inner_scope; 3065 bool is_noreturn = false; 3066 while (scope != outer_scope) { 3067 if (!scope) 3068 return is_noreturn; 3069 3070 switch (scope->id) { 3071 case ScopeIdDefer: { 3072 AstNode *defer_node = scope->source_node; 3073 assert(defer_node->type == NodeTypeDefer); 3074 ReturnKind defer_kind = defer_node->data.defer.kind; 3075 if (defer_kind == ReturnKindUnconditional || 3076 (gen_error_defers && defer_kind == ReturnKindError)) 3077 { 3078 AstNode *defer_expr_node = defer_node->data.defer.expr; 3079 Scope *defer_expr_scope = defer_node->data.defer.expr_scope; 3080 IrInstruction *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); 3081 if (defer_expr_value != irb->codegen->invalid_instruction) { 3082 if (defer_expr_value->value.type != nullptr && defer_expr_value->value.type->id == ZigTypeIdUnreachable) { 3083 is_noreturn = true; 3084 } else { 3085 ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, defer_expr_value)); 3086 } 3087 } 3088 } 3089 scope = scope->parent; 3090 continue; 3091 } 3092 case ScopeIdDecls: 3093 case ScopeIdFnDef: 3094 return is_noreturn; 3095 case ScopeIdBlock: 3096 case ScopeIdVarDecl: 3097 case ScopeIdLoop: 3098 case ScopeIdSuspend: 3099 case ScopeIdCompTime: 3100 case ScopeIdRuntime: 3101 scope = scope->parent; 3102 continue; 3103 case ScopeIdDeferExpr: 3104 case ScopeIdCImport: 3105 case ScopeIdCoroPrelude: 3106 zig_unreachable(); 3107 } 3108 } 3109 return is_noreturn; 3110 } 3111 3112 static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { 3113 assert(basic_block); 3114 3115 irb->current_basic_block = basic_block; 3116 } 3117 3118 static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) { 3119 irb->exec->basic_block_list.append(basic_block); 3120 ir_set_cursor_at_end(irb, basic_block); 3121 } 3122 3123 static ScopeSuspend *get_scope_suspend(Scope *scope) { 3124 while (scope) { 3125 if (scope->id == ScopeIdSuspend) 3126 return (ScopeSuspend *)scope; 3127 if (scope->id == ScopeIdFnDef) 3128 return nullptr; 3129 3130 scope = scope->parent; 3131 } 3132 return nullptr; 3133 } 3134 3135 static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { 3136 while (scope) { 3137 if (scope->id == ScopeIdDeferExpr) 3138 return (ScopeDeferExpr *)scope; 3139 if (scope->id == ScopeIdFnDef) 3140 return nullptr; 3141 3142 scope = scope->parent; 3143 } 3144 return nullptr; 3145 } 3146 3147 static bool exec_is_async(IrExecutable *exec) { 3148 ZigFn *fn_entry = exec_fn_entry(exec); 3149 return fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; 3150 } 3151 3152 static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode *node, IrInstruction *return_value, 3153 bool is_generated_code) 3154 { 3155 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value)); 3156 3157 bool is_async = exec_is_async(irb->exec); 3158 if (!is_async) { 3159 IrInstruction *return_inst = ir_build_return(irb, scope, node, return_value); 3160 return_inst->is_gen = is_generated_code; 3161 return return_inst; 3162 } 3163 3164 IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "Suspended"); 3165 IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "NotSuspended"); 3166 IrBasicBlock *store_awaiter_block = ir_create_basic_block(irb, scope, "StoreAwaiter"); 3167 IrBasicBlock *check_canceled_block = ir_create_basic_block(irb, scope, "CheckCanceled"); 3168 3169 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 3170 IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 3171 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 3172 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 3173 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); 3174 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); 3175 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 3176 3177 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_field_ptr, return_value); 3178 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 3179 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 3180 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, ptr_mask, nullptr, 3181 AtomicRmwOp_or, AtomicOrderSeqCst); 3182 3183 IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 3184 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 3185 ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime); 3186 3187 ir_set_cursor_at_end_and_append_block(irb, suspended_block); 3188 ir_build_unreachable(irb, scope, node); 3189 3190 ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); 3191 IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 3192 // if we ever add null checking safety to the ptrtoint instruction, it needs to be disabled here 3193 IrInstruction *have_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); 3194 ir_build_cond_br(irb, scope, node, have_await_handle, store_awaiter_block, check_canceled_block, is_comptime); 3195 3196 ir_set_cursor_at_end_and_append_block(irb, store_awaiter_block); 3197 IrInstruction *await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, await_handle_addr); 3198 ir_build_store_ptr(irb, scope, node, irb->exec->await_handle_var_ptr, await_handle); 3199 ir_build_br(irb, scope, node, irb->exec->coro_normal_final, is_comptime); 3200 3201 ir_set_cursor_at_end_and_append_block(irb, check_canceled_block); 3202 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 3203 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 3204 return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime); 3205 } 3206 3207 static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 3208 assert(node->type == NodeTypeReturnExpr); 3209 3210 ZigFn *fn_entry = exec_fn_entry(irb->exec); 3211 if (!fn_entry) { 3212 add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition")); 3213 return irb->codegen->invalid_instruction; 3214 } 3215 3216 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); 3217 if (scope_defer_expr) { 3218 if (!scope_defer_expr->reported_err) { 3219 add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression")); 3220 scope_defer_expr->reported_err = true; 3221 } 3222 return irb->codegen->invalid_instruction; 3223 } 3224 3225 Scope *outer_scope = irb->exec->begin_scope; 3226 3227 AstNode *expr_node = node->data.return_expr.expr; 3228 switch (node->data.return_expr.kind) { 3229 case ReturnKindUnconditional: 3230 { 3231 IrInstruction *return_value; 3232 if (expr_node) { 3233 // Temporarily set this so that if we return a type it gets the name of the function 3234 ZigFn *prev_name_fn = irb->exec->name_fn; 3235 irb->exec->name_fn = exec_fn_entry(irb->exec); 3236 return_value = ir_gen_node(irb, expr_node, scope); 3237 irb->exec->name_fn = prev_name_fn; 3238 if (return_value == irb->codegen->invalid_instruction) 3239 return irb->codegen->invalid_instruction; 3240 } else { 3241 return_value = ir_build_const_void(irb, scope, node); 3242 } 3243 3244 size_t defer_counts[2]; 3245 ir_count_defers(irb, scope, outer_scope, defer_counts); 3246 bool have_err_defers = defer_counts[ReturnKindError] > 0; 3247 if (have_err_defers || irb->codegen->have_err_ret_tracing) { 3248 IrBasicBlock *err_block = ir_create_basic_block(irb, scope, "ErrRetErr"); 3249 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk"); 3250 if (!have_err_defers) { 3251 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3252 } 3253 3254 IrInstruction *is_err = ir_build_test_err(irb, scope, node, return_value); 3255 3256 bool should_inline = ir_should_inline(irb->exec, scope); 3257 IrInstruction *is_comptime; 3258 if (should_inline) { 3259 is_comptime = ir_build_const_bool(irb, scope, node, true); 3260 } else { 3261 is_comptime = ir_build_test_comptime(irb, scope, node, is_err); 3262 } 3263 3264 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); 3265 IrBasicBlock *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt"); 3266 3267 ir_set_cursor_at_end_and_append_block(irb, err_block); 3268 if (have_err_defers) { 3269 ir_gen_defers_for_block(irb, scope, outer_scope, true); 3270 } 3271 if (irb->codegen->have_err_ret_tracing && !should_inline) { 3272 ir_build_save_err_ret_addr(irb, scope, node); 3273 } 3274 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 3275 3276 ir_set_cursor_at_end_and_append_block(irb, ok_block); 3277 if (have_err_defers) { 3278 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3279 } 3280 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 3281 3282 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); 3283 return ir_gen_async_return(irb, scope, node, return_value, false); 3284 } else { 3285 // generate unconditional defers 3286 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3287 return ir_gen_async_return(irb, scope, node, return_value, false); 3288 } 3289 } 3290 case ReturnKindError: 3291 { 3292 assert(expr_node); 3293 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 3294 if (err_union_ptr == irb->codegen->invalid_instruction) 3295 return irb->codegen->invalid_instruction; 3296 IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr); 3297 IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_val); 3298 3299 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); 3300 IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); 3301 IrInstruction *is_comptime; 3302 bool should_inline = ir_should_inline(irb->exec, scope); 3303 if (should_inline) { 3304 is_comptime = ir_build_const_bool(irb, scope, node, true); 3305 } else { 3306 is_comptime = ir_build_test_comptime(irb, scope, node, is_err_val); 3307 } 3308 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime)); 3309 3310 ir_set_cursor_at_end_and_append_block(irb, return_block); 3311 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { 3312 IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); 3313 if (irb->codegen->have_err_ret_tracing && !should_inline) { 3314 ir_build_save_err_ret_addr(irb, scope, node); 3315 } 3316 ir_gen_async_return(irb, scope, node, err_val, false); 3317 } 3318 3319 ir_set_cursor_at_end_and_append_block(irb, continue_block); 3320 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false); 3321 if (lval == LValPtr) 3322 return unwrapped_ptr; 3323 else 3324 return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); 3325 } 3326 } 3327 zig_unreachable(); 3328 } 3329 3330 static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope, 3331 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime, 3332 bool skip_name_check) 3333 { 3334 ZigVar *variable_entry = allocate<ZigVar>(1); 3335 variable_entry->parent_scope = parent_scope; 3336 variable_entry->shadowable = is_shadowable; 3337 variable_entry->mem_slot_index = SIZE_MAX; 3338 variable_entry->is_comptime = is_comptime; 3339 variable_entry->src_arg_index = SIZE_MAX; 3340 variable_entry->value = create_const_vals(1); 3341 3342 if (name) { 3343 buf_init_from_buf(&variable_entry->name, name); 3344 3345 if (!skip_name_check) { 3346 ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr); 3347 if (existing_var && !existing_var->shadowable) { 3348 ErrorMsg *msg = add_node_error(codegen, node, 3349 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); 3350 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); 3351 variable_entry->value->type = codegen->builtin_types.entry_invalid; 3352 } else { 3353 ZigType *type = get_primitive_type(codegen, name); 3354 if (type != nullptr) { 3355 add_node_error(codegen, node, 3356 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); 3357 variable_entry->value->type = codegen->builtin_types.entry_invalid; 3358 } else { 3359 Tld *tld = find_decl(codegen, parent_scope, name); 3360 if (tld != nullptr) { 3361 ErrorMsg *msg = add_node_error(codegen, node, 3362 buf_sprintf("redefinition of '%s'", buf_ptr(name))); 3363 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); 3364 variable_entry->value->type = codegen->builtin_types.entry_invalid; 3365 } 3366 } 3367 } 3368 } 3369 } else { 3370 assert(is_shadowable); 3371 // TODO make this name not actually be in scope. user should be able to make a variable called "_anon" 3372 // might already be solved, let's just make sure it has test coverage 3373 // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables 3374 buf_init_from_str(&variable_entry->name, "_anon"); 3375 } 3376 3377 variable_entry->src_is_const = src_is_const; 3378 variable_entry->gen_is_const = gen_is_const; 3379 variable_entry->decl_node = node; 3380 variable_entry->child_scope = create_var_scope(node, parent_scope, variable_entry); 3381 3382 return variable_entry; 3383 } 3384 3385 // Set name to nullptr to make the variable anonymous (not visible to programmer). 3386 // After you call this function var->child_scope has the variable in scope 3387 static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name, 3388 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime) 3389 { 3390 bool is_underscored = name ? buf_eql_str(name, "_") : false; 3391 ZigVar *var = create_local_var(irb->codegen, node, scope, 3392 (is_underscored ? nullptr : name), src_is_const, gen_is_const, 3393 (is_underscored ? true : is_shadowable), is_comptime, false); 3394 if (is_comptime != nullptr || gen_is_const) { 3395 var->mem_slot_index = exec_next_mem_slot(irb->exec); 3396 var->owner_exec = irb->exec; 3397 } 3398 assert(var->child_scope); 3399 return var; 3400 } 3401 3402 static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) { 3403 assert(block_node->type == NodeTypeBlock); 3404 3405 ZigList<IrInstruction *> incoming_values = {0}; 3406 ZigList<IrBasicBlock *> incoming_blocks = {0}; 3407 3408 ScopeBlock *scope_block = create_block_scope(block_node, parent_scope); 3409 3410 Scope *outer_block_scope = &scope_block->base; 3411 Scope *child_scope = outer_block_scope; 3412 3413 ZigFn *fn_entry = scope_fn_entry(parent_scope); 3414 if (fn_entry && fn_entry->child_scope == parent_scope) { 3415 fn_entry->def_scope = scope_block; 3416 } 3417 3418 if (block_node->data.block.statements.length == 0) { 3419 // {} 3420 return ir_build_const_void(irb, child_scope, block_node); 3421 } 3422 3423 if (block_node->data.block.name != nullptr) { 3424 scope_block->incoming_blocks = &incoming_blocks; 3425 scope_block->incoming_values = &incoming_values; 3426 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); 3427 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, ir_should_inline(irb->exec, parent_scope)); 3428 } 3429 3430 bool is_continuation_unreachable = false; 3431 IrInstruction *noreturn_return_value = nullptr; 3432 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { 3433 AstNode *statement_node = block_node->data.block.statements.at(i); 3434 3435 IrInstruction *statement_value = ir_gen_node(irb, statement_node, child_scope); 3436 is_continuation_unreachable = instr_is_unreachable(statement_value); 3437 if (is_continuation_unreachable) { 3438 // keep the last noreturn statement value around in case we need to return it 3439 noreturn_return_value = statement_value; 3440 } 3441 if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { 3442 // defer starts a new scope 3443 child_scope = statement_node->data.defer.child_scope; 3444 assert(child_scope); 3445 } else if (statement_value->id == IrInstructionIdDeclVar) { 3446 // variable declarations start a new scope 3447 IrInstructionDeclVar *decl_var_instruction = (IrInstructionDeclVar *)statement_value; 3448 child_scope = decl_var_instruction->var->child_scope; 3449 } else if (statement_value != irb->codegen->invalid_instruction && !is_continuation_unreachable) { 3450 // this statement's value must be void 3451 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); 3452 } 3453 } 3454 3455 if (is_continuation_unreachable) { 3456 assert(noreturn_return_value != nullptr); 3457 if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) { 3458 return noreturn_return_value; 3459 } 3460 3461 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 3462 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 3463 } else { 3464 incoming_blocks.append(irb->current_basic_block); 3465 incoming_values.append(ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node))); 3466 } 3467 3468 if (block_node->data.block.name != nullptr) { 3469 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 3470 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); 3471 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 3472 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 3473 } else { 3474 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 3475 return ir_mark_gen(ir_mark_gen(ir_build_const_void(irb, child_scope, block_node))); 3476 } 3477 } 3478 3479 static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 3480 IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 3481 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3482 3483 if (op1 == irb->codegen->invalid_instruction || op2 == irb->codegen->invalid_instruction) 3484 return irb->codegen->invalid_instruction; 3485 3486 return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 3487 } 3488 3489 static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { 3490 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); 3491 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3492 3493 if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) 3494 return irb->codegen->invalid_instruction; 3495 3496 ir_build_store_ptr(irb, scope, node, lvalue, rvalue); 3497 return ir_build_const_void(irb, scope, node); 3498 } 3499 3500 static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 3501 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); 3502 if (lvalue == irb->codegen->invalid_instruction) 3503 return lvalue; 3504 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 3505 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3506 if (op2 == irb->codegen->invalid_instruction) 3507 return op2; 3508 IrInstruction *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 3509 ir_build_store_ptr(irb, scope, node, lvalue, result); 3510 return ir_build_const_void(irb, scope, node); 3511 } 3512 3513 static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node) { 3514 assert(node->type == NodeTypeBinOpExpr); 3515 3516 IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 3517 if (val1 == irb->codegen->invalid_instruction) 3518 return irb->codegen->invalid_instruction; 3519 IrBasicBlock *post_val1_block = irb->current_basic_block; 3520 3521 IrInstruction *is_comptime; 3522 if (ir_should_inline(irb->exec, scope)) { 3523 is_comptime = ir_build_const_bool(irb, scope, node, true); 3524 } else { 3525 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 3526 } 3527 3528 // block for when val1 == false 3529 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse"); 3530 // block for when val1 == true (don't even evaluate the second part) 3531 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue"); 3532 3533 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 3534 3535 ir_set_cursor_at_end_and_append_block(irb, false_block); 3536 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3537 if (val2 == irb->codegen->invalid_instruction) 3538 return irb->codegen->invalid_instruction; 3539 IrBasicBlock *post_val2_block = irb->current_basic_block; 3540 3541 ir_build_br(irb, scope, node, true_block, is_comptime); 3542 3543 ir_set_cursor_at_end_and_append_block(irb, true_block); 3544 3545 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 3546 incoming_values[0] = val1; 3547 incoming_values[1] = val2; 3548 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 3549 incoming_blocks[0] = post_val1_block; 3550 incoming_blocks[1] = post_val2_block; 3551 3552 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 3553 } 3554 3555 static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { 3556 assert(node->type == NodeTypeBinOpExpr); 3557 3558 IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 3559 if (val1 == irb->codegen->invalid_instruction) 3560 return irb->codegen->invalid_instruction; 3561 IrBasicBlock *post_val1_block = irb->current_basic_block; 3562 3563 IrInstruction *is_comptime; 3564 if (ir_should_inline(irb->exec, scope)) { 3565 is_comptime = ir_build_const_bool(irb, scope, node, true); 3566 } else { 3567 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 3568 } 3569 3570 // block for when val1 == true 3571 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue"); 3572 // block for when val1 == false (don't even evaluate the second part) 3573 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse"); 3574 3575 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 3576 3577 ir_set_cursor_at_end_and_append_block(irb, true_block); 3578 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3579 if (val2 == irb->codegen->invalid_instruction) 3580 return irb->codegen->invalid_instruction; 3581 IrBasicBlock *post_val2_block = irb->current_basic_block; 3582 3583 ir_build_br(irb, scope, node, false_block, is_comptime); 3584 3585 ir_set_cursor_at_end_and_append_block(irb, false_block); 3586 3587 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 3588 incoming_values[0] = val1; 3589 incoming_values[1] = val2; 3590 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 3591 incoming_blocks[0] = post_val1_block; 3592 incoming_blocks[1] = post_val2_block; 3593 3594 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 3595 } 3596 3597 static IrInstruction *ir_gen_maybe_ok_or(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 3598 assert(node->type == NodeTypeBinOpExpr); 3599 3600 AstNode *op1_node = node->data.bin_op_expr.op1; 3601 AstNode *op2_node = node->data.bin_op_expr.op2; 3602 3603 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); 3604 if (maybe_ptr == irb->codegen->invalid_instruction) 3605 return irb->codegen->invalid_instruction; 3606 3607 IrInstruction *maybe_val = ir_build_load_ptr(irb, parent_scope, node, maybe_ptr); 3608 IrInstruction *is_non_null = ir_build_test_nonnull(irb, parent_scope, node, maybe_val); 3609 3610 IrInstruction *is_comptime; 3611 if (ir_should_inline(irb->exec, parent_scope)) { 3612 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 3613 } else { 3614 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_non_null); 3615 } 3616 3617 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); 3618 IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); 3619 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); 3620 ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); 3621 3622 ir_set_cursor_at_end_and_append_block(irb, null_block); 3623 IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope); 3624 if (null_result == irb->codegen->invalid_instruction) 3625 return irb->codegen->invalid_instruction; 3626 IrBasicBlock *after_null_block = irb->current_basic_block; 3627 if (!instr_is_unreachable(null_result)) 3628 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 3629 3630 ir_set_cursor_at_end_and_append_block(irb, ok_block); 3631 IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, parent_scope, node, maybe_ptr, false); 3632 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 3633 IrBasicBlock *after_ok_block = irb->current_basic_block; 3634 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 3635 3636 ir_set_cursor_at_end_and_append_block(irb, end_block); 3637 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 3638 incoming_values[0] = null_result; 3639 incoming_values[1] = unwrapped_payload; 3640 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 3641 incoming_blocks[0] = after_null_block; 3642 incoming_blocks[1] = after_ok_block; 3643 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); 3644 } 3645 3646 static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 3647 assert(node->type == NodeTypeBinOpExpr); 3648 3649 AstNode *op1_node = node->data.bin_op_expr.op1; 3650 AstNode *op2_node = node->data.bin_op_expr.op2; 3651 3652 IrInstruction *err_set = ir_gen_node(irb, op1_node, parent_scope); 3653 if (err_set == irb->codegen->invalid_instruction) 3654 return irb->codegen->invalid_instruction; 3655 3656 IrInstruction *payload = ir_gen_node(irb, op2_node, parent_scope); 3657 if (payload == irb->codegen->invalid_instruction) 3658 return irb->codegen->invalid_instruction; 3659 3660 return ir_build_error_union(irb, parent_scope, node, err_set, payload); 3661 } 3662 3663 static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) { 3664 assert(node->type == NodeTypeBinOpExpr); 3665 3666 BinOpType bin_op_type = node->data.bin_op_expr.bin_op; 3667 switch (bin_op_type) { 3668 case BinOpTypeInvalid: 3669 zig_unreachable(); 3670 case BinOpTypeAssign: 3671 return ir_gen_assign(irb, scope, node); 3672 case BinOpTypeAssignTimes: 3673 return ir_gen_assign_op(irb, scope, node, IrBinOpMult); 3674 case BinOpTypeAssignTimesWrap: 3675 return ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap); 3676 case BinOpTypeAssignDiv: 3677 return ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified); 3678 case BinOpTypeAssignMod: 3679 return ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified); 3680 case BinOpTypeAssignPlus: 3681 return ir_gen_assign_op(irb, scope, node, IrBinOpAdd); 3682 case BinOpTypeAssignPlusWrap: 3683 return ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap); 3684 case BinOpTypeAssignMinus: 3685 return ir_gen_assign_op(irb, scope, node, IrBinOpSub); 3686 case BinOpTypeAssignMinusWrap: 3687 return ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap); 3688 case BinOpTypeAssignBitShiftLeft: 3689 return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy); 3690 case BinOpTypeAssignBitShiftRight: 3691 return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy); 3692 case BinOpTypeAssignBitAnd: 3693 return ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd); 3694 case BinOpTypeAssignBitXor: 3695 return ir_gen_assign_op(irb, scope, node, IrBinOpBinXor); 3696 case BinOpTypeAssignBitOr: 3697 return ir_gen_assign_op(irb, scope, node, IrBinOpBinOr); 3698 case BinOpTypeAssignMergeErrorSets: 3699 return ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets); 3700 case BinOpTypeBoolOr: 3701 return ir_gen_bool_or(irb, scope, node); 3702 case BinOpTypeBoolAnd: 3703 return ir_gen_bool_and(irb, scope, node); 3704 case BinOpTypeCmpEq: 3705 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq); 3706 case BinOpTypeCmpNotEq: 3707 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq); 3708 case BinOpTypeCmpLessThan: 3709 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan); 3710 case BinOpTypeCmpGreaterThan: 3711 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan); 3712 case BinOpTypeCmpLessOrEq: 3713 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq); 3714 case BinOpTypeCmpGreaterOrEq: 3715 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq); 3716 case BinOpTypeBinOr: 3717 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr); 3718 case BinOpTypeBinXor: 3719 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor); 3720 case BinOpTypeBinAnd: 3721 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd); 3722 case BinOpTypeBitShiftLeft: 3723 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy); 3724 case BinOpTypeBitShiftRight: 3725 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy); 3726 case BinOpTypeAdd: 3727 return ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd); 3728 case BinOpTypeAddWrap: 3729 return ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap); 3730 case BinOpTypeSub: 3731 return ir_gen_bin_op_id(irb, scope, node, IrBinOpSub); 3732 case BinOpTypeSubWrap: 3733 return ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap); 3734 case BinOpTypeMult: 3735 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMult); 3736 case BinOpTypeMultWrap: 3737 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap); 3738 case BinOpTypeDiv: 3739 return ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified); 3740 case BinOpTypeMod: 3741 return ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified); 3742 case BinOpTypeArrayCat: 3743 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat); 3744 case BinOpTypeArrayMult: 3745 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult); 3746 case BinOpTypeMergeErrorSets: 3747 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets); 3748 case BinOpTypeUnwrapOptional: 3749 return ir_gen_maybe_ok_or(irb, scope, node); 3750 case BinOpTypeErrorUnion: 3751 return ir_gen_error_union(irb, scope, node); 3752 } 3753 zig_unreachable(); 3754 } 3755 3756 static IrInstruction *ir_gen_int_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 3757 assert(node->type == NodeTypeIntLiteral); 3758 3759 return ir_build_const_bigint(irb, scope, node, node->data.int_literal.bigint); 3760 } 3761 3762 static IrInstruction *ir_gen_float_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 3763 assert(node->type == NodeTypeFloatLiteral); 3764 3765 if (node->data.float_literal.overflow) { 3766 add_node_error(irb->codegen, node, buf_sprintf("float literal out of range of any type")); 3767 return irb->codegen->invalid_instruction; 3768 } 3769 3770 return ir_build_const_bigfloat(irb, scope, node, node->data.float_literal.bigfloat); 3771 } 3772 3773 static IrInstruction *ir_gen_char_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 3774 assert(node->type == NodeTypeCharLiteral); 3775 3776 return ir_build_const_uint(irb, scope, node, node->data.char_literal.value); 3777 } 3778 3779 static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 3780 assert(node->type == NodeTypeNullLiteral); 3781 3782 return ir_build_const_null(irb, scope, node); 3783 } 3784 3785 static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 3786 assert(node->type == NodeTypeSymbol); 3787 3788 Buf *variable_name = node->data.symbol_expr.symbol; 3789 3790 if (buf_eql_str(variable_name, "_") && lval == LValPtr) { 3791 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node); 3792 const_instruction->base.value.type = get_pointer_to_type(irb->codegen, 3793 irb->codegen->builtin_types.entry_void, false); 3794 const_instruction->base.value.special = ConstValSpecialStatic; 3795 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard; 3796 return &const_instruction->base; 3797 } 3798 3799 ZigType *primitive_type = get_primitive_type(irb->codegen, variable_name); 3800 if (primitive_type != nullptr) { 3801 IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_type); 3802 if (lval == LValPtr) { 3803 return ir_build_ref(irb, scope, node, value, false, false); 3804 } else { 3805 return value; 3806 } 3807 } 3808 3809 ScopeFnDef *crossed_fndef_scope; 3810 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); 3811 if (var) { 3812 IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); 3813 if (lval == LValPtr) 3814 return var_ptr; 3815 else 3816 return ir_build_load_ptr(irb, scope, node, var_ptr); 3817 } 3818 3819 Tld *tld = find_decl(irb->codegen, scope, variable_name); 3820 if (tld) 3821 return ir_build_decl_ref(irb, scope, node, tld, lval); 3822 3823 if (node->owner->any_imports_failed) { 3824 // skip the error message since we had a failing import in this file 3825 // if an import breaks we don't need redundant undeclared identifier errors 3826 return irb->codegen->invalid_instruction; 3827 } 3828 3829 // TODO put a variable of same name with invalid type in global scope 3830 // so that future references to this same name will find a variable with an invalid type 3831 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); 3832 return irb->codegen->invalid_instruction; 3833 } 3834 3835 static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 3836 assert(node->type == NodeTypeArrayAccessExpr); 3837 3838 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; 3839 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr); 3840 if (array_ref_instruction == irb->codegen->invalid_instruction) 3841 return array_ref_instruction; 3842 3843 AstNode *subscript_node = node->data.array_access_expr.subscript; 3844 IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, scope); 3845 if (subscript_instruction == irb->codegen->invalid_instruction) 3846 return subscript_instruction; 3847 3848 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, 3849 subscript_instruction, true, PtrLenSingle); 3850 if (lval == LValPtr) 3851 return ptr_instruction; 3852 3853 return ir_build_load_ptr(irb, scope, node, ptr_instruction); 3854 } 3855 3856 static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) { 3857 assert(node->type == NodeTypeFieldAccessExpr); 3858 3859 AstNode *container_ref_node = node->data.field_access_expr.struct_expr; 3860 Buf *field_name = node->data.field_access_expr.field_name; 3861 3862 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr); 3863 if (container_ref_instruction == irb->codegen->invalid_instruction) 3864 return container_ref_instruction; 3865 3866 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name); 3867 } 3868 3869 static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) { 3870 assert(node->type == NodeTypeFnCallExpr); 3871 3872 AstNode *type_node = node->data.fn_call_expr.params.at(0); 3873 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 3874 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 3875 AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3); 3876 3877 3878 IrInstruction *type_value = ir_gen_node(irb, type_node, scope); 3879 if (type_value == irb->codegen->invalid_instruction) 3880 return irb->codegen->invalid_instruction; 3881 3882 IrInstruction *op1 = ir_gen_node(irb, op1_node, scope); 3883 if (op1 == irb->codegen->invalid_instruction) 3884 return irb->codegen->invalid_instruction; 3885 3886 IrInstruction *op2 = ir_gen_node(irb, op2_node, scope); 3887 if (op2 == irb->codegen->invalid_instruction) 3888 return irb->codegen->invalid_instruction; 3889 3890 IrInstruction *result_ptr = ir_gen_node(irb, result_ptr_node, scope); 3891 if (result_ptr == irb->codegen->invalid_instruction) 3892 return irb->codegen->invalid_instruction; 3893 3894 return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr); 3895 } 3896 3897 static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 3898 assert(node->type == NodeTypeFnCallExpr); 3899 3900 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; 3901 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 3902 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 3903 3904 if (!entry) { 3905 add_node_error(irb->codegen, node, 3906 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name))); 3907 return irb->codegen->invalid_instruction; 3908 } 3909 3910 BuiltinFnEntry *builtin_fn = entry->value; 3911 size_t actual_param_count = node->data.fn_call_expr.params.length; 3912 3913 if (builtin_fn->param_count != SIZE_MAX && builtin_fn->param_count != actual_param_count) { 3914 add_node_error(irb->codegen, node, 3915 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 3916 builtin_fn->param_count, actual_param_count)); 3917 return irb->codegen->invalid_instruction; 3918 } 3919 3920 bool is_async = exec_is_async(irb->exec); 3921 3922 switch (builtin_fn->id) { 3923 case BuiltinFnIdInvalid: 3924 zig_unreachable(); 3925 case BuiltinFnIdTypeof: 3926 { 3927 AstNode *arg_node = node->data.fn_call_expr.params.at(0); 3928 IrInstruction *arg = ir_gen_node(irb, arg_node, scope); 3929 if (arg == irb->codegen->invalid_instruction) 3930 return arg; 3931 3932 IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); 3933 return ir_lval_wrap(irb, scope, type_of, lval); 3934 } 3935 case BuiltinFnIdSetCold: 3936 { 3937 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3938 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3939 if (arg0_value == irb->codegen->invalid_instruction) 3940 return arg0_value; 3941 3942 IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); 3943 return ir_lval_wrap(irb, scope, set_cold, lval); 3944 } 3945 case BuiltinFnIdSetRuntimeSafety: 3946 { 3947 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3948 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3949 if (arg0_value == irb->codegen->invalid_instruction) 3950 return arg0_value; 3951 3952 IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); 3953 return ir_lval_wrap(irb, scope, set_safety, lval); 3954 } 3955 case BuiltinFnIdSetFloatMode: 3956 { 3957 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3958 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3959 if (arg0_value == irb->codegen->invalid_instruction) 3960 return arg0_value; 3961 3962 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 3963 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 3964 if (arg1_value == irb->codegen->invalid_instruction) 3965 return arg1_value; 3966 3967 IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value, arg1_value); 3968 return ir_lval_wrap(irb, scope, set_float_mode, lval); 3969 } 3970 case BuiltinFnIdSizeof: 3971 { 3972 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3973 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3974 if (arg0_value == irb->codegen->invalid_instruction) 3975 return arg0_value; 3976 3977 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); 3978 return ir_lval_wrap(irb, scope, size_of, lval); 3979 } 3980 case BuiltinFnIdCtz: 3981 { 3982 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3983 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3984 if (arg0_value == irb->codegen->invalid_instruction) 3985 return arg0_value; 3986 3987 IrInstruction *ctz = ir_build_ctz(irb, scope, node, arg0_value); 3988 return ir_lval_wrap(irb, scope, ctz, lval); 3989 } 3990 case BuiltinFnIdPopCount: 3991 { 3992 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3993 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3994 if (arg0_value == irb->codegen->invalid_instruction) 3995 return arg0_value; 3996 3997 IrInstruction *instr = ir_build_pop_count(irb, scope, node, arg0_value); 3998 return ir_lval_wrap(irb, scope, instr, lval); 3999 } 4000 case BuiltinFnIdClz: 4001 { 4002 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4003 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4004 if (arg0_value == irb->codegen->invalid_instruction) 4005 return arg0_value; 4006 4007 IrInstruction *clz = ir_build_clz(irb, scope, node, arg0_value); 4008 return ir_lval_wrap(irb, scope, clz, lval); 4009 } 4010 case BuiltinFnIdImport: 4011 { 4012 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4013 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4014 if (arg0_value == irb->codegen->invalid_instruction) 4015 return arg0_value; 4016 4017 IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); 4018 return ir_lval_wrap(irb, scope, import, lval); 4019 } 4020 case BuiltinFnIdCImport: 4021 { 4022 IrInstruction *c_import = ir_build_c_import(irb, scope, node); 4023 return ir_lval_wrap(irb, scope, c_import, lval); 4024 } 4025 case BuiltinFnIdCInclude: 4026 { 4027 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4028 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4029 if (arg0_value == irb->codegen->invalid_instruction) 4030 return arg0_value; 4031 4032 if (!exec_c_import_buf(irb->exec)) { 4033 add_node_error(irb->codegen, node, buf_sprintf("C include valid only inside C import block")); 4034 return irb->codegen->invalid_instruction; 4035 } 4036 4037 IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value); 4038 return ir_lval_wrap(irb, scope, c_include, lval); 4039 } 4040 case BuiltinFnIdCDefine: 4041 { 4042 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4043 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4044 if (arg0_value == irb->codegen->invalid_instruction) 4045 return arg0_value; 4046 4047 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4048 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4049 if (arg1_value == irb->codegen->invalid_instruction) 4050 return arg1_value; 4051 4052 if (!exec_c_import_buf(irb->exec)) { 4053 add_node_error(irb->codegen, node, buf_sprintf("C define valid only inside C import block")); 4054 return irb->codegen->invalid_instruction; 4055 } 4056 4057 IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); 4058 return ir_lval_wrap(irb, scope, c_define, lval); 4059 } 4060 case BuiltinFnIdCUndef: 4061 { 4062 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4063 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4064 if (arg0_value == irb->codegen->invalid_instruction) 4065 return arg0_value; 4066 4067 if (!exec_c_import_buf(irb->exec)) { 4068 add_node_error(irb->codegen, node, buf_sprintf("C undef valid only inside C import block")); 4069 return irb->codegen->invalid_instruction; 4070 } 4071 4072 IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); 4073 return ir_lval_wrap(irb, scope, c_undef, lval); 4074 } 4075 case BuiltinFnIdMaxValue: 4076 { 4077 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4078 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4079 if (arg0_value == irb->codegen->invalid_instruction) 4080 return arg0_value; 4081 4082 IrInstruction *max_value = ir_build_max_value(irb, scope, node, arg0_value); 4083 return ir_lval_wrap(irb, scope, max_value, lval); 4084 } 4085 case BuiltinFnIdMinValue: 4086 { 4087 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4088 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4089 if (arg0_value == irb->codegen->invalid_instruction) 4090 return arg0_value; 4091 4092 IrInstruction *min_value = ir_build_min_value(irb, scope, node, arg0_value); 4093 return ir_lval_wrap(irb, scope, min_value, lval); 4094 } 4095 case BuiltinFnIdCompileErr: 4096 { 4097 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4098 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4099 if (arg0_value == irb->codegen->invalid_instruction) 4100 return arg0_value; 4101 4102 IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); 4103 return ir_lval_wrap(irb, scope, compile_err, lval); 4104 } 4105 case BuiltinFnIdCompileLog: 4106 { 4107 IrInstruction **args = allocate<IrInstruction*>(actual_param_count); 4108 4109 for (size_t i = 0; i < actual_param_count; i += 1) { 4110 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 4111 args[i] = ir_gen_node(irb, arg_node, scope); 4112 if (args[i] == irb->codegen->invalid_instruction) 4113 return irb->codegen->invalid_instruction; 4114 } 4115 4116 IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); 4117 return ir_lval_wrap(irb, scope, compile_log, lval); 4118 } 4119 case BuiltinFnIdErrName: 4120 { 4121 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4122 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4123 if (arg0_value == irb->codegen->invalid_instruction) 4124 return arg0_value; 4125 4126 IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value); 4127 return ir_lval_wrap(irb, scope, err_name, lval); 4128 } 4129 case BuiltinFnIdEmbedFile: 4130 { 4131 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4132 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4133 if (arg0_value == irb->codegen->invalid_instruction) 4134 return arg0_value; 4135 4136 IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); 4137 return ir_lval_wrap(irb, scope, embed_file, lval); 4138 } 4139 case BuiltinFnIdCmpxchgWeak: 4140 case BuiltinFnIdCmpxchgStrong: 4141 { 4142 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4143 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4144 if (arg0_value == irb->codegen->invalid_instruction) 4145 return arg0_value; 4146 4147 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4148 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4149 if (arg1_value == irb->codegen->invalid_instruction) 4150 return arg1_value; 4151 4152 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4153 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4154 if (arg2_value == irb->codegen->invalid_instruction) 4155 return arg2_value; 4156 4157 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 4158 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 4159 if (arg3_value == irb->codegen->invalid_instruction) 4160 return arg3_value; 4161 4162 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 4163 IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); 4164 if (arg4_value == irb->codegen->invalid_instruction) 4165 return arg4_value; 4166 4167 AstNode *arg5_node = node->data.fn_call_expr.params.at(5); 4168 IrInstruction *arg5_value = ir_gen_node(irb, arg5_node, scope); 4169 if (arg5_value == irb->codegen->invalid_instruction) 4170 return arg5_value; 4171 4172 IrInstruction *cmpxchg = ir_build_cmpxchg(irb, scope, node, arg0_value, arg1_value, 4173 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak), 4174 nullptr, AtomicOrderUnordered, AtomicOrderUnordered); 4175 return ir_lval_wrap(irb, scope, cmpxchg, lval); 4176 } 4177 case BuiltinFnIdFence: 4178 { 4179 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4180 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4181 if (arg0_value == irb->codegen->invalid_instruction) 4182 return arg0_value; 4183 4184 IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); 4185 return ir_lval_wrap(irb, scope, fence, lval); 4186 } 4187 case BuiltinFnIdDivExact: 4188 { 4189 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4190 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4191 if (arg0_value == irb->codegen->invalid_instruction) 4192 return arg0_value; 4193 4194 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4195 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4196 if (arg1_value == irb->codegen->invalid_instruction) 4197 return arg1_value; 4198 4199 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); 4200 return ir_lval_wrap(irb, scope, bin_op, lval); 4201 } 4202 case BuiltinFnIdDivTrunc: 4203 { 4204 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4205 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4206 if (arg0_value == irb->codegen->invalid_instruction) 4207 return arg0_value; 4208 4209 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4210 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4211 if (arg1_value == irb->codegen->invalid_instruction) 4212 return arg1_value; 4213 4214 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); 4215 return ir_lval_wrap(irb, scope, bin_op, lval); 4216 } 4217 case BuiltinFnIdDivFloor: 4218 { 4219 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4220 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4221 if (arg0_value == irb->codegen->invalid_instruction) 4222 return arg0_value; 4223 4224 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4225 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4226 if (arg1_value == irb->codegen->invalid_instruction) 4227 return arg1_value; 4228 4229 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); 4230 return ir_lval_wrap(irb, scope, bin_op, lval); 4231 } 4232 case BuiltinFnIdRem: 4233 { 4234 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4235 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4236 if (arg0_value == irb->codegen->invalid_instruction) 4237 return arg0_value; 4238 4239 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4240 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4241 if (arg1_value == irb->codegen->invalid_instruction) 4242 return arg1_value; 4243 4244 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); 4245 return ir_lval_wrap(irb, scope, bin_op, lval); 4246 } 4247 case BuiltinFnIdMod: 4248 { 4249 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4250 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4251 if (arg0_value == irb->codegen->invalid_instruction) 4252 return arg0_value; 4253 4254 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4255 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4256 if (arg1_value == irb->codegen->invalid_instruction) 4257 return arg1_value; 4258 4259 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); 4260 return ir_lval_wrap(irb, scope, bin_op, lval); 4261 } 4262 case BuiltinFnIdSqrt: 4263 { 4264 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4265 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4266 if (arg0_value == irb->codegen->invalid_instruction) 4267 return arg0_value; 4268 4269 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4270 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4271 if (arg1_value == irb->codegen->invalid_instruction) 4272 return arg1_value; 4273 4274 IrInstruction *ir_sqrt = ir_build_sqrt(irb, scope, node, arg0_value, arg1_value); 4275 return ir_lval_wrap(irb, scope, ir_sqrt, lval); 4276 } 4277 case BuiltinFnIdTruncate: 4278 { 4279 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4280 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4281 if (arg0_value == irb->codegen->invalid_instruction) 4282 return arg0_value; 4283 4284 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4285 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4286 if (arg1_value == irb->codegen->invalid_instruction) 4287 return arg1_value; 4288 4289 IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); 4290 return ir_lval_wrap(irb, scope, truncate, lval); 4291 } 4292 case BuiltinFnIdIntCast: 4293 { 4294 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4295 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4296 if (arg0_value == irb->codegen->invalid_instruction) 4297 return arg0_value; 4298 4299 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4300 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4301 if (arg1_value == irb->codegen->invalid_instruction) 4302 return arg1_value; 4303 4304 IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); 4305 return ir_lval_wrap(irb, scope, result, lval); 4306 } 4307 case BuiltinFnIdFloatCast: 4308 { 4309 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4310 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4311 if (arg0_value == irb->codegen->invalid_instruction) 4312 return arg0_value; 4313 4314 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4315 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4316 if (arg1_value == irb->codegen->invalid_instruction) 4317 return arg1_value; 4318 4319 IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); 4320 return ir_lval_wrap(irb, scope, result, lval); 4321 } 4322 case BuiltinFnIdErrSetCast: 4323 { 4324 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4325 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4326 if (arg0_value == irb->codegen->invalid_instruction) 4327 return arg0_value; 4328 4329 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4330 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4331 if (arg1_value == irb->codegen->invalid_instruction) 4332 return arg1_value; 4333 4334 IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); 4335 return ir_lval_wrap(irb, scope, result, lval); 4336 } 4337 case BuiltinFnIdFromBytes: 4338 { 4339 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4340 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4341 if (arg0_value == irb->codegen->invalid_instruction) 4342 return arg0_value; 4343 4344 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4345 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4346 if (arg1_value == irb->codegen->invalid_instruction) 4347 return arg1_value; 4348 4349 IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value); 4350 return ir_lval_wrap(irb, scope, result, lval); 4351 } 4352 case BuiltinFnIdToBytes: 4353 { 4354 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4355 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4356 if (arg0_value == irb->codegen->invalid_instruction) 4357 return arg0_value; 4358 4359 IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value); 4360 return ir_lval_wrap(irb, scope, result, lval); 4361 } 4362 case BuiltinFnIdIntToFloat: 4363 { 4364 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4365 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4366 if (arg0_value == irb->codegen->invalid_instruction) 4367 return arg0_value; 4368 4369 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4370 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4371 if (arg1_value == irb->codegen->invalid_instruction) 4372 return arg1_value; 4373 4374 IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); 4375 return ir_lval_wrap(irb, scope, result, lval); 4376 } 4377 case BuiltinFnIdFloatToInt: 4378 { 4379 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4380 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4381 if (arg0_value == irb->codegen->invalid_instruction) 4382 return arg0_value; 4383 4384 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4385 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4386 if (arg1_value == irb->codegen->invalid_instruction) 4387 return arg1_value; 4388 4389 IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); 4390 return ir_lval_wrap(irb, scope, result, lval); 4391 } 4392 case BuiltinFnIdErrToInt: 4393 { 4394 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4395 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4396 if (arg0_value == irb->codegen->invalid_instruction) 4397 return arg0_value; 4398 4399 IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value); 4400 return ir_lval_wrap(irb, scope, result, lval); 4401 } 4402 case BuiltinFnIdIntToErr: 4403 { 4404 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4405 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4406 if (arg0_value == irb->codegen->invalid_instruction) 4407 return arg0_value; 4408 4409 IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value); 4410 return ir_lval_wrap(irb, scope, result, lval); 4411 } 4412 case BuiltinFnIdBoolToInt: 4413 { 4414 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4415 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4416 if (arg0_value == irb->codegen->invalid_instruction) 4417 return arg0_value; 4418 4419 IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value); 4420 return ir_lval_wrap(irb, scope, result, lval); 4421 } 4422 case BuiltinFnIdIntType: 4423 { 4424 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4425 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4426 if (arg0_value == irb->codegen->invalid_instruction) 4427 return arg0_value; 4428 4429 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4430 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4431 if (arg1_value == irb->codegen->invalid_instruction) 4432 return arg1_value; 4433 4434 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); 4435 return ir_lval_wrap(irb, scope, int_type, lval); 4436 } 4437 case BuiltinFnIdMemcpy: 4438 { 4439 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4440 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4441 if (arg0_value == irb->codegen->invalid_instruction) 4442 return arg0_value; 4443 4444 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4445 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4446 if (arg1_value == irb->codegen->invalid_instruction) 4447 return arg1_value; 4448 4449 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4450 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4451 if (arg2_value == irb->codegen->invalid_instruction) 4452 return arg2_value; 4453 4454 IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value); 4455 return ir_lval_wrap(irb, scope, ir_memcpy, lval); 4456 } 4457 case BuiltinFnIdMemset: 4458 { 4459 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4460 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4461 if (arg0_value == irb->codegen->invalid_instruction) 4462 return arg0_value; 4463 4464 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4465 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4466 if (arg1_value == irb->codegen->invalid_instruction) 4467 return arg1_value; 4468 4469 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4470 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4471 if (arg2_value == irb->codegen->invalid_instruction) 4472 return arg2_value; 4473 4474 IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value); 4475 return ir_lval_wrap(irb, scope, ir_memset, lval); 4476 } 4477 case BuiltinFnIdMemberCount: 4478 { 4479 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4480 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4481 if (arg0_value == irb->codegen->invalid_instruction) 4482 return arg0_value; 4483 4484 IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value); 4485 return ir_lval_wrap(irb, scope, member_count, lval); 4486 } 4487 case BuiltinFnIdMemberType: 4488 { 4489 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4490 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4491 if (arg0_value == irb->codegen->invalid_instruction) 4492 return arg0_value; 4493 4494 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4495 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4496 if (arg1_value == irb->codegen->invalid_instruction) 4497 return arg1_value; 4498 4499 4500 IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value); 4501 return ir_lval_wrap(irb, scope, member_type, lval); 4502 } 4503 case BuiltinFnIdMemberName: 4504 { 4505 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4506 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4507 if (arg0_value == irb->codegen->invalid_instruction) 4508 return arg0_value; 4509 4510 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4511 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4512 if (arg1_value == irb->codegen->invalid_instruction) 4513 return arg1_value; 4514 4515 4516 IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value); 4517 return ir_lval_wrap(irb, scope, member_name, lval); 4518 } 4519 case BuiltinFnIdField: 4520 { 4521 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4522 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr); 4523 if (arg0_value == irb->codegen->invalid_instruction) 4524 return arg0_value; 4525 4526 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4527 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4528 if (arg1_value == irb->codegen->invalid_instruction) 4529 return arg1_value; 4530 4531 IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value); 4532 4533 if (lval == LValPtr) 4534 return ptr_instruction; 4535 4536 return ir_build_load_ptr(irb, scope, node, ptr_instruction); 4537 } 4538 case BuiltinFnIdTypeInfo: 4539 { 4540 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4541 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4542 if (arg0_value == irb->codegen->invalid_instruction) 4543 return arg0_value; 4544 4545 IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); 4546 return ir_lval_wrap(irb, scope, type_info, lval); 4547 } 4548 case BuiltinFnIdBreakpoint: 4549 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval); 4550 case BuiltinFnIdReturnAddress: 4551 return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval); 4552 case BuiltinFnIdFrameAddress: 4553 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval); 4554 case BuiltinFnIdHandle: 4555 if (!irb->exec->fn_entry) { 4556 add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition")); 4557 return irb->codegen->invalid_instruction; 4558 } 4559 if (!is_async) { 4560 add_node_error(irb->codegen, node, buf_sprintf("@handle() in non-async function")); 4561 return irb->codegen->invalid_instruction; 4562 } 4563 return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval); 4564 case BuiltinFnIdAlignOf: 4565 { 4566 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4567 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4568 if (arg0_value == irb->codegen->invalid_instruction) 4569 return arg0_value; 4570 4571 IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value); 4572 return ir_lval_wrap(irb, scope, align_of, lval); 4573 } 4574 case BuiltinFnIdAddWithOverflow: 4575 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval); 4576 case BuiltinFnIdSubWithOverflow: 4577 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval); 4578 case BuiltinFnIdMulWithOverflow: 4579 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval); 4580 case BuiltinFnIdShlWithOverflow: 4581 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval); 4582 case BuiltinFnIdTypeName: 4583 { 4584 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4585 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4586 if (arg0_value == irb->codegen->invalid_instruction) 4587 return arg0_value; 4588 4589 IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value); 4590 return ir_lval_wrap(irb, scope, type_name, lval); 4591 } 4592 case BuiltinFnIdPanic: 4593 { 4594 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4595 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4596 if (arg0_value == irb->codegen->invalid_instruction) 4597 return arg0_value; 4598 4599 IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); 4600 return ir_lval_wrap(irb, scope, panic, lval); 4601 } 4602 case BuiltinFnIdPtrCast: 4603 { 4604 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4605 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4606 if (arg0_value == irb->codegen->invalid_instruction) 4607 return arg0_value; 4608 4609 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4610 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4611 if (arg1_value == irb->codegen->invalid_instruction) 4612 return arg1_value; 4613 4614 IrInstruction *ptr_cast = ir_build_ptr_cast(irb, scope, node, arg0_value, arg1_value); 4615 return ir_lval_wrap(irb, scope, ptr_cast, lval); 4616 } 4617 case BuiltinFnIdBitCast: 4618 { 4619 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4620 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4621 if (arg0_value == irb->codegen->invalid_instruction) 4622 return arg0_value; 4623 4624 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4625 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4626 if (arg1_value == irb->codegen->invalid_instruction) 4627 return arg1_value; 4628 4629 IrInstruction *bit_cast = ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value); 4630 return ir_lval_wrap(irb, scope, bit_cast, lval); 4631 } 4632 case BuiltinFnIdIntToPtr: 4633 { 4634 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4635 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4636 if (arg0_value == irb->codegen->invalid_instruction) 4637 return arg0_value; 4638 4639 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4640 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4641 if (arg1_value == irb->codegen->invalid_instruction) 4642 return arg1_value; 4643 4644 IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value); 4645 return ir_lval_wrap(irb, scope, int_to_ptr, lval); 4646 } 4647 case BuiltinFnIdPtrToInt: 4648 { 4649 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4650 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4651 if (arg0_value == irb->codegen->invalid_instruction) 4652 return arg0_value; 4653 4654 IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value); 4655 return ir_lval_wrap(irb, scope, ptr_to_int, lval); 4656 } 4657 case BuiltinFnIdTagName: 4658 { 4659 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4660 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4661 if (arg0_value == irb->codegen->invalid_instruction) 4662 return arg0_value; 4663 4664 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value); 4665 IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag); 4666 return ir_lval_wrap(irb, scope, tag_name, lval); 4667 } 4668 case BuiltinFnIdTagType: 4669 { 4670 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4671 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4672 if (arg0_value == irb->codegen->invalid_instruction) 4673 return arg0_value; 4674 4675 IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); 4676 return ir_lval_wrap(irb, scope, tag_type, lval); 4677 } 4678 case BuiltinFnIdFieldParentPtr: 4679 { 4680 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4681 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4682 if (arg0_value == irb->codegen->invalid_instruction) 4683 return arg0_value; 4684 4685 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4686 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4687 if (arg1_value == irb->codegen->invalid_instruction) 4688 return arg1_value; 4689 4690 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4691 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4692 if (arg2_value == irb->codegen->invalid_instruction) 4693 return arg2_value; 4694 4695 IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr); 4696 return ir_lval_wrap(irb, scope, field_parent_ptr, lval); 4697 } 4698 case BuiltinFnIdOffsetOf: 4699 { 4700 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4701 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4702 if (arg0_value == irb->codegen->invalid_instruction) 4703 return arg0_value; 4704 4705 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4706 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4707 if (arg1_value == irb->codegen->invalid_instruction) 4708 return arg1_value; 4709 4710 IrInstruction *offset_of = ir_build_offset_of(irb, scope, node, arg0_value, arg1_value); 4711 return ir_lval_wrap(irb, scope, offset_of, lval); 4712 } 4713 case BuiltinFnIdInlineCall: 4714 case BuiltinFnIdNoInlineCall: 4715 { 4716 if (node->data.fn_call_expr.params.length == 0) { 4717 add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0")); 4718 return irb->codegen->invalid_instruction; 4719 } 4720 4721 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(0); 4722 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 4723 if (fn_ref == irb->codegen->invalid_instruction) 4724 return fn_ref; 4725 4726 size_t arg_count = node->data.fn_call_expr.params.length - 1; 4727 4728 IrInstruction **args = allocate<IrInstruction*>(arg_count); 4729 for (size_t i = 0; i < arg_count; i += 1) { 4730 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 1); 4731 args[i] = ir_gen_node(irb, arg_node, scope); 4732 if (args[i] == irb->codegen->invalid_instruction) 4733 return args[i]; 4734 } 4735 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; 4736 4737 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr); 4738 return ir_lval_wrap(irb, scope, call, lval); 4739 } 4740 case BuiltinFnIdNewStackCall: 4741 { 4742 if (node->data.fn_call_expr.params.length == 0) { 4743 add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0")); 4744 return irb->codegen->invalid_instruction; 4745 } 4746 4747 AstNode *new_stack_node = node->data.fn_call_expr.params.at(0); 4748 IrInstruction *new_stack = ir_gen_node(irb, new_stack_node, scope); 4749 if (new_stack == irb->codegen->invalid_instruction) 4750 return new_stack; 4751 4752 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); 4753 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 4754 if (fn_ref == irb->codegen->invalid_instruction) 4755 return fn_ref; 4756 4757 size_t arg_count = node->data.fn_call_expr.params.length - 2; 4758 4759 IrInstruction **args = allocate<IrInstruction*>(arg_count); 4760 for (size_t i = 0; i < arg_count; i += 1) { 4761 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 2); 4762 args[i] = ir_gen_node(irb, arg_node, scope); 4763 if (args[i] == irb->codegen->invalid_instruction) 4764 return args[i]; 4765 } 4766 4767 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack); 4768 return ir_lval_wrap(irb, scope, call, lval); 4769 } 4770 case BuiltinFnIdTypeId: 4771 { 4772 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4773 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4774 if (arg0_value == irb->codegen->invalid_instruction) 4775 return arg0_value; 4776 4777 IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value); 4778 return ir_lval_wrap(irb, scope, type_id, lval); 4779 } 4780 case BuiltinFnIdShlExact: 4781 { 4782 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4783 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4784 if (arg0_value == irb->codegen->invalid_instruction) 4785 return arg0_value; 4786 4787 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4788 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4789 if (arg1_value == irb->codegen->invalid_instruction) 4790 return arg1_value; 4791 4792 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); 4793 return ir_lval_wrap(irb, scope, bin_op, lval); 4794 } 4795 case BuiltinFnIdShrExact: 4796 { 4797 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4798 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4799 if (arg0_value == irb->codegen->invalid_instruction) 4800 return arg0_value; 4801 4802 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4803 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4804 if (arg1_value == irb->codegen->invalid_instruction) 4805 return arg1_value; 4806 4807 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); 4808 return ir_lval_wrap(irb, scope, bin_op, lval); 4809 } 4810 case BuiltinFnIdSetEvalBranchQuota: 4811 { 4812 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4813 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4814 if (arg0_value == irb->codegen->invalid_instruction) 4815 return arg0_value; 4816 4817 IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); 4818 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval); 4819 } 4820 case BuiltinFnIdAlignCast: 4821 { 4822 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4823 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4824 if (arg0_value == irb->codegen->invalid_instruction) 4825 return arg0_value; 4826 4827 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4828 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4829 if (arg1_value == irb->codegen->invalid_instruction) 4830 return arg1_value; 4831 4832 IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value); 4833 return ir_lval_wrap(irb, scope, align_cast, lval); 4834 } 4835 case BuiltinFnIdOpaqueType: 4836 { 4837 IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); 4838 return ir_lval_wrap(irb, scope, opaque_type, lval); 4839 } 4840 case BuiltinFnIdSetAlignStack: 4841 { 4842 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4843 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4844 if (arg0_value == irb->codegen->invalid_instruction) 4845 return arg0_value; 4846 4847 IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); 4848 return ir_lval_wrap(irb, scope, set_align_stack, lval); 4849 } 4850 case BuiltinFnIdArgType: 4851 { 4852 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4853 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4854 if (arg0_value == irb->codegen->invalid_instruction) 4855 return arg0_value; 4856 4857 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4858 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4859 if (arg1_value == irb->codegen->invalid_instruction) 4860 return arg1_value; 4861 4862 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); 4863 return ir_lval_wrap(irb, scope, arg_type, lval); 4864 } 4865 case BuiltinFnIdExport: 4866 { 4867 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4868 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4869 if (arg0_value == irb->codegen->invalid_instruction) 4870 return arg0_value; 4871 4872 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4873 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4874 if (arg1_value == irb->codegen->invalid_instruction) 4875 return arg1_value; 4876 4877 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4878 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4879 if (arg2_value == irb->codegen->invalid_instruction) 4880 return arg2_value; 4881 4882 IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); 4883 return ir_lval_wrap(irb, scope, ir_export, lval); 4884 } 4885 case BuiltinFnIdErrorReturnTrace: 4886 { 4887 IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null); 4888 return ir_lval_wrap(irb, scope, error_return_trace, lval); 4889 } 4890 case BuiltinFnIdAtomicRmw: 4891 { 4892 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4893 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4894 if (arg0_value == irb->codegen->invalid_instruction) 4895 return arg0_value; 4896 4897 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4898 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4899 if (arg1_value == irb->codegen->invalid_instruction) 4900 return arg1_value; 4901 4902 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4903 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4904 if (arg2_value == irb->codegen->invalid_instruction) 4905 return arg2_value; 4906 4907 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 4908 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 4909 if (arg3_value == irb->codegen->invalid_instruction) 4910 return arg3_value; 4911 4912 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 4913 IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); 4914 if (arg4_value == irb->codegen->invalid_instruction) 4915 return arg4_value; 4916 4917 return ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, 4918 arg4_value, 4919 // these 2 values don't mean anything since we passed non-null values for other args 4920 AtomicRmwOp_xchg, AtomicOrderMonotonic); 4921 } 4922 case BuiltinFnIdAtomicLoad: 4923 { 4924 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4925 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4926 if (arg0_value == irb->codegen->invalid_instruction) 4927 return arg0_value; 4928 4929 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4930 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4931 if (arg1_value == irb->codegen->invalid_instruction) 4932 return arg1_value; 4933 4934 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4935 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4936 if (arg2_value == irb->codegen->invalid_instruction) 4937 return arg2_value; 4938 4939 return ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, 4940 // this value does not mean anything since we passed non-null values for other arg 4941 AtomicOrderMonotonic); 4942 } 4943 case BuiltinFnIdIntToEnum: 4944 { 4945 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4946 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4947 if (arg0_value == irb->codegen->invalid_instruction) 4948 return arg0_value; 4949 4950 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4951 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4952 if (arg1_value == irb->codegen->invalid_instruction) 4953 return arg1_value; 4954 4955 IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value); 4956 return ir_lval_wrap(irb, scope, result, lval); 4957 } 4958 case BuiltinFnIdEnumToInt: 4959 { 4960 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4961 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4962 if (arg0_value == irb->codegen->invalid_instruction) 4963 return arg0_value; 4964 4965 IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); 4966 return ir_lval_wrap(irb, scope, result, lval); 4967 } 4968 } 4969 zig_unreachable(); 4970 } 4971 4972 static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 4973 assert(node->type == NodeTypeFnCallExpr); 4974 4975 if (node->data.fn_call_expr.is_builtin) 4976 return ir_gen_builtin_fn_call(irb, scope, node, lval); 4977 4978 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; 4979 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 4980 if (fn_ref == irb->codegen->invalid_instruction) 4981 return fn_ref; 4982 4983 size_t arg_count = node->data.fn_call_expr.params.length; 4984 IrInstruction **args = allocate<IrInstruction*>(arg_count); 4985 for (size_t i = 0; i < arg_count; i += 1) { 4986 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 4987 args[i] = ir_gen_node(irb, arg_node, scope); 4988 if (args[i] == irb->codegen->invalid_instruction) 4989 return args[i]; 4990 } 4991 4992 bool is_async = node->data.fn_call_expr.is_async; 4993 IrInstruction *async_allocator = nullptr; 4994 if (is_async) { 4995 if (node->data.fn_call_expr.async_allocator) { 4996 async_allocator = ir_gen_node(irb, node->data.fn_call_expr.async_allocator, scope); 4997 if (async_allocator == irb->codegen->invalid_instruction) 4998 return async_allocator; 4999 } 5000 } 5001 5002 IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, is_async, async_allocator, nullptr); 5003 return ir_lval_wrap(irb, scope, fn_call, lval); 5004 } 5005 5006 static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5007 assert(node->type == NodeTypeIfBoolExpr); 5008 5009 IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); 5010 if (condition == irb->codegen->invalid_instruction) 5011 return condition; 5012 5013 IrInstruction *is_comptime; 5014 if (ir_should_inline(irb->exec, scope)) { 5015 is_comptime = ir_build_const_bool(irb, scope, node, true); 5016 } else { 5017 is_comptime = ir_build_test_comptime(irb, scope, node, condition); 5018 } 5019 5020 AstNode *then_node = node->data.if_bool_expr.then_block; 5021 AstNode *else_node = node->data.if_bool_expr.else_node; 5022 5023 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "Then"); 5024 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); 5025 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); 5026 5027 ir_build_cond_br(irb, scope, condition->source_node, condition, then_block, else_block, is_comptime); 5028 5029 ir_set_cursor_at_end_and_append_block(irb, then_block); 5030 5031 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); 5032 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope); 5033 if (then_expr_result == irb->codegen->invalid_instruction) 5034 return then_expr_result; 5035 IrBasicBlock *after_then_block = irb->current_basic_block; 5036 if (!instr_is_unreachable(then_expr_result)) 5037 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5038 5039 ir_set_cursor_at_end_and_append_block(irb, else_block); 5040 IrInstruction *else_expr_result; 5041 if (else_node) { 5042 else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); 5043 if (else_expr_result == irb->codegen->invalid_instruction) 5044 return else_expr_result; 5045 } else { 5046 else_expr_result = ir_build_const_void(irb, scope, node); 5047 } 5048 IrBasicBlock *after_else_block = irb->current_basic_block; 5049 if (!instr_is_unreachable(else_expr_result)) 5050 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5051 5052 ir_set_cursor_at_end_and_append_block(irb, endif_block); 5053 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 5054 incoming_values[0] = then_expr_result; 5055 incoming_values[1] = else_expr_result; 5056 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 5057 incoming_blocks[0] = after_then_block; 5058 incoming_blocks[1] = after_else_block; 5059 5060 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 5061 } 5062 5063 static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { 5064 assert(node->type == NodeTypePrefixOpExpr); 5065 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 5066 5067 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); 5068 if (value == irb->codegen->invalid_instruction) 5069 return value; 5070 5071 return ir_build_un_op(irb, scope, node, op_id, value); 5072 } 5073 5074 static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id) { 5075 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); 5076 } 5077 5078 static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval) { 5079 if (lval != LValPtr) 5080 return value; 5081 if (value == irb->codegen->invalid_instruction) 5082 return value; 5083 5084 // We needed a pointer to a value, but we got a value. So we create 5085 // an instruction which just makes a const pointer of it. 5086 return ir_build_ref(irb, scope, value->source_node, value, false, false); 5087 } 5088 5089 static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) { 5090 assert(node->type == NodeTypePointerType); 5091 PtrLen ptr_len = (node->data.pointer_type.star_token->id == TokenIdStar || 5092 node->data.pointer_type.star_token->id == TokenIdStarStar) ? PtrLenSingle : PtrLenUnknown; 5093 bool is_const = node->data.pointer_type.is_const; 5094 bool is_volatile = node->data.pointer_type.is_volatile; 5095 AstNode *expr_node = node->data.pointer_type.op_expr; 5096 AstNode *align_expr = node->data.pointer_type.align_expr; 5097 5098 IrInstruction *align_value; 5099 if (align_expr != nullptr) { 5100 align_value = ir_gen_node(irb, align_expr, scope); 5101 if (align_value == irb->codegen->invalid_instruction) 5102 return align_value; 5103 } else { 5104 align_value = nullptr; 5105 } 5106 5107 IrInstruction *child_type = ir_gen_node(irb, expr_node, scope); 5108 if (child_type == irb->codegen->invalid_instruction) 5109 return child_type; 5110 5111 uint32_t bit_offset_start = 0; 5112 if (node->data.pointer_type.bit_offset_start != nullptr) { 5113 if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_start, 32, false)) { 5114 Buf *val_buf = buf_alloc(); 5115 bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10); 5116 exec_add_error_node(irb->codegen, irb->exec, node, 5117 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); 5118 return irb->codegen->invalid_instruction; 5119 } 5120 bit_offset_start = bigint_as_unsigned(node->data.pointer_type.bit_offset_start); 5121 } 5122 5123 uint32_t bit_offset_end = 0; 5124 if (node->data.pointer_type.bit_offset_end != nullptr) { 5125 if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_end, 32, false)) { 5126 Buf *val_buf = buf_alloc(); 5127 bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_end, 10); 5128 exec_add_error_node(irb->codegen, irb->exec, node, 5129 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); 5130 return irb->codegen->invalid_instruction; 5131 } 5132 bit_offset_end = bigint_as_unsigned(node->data.pointer_type.bit_offset_end); 5133 } 5134 5135 if ((bit_offset_start != 0 || bit_offset_end != 0) && bit_offset_start >= bit_offset_end) { 5136 exec_add_error_node(irb->codegen, irb->exec, node, 5137 buf_sprintf("bit offset start must be less than bit offset end")); 5138 return irb->codegen->invalid_instruction; 5139 } 5140 5141 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, 5142 ptr_len, align_value, bit_offset_start, bit_offset_end); 5143 } 5144 5145 static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node, 5146 LVal lval) 5147 { 5148 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 5149 if (err_union_ptr == irb->codegen->invalid_instruction) 5150 return irb->codegen->invalid_instruction; 5151 5152 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true); 5153 if (payload_ptr == irb->codegen->invalid_instruction) 5154 return irb->codegen->invalid_instruction; 5155 5156 if (lval == LValPtr) 5157 return payload_ptr; 5158 5159 return ir_build_load_ptr(irb, scope, source_node, payload_ptr); 5160 } 5161 5162 static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) { 5163 assert(node->type == NodeTypePrefixOpExpr); 5164 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 5165 5166 IrInstruction *value = ir_gen_node(irb, expr_node, scope); 5167 if (value == irb->codegen->invalid_instruction) 5168 return irb->codegen->invalid_instruction; 5169 5170 return ir_build_bool_not(irb, scope, node, value); 5171 } 5172 5173 static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 5174 assert(node->type == NodeTypePrefixOpExpr); 5175 5176 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; 5177 5178 switch (prefix_op) { 5179 case PrefixOpInvalid: 5180 zig_unreachable(); 5181 case PrefixOpBoolNot: 5182 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval); 5183 case PrefixOpBinNot: 5184 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval); 5185 case PrefixOpNegation: 5186 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval); 5187 case PrefixOpNegationWrap: 5188 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval); 5189 case PrefixOpOptional: 5190 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval); 5191 case PrefixOpAddrOf: { 5192 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 5193 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval); 5194 } 5195 } 5196 zig_unreachable(); 5197 } 5198 5199 static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5200 assert(node->type == NodeTypeContainerInitExpr); 5201 5202 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; 5203 ContainerInitKind kind = container_init_expr->kind; 5204 5205 IrInstruction *container_type = ir_gen_node(irb, container_init_expr->type, scope); 5206 if (container_type == irb->codegen->invalid_instruction) 5207 return container_type; 5208 5209 if (kind == ContainerInitKindStruct) { 5210 size_t field_count = container_init_expr->entries.length; 5211 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); 5212 for (size_t i = 0; i < field_count; i += 1) { 5213 AstNode *entry_node = container_init_expr->entries.at(i); 5214 assert(entry_node->type == NodeTypeStructValueField); 5215 5216 Buf *name = entry_node->data.struct_val_field.name; 5217 AstNode *expr_node = entry_node->data.struct_val_field.expr; 5218 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); 5219 if (expr_value == irb->codegen->invalid_instruction) 5220 return expr_value; 5221 5222 fields[i].name = name; 5223 fields[i].value = expr_value; 5224 fields[i].source_node = entry_node; 5225 } 5226 return ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields); 5227 } else if (kind == ContainerInitKindArray) { 5228 size_t item_count = container_init_expr->entries.length; 5229 IrInstruction **values = allocate<IrInstruction *>(item_count); 5230 for (size_t i = 0; i < item_count; i += 1) { 5231 AstNode *expr_node = container_init_expr->entries.at(i); 5232 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); 5233 if (expr_value == irb->codegen->invalid_instruction) 5234 return expr_value; 5235 5236 values[i] = expr_value; 5237 } 5238 return ir_build_container_init_list(irb, scope, node, container_type, item_count, values); 5239 } else { 5240 zig_unreachable(); 5241 } 5242 } 5243 5244 static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) { 5245 assert(node->type == NodeTypeVariableDeclaration); 5246 5247 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; 5248 5249 if (buf_eql_str(variable_declaration->symbol, "_")) { 5250 add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol")); 5251 return irb->codegen->invalid_instruction; 5252 } 5253 5254 IrInstruction *type_instruction; 5255 if (variable_declaration->type != nullptr) { 5256 type_instruction = ir_gen_node(irb, variable_declaration->type, scope); 5257 if (type_instruction == irb->codegen->invalid_instruction) 5258 return type_instruction; 5259 } else { 5260 type_instruction = nullptr; 5261 } 5262 5263 bool is_shadowable = false; 5264 bool is_const = variable_declaration->is_const; 5265 bool is_extern = variable_declaration->is_extern; 5266 5267 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, 5268 ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime); 5269 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, 5270 is_const, is_const, is_shadowable, is_comptime); 5271 // we detect IrInstructionIdDeclVar in gen_block to make sure the next node 5272 // is inside var->child_scope 5273 5274 if (!is_extern && !variable_declaration->expr) { 5275 var->value->type = irb->codegen->builtin_types.entry_invalid; 5276 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); 5277 return irb->codegen->invalid_instruction; 5278 } 5279 5280 IrInstruction *align_value = nullptr; 5281 if (variable_declaration->align_expr != nullptr) { 5282 align_value = ir_gen_node(irb, variable_declaration->align_expr, scope); 5283 if (align_value == irb->codegen->invalid_instruction) 5284 return align_value; 5285 } 5286 5287 if (variable_declaration->section_expr != nullptr) { 5288 add_node_error(irb->codegen, variable_declaration->section_expr, 5289 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol))); 5290 } 5291 5292 // Temporarily set the name of the IrExecutable to the VariableDeclaration 5293 // so that the struct or enum from the init expression inherits the name. 5294 Buf *old_exec_name = irb->exec->name; 5295 irb->exec->name = variable_declaration->symbol; 5296 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope); 5297 irb->exec->name = old_exec_name; 5298 5299 if (init_value == irb->codegen->invalid_instruction) 5300 return init_value; 5301 5302 return ir_build_var_decl(irb, scope, node, var, type_instruction, align_value, init_value); 5303 } 5304 5305 static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5306 assert(node->type == NodeTypeWhileExpr); 5307 5308 AstNode *continue_expr_node = node->data.while_expr.continue_expr; 5309 AstNode *else_node = node->data.while_expr.else_node; 5310 5311 IrBasicBlock *cond_block = ir_create_basic_block(irb, scope, "WhileCond"); 5312 IrBasicBlock *body_block = ir_create_basic_block(irb, scope, "WhileBody"); 5313 IrBasicBlock *continue_block = continue_expr_node ? 5314 ir_create_basic_block(irb, scope, "WhileContinue") : cond_block; 5315 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "WhileEnd"); 5316 IrBasicBlock *else_block = else_node ? 5317 ir_create_basic_block(irb, scope, "WhileElse") : end_block; 5318 5319 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, 5320 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline); 5321 ir_build_br(irb, scope, node, cond_block, is_comptime); 5322 5323 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); 5324 Buf *var_symbol = node->data.while_expr.var_symbol; 5325 Buf *err_symbol = node->data.while_expr.err_symbol; 5326 if (err_symbol != nullptr) { 5327 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5328 5329 Scope *payload_scope; 5330 AstNode *symbol_node = node; // TODO make more accurate 5331 ZigVar *payload_var; 5332 if (var_symbol) { 5333 // TODO make it an error to write to payload variable 5334 payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 5335 true, false, false, is_comptime); 5336 payload_scope = payload_var->child_scope; 5337 } else { 5338 payload_scope = subexpr_scope; 5339 } 5340 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); 5341 if (err_val_ptr == irb->codegen->invalid_instruction) 5342 return err_val_ptr; 5343 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr); 5344 IrInstruction *is_err = ir_build_test_err(irb, scope, node->data.while_expr.condition, err_val); 5345 IrBasicBlock *after_cond_block = irb->current_basic_block; 5346 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 5347 if (!instr_is_unreachable(is_err)) { 5348 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, 5349 else_block, body_block, is_comptime)); 5350 } 5351 5352 ir_set_cursor_at_end_and_append_block(irb, body_block); 5353 if (var_symbol) { 5354 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, 5355 err_val_ptr, false); 5356 IrInstruction *var_value = node->data.while_expr.var_is_ptr ? 5357 var_ptr_value : ir_build_load_ptr(irb, payload_scope, symbol_node, var_ptr_value); 5358 ir_build_var_decl(irb, payload_scope, symbol_node, payload_var, nullptr, nullptr, var_value); 5359 } 5360 5361 ZigList<IrInstruction *> incoming_values = {0}; 5362 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5363 5364 ScopeLoop *loop_scope = create_loop_scope(node, payload_scope); 5365 loop_scope->break_block = end_block; 5366 loop_scope->continue_block = continue_block; 5367 loop_scope->is_comptime = is_comptime; 5368 loop_scope->incoming_blocks = &incoming_blocks; 5369 loop_scope->incoming_values = &incoming_values; 5370 5371 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 5372 if (body_result == irb->codegen->invalid_instruction) 5373 return body_result; 5374 5375 if (!instr_is_unreachable(body_result)) { 5376 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result)); 5377 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime)); 5378 } 5379 5380 if (continue_expr_node) { 5381 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5382 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope); 5383 if (expr_result == irb->codegen->invalid_instruction) 5384 return expr_result; 5385 if (!instr_is_unreachable(expr_result)) 5386 ir_mark_gen(ir_build_br(irb, payload_scope, node, cond_block, is_comptime)); 5387 } 5388 5389 IrInstruction *else_result = nullptr; 5390 if (else_node) { 5391 ir_set_cursor_at_end_and_append_block(irb, else_block); 5392 5393 // TODO make it an error to write to error variable 5394 AstNode *err_symbol_node = else_node; // TODO make more accurate 5395 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, 5396 true, false, false, is_comptime); 5397 Scope *err_scope = err_var->child_scope; 5398 IrInstruction *err_var_value = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); 5399 ir_build_var_decl(irb, err_scope, symbol_node, err_var, nullptr, nullptr, err_var_value); 5400 5401 else_result = ir_gen_node(irb, else_node, err_scope); 5402 if (else_result == irb->codegen->invalid_instruction) 5403 return else_result; 5404 if (!instr_is_unreachable(else_result)) 5405 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 5406 } 5407 IrBasicBlock *after_else_block = irb->current_basic_block; 5408 ir_set_cursor_at_end_and_append_block(irb, end_block); 5409 if (else_result) { 5410 incoming_blocks.append(after_else_block); 5411 incoming_values.append(else_result); 5412 } else { 5413 incoming_blocks.append(after_cond_block); 5414 incoming_values.append(void_else_result); 5415 } 5416 5417 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5418 } else if (var_symbol != nullptr) { 5419 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5420 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); 5421 // TODO make it an error to write to payload variable 5422 AstNode *symbol_node = node; // TODO make more accurate 5423 5424 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 5425 true, false, false, is_comptime); 5426 Scope *child_scope = payload_var->child_scope; 5427 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); 5428 if (maybe_val_ptr == irb->codegen->invalid_instruction) 5429 return maybe_val_ptr; 5430 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); 5431 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); 5432 IrBasicBlock *after_cond_block = irb->current_basic_block; 5433 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 5434 if (!instr_is_unreachable(is_non_null)) { 5435 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, 5436 body_block, else_block, is_comptime)); 5437 } 5438 5439 ir_set_cursor_at_end_and_append_block(irb, body_block); 5440 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, child_scope, symbol_node, maybe_val_ptr, false); 5441 IrInstruction *var_value = node->data.while_expr.var_is_ptr ? 5442 var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value); 5443 ir_build_var_decl(irb, child_scope, symbol_node, payload_var, nullptr, nullptr, var_value); 5444 5445 ZigList<IrInstruction *> incoming_values = {0}; 5446 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5447 5448 ScopeLoop *loop_scope = create_loop_scope(node, child_scope); 5449 loop_scope->break_block = end_block; 5450 loop_scope->continue_block = continue_block; 5451 loop_scope->is_comptime = is_comptime; 5452 loop_scope->incoming_blocks = &incoming_blocks; 5453 loop_scope->incoming_values = &incoming_values; 5454 5455 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 5456 if (body_result == irb->codegen->invalid_instruction) 5457 return body_result; 5458 5459 if (!instr_is_unreachable(body_result)) { 5460 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result)); 5461 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 5462 } 5463 5464 if (continue_expr_node) { 5465 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5466 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, child_scope); 5467 if (expr_result == irb->codegen->invalid_instruction) 5468 return expr_result; 5469 if (!instr_is_unreachable(expr_result)) 5470 ir_mark_gen(ir_build_br(irb, child_scope, node, cond_block, is_comptime)); 5471 } 5472 5473 IrInstruction *else_result = nullptr; 5474 if (else_node) { 5475 ir_set_cursor_at_end_and_append_block(irb, else_block); 5476 5477 else_result = ir_gen_node(irb, else_node, scope); 5478 if (else_result == irb->codegen->invalid_instruction) 5479 return else_result; 5480 if (!instr_is_unreachable(else_result)) 5481 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 5482 } 5483 IrBasicBlock *after_else_block = irb->current_basic_block; 5484 ir_set_cursor_at_end_and_append_block(irb, end_block); 5485 if (else_result) { 5486 incoming_blocks.append(after_else_block); 5487 incoming_values.append(else_result); 5488 } else { 5489 incoming_blocks.append(after_cond_block); 5490 incoming_values.append(void_else_result); 5491 } 5492 5493 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5494 } else { 5495 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5496 IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); 5497 if (cond_val == irb->codegen->invalid_instruction) 5498 return cond_val; 5499 IrBasicBlock *after_cond_block = irb->current_basic_block; 5500 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 5501 if (!instr_is_unreachable(cond_val)) { 5502 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, 5503 body_block, else_block, is_comptime)); 5504 } 5505 5506 ir_set_cursor_at_end_and_append_block(irb, body_block); 5507 5508 ZigList<IrInstruction *> incoming_values = {0}; 5509 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5510 5511 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); 5512 5513 ScopeLoop *loop_scope = create_loop_scope(node, subexpr_scope); 5514 loop_scope->break_block = end_block; 5515 loop_scope->continue_block = continue_block; 5516 loop_scope->is_comptime = is_comptime; 5517 loop_scope->incoming_blocks = &incoming_blocks; 5518 loop_scope->incoming_values = &incoming_values; 5519 5520 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 5521 if (body_result == irb->codegen->invalid_instruction) 5522 return body_result; 5523 5524 if (!instr_is_unreachable(body_result)) { 5525 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result)); 5526 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime)); 5527 } 5528 5529 if (continue_expr_node) { 5530 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5531 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, subexpr_scope); 5532 if (expr_result == irb->codegen->invalid_instruction) 5533 return expr_result; 5534 if (!instr_is_unreachable(expr_result)) 5535 ir_mark_gen(ir_build_br(irb, scope, node, cond_block, is_comptime)); 5536 } 5537 5538 IrInstruction *else_result = nullptr; 5539 if (else_node) { 5540 ir_set_cursor_at_end_and_append_block(irb, else_block); 5541 5542 else_result = ir_gen_node(irb, else_node, subexpr_scope); 5543 if (else_result == irb->codegen->invalid_instruction) 5544 return else_result; 5545 if (!instr_is_unreachable(else_result)) 5546 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 5547 } 5548 IrBasicBlock *after_else_block = irb->current_basic_block; 5549 ir_set_cursor_at_end_and_append_block(irb, end_block); 5550 if (else_result) { 5551 incoming_blocks.append(after_else_block); 5552 incoming_values.append(else_result); 5553 } else { 5554 incoming_blocks.append(after_cond_block); 5555 incoming_values.append(void_else_result); 5556 } 5557 5558 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5559 } 5560 } 5561 5562 static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 5563 assert(node->type == NodeTypeForExpr); 5564 5565 AstNode *array_node = node->data.for_expr.array_expr; 5566 AstNode *elem_node = node->data.for_expr.elem_node; 5567 AstNode *index_node = node->data.for_expr.index_node; 5568 AstNode *body_node = node->data.for_expr.body; 5569 AstNode *else_node = node->data.for_expr.else_node; 5570 5571 if (!elem_node) { 5572 add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter")); 5573 return irb->codegen->invalid_instruction; 5574 } 5575 assert(elem_node->type == NodeTypeSymbol); 5576 5577 IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr); 5578 if (array_val_ptr == irb->codegen->invalid_instruction) 5579 return array_val_ptr; 5580 5581 IrInstruction *array_val = ir_build_load_ptr(irb, parent_scope, array_node, array_val_ptr); 5582 5583 IrInstruction *pointer_type = ir_build_to_ptr_type(irb, parent_scope, array_node, array_val); 5584 IrInstruction *elem_var_type; 5585 if (node->data.for_expr.elem_is_ptr) { 5586 elem_var_type = pointer_type; 5587 } else { 5588 elem_var_type = ir_build_ptr_type_child(irb, parent_scope, elem_node, pointer_type); 5589 } 5590 5591 IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, 5592 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); 5593 5594 // TODO make it an error to write to element variable or i variable. 5595 Buf *elem_var_name = elem_node->data.symbol_expr.symbol; 5596 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); 5597 Scope *child_scope = elem_var->child_scope; 5598 5599 IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node); 5600 ir_build_var_decl(irb, child_scope, elem_node, elem_var, elem_var_type, nullptr, undefined_value); 5601 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var); 5602 5603 AstNode *index_var_source_node; 5604 ZigVar *index_var; 5605 if (index_node) { 5606 index_var_source_node = index_node; 5607 Buf *index_var_name = index_node->data.symbol_expr.symbol; 5608 index_var = ir_create_var(irb, index_node, child_scope, index_var_name, true, false, false, is_comptime); 5609 } else { 5610 index_var_source_node = node; 5611 index_var = ir_create_var(irb, node, child_scope, nullptr, true, false, true, is_comptime); 5612 } 5613 child_scope = index_var->child_scope; 5614 5615 IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize); 5616 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0); 5617 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1); 5618 ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, nullptr, zero); 5619 IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var); 5620 5621 5622 IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond"); 5623 IrBasicBlock *body_block = ir_create_basic_block(irb, child_scope, "ForBody"); 5624 IrBasicBlock *end_block = ir_create_basic_block(irb, child_scope, "ForEnd"); 5625 IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, child_scope, "ForElse") : end_block; 5626 IrBasicBlock *continue_block = ir_create_basic_block(irb, child_scope, "ForContinue"); 5627 5628 IrInstruction *len_val = ir_build_array_len(irb, child_scope, node, array_val); 5629 ir_build_br(irb, child_scope, node, cond_block, is_comptime); 5630 5631 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5632 IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr); 5633 IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); 5634 IrBasicBlock *after_cond_block = irb->current_basic_block; 5635 IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); 5636 ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime)); 5637 5638 ir_set_cursor_at_end_and_append_block(irb, body_block); 5639 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false, PtrLenSingle); 5640 IrInstruction *elem_val; 5641 if (node->data.for_expr.elem_is_ptr) { 5642 elem_val = elem_ptr; 5643 } else { 5644 elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr); 5645 } 5646 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val)); 5647 5648 ZigList<IrInstruction *> incoming_values = {0}; 5649 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5650 ScopeLoop *loop_scope = create_loop_scope(node, child_scope); 5651 loop_scope->break_block = end_block; 5652 loop_scope->continue_block = continue_block; 5653 loop_scope->is_comptime = is_comptime; 5654 loop_scope->incoming_blocks = &incoming_blocks; 5655 loop_scope->incoming_values = &incoming_values; 5656 5657 IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base); 5658 5659 if (!instr_is_unreachable(body_result)) 5660 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 5661 5662 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5663 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); 5664 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)); 5665 ir_build_br(irb, child_scope, node, cond_block, is_comptime); 5666 5667 IrInstruction *else_result = nullptr; 5668 if (else_node) { 5669 ir_set_cursor_at_end_and_append_block(irb, else_block); 5670 5671 else_result = ir_gen_node(irb, else_node, parent_scope); 5672 if (else_result == irb->codegen->invalid_instruction) 5673 return else_result; 5674 if (!instr_is_unreachable(else_result)) 5675 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 5676 } 5677 IrBasicBlock *after_else_block = irb->current_basic_block; 5678 ir_set_cursor_at_end_and_append_block(irb, end_block); 5679 5680 if (else_result) { 5681 incoming_blocks.append(after_else_block); 5682 incoming_values.append(else_result); 5683 } else { 5684 incoming_blocks.append(after_cond_block); 5685 incoming_values.append(void_else_value); 5686 } 5687 5688 return ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5689 } 5690 5691 static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 5692 assert(node->type == NodeTypeThisLiteral); 5693 5694 if (!scope->parent) 5695 return ir_build_const_import(irb, scope, node, node->owner); 5696 5697 ZigFn *fn_entry = scope_get_fn_if_root(scope); 5698 if (fn_entry) 5699 return ir_build_const_fn(irb, scope, node, fn_entry); 5700 5701 while (scope->id != ScopeIdBlock && scope->id != ScopeIdDecls) { 5702 scope = scope->parent; 5703 } 5704 5705 if (scope->id == ScopeIdDecls) { 5706 ScopeDecls *decls_scope = (ScopeDecls *)scope; 5707 ZigType *container_type = decls_scope->container_type; 5708 assert(container_type); 5709 return ir_build_const_type(irb, scope, node, container_type); 5710 } 5711 5712 if (scope->id == ScopeIdBlock) 5713 return ir_build_const_scope(irb, scope, node, scope); 5714 5715 zig_unreachable(); 5716 } 5717 5718 static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 5719 assert(node->type == NodeTypeBoolLiteral); 5720 return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value); 5721 } 5722 5723 static IrInstruction *ir_gen_string_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 5724 assert(node->type == NodeTypeStringLiteral); 5725 5726 if (node->data.string_literal.c) { 5727 return ir_build_const_c_str_lit(irb, scope, node, node->data.string_literal.buf); 5728 } else { 5729 return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf); 5730 } 5731 } 5732 5733 static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *node) { 5734 assert(node->type == NodeTypeArrayType); 5735 5736 AstNode *size_node = node->data.array_type.size; 5737 AstNode *child_type_node = node->data.array_type.child_type; 5738 bool is_const = node->data.array_type.is_const; 5739 bool is_volatile = node->data.array_type.is_volatile; 5740 AstNode *align_expr = node->data.array_type.align_expr; 5741 5742 if (size_node) { 5743 if (is_const) { 5744 add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); 5745 return irb->codegen->invalid_instruction; 5746 } 5747 if (is_volatile) { 5748 add_node_error(irb->codegen, node, buf_create_from_str("volatile qualifier invalid on array type")); 5749 return irb->codegen->invalid_instruction; 5750 } 5751 if (align_expr != nullptr) { 5752 add_node_error(irb->codegen, node, buf_create_from_str("align qualifier invalid on array type")); 5753 return irb->codegen->invalid_instruction; 5754 } 5755 5756 IrInstruction *size_value = ir_gen_node(irb, size_node, scope); 5757 if (size_value == irb->codegen->invalid_instruction) 5758 return size_value; 5759 5760 IrInstruction *child_type = ir_gen_node(irb, child_type_node, scope); 5761 if (child_type == irb->codegen->invalid_instruction) 5762 return child_type; 5763 5764 return ir_build_array_type(irb, scope, node, size_value, child_type); 5765 } else { 5766 IrInstruction *align_value; 5767 if (align_expr != nullptr) { 5768 align_value = ir_gen_node(irb, align_expr, scope); 5769 if (align_value == irb->codegen->invalid_instruction) 5770 return align_value; 5771 } else { 5772 align_value = nullptr; 5773 } 5774 5775 IrInstruction *child_type = ir_gen_node(irb, child_type_node, scope); 5776 if (child_type == irb->codegen->invalid_instruction) 5777 return child_type; 5778 5779 return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, align_value); 5780 } 5781 } 5782 5783 static IrInstruction *ir_gen_promise_type(IrBuilder *irb, Scope *scope, AstNode *node) { 5784 assert(node->type == NodeTypePromiseType); 5785 5786 AstNode *payload_type_node = node->data.promise_type.payload_type; 5787 IrInstruction *payload_type_value = nullptr; 5788 5789 if (payload_type_node != nullptr) { 5790 payload_type_value = ir_gen_node(irb, payload_type_node, scope); 5791 if (payload_type_value == irb->codegen->invalid_instruction) 5792 return payload_type_value; 5793 5794 } 5795 5796 return ir_build_promise_type(irb, scope, node, payload_type_value); 5797 } 5798 5799 static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 5800 assert(node->type == NodeTypeUndefinedLiteral); 5801 return ir_build_const_undefined(irb, scope, node); 5802 } 5803 5804 static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5805 assert(node->type == NodeTypeAsmExpr); 5806 5807 IrInstruction **input_list = allocate<IrInstruction *>(node->data.asm_expr.input_list.length); 5808 IrInstruction **output_types = allocate<IrInstruction *>(node->data.asm_expr.output_list.length); 5809 ZigVar **output_vars = allocate<ZigVar *>(node->data.asm_expr.output_list.length); 5810 size_t return_count = 0; 5811 bool is_volatile = node->data.asm_expr.is_volatile; 5812 if (!is_volatile && node->data.asm_expr.output_list.length == 0) { 5813 add_node_error(irb->codegen, node, 5814 buf_sprintf("assembly expression with no output must be marked volatile")); 5815 return irb->codegen->invalid_instruction; 5816 } 5817 for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1) { 5818 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); 5819 if (asm_output->return_type) { 5820 return_count += 1; 5821 5822 IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, scope); 5823 if (return_type == irb->codegen->invalid_instruction) 5824 return irb->codegen->invalid_instruction; 5825 if (return_count > 1) { 5826 add_node_error(irb->codegen, node, 5827 buf_sprintf("inline assembly allows up to one output value")); 5828 return irb->codegen->invalid_instruction; 5829 } 5830 output_types[i] = return_type; 5831 } else { 5832 Buf *variable_name = asm_output->variable_name; 5833 // TODO there is some duplication here with ir_gen_symbol. I need to do a full audit of how 5834 // inline assembly works. https://github.com/ziglang/zig/issues/215 5835 ZigVar *var = find_variable(irb->codegen, scope, variable_name, nullptr); 5836 if (var) { 5837 output_vars[i] = var; 5838 } else { 5839 add_node_error(irb->codegen, node, 5840 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); 5841 return irb->codegen->invalid_instruction; 5842 } 5843 } 5844 } 5845 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) { 5846 AsmInput *asm_input = node->data.asm_expr.input_list.at(i); 5847 IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, scope); 5848 if (input_value == irb->codegen->invalid_instruction) 5849 return irb->codegen->invalid_instruction; 5850 5851 input_list[i] = input_value; 5852 } 5853 5854 return ir_build_asm(irb, scope, node, input_list, output_types, output_vars, return_count, is_volatile); 5855 } 5856 5857 static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5858 assert(node->type == NodeTypeTestExpr); 5859 5860 Buf *var_symbol = node->data.test_expr.var_symbol; 5861 AstNode *expr_node = node->data.test_expr.target_node; 5862 AstNode *then_node = node->data.test_expr.then_node; 5863 AstNode *else_node = node->data.test_expr.else_node; 5864 bool var_is_ptr = node->data.test_expr.var_is_ptr; 5865 5866 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 5867 if (maybe_val_ptr == irb->codegen->invalid_instruction) 5868 return maybe_val_ptr; 5869 5870 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); 5871 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_val); 5872 5873 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "OptionalThen"); 5874 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "OptionalElse"); 5875 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "OptionalEndIf"); 5876 5877 IrInstruction *is_comptime; 5878 if (ir_should_inline(irb->exec, scope)) { 5879 is_comptime = ir_build_const_bool(irb, scope, node, true); 5880 } else { 5881 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); 5882 } 5883 ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime); 5884 5885 ir_set_cursor_at_end_and_append_block(irb, then_block); 5886 5887 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); 5888 Scope *var_scope; 5889 if (var_symbol) { 5890 IrInstruction *var_type = nullptr; 5891 bool is_shadowable = false; 5892 bool is_const = true; 5893 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 5894 var_symbol, is_const, is_const, is_shadowable, is_comptime); 5895 5896 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, subexpr_scope, node, maybe_val_ptr, false); 5897 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); 5898 ir_build_var_decl(irb, subexpr_scope, node, var, var_type, nullptr, var_value); 5899 var_scope = var->child_scope; 5900 } else { 5901 var_scope = subexpr_scope; 5902 } 5903 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); 5904 if (then_expr_result == irb->codegen->invalid_instruction) 5905 return then_expr_result; 5906 IrBasicBlock *after_then_block = irb->current_basic_block; 5907 if (!instr_is_unreachable(then_expr_result)) 5908 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5909 5910 ir_set_cursor_at_end_and_append_block(irb, else_block); 5911 IrInstruction *else_expr_result; 5912 if (else_node) { 5913 else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); 5914 if (else_expr_result == irb->codegen->invalid_instruction) 5915 return else_expr_result; 5916 } else { 5917 else_expr_result = ir_build_const_void(irb, scope, node); 5918 } 5919 IrBasicBlock *after_else_block = irb->current_basic_block; 5920 if (!instr_is_unreachable(else_expr_result)) 5921 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5922 5923 ir_set_cursor_at_end_and_append_block(irb, endif_block); 5924 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 5925 incoming_values[0] = then_expr_result; 5926 incoming_values[1] = else_expr_result; 5927 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 5928 incoming_blocks[0] = after_then_block; 5929 incoming_blocks[1] = after_else_block; 5930 5931 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 5932 } 5933 5934 static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5935 assert(node->type == NodeTypeIfErrorExpr); 5936 5937 AstNode *target_node = node->data.if_err_expr.target_node; 5938 AstNode *then_node = node->data.if_err_expr.then_node; 5939 AstNode *else_node = node->data.if_err_expr.else_node; 5940 bool var_is_ptr = node->data.if_err_expr.var_is_ptr; 5941 bool var_is_const = true; 5942 Buf *var_symbol = node->data.if_err_expr.var_symbol; 5943 Buf *err_symbol = node->data.if_err_expr.err_symbol; 5944 5945 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); 5946 if (err_val_ptr == irb->codegen->invalid_instruction) 5947 return err_val_ptr; 5948 5949 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 5950 IrInstruction *is_err = ir_build_test_err(irb, scope, node, err_val); 5951 5952 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); 5953 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); 5954 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "TryEnd"); 5955 5956 bool force_comptime = ir_should_inline(irb->exec, scope); 5957 IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); 5958 ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); 5959 5960 ir_set_cursor_at_end_and_append_block(irb, ok_block); 5961 5962 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); 5963 Scope *var_scope; 5964 if (var_symbol) { 5965 IrInstruction *var_type = nullptr; 5966 bool is_shadowable = false; 5967 IrInstruction *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val); 5968 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 5969 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); 5970 5971 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false); 5972 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); 5973 ir_build_var_decl(irb, subexpr_scope, node, var, var_type, nullptr, var_value); 5974 var_scope = var->child_scope; 5975 } else { 5976 var_scope = subexpr_scope; 5977 } 5978 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); 5979 if (then_expr_result == irb->codegen->invalid_instruction) 5980 return then_expr_result; 5981 IrBasicBlock *after_then_block = irb->current_basic_block; 5982 if (!instr_is_unreachable(then_expr_result)) 5983 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5984 5985 ir_set_cursor_at_end_and_append_block(irb, else_block); 5986 5987 IrInstruction *else_expr_result; 5988 if (else_node) { 5989 Scope *err_var_scope; 5990 if (err_symbol) { 5991 IrInstruction *var_type = nullptr; 5992 bool is_shadowable = false; 5993 bool is_const = true; 5994 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 5995 err_symbol, is_const, is_const, is_shadowable, is_comptime); 5996 5997 IrInstruction *var_value = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr); 5998 ir_build_var_decl(irb, subexpr_scope, node, var, var_type, nullptr, var_value); 5999 err_var_scope = var->child_scope; 6000 } else { 6001 err_var_scope = subexpr_scope; 6002 } 6003 else_expr_result = ir_gen_node(irb, else_node, err_var_scope); 6004 if (else_expr_result == irb->codegen->invalid_instruction) 6005 return else_expr_result; 6006 } else { 6007 else_expr_result = ir_build_const_void(irb, scope, node); 6008 } 6009 IrBasicBlock *after_else_block = irb->current_basic_block; 6010 if (!instr_is_unreachable(else_expr_result)) 6011 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 6012 6013 ir_set_cursor_at_end_and_append_block(irb, endif_block); 6014 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 6015 incoming_values[0] = then_expr_result; 6016 incoming_values[1] = else_expr_result; 6017 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 6018 incoming_blocks[0] = after_then_block; 6019 incoming_blocks[1] = after_else_block; 6020 6021 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 6022 } 6023 6024 static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, 6025 IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, 6026 IrInstruction *target_value_ptr, IrInstruction *prong_value, 6027 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values) 6028 { 6029 assert(switch_node->type == NodeTypeSwitchExpr); 6030 assert(prong_node->type == NodeTypeSwitchProng); 6031 6032 AstNode *expr_node = prong_node->data.switch_prong.expr; 6033 AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol; 6034 Scope *child_scope; 6035 if (var_symbol_node) { 6036 assert(var_symbol_node->type == NodeTypeSymbol); 6037 Buf *var_name = var_symbol_node->data.symbol_expr.symbol; 6038 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr; 6039 6040 bool is_shadowable = false; 6041 bool is_const = true; 6042 ZigVar *var = ir_create_var(irb, var_symbol_node, scope, 6043 var_name, is_const, is_const, is_shadowable, var_is_comptime); 6044 child_scope = var->child_scope; 6045 IrInstruction *var_value; 6046 if (prong_value) { 6047 IrInstruction *var_ptr_value = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, prong_value); 6048 var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); 6049 } else { 6050 var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr); 6051 } 6052 IrInstruction *var_type = nullptr; // infer the type 6053 ir_build_var_decl(irb, scope, var_symbol_node, var, var_type, nullptr, var_value); 6054 } else { 6055 child_scope = scope; 6056 } 6057 6058 IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope); 6059 if (expr_result == irb->codegen->invalid_instruction) 6060 return false; 6061 if (!instr_is_unreachable(expr_result)) 6062 ir_mark_gen(ir_build_br(irb, scope, switch_node, end_block, is_comptime)); 6063 incoming_blocks->append(irb->current_basic_block); 6064 incoming_values->append(expr_result); 6065 return true; 6066 } 6067 6068 static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 6069 assert(node->type == NodeTypeSwitchExpr); 6070 6071 AstNode *target_node = node->data.switch_expr.expr; 6072 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); 6073 if (target_value_ptr == irb->codegen->invalid_instruction) 6074 return target_value_ptr; 6075 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); 6076 6077 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "SwitchElse"); 6078 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "SwitchEnd"); 6079 6080 size_t prong_count = node->data.switch_expr.prongs.length; 6081 ZigList<IrInstructionSwitchBrCase> cases = {0}; 6082 6083 IrInstruction *is_comptime; 6084 IrInstruction *var_is_comptime; 6085 if (ir_should_inline(irb->exec, scope)) { 6086 is_comptime = ir_build_const_bool(irb, scope, node, true); 6087 var_is_comptime = is_comptime; 6088 } else { 6089 is_comptime = ir_build_test_comptime(irb, scope, node, target_value); 6090 var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr); 6091 } 6092 6093 ZigList<IrInstruction *> incoming_values = {0}; 6094 ZigList<IrBasicBlock *> incoming_blocks = {0}; 6095 ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0}; 6096 6097 // First do the else and the ranges 6098 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); 6099 Scope *comptime_scope = create_comptime_scope(node, scope); 6100 AstNode *else_prong = nullptr; 6101 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 6102 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 6103 size_t prong_item_count = prong_node->data.switch_prong.items.length; 6104 if (prong_item_count == 0) { 6105 if (else_prong) { 6106 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 6107 buf_sprintf("multiple else prongs in switch expression")); 6108 add_error_note(irb->codegen, msg, else_prong, 6109 buf_sprintf("previous else prong is here")); 6110 return irb->codegen->invalid_instruction; 6111 } 6112 else_prong = prong_node; 6113 6114 IrBasicBlock *prev_block = irb->current_basic_block; 6115 ir_set_cursor_at_end_and_append_block(irb, else_block); 6116 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 6117 is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values)) 6118 { 6119 return irb->codegen->invalid_instruction; 6120 } 6121 ir_set_cursor_at_end(irb, prev_block); 6122 } else if (prong_node->data.switch_prong.any_items_are_range) { 6123 IrInstruction *ok_bit = nullptr; 6124 AstNode *last_item_node = nullptr; 6125 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 6126 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 6127 last_item_node = item_node; 6128 if (item_node->type == NodeTypeSwitchRange) { 6129 AstNode *start_node = item_node->data.switch_range.start; 6130 AstNode *end_node = item_node->data.switch_range.end; 6131 6132 IrInstruction *start_value = ir_gen_node(irb, start_node, comptime_scope); 6133 if (start_value == irb->codegen->invalid_instruction) 6134 return irb->codegen->invalid_instruction; 6135 6136 IrInstruction *end_value = ir_gen_node(irb, end_node, comptime_scope); 6137 if (end_value == irb->codegen->invalid_instruction) 6138 return irb->codegen->invalid_instruction; 6139 6140 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 6141 check_range->start = start_value; 6142 check_range->end = end_value; 6143 6144 IrInstruction *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq, 6145 target_value, start_value, false); 6146 IrInstruction *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq, 6147 target_value, end_value, false); 6148 IrInstruction *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd, 6149 lower_range_ok, upper_range_ok, false); 6150 if (ok_bit) { 6151 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false); 6152 } else { 6153 ok_bit = both_ok; 6154 } 6155 } else { 6156 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); 6157 if (item_value == irb->codegen->invalid_instruction) 6158 return irb->codegen->invalid_instruction; 6159 6160 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 6161 check_range->start = item_value; 6162 check_range->end = item_value; 6163 6164 IrInstruction *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq, 6165 item_value, target_value, false); 6166 if (ok_bit) { 6167 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false); 6168 } else { 6169 ok_bit = cmp_ok; 6170 } 6171 } 6172 } 6173 6174 IrBasicBlock *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes"); 6175 IrBasicBlock *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo"); 6176 6177 assert(ok_bit); 6178 assert(last_item_node); 6179 ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, 6180 range_block_no, is_comptime)); 6181 6182 ir_set_cursor_at_end_and_append_block(irb, range_block_yes); 6183 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 6184 is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values)) 6185 { 6186 return irb->codegen->invalid_instruction; 6187 } 6188 6189 ir_set_cursor_at_end_and_append_block(irb, range_block_no); 6190 } 6191 } 6192 6193 // next do the non-else non-ranges 6194 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 6195 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 6196 size_t prong_item_count = prong_node->data.switch_prong.items.length; 6197 if (prong_item_count == 0) 6198 continue; 6199 if (prong_node->data.switch_prong.any_items_are_range) 6200 continue; 6201 6202 IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); 6203 IrInstruction *last_item_value = nullptr; 6204 6205 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 6206 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 6207 assert(item_node->type != NodeTypeSwitchRange); 6208 6209 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); 6210 if (item_value == irb->codegen->invalid_instruction) 6211 return irb->codegen->invalid_instruction; 6212 6213 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 6214 check_range->start = item_value; 6215 check_range->end = item_value; 6216 6217 IrInstructionSwitchBrCase *this_case = cases.add_one(); 6218 this_case->value = item_value; 6219 this_case->block = prong_block; 6220 6221 last_item_value = item_value; 6222 } 6223 IrInstruction *only_item_value = (prong_item_count == 1) ? last_item_value : nullptr; 6224 6225 IrBasicBlock *prev_block = irb->current_basic_block; 6226 ir_set_cursor_at_end_and_append_block(irb, prong_block); 6227 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 6228 is_comptime, var_is_comptime, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values)) 6229 { 6230 return irb->codegen->invalid_instruction; 6231 } 6232 6233 ir_set_cursor_at_end(irb, prev_block); 6234 6235 } 6236 6237 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length, 6238 else_prong != nullptr); 6239 6240 if (cases.length == 0) { 6241 ir_build_br(irb, scope, node, else_block, is_comptime); 6242 } else { 6243 ir_build_switch_br(irb, scope, node, target_value, else_block, cases.length, cases.items, is_comptime, switch_prongs_void); 6244 } 6245 6246 if (!else_prong) { 6247 ir_set_cursor_at_end_and_append_block(irb, else_block); 6248 ir_build_unreachable(irb, scope, node); 6249 } 6250 6251 ir_set_cursor_at_end_and_append_block(irb, end_block); 6252 assert(incoming_blocks.length == incoming_values.length); 6253 if (incoming_blocks.length == 0) { 6254 return ir_build_const_void(irb, scope, node); 6255 } else { 6256 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 6257 } 6258 } 6259 6260 static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { 6261 assert(node->type == NodeTypeCompTime); 6262 6263 Scope *child_scope = create_comptime_scope(node, parent_scope); 6264 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval); 6265 } 6266 6267 static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { 6268 IrInstruction *is_comptime; 6269 if (ir_should_inline(irb->exec, break_scope)) { 6270 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 6271 } else { 6272 is_comptime = block_scope->is_comptime; 6273 } 6274 6275 IrInstruction *result_value; 6276 if (node->data.break_expr.expr) { 6277 result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); 6278 if (result_value == irb->codegen->invalid_instruction) 6279 return irb->codegen->invalid_instruction; 6280 } else { 6281 result_value = ir_build_const_void(irb, break_scope, node); 6282 } 6283 6284 IrBasicBlock *dest_block = block_scope->end_block; 6285 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 6286 6287 block_scope->incoming_blocks->append(irb->current_basic_block); 6288 block_scope->incoming_values->append(result_value); 6289 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 6290 } 6291 6292 static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *node) { 6293 assert(node->type == NodeTypeBreak); 6294 6295 // Search up the scope. We'll find one of these things first: 6296 // * function definition scope or global scope => error, break outside loop 6297 // * defer expression scope => error, cannot break out of defer expression 6298 // * loop scope => OK 6299 // * (if it's a labeled break) labeled block => OK 6300 6301 Scope *search_scope = break_scope; 6302 ScopeLoop *loop_scope; 6303 for (;;) { 6304 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 6305 if (node->data.break_expr.name != nullptr) { 6306 add_node_error(irb->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name))); 6307 return irb->codegen->invalid_instruction; 6308 } else { 6309 add_node_error(irb->codegen, node, buf_sprintf("break expression outside loop")); 6310 return irb->codegen->invalid_instruction; 6311 } 6312 } else if (search_scope->id == ScopeIdDeferExpr) { 6313 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of defer expression")); 6314 return irb->codegen->invalid_instruction; 6315 } else if (search_scope->id == ScopeIdLoop) { 6316 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 6317 if (node->data.break_expr.name == nullptr || 6318 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name))) 6319 { 6320 loop_scope = this_loop_scope; 6321 break; 6322 } 6323 } else if (search_scope->id == ScopeIdBlock) { 6324 ScopeBlock *this_block_scope = (ScopeBlock *)search_scope; 6325 if (node->data.break_expr.name != nullptr && 6326 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name))) 6327 { 6328 assert(this_block_scope->end_block != nullptr); 6329 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope); 6330 } 6331 } else if (search_scope->id == ScopeIdSuspend) { 6332 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of suspend block")); 6333 return irb->codegen->invalid_instruction; 6334 } 6335 search_scope = search_scope->parent; 6336 } 6337 6338 IrInstruction *is_comptime; 6339 if (ir_should_inline(irb->exec, break_scope)) { 6340 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 6341 } else { 6342 is_comptime = loop_scope->is_comptime; 6343 } 6344 6345 IrInstruction *result_value; 6346 if (node->data.break_expr.expr) { 6347 result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); 6348 if (result_value == irb->codegen->invalid_instruction) 6349 return irb->codegen->invalid_instruction; 6350 } else { 6351 result_value = ir_build_const_void(irb, break_scope, node); 6352 } 6353 6354 IrBasicBlock *dest_block = loop_scope->break_block; 6355 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 6356 6357 loop_scope->incoming_blocks->append(irb->current_basic_block); 6358 loop_scope->incoming_values->append(result_value); 6359 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 6360 } 6361 6362 static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, AstNode *node) { 6363 assert(node->type == NodeTypeContinue); 6364 6365 // Search up the scope. We'll find one of these things first: 6366 // * function definition scope or global scope => error, break outside loop 6367 // * defer expression scope => error, cannot break out of defer expression 6368 // * loop scope => OK 6369 6370 ZigList<ScopeRuntime *> runtime_scopes = {}; 6371 6372 Scope *search_scope = continue_scope; 6373 ScopeLoop *loop_scope; 6374 for (;;) { 6375 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 6376 if (node->data.continue_expr.name != nullptr) { 6377 add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name))); 6378 return irb->codegen->invalid_instruction; 6379 } else { 6380 add_node_error(irb->codegen, node, buf_sprintf("continue expression outside loop")); 6381 return irb->codegen->invalid_instruction; 6382 } 6383 } else if (search_scope->id == ScopeIdDeferExpr) { 6384 add_node_error(irb->codegen, node, buf_sprintf("cannot continue out of defer expression")); 6385 return irb->codegen->invalid_instruction; 6386 } else if (search_scope->id == ScopeIdLoop) { 6387 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 6388 if (node->data.continue_expr.name == nullptr || 6389 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name))) 6390 { 6391 loop_scope = this_loop_scope; 6392 break; 6393 } 6394 } else if (search_scope->id == ScopeIdRuntime) { 6395 ScopeRuntime *scope_runtime = (ScopeRuntime *)search_scope; 6396 runtime_scopes.append(scope_runtime); 6397 } 6398 search_scope = search_scope->parent; 6399 } 6400 6401 IrInstruction *is_comptime; 6402 if (ir_should_inline(irb->exec, continue_scope)) { 6403 is_comptime = ir_build_const_bool(irb, continue_scope, node, true); 6404 } else { 6405 is_comptime = loop_scope->is_comptime; 6406 } 6407 6408 for (size_t i = 0; i < runtime_scopes.length; i += 1) { 6409 ScopeRuntime *scope_runtime = runtime_scopes.at(i); 6410 ir_mark_gen(ir_build_check_runtime_scope(irb, continue_scope, node, scope_runtime->is_comptime, is_comptime)); 6411 } 6412 6413 IrBasicBlock *dest_block = loop_scope->continue_block; 6414 ir_gen_defers_for_block(irb, continue_scope, dest_block->scope, false); 6415 return ir_mark_gen(ir_build_br(irb, continue_scope, node, dest_block, is_comptime)); 6416 } 6417 6418 static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) { 6419 assert(node->type == NodeTypeErrorType); 6420 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set); 6421 } 6422 6423 static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6424 assert(node->type == NodeTypeDefer); 6425 6426 ScopeDefer *defer_child_scope = create_defer_scope(node, parent_scope); 6427 node->data.defer.child_scope = &defer_child_scope->base; 6428 6429 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(node, parent_scope); 6430 node->data.defer.expr_scope = &defer_expr_scope->base; 6431 6432 return ir_build_const_void(irb, parent_scope, node); 6433 } 6434 6435 static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) { 6436 assert(node->type == NodeTypeSliceExpr); 6437 6438 AstNodeSliceExpr *slice_expr = &node->data.slice_expr; 6439 AstNode *array_node = slice_expr->array_ref_expr; 6440 AstNode *start_node = slice_expr->start; 6441 AstNode *end_node = slice_expr->end; 6442 6443 IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr); 6444 if (ptr_value == irb->codegen->invalid_instruction) 6445 return irb->codegen->invalid_instruction; 6446 6447 IrInstruction *start_value = ir_gen_node(irb, start_node, scope); 6448 if (start_value == irb->codegen->invalid_instruction) 6449 return irb->codegen->invalid_instruction; 6450 6451 IrInstruction *end_value; 6452 if (end_node) { 6453 end_value = ir_gen_node(irb, end_node, scope); 6454 if (end_value == irb->codegen->invalid_instruction) 6455 return irb->codegen->invalid_instruction; 6456 } else { 6457 end_value = nullptr; 6458 } 6459 6460 return ir_build_slice(irb, scope, node, ptr_value, start_value, end_value, true); 6461 } 6462 6463 static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6464 assert(node->type == NodeTypeUnwrapErrorExpr); 6465 6466 AstNode *op1_node = node->data.unwrap_err_expr.op1; 6467 AstNode *op2_node = node->data.unwrap_err_expr.op2; 6468 AstNode *var_node = node->data.unwrap_err_expr.symbol; 6469 6470 if (op2_node->type == NodeTypeUnreachable) { 6471 if (var_node != nullptr) { 6472 assert(var_node->type == NodeTypeSymbol); 6473 Buf *var_name = var_node->data.symbol_expr.symbol; 6474 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); 6475 return irb->codegen->invalid_instruction; 6476 } 6477 return ir_gen_err_assert_ok(irb, parent_scope, node, op1_node, LValNone); 6478 } 6479 6480 6481 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); 6482 if (err_union_ptr == irb->codegen->invalid_instruction) 6483 return irb->codegen->invalid_instruction; 6484 6485 IrInstruction *err_union_val = ir_build_load_ptr(irb, parent_scope, node, err_union_ptr); 6486 IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_union_val); 6487 6488 IrInstruction *is_comptime; 6489 if (ir_should_inline(irb->exec, parent_scope)) { 6490 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 6491 } else { 6492 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_err); 6493 } 6494 6495 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); 6496 IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); 6497 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); 6498 ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); 6499 6500 ir_set_cursor_at_end_and_append_block(irb, err_block); 6501 Scope *err_scope; 6502 if (var_node) { 6503 assert(var_node->type == NodeTypeSymbol); 6504 Buf *var_name = var_node->data.symbol_expr.symbol; 6505 bool is_const = true; 6506 bool is_shadowable = false; 6507 ZigVar *var = ir_create_var(irb, node, parent_scope, var_name, 6508 is_const, is_const, is_shadowable, is_comptime); 6509 err_scope = var->child_scope; 6510 IrInstruction *err_val = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); 6511 ir_build_var_decl(irb, err_scope, var_node, var, nullptr, nullptr, err_val); 6512 } else { 6513 err_scope = parent_scope; 6514 } 6515 IrInstruction *err_result = ir_gen_node(irb, op2_node, err_scope); 6516 if (err_result == irb->codegen->invalid_instruction) 6517 return irb->codegen->invalid_instruction; 6518 IrBasicBlock *after_err_block = irb->current_basic_block; 6519 if (!instr_is_unreachable(err_result)) 6520 ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime)); 6521 6522 ir_set_cursor_at_end_and_append_block(irb, ok_block); 6523 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false); 6524 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 6525 IrBasicBlock *after_ok_block = irb->current_basic_block; 6526 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 6527 6528 ir_set_cursor_at_end_and_append_block(irb, end_block); 6529 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 6530 incoming_values[0] = err_result; 6531 incoming_values[1] = unwrapped_payload; 6532 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 6533 incoming_blocks[0] = after_err_block; 6534 incoming_blocks[1] = after_ok_block; 6535 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); 6536 } 6537 6538 static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { 6539 if (inner_scope == nullptr || inner_scope == outer_scope) return false; 6540 bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent); 6541 if (inner_scope->id != ScopeIdVarDecl) 6542 return need_comma; 6543 6544 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; 6545 if (need_comma) 6546 buf_append_char(name, ','); 6547 render_const_value(codegen, name, var_scope->var->value); 6548 return true; 6549 } 6550 6551 static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, AstNode *source_node) { 6552 if (exec->name) { 6553 return exec->name; 6554 } else if (exec->name_fn != nullptr) { 6555 Buf *name = buf_alloc(); 6556 buf_append_buf(name, &exec->name_fn->symbol_name); 6557 buf_appendf(name, "("); 6558 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope); 6559 buf_appendf(name, ")"); 6560 return name; 6561 } else { 6562 //Note: C-imports do not have valid location information 6563 return buf_sprintf("(anonymous %s at %s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ")", kind_name, 6564 (source_node->owner->path != nullptr) ? buf_ptr(source_node->owner->path) : "(null)", source_node->line + 1, source_node->column + 1); 6565 } 6566 } 6567 6568 static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6569 assert(node->type == NodeTypeContainerDecl); 6570 6571 ContainerKind kind = node->data.container_decl.kind; 6572 Buf *name = get_anon_type_name(irb->codegen, irb->exec, container_string(kind), node); 6573 6574 VisibMod visib_mod = VisibModPub; 6575 TldContainer *tld_container = allocate<TldContainer>(1); 6576 init_tld(&tld_container->base, TldIdContainer, name, visib_mod, node, parent_scope); 6577 6578 ContainerLayout layout = node->data.container_decl.layout; 6579 ZigType *container_type = get_partial_container_type(irb->codegen, parent_scope, 6580 kind, node, buf_ptr(name), layout); 6581 ScopeDecls *child_scope = get_container_scope(container_type); 6582 6583 tld_container->type_entry = container_type; 6584 tld_container->decls_scope = child_scope; 6585 6586 for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) { 6587 AstNode *child_node = node->data.container_decl.decls.at(i); 6588 scan_decls(irb->codegen, child_scope, child_node); 6589 } 6590 irb->codegen->resolve_queue.append(&tld_container->base); 6591 6592 // Add this to the list to mark as invalid if analyzing this exec fails. 6593 irb->exec->tld_list.append(&tld_container->base); 6594 6595 return ir_build_const_type(irb, parent_scope, node, container_type); 6596 } 6597 6598 // errors should be populated with set1's values 6599 static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigType *set1, ZigType *set2) { 6600 assert(set1->id == ZigTypeIdErrorSet); 6601 assert(set2->id == ZigTypeIdErrorSet); 6602 6603 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 6604 buf_resize(&err_set_type->name, 0); 6605 buf_appendf(&err_set_type->name, "error{"); 6606 6607 for (uint32_t i = 0, count = set1->data.error_set.err_count; i < count; i += 1) { 6608 assert(errors[set1->data.error_set.errors[i]->value] == set1->data.error_set.errors[i]); 6609 } 6610 6611 uint32_t count = set1->data.error_set.err_count; 6612 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 6613 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 6614 if (errors[error_entry->value] == nullptr) { 6615 count += 1; 6616 } 6617 } 6618 6619 err_set_type->is_copyable = true; 6620 err_set_type->type_ref = g->builtin_types.entry_global_error_set->type_ref; 6621 err_set_type->di_type = g->builtin_types.entry_global_error_set->di_type; 6622 err_set_type->data.error_set.err_count = count; 6623 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(count); 6624 6625 for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { 6626 ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; 6627 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 6628 err_set_type->data.error_set.errors[i] = error_entry; 6629 } 6630 6631 uint32_t index = set1->data.error_set.err_count; 6632 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 6633 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 6634 if (errors[error_entry->value] == nullptr) { 6635 errors[error_entry->value] = error_entry; 6636 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 6637 err_set_type->data.error_set.errors[index] = error_entry; 6638 index += 1; 6639 } 6640 } 6641 assert(index == count); 6642 assert(count != 0); 6643 6644 buf_appendf(&err_set_type->name, "}"); 6645 6646 g->error_di_types.append(&err_set_type->di_type); 6647 6648 return err_set_type; 6649 6650 } 6651 6652 static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstNode *node, 6653 ErrorTableEntry *err_entry) 6654 { 6655 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 6656 buf_resize(&err_set_type->name, 0); 6657 buf_appendf(&err_set_type->name, "error{%s}", buf_ptr(&err_entry->name)); 6658 err_set_type->is_copyable = true; 6659 err_set_type->type_ref = g->builtin_types.entry_global_error_set->type_ref; 6660 err_set_type->di_type = g->builtin_types.entry_global_error_set->di_type; 6661 err_set_type->data.error_set.err_count = 1; 6662 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1); 6663 6664 g->error_di_types.append(&err_set_type->di_type); 6665 6666 err_set_type->data.error_set.errors[0] = err_entry; 6667 6668 return err_set_type; 6669 } 6670 6671 static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6672 assert(node->type == NodeTypeErrorSetDecl); 6673 6674 uint32_t err_count = node->data.err_set_decl.decls.length; 6675 6676 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error set", node); 6677 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 6678 buf_init_from_buf(&err_set_type->name, type_name); 6679 err_set_type->is_copyable = true; 6680 err_set_type->data.error_set.err_count = err_count; 6681 err_set_type->type_ref = irb->codegen->builtin_types.entry_global_error_set->type_ref; 6682 err_set_type->di_type = irb->codegen->builtin_types.entry_global_error_set->di_type; 6683 irb->codegen->error_di_types.append(&err_set_type->di_type); 6684 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(err_count); 6685 6686 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(irb->codegen->errors_by_index.length + err_count); 6687 6688 for (uint32_t i = 0; i < err_count; i += 1) { 6689 AstNode *symbol_node = node->data.err_set_decl.decls.at(i); 6690 assert(symbol_node->type == NodeTypeSymbol); 6691 Buf *err_name = symbol_node->data.symbol_expr.symbol; 6692 ErrorTableEntry *err = allocate<ErrorTableEntry>(1); 6693 err->decl_node = symbol_node; 6694 buf_init_from_buf(&err->name, err_name); 6695 6696 auto existing_entry = irb->codegen->error_table.put_unique(err_name, err); 6697 if (existing_entry) { 6698 err->value = existing_entry->value->value; 6699 } else { 6700 size_t error_value_count = irb->codegen->errors_by_index.length; 6701 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)irb->codegen->err_tag_type->data.integral.bit_count)); 6702 err->value = error_value_count; 6703 irb->codegen->errors_by_index.append(err); 6704 irb->codegen->err_enumerators.append(ZigLLVMCreateDebugEnumerator(irb->codegen->dbuilder, 6705 buf_ptr(err_name), error_value_count)); 6706 } 6707 err_set_type->data.error_set.errors[i] = err; 6708 6709 ErrorTableEntry *prev_err = errors[err->value]; 6710 if (prev_err != nullptr) { 6711 ErrorMsg *msg = add_node_error(irb->codegen, err->decl_node, buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name))); 6712 add_error_note(irb->codegen, msg, prev_err->decl_node, buf_sprintf("other error here")); 6713 return irb->codegen->invalid_instruction; 6714 } 6715 errors[err->value] = err; 6716 } 6717 free(errors); 6718 return ir_build_const_type(irb, parent_scope, node, err_set_type); 6719 } 6720 6721 static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6722 assert(node->type == NodeTypeFnProto); 6723 6724 size_t param_count = node->data.fn_proto.params.length; 6725 IrInstruction **param_types = allocate<IrInstruction*>(param_count); 6726 6727 bool is_var_args = false; 6728 for (size_t i = 0; i < param_count; i += 1) { 6729 AstNode *param_node = node->data.fn_proto.params.at(i); 6730 if (param_node->data.param_decl.is_var_args) { 6731 is_var_args = true; 6732 break; 6733 } 6734 if (param_node->data.param_decl.var_token == nullptr) { 6735 AstNode *type_node = param_node->data.param_decl.type; 6736 IrInstruction *type_value = ir_gen_node(irb, type_node, parent_scope); 6737 if (type_value == irb->codegen->invalid_instruction) 6738 return irb->codegen->invalid_instruction; 6739 param_types[i] = type_value; 6740 } else { 6741 param_types[i] = nullptr; 6742 } 6743 } 6744 6745 IrInstruction *align_value = nullptr; 6746 if (node->data.fn_proto.align_expr != nullptr) { 6747 align_value = ir_gen_node(irb, node->data.fn_proto.align_expr, parent_scope); 6748 if (align_value == irb->codegen->invalid_instruction) 6749 return irb->codegen->invalid_instruction; 6750 } 6751 6752 IrInstruction *return_type; 6753 if (node->data.fn_proto.return_var_token == nullptr) { 6754 if (node->data.fn_proto.return_type == nullptr) { 6755 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void); 6756 } else { 6757 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope); 6758 if (return_type == irb->codegen->invalid_instruction) 6759 return irb->codegen->invalid_instruction; 6760 } 6761 } else { 6762 add_node_error(irb->codegen, node, 6763 buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); 6764 return irb->codegen->invalid_instruction; 6765 //return_type = nullptr; 6766 } 6767 6768 IrInstruction *async_allocator_type_value = nullptr; 6769 if (node->data.fn_proto.async_allocator_type != nullptr) { 6770 async_allocator_type_value = ir_gen_node(irb, node->data.fn_proto.async_allocator_type, parent_scope); 6771 if (async_allocator_type_value == irb->codegen->invalid_instruction) 6772 return irb->codegen->invalid_instruction; 6773 } 6774 6775 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, 6776 async_allocator_type_value, is_var_args); 6777 } 6778 6779 static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode *node, 6780 IrInstruction *target_inst, bool cancel_non_suspended, bool cancel_awaited) 6781 { 6782 IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "CancelDone"); 6783 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); 6784 IrBasicBlock *pre_return_block = ir_create_basic_block(irb, scope, "PreReturn"); 6785 IrBasicBlock *post_return_block = ir_create_basic_block(irb, scope, "PostReturn"); 6786 IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel"); 6787 6788 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 6789 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 6790 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); 6791 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 6792 IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node, 6793 get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void)); 6794 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 6795 IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 6796 IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100 6797 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 6798 6799 // TODO relies on Zig not re-ordering fields 6800 IrInstruction *casted_target_inst = ir_build_ptr_cast(irb, scope, node, promise_T_type_val, target_inst); 6801 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); 6802 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 6803 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 6804 atomic_state_field_name); 6805 6806 // set the is_canceled bit 6807 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 6808 usize_type_val, atomic_state_ptr, nullptr, is_canceled_mask, nullptr, 6809 AtomicRmwOp_or, AtomicOrderSeqCst); 6810 6811 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 6812 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 6813 ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime); 6814 6815 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 6816 IrInstruction *awaiter_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 6817 IrInstruction *is_returned_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, awaiter_addr, ptr_mask, false); 6818 ir_build_cond_br(irb, scope, node, is_returned_bool, post_return_block, pre_return_block, is_comptime); 6819 6820 ir_set_cursor_at_end_and_append_block(irb, post_return_block); 6821 if (cancel_awaited) { 6822 ir_build_br(irb, scope, node, do_cancel_block, is_comptime); 6823 } else { 6824 IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false); 6825 IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false); 6826 ir_build_cond_br(irb, scope, node, is_awaited_bool, done_block, do_cancel_block, is_comptime); 6827 } 6828 6829 ir_set_cursor_at_end_and_append_block(irb, pre_return_block); 6830 if (cancel_awaited) { 6831 if (cancel_non_suspended) { 6832 ir_build_br(irb, scope, node, do_cancel_block, is_comptime); 6833 } else { 6834 IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 6835 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 6836 ir_build_cond_br(irb, scope, node, is_suspended_bool, do_cancel_block, done_block, is_comptime); 6837 } 6838 } else { 6839 ir_build_br(irb, scope, node, done_block, is_comptime); 6840 } 6841 6842 ir_set_cursor_at_end_and_append_block(irb, do_cancel_block); 6843 ir_build_cancel(irb, scope, node, target_inst); 6844 ir_build_br(irb, scope, node, done_block, is_comptime); 6845 6846 ir_set_cursor_at_end_and_append_block(irb, done_block); 6847 return ir_build_const_void(irb, scope, node); 6848 } 6849 6850 static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *scope, AstNode *node) { 6851 assert(node->type == NodeTypeCancel); 6852 6853 IrInstruction *target_inst = ir_gen_node(irb, node->data.cancel_expr.expr, scope); 6854 if (target_inst == irb->codegen->invalid_instruction) 6855 return irb->codegen->invalid_instruction; 6856 6857 return ir_gen_cancel_target(irb, scope, node, target_inst, false, true); 6858 } 6859 6860 static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode *node, 6861 IrInstruction *target_inst) 6862 { 6863 IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "ResumeDone"); 6864 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); 6865 IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "IsSuspended"); 6866 IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "IsNotSuspended"); 6867 6868 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 6869 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 6870 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 6871 IrInstruction *and_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, is_suspended_mask); 6872 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); 6873 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 6874 IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node, 6875 get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void)); 6876 6877 // TODO relies on Zig not re-ordering fields 6878 IrInstruction *casted_target_inst = ir_build_ptr_cast(irb, scope, node, promise_T_type_val, target_inst); 6879 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); 6880 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 6881 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 6882 atomic_state_field_name); 6883 6884 // clear the is_suspended bit 6885 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 6886 usize_type_val, atomic_state_ptr, nullptr, and_mask, nullptr, 6887 AtomicRmwOp_and, AtomicOrderSeqCst); 6888 6889 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 6890 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 6891 ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime); 6892 6893 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 6894 IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 6895 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 6896 ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime); 6897 6898 ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); 6899 ir_build_unreachable(irb, scope, node); 6900 6901 ir_set_cursor_at_end_and_append_block(irb, suspended_block); 6902 ir_build_coro_resume(irb, scope, node, target_inst); 6903 ir_build_br(irb, scope, node, done_block, is_comptime); 6904 6905 ir_set_cursor_at_end_and_append_block(irb, done_block); 6906 return ir_build_const_void(irb, scope, node); 6907 } 6908 6909 static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) { 6910 assert(node->type == NodeTypeResume); 6911 6912 IrInstruction *target_inst = ir_gen_node(irb, node->data.resume_expr.expr, scope); 6913 if (target_inst == irb->codegen->invalid_instruction) 6914 return irb->codegen->invalid_instruction; 6915 6916 return ir_gen_resume_target(irb, scope, node, target_inst); 6917 } 6918 6919 static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 6920 assert(node->type == NodeTypeAwaitExpr); 6921 6922 IrInstruction *target_inst = ir_gen_node(irb, node->data.await_expr.expr, scope); 6923 if (target_inst == irb->codegen->invalid_instruction) 6924 return irb->codegen->invalid_instruction; 6925 6926 ZigFn *fn_entry = exec_fn_entry(irb->exec); 6927 if (!fn_entry) { 6928 add_node_error(irb->codegen, node, buf_sprintf("await outside function definition")); 6929 return irb->codegen->invalid_instruction; 6930 } 6931 if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) { 6932 add_node_error(irb->codegen, node, buf_sprintf("await in non-async function")); 6933 return irb->codegen->invalid_instruction; 6934 } 6935 6936 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); 6937 if (scope_defer_expr) { 6938 if (!scope_defer_expr->reported_err) { 6939 add_node_error(irb->codegen, node, buf_sprintf("cannot await inside defer expression")); 6940 scope_defer_expr->reported_err = true; 6941 } 6942 return irb->codegen->invalid_instruction; 6943 } 6944 6945 Scope *outer_scope = irb->exec->begin_scope; 6946 6947 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst); 6948 Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); 6949 IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); 6950 6951 if (irb->codegen->have_err_ret_tracing) { 6952 IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); 6953 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); 6954 IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); 6955 ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr); 6956 } 6957 6958 IrBasicBlock *already_awaited_block = ir_create_basic_block(irb, scope, "AlreadyAwaited"); 6959 IrBasicBlock *not_awaited_block = ir_create_basic_block(irb, scope, "NotAwaited"); 6960 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); 6961 IrBasicBlock *yes_suspend_block = ir_create_basic_block(irb, scope, "YesSuspend"); 6962 IrBasicBlock *no_suspend_block = ir_create_basic_block(irb, scope, "NoSuspend"); 6963 IrBasicBlock *merge_block = ir_create_basic_block(irb, scope, "MergeSuspend"); 6964 IrBasicBlock *cleanup_block = ir_create_basic_block(irb, scope, "SuspendCleanup"); 6965 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "SuspendResume"); 6966 IrBasicBlock *cancel_target_block = ir_create_basic_block(irb, scope, "CancelTarget"); 6967 IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel"); 6968 IrBasicBlock *do_defers_block = ir_create_basic_block(irb, scope, "DoDefers"); 6969 IrBasicBlock *destroy_block = ir_create_basic_block(irb, scope, "DestroyBlock"); 6970 IrBasicBlock *my_suspended_block = ir_create_basic_block(irb, scope, "AlreadySuspended"); 6971 IrBasicBlock *my_not_suspended_block = ir_create_basic_block(irb, scope, "NotAlreadySuspended"); 6972 IrBasicBlock *do_suspend_block = ir_create_basic_block(irb, scope, "DoSuspend"); 6973 6974 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 6975 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 6976 atomic_state_field_name); 6977 6978 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); 6979 IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false); 6980 IrInstruction *undefined_value = ir_build_const_undefined(irb, scope, node); 6981 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 6982 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 6983 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 6984 IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 6985 IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100 6986 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 6987 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 6988 6989 ZigVar *result_var = ir_create_var(irb, node, scope, nullptr, 6990 false, false, true, const_bool_false); 6991 IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst); 6992 IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type); 6993 ir_build_await_bookkeeping(irb, scope, node, promise_result_type); 6994 ir_build_var_decl(irb, scope, node, result_var, promise_result_type, nullptr, undefined_value); 6995 IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var); 6996 ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr); 6997 IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle); 6998 6999 IrInstruction *coro_handle_addr = ir_build_ptr_to_int(irb, scope, node, irb->exec->coro_handle); 7000 IrInstruction *mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, coro_handle_addr, await_mask, false); 7001 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 7002 usize_type_val, atomic_state_ptr, nullptr, mask_bits, nullptr, 7003 AtomicRmwOp_or, AtomicOrderSeqCst); 7004 7005 IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false); 7006 IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false); 7007 ir_build_cond_br(irb, scope, node, is_awaited_bool, already_awaited_block, not_awaited_block, const_bool_false); 7008 7009 ir_set_cursor_at_end_and_append_block(irb, already_awaited_block); 7010 ir_build_unreachable(irb, scope, node); 7011 7012 ir_set_cursor_at_end_and_append_block(irb, not_awaited_block); 7013 IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 7014 IrInstruction *is_non_null = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); 7015 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 7016 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 7017 ir_build_cond_br(irb, scope, node, is_canceled_bool, cancel_target_block, not_canceled_block, const_bool_false); 7018 7019 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 7020 ir_build_cond_br(irb, scope, node, is_non_null, no_suspend_block, yes_suspend_block, const_bool_false); 7021 7022 ir_set_cursor_at_end_and_append_block(irb, cancel_target_block); 7023 ir_build_cancel(irb, scope, node, target_inst); 7024 ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false)); 7025 7026 ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); 7027 if (irb->codegen->have_err_ret_tracing) { 7028 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); 7029 IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); 7030 IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); 7031 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); 7032 } 7033 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); 7034 IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); 7035 // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to, 7036 // because we're about to destroy the memory. So we store it into our result variable. 7037 IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr); 7038 ir_build_store_ptr(irb, scope, node, my_result_var_ptr, no_suspend_result); 7039 ir_build_cancel(irb, scope, node, target_inst); 7040 ir_build_br(irb, scope, node, merge_block, const_bool_false); 7041 7042 7043 ir_set_cursor_at_end_and_append_block(irb, yes_suspend_block); 7044 IrInstruction *my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 7045 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr, 7046 AtomicRmwOp_or, AtomicOrderSeqCst); 7047 IrInstruction *my_is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_suspended_mask, false); 7048 IrInstruction *my_is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_suspended_value, zero, false); 7049 ir_build_cond_br(irb, scope, node, my_is_suspended_bool, my_suspended_block, my_not_suspended_block, const_bool_false); 7050 7051 ir_set_cursor_at_end_and_append_block(irb, my_suspended_block); 7052 ir_build_unreachable(irb, scope, node); 7053 7054 ir_set_cursor_at_end_and_append_block(irb, my_not_suspended_block); 7055 IrInstruction *my_is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_canceled_mask, false); 7056 IrInstruction *my_is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_canceled_value, zero, false); 7057 ir_build_cond_br(irb, scope, node, my_is_canceled_bool, cleanup_block, do_suspend_block, const_bool_false); 7058 7059 ir_set_cursor_at_end_and_append_block(irb, do_suspend_block); 7060 IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, save_token, const_bool_false); 7061 7062 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); 7063 cases[0].value = ir_build_const_u8(irb, scope, node, 0); 7064 cases[0].block = resume_block; 7065 cases[1].value = ir_build_const_u8(irb, scope, node, 1); 7066 cases[1].block = destroy_block; 7067 ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 7068 2, cases, const_bool_false, nullptr); 7069 7070 ir_set_cursor_at_end_and_append_block(irb, destroy_block); 7071 ir_gen_cancel_target(irb, scope, node, target_inst, false, true); 7072 ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false)); 7073 7074 ir_set_cursor_at_end_and_append_block(irb, cleanup_block); 7075 IrInstruction *my_mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, ptr_mask, is_canceled_mask, false); 7076 IrInstruction *b_my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 7077 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, my_mask_bits, nullptr, 7078 AtomicRmwOp_or, AtomicOrderSeqCst); 7079 IrInstruction *my_await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, b_my_prev_atomic_value, ptr_mask, false); 7080 IrInstruction *dont_have_my_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, my_await_handle_addr, zero, false); 7081 IrInstruction *dont_destroy_ourselves = ir_build_bin_op(irb, scope, node, IrBinOpBoolAnd, dont_have_my_await_handle, is_canceled_bool, false); 7082 ir_build_cond_br(irb, scope, node, dont_have_my_await_handle, do_defers_block, do_cancel_block, const_bool_false); 7083 7084 ir_set_cursor_at_end_and_append_block(irb, do_cancel_block); 7085 IrInstruction *my_await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, my_await_handle_addr); 7086 ir_gen_cancel_target(irb, scope, node, my_await_handle, true, false); 7087 ir_mark_gen(ir_build_br(irb, scope, node, do_defers_block, const_bool_false)); 7088 7089 ir_set_cursor_at_end_and_append_block(irb, do_defers_block); 7090 ir_gen_defers_for_block(irb, scope, outer_scope, true); 7091 ir_mark_gen(ir_build_cond_br(irb, scope, node, dont_destroy_ourselves, irb->exec->coro_early_final, irb->exec->coro_final_cleanup_block, const_bool_false)); 7092 7093 ir_set_cursor_at_end_and_append_block(irb, resume_block); 7094 ir_build_br(irb, scope, node, merge_block, const_bool_false); 7095 7096 ir_set_cursor_at_end_and_append_block(irb, merge_block); 7097 return ir_build_load_ptr(irb, scope, node, my_result_var_ptr); 7098 } 7099 7100 static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 7101 assert(node->type == NodeTypeSuspend); 7102 7103 ZigFn *fn_entry = exec_fn_entry(irb->exec); 7104 if (!fn_entry) { 7105 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition")); 7106 return irb->codegen->invalid_instruction; 7107 } 7108 if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) { 7109 add_node_error(irb->codegen, node, buf_sprintf("suspend in non-async function")); 7110 return irb->codegen->invalid_instruction; 7111 } 7112 7113 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(parent_scope); 7114 if (scope_defer_expr) { 7115 if (!scope_defer_expr->reported_err) { 7116 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside defer expression")); 7117 add_error_note(irb->codegen, msg, scope_defer_expr->base.source_node, buf_sprintf("defer here")); 7118 scope_defer_expr->reported_err = true; 7119 } 7120 return irb->codegen->invalid_instruction; 7121 } 7122 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope); 7123 if (existing_suspend_scope) { 7124 if (!existing_suspend_scope->reported_err) { 7125 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block")); 7126 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here")); 7127 existing_suspend_scope->reported_err = true; 7128 } 7129 return irb->codegen->invalid_instruction; 7130 } 7131 7132 Scope *outer_scope = irb->exec->begin_scope; 7133 7134 IrBasicBlock *cleanup_block = ir_create_basic_block(irb, parent_scope, "SuspendCleanup"); 7135 IrBasicBlock *resume_block = ir_create_basic_block(irb, parent_scope, "SuspendResume"); 7136 IrBasicBlock *suspended_block = ir_create_basic_block(irb, parent_scope, "AlreadySuspended"); 7137 IrBasicBlock *canceled_block = ir_create_basic_block(irb, parent_scope, "IsCanceled"); 7138 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, parent_scope, "NotCanceled"); 7139 IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, parent_scope, "NotAlreadySuspended"); 7140 IrBasicBlock *cancel_awaiter_block = ir_create_basic_block(irb, parent_scope, "CancelAwaiter"); 7141 7142 IrInstruction *promise_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_promise); 7143 IrInstruction *const_bool_true = ir_build_const_bool(irb, parent_scope, node, true); 7144 IrInstruction *const_bool_false = ir_build_const_bool(irb, parent_scope, node, false); 7145 IrInstruction *usize_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_usize); 7146 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, parent_scope, node, 0x1); // 0b001 7147 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, parent_scope, node, 0x2); // 0b010 7148 IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0); 7149 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, parent_scope, node, 0x7); // 0b111 7150 IrInstruction *ptr_mask = ir_build_un_op(irb, parent_scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 7151 7152 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, parent_scope, node, 7153 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr, 7154 AtomicRmwOp_or, AtomicOrderSeqCst); 7155 7156 IrInstruction *is_canceled_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 7157 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 7158 ir_build_cond_br(irb, parent_scope, node, is_canceled_bool, canceled_block, not_canceled_block, const_bool_false); 7159 7160 ir_set_cursor_at_end_and_append_block(irb, canceled_block); 7161 IrInstruction *await_handle_addr = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 7162 IrInstruction *have_await_handle = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); 7163 IrBasicBlock *post_canceled_block = irb->current_basic_block; 7164 ir_build_cond_br(irb, parent_scope, node, have_await_handle, cancel_awaiter_block, cleanup_block, const_bool_false); 7165 7166 ir_set_cursor_at_end_and_append_block(irb, cancel_awaiter_block); 7167 IrInstruction *await_handle = ir_build_int_to_ptr(irb, parent_scope, node, promise_type_val, await_handle_addr); 7168 ir_gen_cancel_target(irb, parent_scope, node, await_handle, true, false); 7169 IrBasicBlock *post_cancel_awaiter_block = irb->current_basic_block; 7170 ir_build_br(irb, parent_scope, node, cleanup_block, const_bool_false); 7171 7172 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 7173 IrInstruction *is_suspended_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 7174 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 7175 ir_build_cond_br(irb, parent_scope, node, is_suspended_bool, suspended_block, not_suspended_block, const_bool_false); 7176 7177 ir_set_cursor_at_end_and_append_block(irb, suspended_block); 7178 ir_build_unreachable(irb, parent_scope, node); 7179 7180 ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); 7181 IrInstruction *suspend_code; 7182 if (node->data.suspend.block == nullptr) { 7183 suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false); 7184 } else { 7185 Scope *child_scope; 7186 ScopeSuspend *suspend_scope = create_suspend_scope(node, parent_scope); 7187 suspend_scope->resume_block = resume_block; 7188 child_scope = &suspend_scope->base; 7189 IrInstruction *save_token = ir_build_coro_save(irb, child_scope, node, irb->exec->coro_handle); 7190 ir_gen_node(irb, node->data.suspend.block, child_scope); 7191 suspend_code = ir_mark_gen(ir_build_coro_suspend(irb, parent_scope, node, save_token, const_bool_false)); 7192 } 7193 7194 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); 7195 cases[0].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 0)); 7196 cases[0].block = resume_block; 7197 cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1)); 7198 cases[1].block = canceled_block; 7199 ir_mark_gen(ir_build_switch_br(irb, parent_scope, node, suspend_code, irb->exec->coro_suspend_block, 7200 2, cases, const_bool_false, nullptr)); 7201 7202 ir_set_cursor_at_end_and_append_block(irb, cleanup_block); 7203 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 7204 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 7205 incoming_blocks[0] = post_canceled_block; 7206 incoming_values[0] = const_bool_true; 7207 incoming_blocks[1] = post_cancel_awaiter_block; 7208 incoming_values[1] = const_bool_false; 7209 IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); 7210 ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); 7211 ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false)); 7212 7213 ir_set_cursor_at_end_and_append_block(irb, resume_block); 7214 return ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); 7215 } 7216 7217 static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, 7218 LVal lval) 7219 { 7220 assert(scope); 7221 switch (node->type) { 7222 case NodeTypeStructValueField: 7223 case NodeTypeRoot: 7224 case NodeTypeParamDecl: 7225 case NodeTypeUse: 7226 case NodeTypeSwitchProng: 7227 case NodeTypeSwitchRange: 7228 case NodeTypeStructField: 7229 case NodeTypeFnDef: 7230 case NodeTypeTestDecl: 7231 zig_unreachable(); 7232 case NodeTypeBlock: 7233 return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); 7234 case NodeTypeGroupedExpr: 7235 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval); 7236 case NodeTypeBinOpExpr: 7237 return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval); 7238 case NodeTypeIntLiteral: 7239 return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval); 7240 case NodeTypeFloatLiteral: 7241 return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval); 7242 case NodeTypeCharLiteral: 7243 return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval); 7244 case NodeTypeSymbol: 7245 return ir_gen_symbol(irb, scope, node, lval); 7246 case NodeTypeFnCallExpr: 7247 return ir_gen_fn_call(irb, scope, node, lval); 7248 case NodeTypeIfBoolExpr: 7249 return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval); 7250 case NodeTypePrefixOpExpr: 7251 return ir_gen_prefix_op_expr(irb, scope, node, lval); 7252 case NodeTypeContainerInitExpr: 7253 return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval); 7254 case NodeTypeVariableDeclaration: 7255 return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval); 7256 case NodeTypeWhileExpr: 7257 return ir_lval_wrap(irb, scope, ir_gen_while_expr(irb, scope, node), lval); 7258 case NodeTypeForExpr: 7259 return ir_lval_wrap(irb, scope, ir_gen_for_expr(irb, scope, node), lval); 7260 case NodeTypeArrayAccessExpr: 7261 return ir_gen_array_access(irb, scope, node, lval); 7262 case NodeTypeReturnExpr: 7263 return ir_gen_return(irb, scope, node, lval); 7264 case NodeTypeFieldAccessExpr: 7265 { 7266 IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); 7267 if (ptr_instruction == irb->codegen->invalid_instruction) 7268 return ptr_instruction; 7269 if (lval == LValPtr) 7270 return ptr_instruction; 7271 7272 return ir_build_load_ptr(irb, scope, node, ptr_instruction); 7273 } 7274 case NodeTypePtrDeref: { 7275 AstNode *expr_node = node->data.ptr_deref_expr.target; 7276 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); 7277 if (value == irb->codegen->invalid_instruction) 7278 return value; 7279 7280 return ir_build_un_op(irb, scope, node, IrUnOpDereference, value); 7281 } 7282 case NodeTypeUnwrapOptional: { 7283 AstNode *expr_node = node->data.unwrap_optional.expr; 7284 7285 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 7286 if (maybe_ptr == irb->codegen->invalid_instruction) 7287 return irb->codegen->invalid_instruction; 7288 7289 IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, scope, node, maybe_ptr, true); 7290 if (lval == LValPtr) 7291 return unwrapped_ptr; 7292 7293 return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); 7294 } 7295 case NodeTypeThisLiteral: 7296 return ir_lval_wrap(irb, scope, ir_gen_this_literal(irb, scope, node), lval); 7297 case NodeTypeBoolLiteral: 7298 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval); 7299 case NodeTypeArrayType: 7300 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval); 7301 case NodeTypePointerType: 7302 return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval); 7303 case NodeTypePromiseType: 7304 return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval); 7305 case NodeTypeStringLiteral: 7306 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval); 7307 case NodeTypeUndefinedLiteral: 7308 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval); 7309 case NodeTypeAsmExpr: 7310 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval); 7311 case NodeTypeNullLiteral: 7312 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); 7313 case NodeTypeIfErrorExpr: 7314 return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval); 7315 case NodeTypeTestExpr: 7316 return ir_lval_wrap(irb, scope, ir_gen_test_expr(irb, scope, node), lval); 7317 case NodeTypeSwitchExpr: 7318 return ir_lval_wrap(irb, scope, ir_gen_switch_expr(irb, scope, node), lval); 7319 case NodeTypeCompTime: 7320 return ir_gen_comptime(irb, scope, node, lval); 7321 case NodeTypeErrorType: 7322 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval); 7323 case NodeTypeBreak: 7324 return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval); 7325 case NodeTypeContinue: 7326 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval); 7327 case NodeTypeUnreachable: 7328 return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval); 7329 case NodeTypeDefer: 7330 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval); 7331 case NodeTypeSliceExpr: 7332 return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval); 7333 case NodeTypeUnwrapErrorExpr: 7334 return ir_lval_wrap(irb, scope, ir_gen_err_ok_or(irb, scope, node), lval); 7335 case NodeTypeContainerDecl: 7336 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval); 7337 case NodeTypeFnProto: 7338 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval); 7339 case NodeTypeErrorSetDecl: 7340 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval); 7341 case NodeTypeCancel: 7342 return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval); 7343 case NodeTypeResume: 7344 return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval); 7345 case NodeTypeAwaitExpr: 7346 return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval); 7347 case NodeTypeSuspend: 7348 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval); 7349 } 7350 zig_unreachable(); 7351 } 7352 7353 static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) { 7354 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval); 7355 irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); 7356 return result; 7357 } 7358 7359 static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { 7360 return ir_gen_node_extra(irb, node, scope, LValNone); 7361 } 7362 7363 static void invalidate_exec(IrExecutable *exec) { 7364 if (exec->invalid) 7365 return; 7366 7367 exec->invalid = true; 7368 7369 for (size_t i = 0; i < exec->tld_list.length; i += 1) { 7370 exec->tld_list.items[i]->resolution = TldResolutionInvalid; 7371 } 7372 7373 if (exec->source_exec != nullptr) 7374 invalidate_exec(exec->source_exec); 7375 } 7376 7377 7378 bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) { 7379 assert(node->owner); 7380 7381 IrBuilder ir_builder = {0}; 7382 IrBuilder *irb = &ir_builder; 7383 7384 irb->codegen = codegen; 7385 irb->exec = ir_executable; 7386 7387 IrBasicBlock *entry_block = ir_create_basic_block(irb, scope, "Entry"); 7388 ir_set_cursor_at_end_and_append_block(irb, entry_block); 7389 // Entry block gets a reference because we enter it to begin. 7390 ir_ref_bb(irb->current_basic_block); 7391 7392 ZigFn *fn_entry = exec_fn_entry(irb->exec); 7393 bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; 7394 IrInstruction *coro_id; 7395 IrInstruction *u8_ptr_type; 7396 IrInstruction *const_bool_false; 7397 IrInstruction *coro_promise_ptr; 7398 IrInstruction *err_ret_trace_ptr; 7399 ZigType *return_type; 7400 Buf *result_ptr_field_name; 7401 ZigVar *coro_size_var; 7402 if (is_async) { 7403 // create the coro promise 7404 Scope *coro_scope = create_coro_prelude_scope(node, scope); 7405 const_bool_false = ir_build_const_bool(irb, coro_scope, node, false); 7406 ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); 7407 7408 return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; 7409 IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); 7410 ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type); 7411 IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type); 7412 // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa 7413 ir_build_var_decl(irb, coro_scope, node, promise_var, coro_frame_type_value, nullptr, undef); 7414 coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var); 7415 7416 ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); 7417 IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); 7418 IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node, 7419 get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); 7420 ir_build_var_decl(irb, coro_scope, node, await_handle_var, await_handle_type_val, nullptr, null_value); 7421 irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var); 7422 7423 u8_ptr_type = ir_build_const_type(irb, coro_scope, node, 7424 get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false)); 7425 IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast(irb, coro_scope, node, u8_ptr_type, coro_promise_ptr); 7426 coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr); 7427 coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); 7428 IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node); 7429 ir_build_var_decl(irb, coro_scope, node, coro_size_var, nullptr, nullptr, coro_size); 7430 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node, 7431 ImplicitAllocatorIdArg); 7432 irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false); 7433 ir_build_var_decl(irb, coro_scope, node, irb->exec->coro_allocator_var, nullptr, nullptr, implicit_allocator_ptr); 7434 Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME); 7435 IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, alloc_field_name); 7436 IrInstruction *alloc_fn = ir_build_load_ptr(irb, coro_scope, node, alloc_fn_ptr); 7437 IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, alloc_fn, coro_size); 7438 IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr); 7439 IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, coro_scope, "AllocError"); 7440 IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, coro_scope, "AllocOk"); 7441 ir_build_cond_br(irb, coro_scope, node, alloc_result_is_ok, alloc_ok_block, alloc_err_block, const_bool_false); 7442 7443 ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); 7444 // we can return undefined here, because the caller passes a pointer to the error struct field 7445 // in the error union result, and we populate it in case of allocation failure. 7446 ir_build_return(irb, coro_scope, node, undef); 7447 7448 ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); 7449 IrInstruction *coro_mem_ptr = ir_build_ptr_cast(irb, coro_scope, node, u8_ptr_type, maybe_coro_mem_ptr); 7450 irb->exec->coro_handle = ir_build_coro_begin(irb, coro_scope, node, coro_id, coro_mem_ptr); 7451 7452 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 7453 irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 7454 atomic_state_field_name); 7455 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 7456 ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero); 7457 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); 7458 irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); 7459 result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); 7460 irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); 7461 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); 7462 if (irb->codegen->have_err_ret_tracing) { 7463 // initialize the error return trace 7464 Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME); 7465 IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name); 7466 7467 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); 7468 err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); 7469 ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr); 7470 7471 // coordinate with builtin.zig 7472 Buf *index_name = buf_create_from_str("index"); 7473 IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name); 7474 ir_build_store_ptr(irb, scope, node, index_ptr, zero); 7475 7476 Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); 7477 IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name); 7478 7479 IrInstruction *slice_value = ir_build_slice(irb, scope, node, return_addresses_ptr, zero, nullptr, false); 7480 ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value); 7481 } 7482 7483 7484 irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal"); 7485 irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal"); 7486 irb->exec->coro_suspend_block = ir_create_basic_block(irb, scope, "Suspend"); 7487 irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup"); 7488 } 7489 7490 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone); 7491 assert(result); 7492 if (irb->exec->invalid) 7493 return false; 7494 7495 if (!instr_is_unreachable(result)) { 7496 // no need for save_err_ret_addr because this cannot return error 7497 ir_gen_async_return(irb, scope, result->source_node, result, true); 7498 } 7499 7500 if (is_async) { 7501 IrBasicBlock *invalid_resume_block = ir_create_basic_block(irb, scope, "InvalidResume"); 7502 IrBasicBlock *check_free_block = ir_create_basic_block(irb, scope, "CheckFree"); 7503 7504 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_early_final); 7505 IrInstruction *const_bool_true = ir_build_const_bool(irb, scope, node, true); 7506 IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, nullptr, const_bool_true); 7507 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); 7508 cases[0].value = ir_build_const_u8(irb, scope, node, 0); 7509 cases[0].block = invalid_resume_block; 7510 cases[1].value = ir_build_const_u8(irb, scope, node, 1); 7511 cases[1].block = irb->exec->coro_final_cleanup_block; 7512 ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr); 7513 7514 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_suspend_block); 7515 ir_build_coro_end(irb, scope, node); 7516 ir_build_return(irb, scope, node, irb->exec->coro_handle); 7517 7518 ir_set_cursor_at_end_and_append_block(irb, invalid_resume_block); 7519 ir_build_unreachable(irb, scope, node); 7520 7521 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_normal_final); 7522 if (type_has_bits(return_type)) { 7523 IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node, 7524 get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8, 7525 false, false, PtrLenUnknown, get_abi_alignment(irb->codegen, irb->codegen->builtin_types.entry_u8), 7526 0, 0)); 7527 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr); 7528 IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len, result_ptr); 7529 IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len, 7530 irb->exec->coro_result_field_ptr); 7531 IrInstruction *return_type_inst = ir_build_const_type(irb, scope, node, 7532 fn_entry->type_entry->data.fn.fn_type_id.return_type); 7533 IrInstruction *size_of_ret_val = ir_build_size_of(irb, scope, node, return_type_inst); 7534 ir_build_memcpy(irb, scope, node, result_ptr_as_u8_ptr, return_value_ptr_as_u8_ptr, size_of_ret_val); 7535 } 7536 if (irb->codegen->have_err_ret_tracing) { 7537 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); 7538 IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); 7539 IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr); 7540 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr); 7541 } 7542 // Before we destroy the coroutine frame, we need to load the target promise into 7543 // a register or local variable which does not get spilled into the frame, 7544 // otherwise llvm tries to access memory inside the destroyed frame. 7545 IrInstruction *unwrapped_await_handle_ptr = ir_build_unwrap_maybe(irb, scope, node, 7546 irb->exec->await_handle_var_ptr, false); 7547 IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); 7548 ir_build_br(irb, scope, node, check_free_block, const_bool_false); 7549 7550 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_final_cleanup_block); 7551 ir_build_br(irb, scope, node, check_free_block, const_bool_false); 7552 7553 ir_set_cursor_at_end_and_append_block(irb, check_free_block); 7554 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 7555 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 7556 incoming_blocks[0] = irb->exec->coro_final_cleanup_block; 7557 incoming_values[0] = const_bool_false; 7558 incoming_blocks[1] = irb->exec->coro_normal_final; 7559 incoming_values[1] = const_bool_true; 7560 IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 7561 7562 IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); 7563 IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); 7564 merge_incoming_blocks[0] = irb->exec->coro_final_cleanup_block; 7565 merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); 7566 merge_incoming_blocks[1] = irb->exec->coro_normal_final; 7567 merge_incoming_values[1] = await_handle_in_block; 7568 IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values); 7569 7570 Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME); 7571 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, 7572 ImplicitAllocatorIdLocalVar); 7573 IrInstruction *free_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, free_field_name); 7574 IrInstruction *free_fn = ir_build_load_ptr(irb, scope, node, free_fn_ptr); 7575 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 7576 IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); 7577 IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node, 7578 get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8, 7579 false, false, PtrLenUnknown, get_abi_alignment(irb->codegen, irb->codegen->builtin_types.entry_u8), 7580 0, 0)); 7581 IrInstruction *coro_mem_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len, coro_mem_ptr_maybe); 7582 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false); 7583 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var); 7584 IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr); 7585 IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false); 7586 size_t arg_count = 2; 7587 IrInstruction **args = allocate<IrInstruction *>(arg_count); 7588 args[0] = implicit_allocator_ptr; // self 7589 args[1] = mem_slice; // old_mem 7590 ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr); 7591 7592 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); 7593 ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false); 7594 7595 ir_set_cursor_at_end_and_append_block(irb, resume_block); 7596 ir_gen_resume_target(irb, scope, node, awaiter_handle); 7597 ir_build_br(irb, scope, node, irb->exec->coro_suspend_block, const_bool_false); 7598 } 7599 7600 return true; 7601 } 7602 7603 bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { 7604 assert(fn_entry); 7605 7606 IrExecutable *ir_executable = &fn_entry->ir_executable; 7607 AstNode *body_node = fn_entry->body_node; 7608 7609 assert(fn_entry->child_scope); 7610 7611 return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); 7612 } 7613 7614 static void add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) { 7615 if (!exec || !exec->source_node || limit < 0) return; 7616 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); 7617 7618 add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1); 7619 } 7620 7621 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) { 7622 invalidate_exec(exec); 7623 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); 7624 if (exec->parent_exec) { 7625 add_call_stack_errors(codegen, exec, err_msg, 10); 7626 } 7627 return err_msg; 7628 } 7629 7630 static ErrorMsg *ir_add_error_node(IrAnalyze *ira, AstNode *source_node, Buf *msg) { 7631 return exec_add_error_node(ira->codegen, ira->new_irb.exec, source_node, msg); 7632 } 7633 7634 static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction, Buf *msg) { 7635 return ir_add_error_node(ira, source_instruction->source_node, msg); 7636 } 7637 7638 static ConstExprValue *ir_const_ptr_pointee(IrAnalyze *ira, ConstExprValue *const_val, AstNode *source_node) { 7639 ConstExprValue *val = const_ptr_pointee_unchecked(ira->codegen, const_val); 7640 assert(val != nullptr); 7641 assert(const_val->type->id == ZigTypeIdPointer); 7642 ZigType *expected_type = const_val->type->data.pointer.child_type; 7643 if (!types_have_same_zig_comptime_repr(val->type, expected_type)) { 7644 ir_add_error_node(ira, source_node, 7645 buf_sprintf("TODO handle comptime reinterpreted pointer. See https://github.com/ziglang/zig/issues/955")); 7646 return nullptr; 7647 } 7648 return val; 7649 } 7650 7651 static IrInstruction *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec) { 7652 IrBasicBlock *bb = exec->basic_block_list.at(0); 7653 for (size_t i = 0; i < bb->instruction_list.length; i += 1) { 7654 IrInstruction *instruction = bb->instruction_list.at(i); 7655 if (instruction->id == IrInstructionIdReturn) { 7656 IrInstructionReturn *ret_inst = (IrInstructionReturn *)instruction; 7657 IrInstruction *value = ret_inst->value; 7658 if (value->value.special == ConstValSpecialRuntime) { 7659 exec_add_error_node(codegen, exec, value->source_node, 7660 buf_sprintf("unable to evaluate constant expression")); 7661 return codegen->invalid_instruction; 7662 } 7663 return value; 7664 } else if (ir_has_side_effects(instruction)) { 7665 exec_add_error_node(codegen, exec, instruction->source_node, 7666 buf_sprintf("unable to evaluate constant expression")); 7667 return codegen->invalid_instruction; 7668 } 7669 } 7670 return codegen->invalid_instruction; 7671 } 7672 7673 static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) { 7674 if (ir_should_inline(ira->new_irb.exec, source_instruction->scope)) { 7675 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression")); 7676 return false; 7677 } 7678 return true; 7679 } 7680 7681 static bool const_val_fits_in_num_lit(ConstExprValue *const_val, ZigType *num_lit_type) { 7682 return ((num_lit_type->id == ZigTypeIdComptimeFloat && 7683 (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat)) || 7684 (num_lit_type->id == ZigTypeIdComptimeInt && 7685 (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt))); 7686 } 7687 7688 static bool float_has_fraction(ConstExprValue *const_val) { 7689 if (const_val->type->id == ZigTypeIdComptimeFloat) { 7690 return bigfloat_has_fraction(&const_val->data.x_bigfloat); 7691 } else if (const_val->type->id == ZigTypeIdFloat) { 7692 switch (const_val->type->data.floating.bit_count) { 7693 case 16: 7694 { 7695 float16_t floored = f16_roundToInt(const_val->data.x_f16, softfloat_round_minMag, false); 7696 return !f16_eq(floored, const_val->data.x_f16); 7697 } 7698 case 32: 7699 return floorf(const_val->data.x_f32) != const_val->data.x_f32; 7700 case 64: 7701 return floor(const_val->data.x_f64) != const_val->data.x_f64; 7702 case 128: 7703 { 7704 float128_t floored; 7705 f128M_roundToInt(&const_val->data.x_f128, softfloat_round_minMag, false, &floored); 7706 return !f128M_eq(&floored, &const_val->data.x_f128); 7707 } 7708 default: 7709 zig_unreachable(); 7710 } 7711 } else { 7712 zig_unreachable(); 7713 } 7714 } 7715 7716 static void float_append_buf(Buf *buf, ConstExprValue *const_val) { 7717 if (const_val->type->id == ZigTypeIdComptimeFloat) { 7718 bigfloat_append_buf(buf, &const_val->data.x_bigfloat); 7719 } else if (const_val->type->id == ZigTypeIdFloat) { 7720 switch (const_val->type->data.floating.bit_count) { 7721 case 16: 7722 buf_appendf(buf, "%f", zig_f16_to_double(const_val->data.x_f16)); 7723 break; 7724 case 32: 7725 buf_appendf(buf, "%f", const_val->data.x_f32); 7726 break; 7727 case 64: 7728 buf_appendf(buf, "%f", const_val->data.x_f64); 7729 break; 7730 case 128: 7731 { 7732 // TODO actual implementation 7733 const size_t extra_len = 100; 7734 size_t old_len = buf_len(buf); 7735 buf_resize(buf, old_len + extra_len); 7736 7737 float64_t f64_value = f128M_to_f64(&const_val->data.x_f128); 7738 double double_value; 7739 memcpy(&double_value, &f64_value, sizeof(double)); 7740 7741 int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value); 7742 assert(len > 0); 7743 buf_resize(buf, old_len + len); 7744 break; 7745 } 7746 default: 7747 zig_unreachable(); 7748 } 7749 } else { 7750 zig_unreachable(); 7751 } 7752 } 7753 7754 static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) { 7755 if (const_val->type->id == ZigTypeIdComptimeFloat) { 7756 bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat); 7757 } else if (const_val->type->id == ZigTypeIdFloat) { 7758 switch (const_val->type->data.floating.bit_count) { 7759 case 16: 7760 { 7761 double x = zig_f16_to_double(const_val->data.x_f16); 7762 if (x >= 0) { 7763 bigint_init_unsigned(bigint, (uint64_t)x); 7764 } else { 7765 bigint_init_unsigned(bigint, (uint64_t)-x); 7766 bigint->is_negative = true; 7767 } 7768 break; 7769 } 7770 case 32: 7771 if (const_val->data.x_f32 >= 0) { 7772 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f32)); 7773 } else { 7774 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f32)); 7775 bigint->is_negative = true; 7776 } 7777 break; 7778 case 64: 7779 if (const_val->data.x_f64 >= 0) { 7780 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f64)); 7781 } else { 7782 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f64)); 7783 bigint->is_negative = true; 7784 } 7785 break; 7786 case 128: 7787 { 7788 BigFloat tmp_float; 7789 bigfloat_init_128(&tmp_float, const_val->data.x_f128); 7790 bigint_init_bigfloat(bigint, &tmp_float); 7791 } 7792 break; 7793 default: 7794 zig_unreachable(); 7795 } 7796 } else { 7797 zig_unreachable(); 7798 } 7799 } 7800 7801 static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) { 7802 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 7803 bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat); 7804 } else if (dest_val->type->id == ZigTypeIdFloat) { 7805 switch (dest_val->type->data.floating.bit_count) { 7806 case 16: 7807 dest_val->data.x_f16 = bigfloat_to_f16(bigfloat); 7808 break; 7809 case 32: 7810 dest_val->data.x_f32 = bigfloat_to_f32(bigfloat); 7811 break; 7812 case 64: 7813 dest_val->data.x_f64 = bigfloat_to_f64(bigfloat); 7814 break; 7815 case 128: 7816 dest_val->data.x_f128 = bigfloat_to_f128(bigfloat); 7817 break; 7818 default: 7819 zig_unreachable(); 7820 } 7821 } else { 7822 zig_unreachable(); 7823 } 7824 } 7825 7826 static void float_init_f16(ConstExprValue *dest_val, float16_t x) { 7827 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 7828 bigfloat_init_16(&dest_val->data.x_bigfloat, x); 7829 } else if (dest_val->type->id == ZigTypeIdFloat) { 7830 switch (dest_val->type->data.floating.bit_count) { 7831 case 16: 7832 dest_val->data.x_f16 = x; 7833 break; 7834 case 32: 7835 dest_val->data.x_f32 = zig_f16_to_double(x); 7836 break; 7837 case 64: 7838 dest_val->data.x_f64 = zig_f16_to_double(x); 7839 break; 7840 case 128: 7841 f16_to_f128M(x, &dest_val->data.x_f128); 7842 break; 7843 default: 7844 zig_unreachable(); 7845 } 7846 } else { 7847 zig_unreachable(); 7848 } 7849 } 7850 7851 static void float_init_f32(ConstExprValue *dest_val, float x) { 7852 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 7853 bigfloat_init_32(&dest_val->data.x_bigfloat, x); 7854 } else if (dest_val->type->id == ZigTypeIdFloat) { 7855 switch (dest_val->type->data.floating.bit_count) { 7856 case 16: 7857 dest_val->data.x_f16 = zig_double_to_f16(x); 7858 break; 7859 case 32: 7860 dest_val->data.x_f32 = x; 7861 break; 7862 case 64: 7863 dest_val->data.x_f64 = x; 7864 break; 7865 case 128: 7866 { 7867 float32_t x_f32; 7868 memcpy(&x_f32, &x, sizeof(float)); 7869 f32_to_f128M(x_f32, &dest_val->data.x_f128); 7870 break; 7871 } 7872 default: 7873 zig_unreachable(); 7874 } 7875 } else { 7876 zig_unreachable(); 7877 } 7878 } 7879 7880 static void float_init_f64(ConstExprValue *dest_val, double x) { 7881 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 7882 bigfloat_init_64(&dest_val->data.x_bigfloat, x); 7883 } else if (dest_val->type->id == ZigTypeIdFloat) { 7884 switch (dest_val->type->data.floating.bit_count) { 7885 case 16: 7886 dest_val->data.x_f16 = zig_double_to_f16(x); 7887 break; 7888 case 32: 7889 dest_val->data.x_f32 = x; 7890 break; 7891 case 64: 7892 dest_val->data.x_f64 = x; 7893 break; 7894 case 128: 7895 { 7896 float64_t x_f64; 7897 memcpy(&x_f64, &x, sizeof(double)); 7898 f64_to_f128M(x_f64, &dest_val->data.x_f128); 7899 break; 7900 } 7901 default: 7902 zig_unreachable(); 7903 } 7904 } else { 7905 zig_unreachable(); 7906 } 7907 } 7908 7909 static void float_init_f128(ConstExprValue *dest_val, float128_t x) { 7910 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 7911 bigfloat_init_128(&dest_val->data.x_bigfloat, x); 7912 } else if (dest_val->type->id == ZigTypeIdFloat) { 7913 switch (dest_val->type->data.floating.bit_count) { 7914 case 16: 7915 dest_val->data.x_f16 = f128M_to_f16(&x); 7916 break; 7917 case 32: 7918 { 7919 float32_t f32_val = f128M_to_f32(&x); 7920 memcpy(&dest_val->data.x_f32, &f32_val, sizeof(float)); 7921 break; 7922 } 7923 case 64: 7924 { 7925 float64_t f64_val = f128M_to_f64(&x); 7926 memcpy(&dest_val->data.x_f64, &f64_val, sizeof(double)); 7927 break; 7928 } 7929 case 128: 7930 { 7931 memcpy(&dest_val->data.x_f128, &x, sizeof(float128_t)); 7932 break; 7933 } 7934 default: 7935 zig_unreachable(); 7936 } 7937 } else { 7938 zig_unreachable(); 7939 } 7940 } 7941 7942 static void float_init_float(ConstExprValue *dest_val, ConstExprValue *src_val) { 7943 if (src_val->type->id == ZigTypeIdComptimeFloat) { 7944 float_init_bigfloat(dest_val, &src_val->data.x_bigfloat); 7945 } else if (src_val->type->id == ZigTypeIdFloat) { 7946 switch (src_val->type->data.floating.bit_count) { 7947 case 16: 7948 float_init_f16(dest_val, src_val->data.x_f16); 7949 break; 7950 case 32: 7951 float_init_f32(dest_val, src_val->data.x_f32); 7952 break; 7953 case 64: 7954 float_init_f64(dest_val, src_val->data.x_f64); 7955 break; 7956 case 128: 7957 float_init_f128(dest_val, src_val->data.x_f128); 7958 break; 7959 default: 7960 zig_unreachable(); 7961 } 7962 } else { 7963 zig_unreachable(); 7964 } 7965 } 7966 7967 static Cmp float_cmp(ConstExprValue *op1, ConstExprValue *op2) { 7968 assert(op1->type == op2->type); 7969 if (op1->type->id == ZigTypeIdComptimeFloat) { 7970 return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat); 7971 } else if (op1->type->id == ZigTypeIdFloat) { 7972 switch (op1->type->data.floating.bit_count) { 7973 case 16: 7974 if (f16_lt(op1->data.x_f16, op2->data.x_f16)) { 7975 return CmpLT; 7976 } else if (f16_lt(op2->data.x_f16, op1->data.x_f16)) { 7977 return CmpGT; 7978 } else { 7979 return CmpEQ; 7980 } 7981 case 32: 7982 if (op1->data.x_f32 > op2->data.x_f32) { 7983 return CmpGT; 7984 } else if (op1->data.x_f32 < op2->data.x_f32) { 7985 return CmpLT; 7986 } else { 7987 return CmpEQ; 7988 } 7989 case 64: 7990 if (op1->data.x_f64 > op2->data.x_f64) { 7991 return CmpGT; 7992 } else if (op1->data.x_f64 < op2->data.x_f64) { 7993 return CmpLT; 7994 } else { 7995 return CmpEQ; 7996 } 7997 case 128: 7998 if (f128M_lt(&op1->data.x_f128, &op2->data.x_f128)) { 7999 return CmpLT; 8000 } else if (f128M_eq(&op1->data.x_f128, &op2->data.x_f128)) { 8001 return CmpEQ; 8002 } else { 8003 return CmpGT; 8004 } 8005 default: 8006 zig_unreachable(); 8007 } 8008 } else { 8009 zig_unreachable(); 8010 } 8011 } 8012 8013 static Cmp float_cmp_zero(ConstExprValue *op) { 8014 if (op->type->id == ZigTypeIdComptimeFloat) { 8015 return bigfloat_cmp_zero(&op->data.x_bigfloat); 8016 } else if (op->type->id == ZigTypeIdFloat) { 8017 switch (op->type->data.floating.bit_count) { 8018 case 16: 8019 { 8020 const float16_t zero = zig_double_to_f16(0); 8021 if (f16_lt(op->data.x_f16, zero)) { 8022 return CmpLT; 8023 } else if (f16_lt(zero, op->data.x_f16)) { 8024 return CmpGT; 8025 } else { 8026 return CmpEQ; 8027 } 8028 } 8029 case 32: 8030 if (op->data.x_f32 < 0.0) { 8031 return CmpLT; 8032 } else if (op->data.x_f32 > 0.0) { 8033 return CmpGT; 8034 } else { 8035 return CmpEQ; 8036 } 8037 case 64: 8038 if (op->data.x_f64 < 0.0) { 8039 return CmpLT; 8040 } else if (op->data.x_f64 > 0.0) { 8041 return CmpGT; 8042 } else { 8043 return CmpEQ; 8044 } 8045 case 128: 8046 float128_t zero_float; 8047 ui32_to_f128M(0, &zero_float); 8048 if (f128M_lt(&op->data.x_f128, &zero_float)) { 8049 return CmpLT; 8050 } else if (f128M_eq(&op->data.x_f128, &zero_float)) { 8051 return CmpEQ; 8052 } else { 8053 return CmpGT; 8054 } 8055 default: 8056 zig_unreachable(); 8057 } 8058 } else { 8059 zig_unreachable(); 8060 } 8061 } 8062 8063 static void float_add(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8064 assert(op1->type == op2->type); 8065 out_val->type = op1->type; 8066 if (op1->type->id == ZigTypeIdComptimeFloat) { 8067 bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8068 } else if (op1->type->id == ZigTypeIdFloat) { 8069 switch (op1->type->data.floating.bit_count) { 8070 case 16: 8071 out_val->data.x_f16 = f16_add(op1->data.x_f16, op2->data.x_f16); 8072 return; 8073 case 32: 8074 out_val->data.x_f32 = op1->data.x_f32 + op2->data.x_f32; 8075 return; 8076 case 64: 8077 out_val->data.x_f64 = op1->data.x_f64 + op2->data.x_f64; 8078 return; 8079 case 128: 8080 f128M_add(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8081 return; 8082 default: 8083 zig_unreachable(); 8084 } 8085 } else { 8086 zig_unreachable(); 8087 } 8088 } 8089 8090 static void float_sub(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8091 assert(op1->type == op2->type); 8092 out_val->type = op1->type; 8093 if (op1->type->id == ZigTypeIdComptimeFloat) { 8094 bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8095 } else if (op1->type->id == ZigTypeIdFloat) { 8096 switch (op1->type->data.floating.bit_count) { 8097 case 16: 8098 out_val->data.x_f16 = f16_sub(op1->data.x_f16, op2->data.x_f16); 8099 return; 8100 case 32: 8101 out_val->data.x_f32 = op1->data.x_f32 - op2->data.x_f32; 8102 return; 8103 case 64: 8104 out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64; 8105 return; 8106 case 128: 8107 f128M_sub(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8108 return; 8109 default: 8110 zig_unreachable(); 8111 } 8112 } else { 8113 zig_unreachable(); 8114 } 8115 } 8116 8117 static void float_mul(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8118 assert(op1->type == op2->type); 8119 out_val->type = op1->type; 8120 if (op1->type->id == ZigTypeIdComptimeFloat) { 8121 bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8122 } else if (op1->type->id == ZigTypeIdFloat) { 8123 switch (op1->type->data.floating.bit_count) { 8124 case 16: 8125 out_val->data.x_f16 = f16_mul(op1->data.x_f16, op2->data.x_f16); 8126 return; 8127 case 32: 8128 out_val->data.x_f32 = op1->data.x_f32 * op2->data.x_f32; 8129 return; 8130 case 64: 8131 out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64; 8132 return; 8133 case 128: 8134 f128M_mul(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8135 return; 8136 default: 8137 zig_unreachable(); 8138 } 8139 } else { 8140 zig_unreachable(); 8141 } 8142 } 8143 8144 static void float_div(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8145 assert(op1->type == op2->type); 8146 out_val->type = op1->type; 8147 if (op1->type->id == ZigTypeIdComptimeFloat) { 8148 bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8149 } else if (op1->type->id == ZigTypeIdFloat) { 8150 switch (op1->type->data.floating.bit_count) { 8151 case 16: 8152 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 8153 return; 8154 case 32: 8155 out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32; 8156 return; 8157 case 64: 8158 out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64; 8159 return; 8160 case 128: 8161 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8162 return; 8163 default: 8164 zig_unreachable(); 8165 } 8166 } else { 8167 zig_unreachable(); 8168 } 8169 } 8170 8171 static void float_div_trunc(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8172 assert(op1->type == op2->type); 8173 out_val->type = op1->type; 8174 if (op1->type->id == ZigTypeIdComptimeFloat) { 8175 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8176 } else if (op1->type->id == ZigTypeIdFloat) { 8177 switch (op1->type->data.floating.bit_count) { 8178 case 16: 8179 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 8180 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_minMag, false); 8181 return; 8182 case 32: 8183 out_val->data.x_f32 = truncf(op1->data.x_f32 / op2->data.x_f32); 8184 return; 8185 case 64: 8186 out_val->data.x_f64 = trunc(op1->data.x_f64 / op2->data.x_f64); 8187 return; 8188 case 128: 8189 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8190 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_minMag, false, &out_val->data.x_f128); 8191 return; 8192 default: 8193 zig_unreachable(); 8194 } 8195 } else { 8196 zig_unreachable(); 8197 } 8198 } 8199 8200 static void float_div_floor(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8201 assert(op1->type == op2->type); 8202 out_val->type = op1->type; 8203 if (op1->type->id == ZigTypeIdComptimeFloat) { 8204 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8205 } else if (op1->type->id == ZigTypeIdFloat) { 8206 switch (op1->type->data.floating.bit_count) { 8207 case 16: 8208 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 8209 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_min, false); 8210 return; 8211 case 32: 8212 out_val->data.x_f32 = floorf(op1->data.x_f32 / op2->data.x_f32); 8213 return; 8214 case 64: 8215 out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64); 8216 return; 8217 case 128: 8218 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8219 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_min, false, &out_val->data.x_f128); 8220 return; 8221 default: 8222 zig_unreachable(); 8223 } 8224 } else { 8225 zig_unreachable(); 8226 } 8227 } 8228 8229 static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8230 assert(op1->type == op2->type); 8231 out_val->type = op1->type; 8232 if (op1->type->id == ZigTypeIdComptimeFloat) { 8233 bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8234 } else if (op1->type->id == ZigTypeIdFloat) { 8235 switch (op1->type->data.floating.bit_count) { 8236 case 16: 8237 out_val->data.x_f16 = f16_rem(op1->data.x_f16, op2->data.x_f16); 8238 return; 8239 case 32: 8240 out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32); 8241 return; 8242 case 64: 8243 out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64); 8244 return; 8245 case 128: 8246 f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8247 return; 8248 default: 8249 zig_unreachable(); 8250 } 8251 } else { 8252 zig_unreachable(); 8253 } 8254 } 8255 8256 // c = a - b * trunc(a / b) 8257 static float16_t zig_f16_mod(float16_t a, float16_t b) { 8258 float16_t c; 8259 c = f16_div(a, b); 8260 c = f16_roundToInt(c, softfloat_round_min, true); 8261 c = f16_mul(b, c); 8262 c = f16_sub(a, c); 8263 return c; 8264 } 8265 8266 // c = a - b * trunc(a / b) 8267 static void zig_f128M_mod(const float128_t* a, const float128_t* b, float128_t* c) { 8268 f128M_div(a, b, c); 8269 f128M_roundToInt(c, softfloat_round_min, true, c); 8270 f128M_mul(b, c, c); 8271 f128M_sub(a, c, c); 8272 } 8273 8274 static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8275 assert(op1->type == op2->type); 8276 out_val->type = op1->type; 8277 if (op1->type->id == ZigTypeIdComptimeFloat) { 8278 bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8279 } else if (op1->type->id == ZigTypeIdFloat) { 8280 switch (op1->type->data.floating.bit_count) { 8281 case 16: 8282 out_val->data.x_f16 = zig_f16_mod(op1->data.x_f16, op2->data.x_f16); 8283 return; 8284 case 32: 8285 out_val->data.x_f32 = fmodf(fmodf(op1->data.x_f32, op2->data.x_f32) + op2->data.x_f32, op2->data.x_f32); 8286 return; 8287 case 64: 8288 out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64); 8289 return; 8290 case 128: 8291 zig_f128M_mod(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8292 return; 8293 default: 8294 zig_unreachable(); 8295 } 8296 } else { 8297 zig_unreachable(); 8298 } 8299 } 8300 8301 static void float_negate(ConstExprValue *out_val, ConstExprValue *op) { 8302 out_val->type = op->type; 8303 if (op->type->id == ZigTypeIdComptimeFloat) { 8304 bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat); 8305 } else if (op->type->id == ZigTypeIdFloat) { 8306 switch (op->type->data.floating.bit_count) { 8307 case 16: 8308 { 8309 const float16_t zero = zig_double_to_f16(0); 8310 out_val->data.x_f16 = f16_sub(zero, op->data.x_f16); 8311 return; 8312 } 8313 case 32: 8314 out_val->data.x_f32 = -op->data.x_f32; 8315 return; 8316 case 64: 8317 out_val->data.x_f64 = -op->data.x_f64; 8318 return; 8319 case 128: 8320 float128_t zero_f128; 8321 ui32_to_f128M(0, &zero_f128); 8322 f128M_sub(&zero_f128, &op->data.x_f128, &out_val->data.x_f128); 8323 return; 8324 default: 8325 zig_unreachable(); 8326 } 8327 } else { 8328 zig_unreachable(); 8329 } 8330 } 8331 8332 void float_write_ieee597(ConstExprValue *op, uint8_t *buf, bool is_big_endian) { 8333 if (op->type->id == ZigTypeIdFloat) { 8334 switch (op->type->data.floating.bit_count) { 8335 case 16: 8336 memcpy(buf, &op->data.x_f16, 2); // TODO wrong when compiler is big endian 8337 return; 8338 case 32: 8339 memcpy(buf, &op->data.x_f32, 4); // TODO wrong when compiler is big endian 8340 return; 8341 case 64: 8342 memcpy(buf, &op->data.x_f64, 8); // TODO wrong when compiler is big endian 8343 return; 8344 case 128: 8345 memcpy(buf, &op->data.x_f128, 16); // TODO wrong when compiler is big endian 8346 return; 8347 default: 8348 zig_unreachable(); 8349 } 8350 } else { 8351 zig_unreachable(); 8352 } 8353 } 8354 8355 void float_read_ieee597(ConstExprValue *val, uint8_t *buf, bool is_big_endian) { 8356 if (val->type->id == ZigTypeIdFloat) { 8357 switch (val->type->data.floating.bit_count) { 8358 case 16: 8359 memcpy(&val->data.x_f16, buf, 2); // TODO wrong when compiler is big endian 8360 return; 8361 case 32: 8362 memcpy(&val->data.x_f32, buf, 4); // TODO wrong when compiler is big endian 8363 return; 8364 case 64: 8365 memcpy(&val->data.x_f64, buf, 8); // TODO wrong when compiler is big endian 8366 return; 8367 case 128: 8368 memcpy(&val->data.x_f128, buf, 16); // TODO wrong when compiler is big endian 8369 return; 8370 default: 8371 zig_unreachable(); 8372 } 8373 } else { 8374 zig_unreachable(); 8375 } 8376 } 8377 8378 static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, ZigType *other_type, 8379 bool explicit_cast) 8380 { 8381 if (type_is_invalid(other_type)) { 8382 return false; 8383 } 8384 8385 ConstExprValue *const_val = &instruction->value; 8386 assert(const_val->special != ConstValSpecialRuntime); 8387 8388 bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || 8389 const_val->type->id == ZigTypeIdComptimeInt); 8390 bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || 8391 const_val->type->id == ZigTypeIdComptimeFloat); 8392 if (other_type->id == ZigTypeIdFloat) { 8393 return true; 8394 } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { 8395 if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 8396 Buf *val_buf = buf_alloc(); 8397 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 8398 ir_add_error(ira, instruction, 8399 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 8400 buf_ptr(val_buf), 8401 buf_ptr(&other_type->name))); 8402 return false; 8403 } 8404 if (bigint_fits_in_bits(&const_val->data.x_bigint, other_type->data.integral.bit_count, 8405 other_type->data.integral.is_signed)) 8406 { 8407 return true; 8408 } 8409 } else if (const_val_fits_in_num_lit(const_val, other_type)) { 8410 return true; 8411 } else if (other_type->id == ZigTypeIdOptional) { 8412 ZigType *child_type = other_type->data.maybe.child_type; 8413 if (const_val_fits_in_num_lit(const_val, child_type)) { 8414 return true; 8415 } else if (child_type->id == ZigTypeIdInt && const_val_is_int) { 8416 if (!child_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 8417 Buf *val_buf = buf_alloc(); 8418 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 8419 ir_add_error(ira, instruction, 8420 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 8421 buf_ptr(val_buf), 8422 buf_ptr(&child_type->name))); 8423 return false; 8424 } 8425 if (bigint_fits_in_bits(&const_val->data.x_bigint, 8426 child_type->data.integral.bit_count, 8427 child_type->data.integral.is_signed)) 8428 { 8429 return true; 8430 } 8431 } else if (child_type->id == ZigTypeIdFloat && const_val_is_float) { 8432 return true; 8433 } 8434 } 8435 if (explicit_cast && (other_type->id == ZigTypeIdInt || other_type->id == ZigTypeIdComptimeInt) && 8436 const_val_is_float) 8437 { 8438 if (float_has_fraction(const_val)) { 8439 Buf *val_buf = buf_alloc(); 8440 float_append_buf(val_buf, const_val); 8441 8442 ir_add_error(ira, instruction, 8443 buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", 8444 buf_ptr(val_buf), 8445 buf_ptr(&other_type->name))); 8446 return false; 8447 } else { 8448 if (other_type->id == ZigTypeIdComptimeInt) { 8449 return true; 8450 } else { 8451 BigInt bigint; 8452 float_init_bigint(&bigint, const_val); 8453 if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count, 8454 other_type->data.integral.is_signed)) 8455 { 8456 return true; 8457 } 8458 } 8459 } 8460 } 8461 8462 const char *num_lit_str; 8463 Buf *val_buf = buf_alloc(); 8464 if (const_val_is_float) { 8465 num_lit_str = "float"; 8466 float_append_buf(val_buf, const_val); 8467 } else { 8468 num_lit_str = "integer"; 8469 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 8470 } 8471 8472 ir_add_error(ira, instruction, 8473 buf_sprintf("%s value %s cannot be implicitly casted to type '%s'", 8474 num_lit_str, 8475 buf_ptr(val_buf), 8476 buf_ptr(&other_type->name))); 8477 return false; 8478 } 8479 8480 static bool is_slice(ZigType *type) { 8481 return type->id == ZigTypeIdStruct && type->data.structure.is_slice; 8482 } 8483 8484 static bool slice_is_const(ZigType *type) { 8485 assert(is_slice(type)); 8486 return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; 8487 } 8488 8489 static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigType *set2, 8490 AstNode *source_node) 8491 { 8492 assert(set1->id == ZigTypeIdErrorSet); 8493 assert(set2->id == ZigTypeIdErrorSet); 8494 8495 if (!resolve_inferred_error_set(ira->codegen, set1, source_node)) { 8496 return ira->codegen->builtin_types.entry_invalid; 8497 } 8498 if (!resolve_inferred_error_set(ira->codegen, set2, source_node)) { 8499 return ira->codegen->builtin_types.entry_invalid; 8500 } 8501 if (type_is_global_error_set(set1)) { 8502 return set2; 8503 } 8504 if (type_is_global_error_set(set2)) { 8505 return set1; 8506 } 8507 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 8508 for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { 8509 ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; 8510 assert(errors[error_entry->value] == nullptr); 8511 errors[error_entry->value] = error_entry; 8512 } 8513 ZigList<ErrorTableEntry *> intersection_list = {}; 8514 8515 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 8516 buf_resize(&err_set_type->name, 0); 8517 buf_appendf(&err_set_type->name, "error{"); 8518 8519 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 8520 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 8521 ErrorTableEntry *existing_entry = errors[error_entry->value]; 8522 if (existing_entry != nullptr) { 8523 intersection_list.append(existing_entry); 8524 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&existing_entry->name)); 8525 } 8526 } 8527 free(errors); 8528 8529 err_set_type->is_copyable = true; 8530 err_set_type->type_ref = ira->codegen->builtin_types.entry_global_error_set->type_ref; 8531 err_set_type->di_type = ira->codegen->builtin_types.entry_global_error_set->di_type; 8532 err_set_type->data.error_set.err_count = intersection_list.length; 8533 err_set_type->data.error_set.errors = intersection_list.items; 8534 err_set_type->zero_bits = intersection_list.length == 0; 8535 8536 buf_appendf(&err_set_type->name, "}"); 8537 8538 ira->codegen->error_di_types.append(&err_set_type->di_type); 8539 8540 return err_set_type; 8541 } 8542 8543 8544 static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted_type, 8545 ZigType *actual_type, AstNode *source_node, bool wanted_is_mutable) 8546 { 8547 CodeGen *g = ira->codegen; 8548 ConstCastOnly result = {}; 8549 result.id = ConstCastResultIdOk; 8550 8551 if (wanted_type == actual_type) 8552 return result; 8553 8554 // *T and [*]T may const-cast-only to ?*U and ?[*]U, respectively 8555 // but not if we want a mutable pointer 8556 // and not if the actual pointer has zero bits 8557 if (!wanted_is_mutable && wanted_type->id == ZigTypeIdOptional && 8558 wanted_type->data.maybe.child_type->id == ZigTypeIdPointer && 8559 actual_type->id == ZigTypeIdPointer && type_has_bits(actual_type)) 8560 { 8561 ConstCastOnly child = types_match_const_cast_only(ira, 8562 wanted_type->data.maybe.child_type, actual_type, source_node, wanted_is_mutable); 8563 if (child.id != ConstCastResultIdOk) { 8564 result.id = ConstCastResultIdNullWrapPtr; 8565 result.data.null_wrap_ptr_child = allocate_nonzero<ConstCastOnly>(1); 8566 *result.data.null_wrap_ptr_child = child; 8567 } 8568 return result; 8569 } 8570 8571 // *T and [*]T can always cast to *c_void 8572 if (wanted_type->id == ZigTypeIdPointer && 8573 wanted_type->data.pointer.ptr_len == PtrLenSingle && 8574 wanted_type->data.pointer.child_type == g->builtin_types.entry_c_void && 8575 actual_type->id == ZigTypeIdPointer && 8576 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && 8577 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) 8578 { 8579 assert(actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment); 8580 return result; 8581 } 8582 8583 // pointer const 8584 if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer) { 8585 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 8586 actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const); 8587 if (child.id != ConstCastResultIdOk) { 8588 result.id = ConstCastResultIdPointerChild; 8589 result.data.pointer_mismatch = allocate_nonzero<ConstCastPointerMismatch>(1); 8590 result.data.pointer_mismatch->child = child; 8591 result.data.pointer_mismatch->wanted_child = wanted_type->data.pointer.child_type; 8592 result.data.pointer_mismatch->actual_child = actual_type->data.pointer.child_type; 8593 return result; 8594 } 8595 if ((actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) && 8596 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && 8597 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) && 8598 actual_type->data.pointer.bit_offset == wanted_type->data.pointer.bit_offset && 8599 actual_type->data.pointer.unaligned_bit_count == wanted_type->data.pointer.unaligned_bit_count && 8600 actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment) 8601 { 8602 return result; 8603 } 8604 } 8605 8606 // slice const 8607 if (is_slice(wanted_type) && is_slice(actual_type)) { 8608 ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry; 8609 ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 8610 if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 8611 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && 8612 actual_ptr_type->data.pointer.bit_offset == wanted_ptr_type->data.pointer.bit_offset && 8613 actual_ptr_type->data.pointer.unaligned_bit_count == wanted_ptr_type->data.pointer.unaligned_bit_count && 8614 actual_ptr_type->data.pointer.alignment >= wanted_ptr_type->data.pointer.alignment) 8615 { 8616 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 8617 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 8618 if (child.id != ConstCastResultIdOk) { 8619 result.id = ConstCastResultIdSliceChild; 8620 result.data.slice_mismatch = allocate_nonzero<ConstCastSliceMismatch>(1); 8621 result.data.slice_mismatch->child = child; 8622 result.data.slice_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 8623 result.data.slice_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 8624 } 8625 return result; 8626 } 8627 } 8628 8629 // maybe 8630 if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdOptional) { 8631 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, 8632 actual_type->data.maybe.child_type, source_node, wanted_is_mutable); 8633 if (child.id != ConstCastResultIdOk) { 8634 result.id = ConstCastResultIdOptionalChild; 8635 result.data.optional = allocate_nonzero<ConstCastOptionalMismatch>(1); 8636 result.data.optional->child = child; 8637 result.data.optional->wanted_child = wanted_type->data.maybe.child_type; 8638 result.data.optional->actual_child = actual_type->data.maybe.child_type; 8639 } 8640 return result; 8641 } 8642 8643 // error union 8644 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id == ZigTypeIdErrorUnion) { 8645 ConstCastOnly payload_child = types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, 8646 actual_type->data.error_union.payload_type, source_node, wanted_is_mutable); 8647 if (payload_child.id != ConstCastResultIdOk) { 8648 result.id = ConstCastResultIdErrorUnionPayload; 8649 result.data.error_union_payload = allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1); 8650 result.data.error_union_payload->child = payload_child; 8651 result.data.error_union_payload->wanted_payload = wanted_type->data.error_union.payload_type; 8652 result.data.error_union_payload->actual_payload = actual_type->data.error_union.payload_type; 8653 return result; 8654 } 8655 ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type, 8656 actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable); 8657 if (error_set_child.id != ConstCastResultIdOk) { 8658 result.id = ConstCastResultIdErrorUnionErrorSet; 8659 result.data.error_union_error_set = allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1); 8660 result.data.error_union_error_set->child = error_set_child; 8661 result.data.error_union_error_set->wanted_err_set = wanted_type->data.error_union.err_set_type; 8662 result.data.error_union_error_set->actual_err_set = actual_type->data.error_union.err_set_type; 8663 return result; 8664 } 8665 return result; 8666 } 8667 8668 // error set 8669 if (wanted_type->id == ZigTypeIdErrorSet && actual_type->id == ZigTypeIdErrorSet) { 8670 ZigType *contained_set = actual_type; 8671 ZigType *container_set = wanted_type; 8672 8673 // if the container set is inferred, then this will always work. 8674 if (container_set->data.error_set.infer_fn != nullptr) { 8675 return result; 8676 } 8677 // if the container set is the global one, it will always work. 8678 if (type_is_global_error_set(container_set)) { 8679 return result; 8680 } 8681 8682 if (!resolve_inferred_error_set(ira->codegen, contained_set, source_node)) { 8683 result.id = ConstCastResultIdUnresolvedInferredErrSet; 8684 return result; 8685 } 8686 8687 if (type_is_global_error_set(contained_set)) { 8688 result.id = ConstCastResultIdErrSetGlobal; 8689 return result; 8690 } 8691 8692 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(g->errors_by_index.length); 8693 for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) { 8694 ErrorTableEntry *error_entry = container_set->data.error_set.errors[i]; 8695 assert(errors[error_entry->value] == nullptr); 8696 errors[error_entry->value] = error_entry; 8697 } 8698 for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) { 8699 ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i]; 8700 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 8701 if (error_entry == nullptr) { 8702 if (result.id == ConstCastResultIdOk) { 8703 result.id = ConstCastResultIdErrSet; 8704 result.data.error_set_mismatch = allocate<ConstCastErrSetMismatch>(1); 8705 } 8706 result.data.error_set_mismatch->missing_errors.append(contained_error_entry); 8707 } 8708 } 8709 free(errors); 8710 return result; 8711 } 8712 8713 if (wanted_type == ira->codegen->builtin_types.entry_promise && 8714 actual_type->id == ZigTypeIdPromise) 8715 { 8716 return result; 8717 } 8718 8719 // fn 8720 if (wanted_type->id == ZigTypeIdFn && 8721 actual_type->id == ZigTypeIdFn) 8722 { 8723 if (wanted_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) { 8724 result.id = ConstCastResultIdFnAlign; 8725 return result; 8726 } 8727 if (wanted_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) { 8728 result.id = ConstCastResultIdFnCC; 8729 return result; 8730 } 8731 if (wanted_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) { 8732 result.id = ConstCastResultIdFnVarArgs; 8733 return result; 8734 } 8735 if (wanted_type->data.fn.is_generic != actual_type->data.fn.is_generic) { 8736 result.id = ConstCastResultIdFnIsGeneric; 8737 return result; 8738 } 8739 if (!wanted_type->data.fn.is_generic && 8740 actual_type->data.fn.fn_type_id.return_type->id != ZigTypeIdUnreachable) 8741 { 8742 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.fn.fn_type_id.return_type, 8743 actual_type->data.fn.fn_type_id.return_type, source_node, false); 8744 if (child.id != ConstCastResultIdOk) { 8745 result.id = ConstCastResultIdFnReturnType; 8746 result.data.return_type = allocate_nonzero<ConstCastOnly>(1); 8747 *result.data.return_type = child; 8748 return result; 8749 } 8750 } 8751 if (!wanted_type->data.fn.is_generic && wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync) { 8752 ConstCastOnly child = types_match_const_cast_only(ira, 8753 actual_type->data.fn.fn_type_id.async_allocator_type, 8754 wanted_type->data.fn.fn_type_id.async_allocator_type, 8755 source_node, false); 8756 if (child.id != ConstCastResultIdOk) { 8757 result.id = ConstCastResultIdAsyncAllocatorType; 8758 result.data.async_allocator_type = allocate_nonzero<ConstCastOnly>(1); 8759 *result.data.async_allocator_type = child; 8760 return result; 8761 } 8762 } 8763 if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { 8764 result.id = ConstCastResultIdFnArgCount; 8765 return result; 8766 } 8767 if (wanted_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) { 8768 result.id = ConstCastResultIdFnGenericArgCount; 8769 return result; 8770 } 8771 assert(wanted_type->data.fn.is_generic || 8772 wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count); 8773 for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.next_param_index; i += 1) { 8774 // note it's reversed for parameters 8775 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i]; 8776 FnTypeParamInfo *expected_param_info = &wanted_type->data.fn.fn_type_id.param_info[i]; 8777 8778 ConstCastOnly arg_child = types_match_const_cast_only(ira, actual_param_info->type, 8779 expected_param_info->type, source_node, false); 8780 if (arg_child.id != ConstCastResultIdOk) { 8781 result.id = ConstCastResultIdFnArg; 8782 result.data.fn_arg.arg_index = i; 8783 result.data.fn_arg.child = allocate_nonzero<ConstCastOnly>(1); 8784 *result.data.fn_arg.child = arg_child; 8785 return result; 8786 } 8787 8788 if (expected_param_info->is_noalias != actual_param_info->is_noalias) { 8789 result.id = ConstCastResultIdFnArgNoAlias; 8790 result.data.arg_no_alias.arg_index = i; 8791 return result; 8792 } 8793 } 8794 return result; 8795 } 8796 8797 result.id = ConstCastResultIdType; 8798 result.data.type_mismatch = allocate_nonzero<ConstCastTypeMismatch>(1); 8799 result.data.type_mismatch->wanted_type = wanted_type; 8800 result.data.type_mismatch->actual_type = actual_type; 8801 return result; 8802 } 8803 8804 static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) { 8805 size_t old_errors_count = *errors_count; 8806 *errors_count = g->errors_by_index.length; 8807 *errors = reallocate(*errors, old_errors_count, *errors_count); 8808 } 8809 8810 static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type, IrInstruction **instructions, size_t instruction_count) { 8811 Error err; 8812 assert(instruction_count >= 1); 8813 IrInstruction *prev_inst = instructions[0]; 8814 if (type_is_invalid(prev_inst->value.type)) { 8815 return ira->codegen->builtin_types.entry_invalid; 8816 } 8817 ErrorTableEntry **errors = nullptr; 8818 size_t errors_count = 0; 8819 ZigType *err_set_type = nullptr; 8820 if (prev_inst->value.type->id == ZigTypeIdErrorSet) { 8821 if (type_is_global_error_set(prev_inst->value.type)) { 8822 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 8823 } else { 8824 err_set_type = prev_inst->value.type; 8825 if (!resolve_inferred_error_set(ira->codegen, err_set_type, prev_inst->source_node)) { 8826 return ira->codegen->builtin_types.entry_invalid; 8827 } 8828 update_errors_helper(ira->codegen, &errors, &errors_count); 8829 8830 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8831 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 8832 assert(errors[error_entry->value] == nullptr); 8833 errors[error_entry->value] = error_entry; 8834 } 8835 } 8836 } 8837 8838 bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull); 8839 bool convert_to_const_slice = false; 8840 for (size_t i = 1; i < instruction_count; i += 1) { 8841 IrInstruction *cur_inst = instructions[i]; 8842 ZigType *cur_type = cur_inst->value.type; 8843 ZigType *prev_type = prev_inst->value.type; 8844 8845 if (type_is_invalid(cur_type)) { 8846 return cur_type; 8847 } 8848 8849 if (prev_type->id == ZigTypeIdUnreachable) { 8850 prev_inst = cur_inst; 8851 continue; 8852 } 8853 8854 if (cur_type->id == ZigTypeIdUnreachable) { 8855 continue; 8856 } 8857 8858 if (prev_type->id == ZigTypeIdErrorSet) { 8859 assert(err_set_type != nullptr); 8860 if (cur_type->id == ZigTypeIdErrorSet) { 8861 if (type_is_global_error_set(err_set_type)) { 8862 continue; 8863 } 8864 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { 8865 return ira->codegen->builtin_types.entry_invalid; 8866 } 8867 if (type_is_global_error_set(cur_type)) { 8868 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 8869 prev_inst = cur_inst; 8870 continue; 8871 } 8872 8873 // number of declared errors might have increased now 8874 update_errors_helper(ira->codegen, &errors, &errors_count); 8875 8876 // if err_set_type is a superset of cur_type, keep err_set_type. 8877 // if cur_type is a superset of err_set_type, switch err_set_type to cur_type 8878 bool prev_is_superset = true; 8879 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 8880 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 8881 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 8882 if (error_entry == nullptr) { 8883 prev_is_superset = false; 8884 break; 8885 } 8886 } 8887 if (prev_is_superset) { 8888 continue; 8889 } 8890 8891 // unset everything in errors 8892 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8893 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 8894 errors[error_entry->value] = nullptr; 8895 } 8896 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 8897 assert(errors[i] == nullptr); 8898 } 8899 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 8900 ErrorTableEntry *error_entry = cur_type->data.error_set.errors[i]; 8901 assert(errors[error_entry->value] == nullptr); 8902 errors[error_entry->value] = error_entry; 8903 } 8904 bool cur_is_superset = true; 8905 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8906 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 8907 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 8908 if (error_entry == nullptr) { 8909 cur_is_superset = false; 8910 break; 8911 } 8912 } 8913 if (cur_is_superset) { 8914 err_set_type = cur_type; 8915 prev_inst = cur_inst; 8916 assert(errors != nullptr); 8917 continue; 8918 } 8919 8920 // neither of them are supersets. so we invent a new error set type that is a union of both of them 8921 err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type); 8922 assert(errors != nullptr); 8923 continue; 8924 } else if (cur_type->id == ZigTypeIdErrorUnion) { 8925 if (type_is_global_error_set(err_set_type)) { 8926 prev_inst = cur_inst; 8927 continue; 8928 } 8929 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 8930 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 8931 return ira->codegen->builtin_types.entry_invalid; 8932 } 8933 if (type_is_global_error_set(cur_err_set_type)) { 8934 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 8935 prev_inst = cur_inst; 8936 continue; 8937 } 8938 8939 update_errors_helper(ira->codegen, &errors, &errors_count); 8940 8941 // test if err_set_type is a subset of cur_type's error set 8942 // unset everything in errors 8943 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8944 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 8945 errors[error_entry->value] = nullptr; 8946 } 8947 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 8948 assert(errors[i] == nullptr); 8949 } 8950 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 8951 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 8952 assert(errors[error_entry->value] == nullptr); 8953 errors[error_entry->value] = error_entry; 8954 } 8955 bool cur_is_superset = true; 8956 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8957 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 8958 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 8959 if (error_entry == nullptr) { 8960 cur_is_superset = false; 8961 break; 8962 } 8963 } 8964 if (cur_is_superset) { 8965 err_set_type = cur_err_set_type; 8966 prev_inst = cur_inst; 8967 assert(errors != nullptr); 8968 continue; 8969 } 8970 8971 // not a subset. invent new error set type, union of both of them 8972 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type); 8973 prev_inst = cur_inst; 8974 assert(errors != nullptr); 8975 continue; 8976 } else { 8977 prev_inst = cur_inst; 8978 continue; 8979 } 8980 } 8981 8982 if (cur_type->id == ZigTypeIdErrorSet) { 8983 if (prev_type->id == ZigTypeIdArray) { 8984 convert_to_const_slice = true; 8985 } 8986 if (type_is_global_error_set(cur_type)) { 8987 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 8988 continue; 8989 } 8990 if (err_set_type != nullptr && type_is_global_error_set(err_set_type)) { 8991 continue; 8992 } 8993 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { 8994 return ira->codegen->builtin_types.entry_invalid; 8995 } 8996 8997 update_errors_helper(ira->codegen, &errors, &errors_count); 8998 8999 if (err_set_type == nullptr) { 9000 if (prev_type->id == ZigTypeIdErrorUnion) { 9001 err_set_type = prev_type->data.error_union.err_set_type; 9002 } else { 9003 err_set_type = cur_type; 9004 } 9005 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9006 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9007 assert(errors[error_entry->value] == nullptr); 9008 errors[error_entry->value] = error_entry; 9009 } 9010 if (err_set_type == cur_type) { 9011 continue; 9012 } 9013 } 9014 // check if the cur type error set is a subset 9015 bool prev_is_superset = true; 9016 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 9017 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 9018 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9019 if (error_entry == nullptr) { 9020 prev_is_superset = false; 9021 break; 9022 } 9023 } 9024 if (prev_is_superset) { 9025 continue; 9026 } 9027 // not a subset. invent new error set type, union of both of them 9028 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type); 9029 assert(errors != nullptr); 9030 continue; 9031 } 9032 9033 if (prev_type->id == ZigTypeIdErrorUnion && cur_type->id == ZigTypeIdErrorUnion) { 9034 ZigType *prev_payload_type = prev_type->data.error_union.payload_type; 9035 ZigType *cur_payload_type = cur_type->data.error_union.payload_type; 9036 9037 bool const_cast_prev = types_match_const_cast_only(ira, prev_payload_type, cur_payload_type, 9038 source_node, false).id == ConstCastResultIdOk; 9039 bool const_cast_cur = types_match_const_cast_only(ira, cur_payload_type, prev_payload_type, 9040 source_node, false).id == ConstCastResultIdOk; 9041 9042 if (const_cast_prev || const_cast_cur) { 9043 if (const_cast_cur) { 9044 prev_inst = cur_inst; 9045 } 9046 9047 ZigType *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type; 9048 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 9049 9050 if (!resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) { 9051 return ira->codegen->builtin_types.entry_invalid; 9052 } 9053 9054 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 9055 return ira->codegen->builtin_types.entry_invalid; 9056 } 9057 9058 if (type_is_global_error_set(prev_err_set_type) || type_is_global_error_set(cur_err_set_type)) { 9059 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9060 continue; 9061 } 9062 9063 update_errors_helper(ira->codegen, &errors, &errors_count); 9064 9065 if (err_set_type == nullptr) { 9066 err_set_type = prev_err_set_type; 9067 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 9068 ErrorTableEntry *error_entry = prev_err_set_type->data.error_set.errors[i]; 9069 assert(errors[error_entry->value] == nullptr); 9070 errors[error_entry->value] = error_entry; 9071 } 9072 } 9073 bool prev_is_superset = true; 9074 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 9075 ErrorTableEntry *contained_error_entry = cur_err_set_type->data.error_set.errors[i]; 9076 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9077 if (error_entry == nullptr) { 9078 prev_is_superset = false; 9079 break; 9080 } 9081 } 9082 if (prev_is_superset) { 9083 continue; 9084 } 9085 // unset all the errors 9086 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9087 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9088 errors[error_entry->value] = nullptr; 9089 } 9090 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 9091 assert(errors[i] == nullptr); 9092 } 9093 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 9094 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 9095 assert(errors[error_entry->value] == nullptr); 9096 errors[error_entry->value] = error_entry; 9097 } 9098 bool cur_is_superset = true; 9099 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 9100 ErrorTableEntry *contained_error_entry = prev_err_set_type->data.error_set.errors[i]; 9101 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9102 if (error_entry == nullptr) { 9103 cur_is_superset = false; 9104 break; 9105 } 9106 } 9107 if (cur_is_superset) { 9108 err_set_type = cur_err_set_type; 9109 continue; 9110 } 9111 9112 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, prev_err_set_type); 9113 continue; 9114 } 9115 } 9116 9117 if (prev_type->id == ZigTypeIdNull) { 9118 prev_inst = cur_inst; 9119 continue; 9120 } 9121 9122 if (cur_type->id == ZigTypeIdNull) { 9123 any_are_null = true; 9124 continue; 9125 } 9126 9127 if (types_match_const_cast_only(ira, prev_type, cur_type, source_node, false).id == ConstCastResultIdOk) { 9128 continue; 9129 } 9130 9131 if (types_match_const_cast_only(ira, cur_type, prev_type, source_node, false).id == ConstCastResultIdOk) { 9132 prev_inst = cur_inst; 9133 continue; 9134 } 9135 9136 if (prev_type->id == ZigTypeIdInt && 9137 cur_type->id == ZigTypeIdInt && 9138 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed) 9139 { 9140 if (cur_type->data.integral.bit_count > prev_type->data.integral.bit_count) { 9141 prev_inst = cur_inst; 9142 } 9143 continue; 9144 } 9145 9146 if (prev_type->id == ZigTypeIdFloat && cur_type->id == ZigTypeIdFloat) { 9147 if (cur_type->data.floating.bit_count > prev_type->data.floating.bit_count) { 9148 prev_inst = cur_inst; 9149 } 9150 continue; 9151 } 9152 9153 if (prev_type->id == ZigTypeIdErrorUnion && 9154 types_match_const_cast_only(ira, prev_type->data.error_union.payload_type, cur_type, 9155 source_node, false).id == ConstCastResultIdOk) 9156 { 9157 continue; 9158 } 9159 9160 if (cur_type->id == ZigTypeIdErrorUnion && 9161 types_match_const_cast_only(ira, cur_type->data.error_union.payload_type, prev_type, 9162 source_node, false).id == ConstCastResultIdOk) 9163 { 9164 if (err_set_type != nullptr) { 9165 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 9166 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 9167 return ira->codegen->builtin_types.entry_invalid; 9168 } 9169 if (type_is_global_error_set(cur_err_set_type) || type_is_global_error_set(err_set_type)) { 9170 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9171 prev_inst = cur_inst; 9172 continue; 9173 } 9174 9175 update_errors_helper(ira->codegen, &errors, &errors_count); 9176 9177 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_err_set_type); 9178 } 9179 prev_inst = cur_inst; 9180 continue; 9181 } 9182 9183 if (prev_type->id == ZigTypeIdOptional && 9184 types_match_const_cast_only(ira, prev_type->data.maybe.child_type, cur_type, 9185 source_node, false).id == ConstCastResultIdOk) 9186 { 9187 continue; 9188 } 9189 9190 if (cur_type->id == ZigTypeIdOptional && 9191 types_match_const_cast_only(ira, cur_type->data.maybe.child_type, prev_type, 9192 source_node, false).id == ConstCastResultIdOk) 9193 { 9194 prev_inst = cur_inst; 9195 continue; 9196 } 9197 9198 if (cur_type->id == ZigTypeIdUndefined) { 9199 continue; 9200 } 9201 9202 if (prev_type->id == ZigTypeIdUndefined) { 9203 prev_inst = cur_inst; 9204 continue; 9205 } 9206 9207 if (prev_type->id == ZigTypeIdComptimeInt || 9208 prev_type->id == ZigTypeIdComptimeFloat) 9209 { 9210 if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) { 9211 prev_inst = cur_inst; 9212 continue; 9213 } else { 9214 return ira->codegen->builtin_types.entry_invalid; 9215 } 9216 } 9217 9218 if (cur_type->id == ZigTypeIdComptimeInt || 9219 cur_type->id == ZigTypeIdComptimeFloat) 9220 { 9221 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) { 9222 continue; 9223 } else { 9224 return ira->codegen->builtin_types.entry_invalid; 9225 } 9226 } 9227 9228 if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && 9229 cur_type->data.array.len != prev_type->data.array.len && 9230 types_match_const_cast_only(ira, cur_type->data.array.child_type, prev_type->data.array.child_type, 9231 source_node, false).id == ConstCastResultIdOk) 9232 { 9233 convert_to_const_slice = true; 9234 prev_inst = cur_inst; 9235 continue; 9236 } 9237 9238 if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && 9239 cur_type->data.array.len != prev_type->data.array.len && 9240 types_match_const_cast_only(ira, prev_type->data.array.child_type, cur_type->data.array.child_type, 9241 source_node, false).id == ConstCastResultIdOk) 9242 { 9243 convert_to_const_slice = true; 9244 continue; 9245 } 9246 9247 if (cur_type->id == ZigTypeIdArray && is_slice(prev_type) && 9248 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || 9249 cur_type->data.array.len == 0) && 9250 types_match_const_cast_only(ira, 9251 prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, 9252 cur_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 9253 { 9254 convert_to_const_slice = false; 9255 continue; 9256 } 9257 9258 if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) && 9259 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || 9260 prev_type->data.array.len == 0) && 9261 types_match_const_cast_only(ira, 9262 cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, 9263 prev_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 9264 { 9265 prev_inst = cur_inst; 9266 convert_to_const_slice = false; 9267 continue; 9268 } 9269 9270 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdUnion && 9271 (cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 9272 { 9273 if ((err = type_ensure_zero_bits_known(ira->codegen, cur_type))) 9274 return ira->codegen->builtin_types.entry_invalid; 9275 if (cur_type->data.unionation.tag_type == prev_type) { 9276 continue; 9277 } 9278 } 9279 9280 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdUnion && 9281 (prev_type->data.unionation.decl_node->data.container_decl.auto_enum || prev_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 9282 { 9283 if ((err = type_ensure_zero_bits_known(ira->codegen, prev_type))) 9284 return ira->codegen->builtin_types.entry_invalid; 9285 if (prev_type->data.unionation.tag_type == cur_type) { 9286 prev_inst = cur_inst; 9287 continue; 9288 } 9289 } 9290 9291 ErrorMsg *msg = ir_add_error_node(ira, source_node, 9292 buf_sprintf("incompatible types: '%s' and '%s'", 9293 buf_ptr(&prev_type->name), buf_ptr(&cur_type->name))); 9294 add_error_note(ira->codegen, msg, prev_inst->source_node, 9295 buf_sprintf("type '%s' here", buf_ptr(&prev_type->name))); 9296 add_error_note(ira->codegen, msg, cur_inst->source_node, 9297 buf_sprintf("type '%s' here", buf_ptr(&cur_type->name))); 9298 9299 return ira->codegen->builtin_types.entry_invalid; 9300 } 9301 9302 free(errors); 9303 9304 if (convert_to_const_slice) { 9305 assert(prev_inst->value.type->id == ZigTypeIdArray); 9306 ZigType *ptr_type = get_pointer_to_type_extra( 9307 ira->codegen, prev_inst->value.type->data.array.child_type, 9308 true, false, PtrLenUnknown, 9309 get_abi_alignment(ira->codegen, prev_inst->value.type->data.array.child_type), 9310 0, 0); 9311 ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); 9312 if (err_set_type != nullptr) { 9313 return get_error_union_type(ira->codegen, err_set_type, slice_type); 9314 } else { 9315 return slice_type; 9316 } 9317 } else if (err_set_type != nullptr) { 9318 if (prev_inst->value.type->id == ZigTypeIdErrorSet) { 9319 return err_set_type; 9320 } else if (prev_inst->value.type->id == ZigTypeIdErrorUnion) { 9321 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value.type->data.error_union.payload_type); 9322 } else if (expected_type != nullptr && expected_type->id == ZigTypeIdErrorUnion) { 9323 return get_error_union_type(ira->codegen, err_set_type, expected_type->data.error_union.payload_type); 9324 } else { 9325 if (prev_inst->value.type->id == ZigTypeIdComptimeInt || 9326 prev_inst->value.type->id == ZigTypeIdComptimeFloat) 9327 { 9328 ir_add_error_node(ira, source_node, 9329 buf_sprintf("unable to make error union out of number literal")); 9330 return ira->codegen->builtin_types.entry_invalid; 9331 } else if (prev_inst->value.type->id == ZigTypeIdNull) { 9332 ir_add_error_node(ira, source_node, 9333 buf_sprintf("unable to make error union out of null literal")); 9334 return ira->codegen->builtin_types.entry_invalid; 9335 } else { 9336 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value.type); 9337 } 9338 } 9339 } else if (any_are_null && prev_inst->value.type->id != ZigTypeIdNull) { 9340 if (prev_inst->value.type->id == ZigTypeIdComptimeInt || 9341 prev_inst->value.type->id == ZigTypeIdComptimeFloat) 9342 { 9343 ir_add_error_node(ira, source_node, 9344 buf_sprintf("unable to make maybe out of number literal")); 9345 return ira->codegen->builtin_types.entry_invalid; 9346 } else if (prev_inst->value.type->id == ZigTypeIdOptional) { 9347 return prev_inst->value.type; 9348 } else { 9349 return get_optional_type(ira->codegen, prev_inst->value.type); 9350 } 9351 } else { 9352 return prev_inst->value.type; 9353 } 9354 } 9355 9356 static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry) { 9357 if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) { 9358 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 9359 if (fn_entry != nullptr) { 9360 fn_entry->alloca_list.append(instruction); 9361 } 9362 } 9363 } 9364 9365 static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { 9366 ConstGlobalRefs *global_refs = dest->global_refs; 9367 *dest = *src; 9368 if (!same_global_refs) { 9369 dest->global_refs = global_refs; 9370 if (dest->type->id == ZigTypeIdStruct) { 9371 dest->data.x_struct.fields = allocate_nonzero<ConstExprValue>(dest->type->data.structure.src_field_count); 9372 memcpy(dest->data.x_struct.fields, src->data.x_struct.fields, sizeof(ConstExprValue) * dest->type->data.structure.src_field_count); 9373 } 9374 } 9375 } 9376 9377 static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_instr, 9378 CastOp cast_op, 9379 ConstExprValue *other_val, ZigType *other_type, 9380 ConstExprValue *const_val, ZigType *new_type) 9381 { 9382 const_val->special = other_val->special; 9383 9384 assert(other_val != const_val); 9385 switch (cast_op) { 9386 case CastOpNoCast: 9387 zig_unreachable(); 9388 case CastOpErrSet: 9389 case CastOpBitCast: 9390 case CastOpPtrOfArrayToSlice: 9391 zig_panic("TODO"); 9392 case CastOpNoop: 9393 { 9394 bool same_global_refs = other_val->special == ConstValSpecialStatic; 9395 copy_const_val(const_val, other_val, same_global_refs); 9396 const_val->type = new_type; 9397 break; 9398 } 9399 case CastOpNumLitToConcrete: 9400 if (other_val->type->id == ZigTypeIdComptimeFloat) { 9401 assert(new_type->id == ZigTypeIdFloat); 9402 switch (new_type->data.floating.bit_count) { 9403 case 16: 9404 const_val->data.x_f16 = bigfloat_to_f16(&other_val->data.x_bigfloat); 9405 break; 9406 case 32: 9407 const_val->data.x_f32 = bigfloat_to_f32(&other_val->data.x_bigfloat); 9408 break; 9409 case 64: 9410 const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat); 9411 break; 9412 case 128: 9413 const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat); 9414 break; 9415 default: 9416 zig_unreachable(); 9417 } 9418 } else if (other_val->type->id == ZigTypeIdComptimeInt) { 9419 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint); 9420 } else { 9421 zig_unreachable(); 9422 } 9423 const_val->type = new_type; 9424 break; 9425 case CastOpResizeSlice: 9426 case CastOpBytesToSlice: 9427 // can't do it 9428 zig_unreachable(); 9429 case CastOpIntToFloat: 9430 { 9431 assert(new_type->id == ZigTypeIdFloat); 9432 9433 BigFloat bigfloat; 9434 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint); 9435 switch (new_type->data.floating.bit_count) { 9436 case 16: 9437 const_val->data.x_f16 = bigfloat_to_f16(&bigfloat); 9438 break; 9439 case 32: 9440 const_val->data.x_f32 = bigfloat_to_f32(&bigfloat); 9441 break; 9442 case 64: 9443 const_val->data.x_f64 = bigfloat_to_f64(&bigfloat); 9444 break; 9445 case 128: 9446 const_val->data.x_f128 = bigfloat_to_f128(&bigfloat); 9447 break; 9448 default: 9449 zig_unreachable(); 9450 } 9451 const_val->special = ConstValSpecialStatic; 9452 break; 9453 } 9454 case CastOpFloatToInt: 9455 float_init_bigint(&const_val->data.x_bigint, other_val); 9456 if (new_type->id == ZigTypeIdInt) { 9457 if (!bigint_fits_in_bits(&const_val->data.x_bigint, new_type->data.integral.bit_count, 9458 new_type->data.integral.is_signed)) 9459 { 9460 Buf *int_buf = buf_alloc(); 9461 bigint_append_buf(int_buf, &const_val->data.x_bigint, 10); 9462 9463 ir_add_error(ira, source_instr, 9464 buf_sprintf("integer value '%s' cannot be stored in type '%s'", 9465 buf_ptr(int_buf), buf_ptr(&new_type->name))); 9466 return false; 9467 } 9468 } 9469 9470 const_val->special = ConstValSpecialStatic; 9471 break; 9472 case CastOpBoolToInt: 9473 bigint_init_unsigned(&const_val->data.x_bigint, other_val->data.x_bool ? 1 : 0); 9474 const_val->special = ConstValSpecialStatic; 9475 break; 9476 } 9477 return true; 9478 } 9479 static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 9480 ZigType *wanted_type, CastOp cast_op, bool need_alloca) 9481 { 9482 if ((instr_is_comptime(value) || !type_has_bits(wanted_type)) && 9483 cast_op != CastOpResizeSlice && cast_op != CastOpBytesToSlice) 9484 { 9485 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9486 source_instr->source_node, wanted_type); 9487 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, &value->value, value->value.type, 9488 &result->value, wanted_type)) 9489 { 9490 return ira->codegen->invalid_instruction; 9491 } 9492 return result; 9493 } else { 9494 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op); 9495 result->value.type = wanted_type; 9496 if (need_alloca) { 9497 ir_add_alloca(ira, result, wanted_type); 9498 } 9499 return result; 9500 } 9501 } 9502 9503 static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrInstruction *source_instr, 9504 IrInstruction *value, ZigType *wanted_type) 9505 { 9506 assert(value->value.type->id == ZigTypeIdPointer); 9507 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, value->value.type->data.pointer.alignment); 9508 9509 if (instr_is_comptime(value)) { 9510 ConstExprValue *pointee = ir_const_ptr_pointee(ira, &value->value, source_instr->source_node); 9511 if (pointee == nullptr) 9512 return ira->codegen->invalid_instruction; 9513 if (pointee->special != ConstValSpecialRuntime) { 9514 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9515 source_instr->source_node, wanted_type); 9516 result->value.type = wanted_type; 9517 result->value.data.x_ptr.special = ConstPtrSpecialBaseArray; 9518 result->value.data.x_ptr.mut = value->value.data.x_ptr.mut; 9519 result->value.data.x_ptr.data.base_array.array_val = pointee; 9520 result->value.data.x_ptr.data.base_array.elem_index = 0; 9521 result->value.data.x_ptr.data.base_array.is_cstr = false; 9522 return result; 9523 } 9524 } 9525 9526 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 9527 wanted_type, value, CastOpBitCast); 9528 result->value.type = wanted_type; 9529 return result; 9530 } 9531 9532 static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, 9533 IrInstruction *value, ZigType *wanted_type) 9534 { 9535 wanted_type = adjust_slice_align(ira->codegen, wanted_type, value->value.type->data.pointer.alignment); 9536 9537 if (instr_is_comptime(value)) { 9538 ConstExprValue *pointee = ir_const_ptr_pointee(ira, &value->value, source_instr->source_node); 9539 if (pointee == nullptr) 9540 return ira->codegen->invalid_instruction; 9541 if (pointee->special != ConstValSpecialRuntime) { 9542 assert(value->value.type->id == ZigTypeIdPointer); 9543 ZigType *array_type = value->value.type->data.pointer.child_type; 9544 assert(is_slice(wanted_type)); 9545 bool is_const = wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; 9546 9547 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9548 source_instr->source_node, wanted_type); 9549 init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const); 9550 result->value.data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = 9551 value->value.data.x_ptr.mut; 9552 result->value.type = wanted_type; 9553 return result; 9554 } 9555 } 9556 9557 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 9558 wanted_type, value, CastOpPtrOfArrayToSlice); 9559 result->value.type = wanted_type; 9560 ir_add_alloca(ira, result, wanted_type); 9561 return result; 9562 } 9563 9564 static bool is_container(ZigType *type) { 9565 return type->id == ZigTypeIdStruct || 9566 type->id == ZigTypeIdEnum || 9567 type->id == ZigTypeIdUnion; 9568 } 9569 9570 static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { 9571 assert(old_bb); 9572 9573 if (old_bb->other) { 9574 if (ref_old_instruction == nullptr || old_bb->other->ref_instruction != ref_old_instruction) { 9575 return old_bb->other; 9576 } 9577 } 9578 9579 IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb); 9580 new_bb->ref_instruction = ref_old_instruction; 9581 9582 return new_bb; 9583 } 9584 9585 static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { 9586 assert(ref_old_instruction != nullptr); 9587 IrBasicBlock *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction); 9588 if (new_bb->must_be_comptime_source_instr) { 9589 ErrorMsg *msg = ir_add_error(ira, ref_old_instruction, 9590 buf_sprintf("control flow attempts to use compile-time variable at runtime")); 9591 add_error_note(ira->codegen, msg, new_bb->must_be_comptime_source_instr->source_node, 9592 buf_sprintf("compile-time variable assigned here")); 9593 return nullptr; 9594 } 9595 return new_bb; 9596 } 9597 9598 static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { 9599 ira->instruction_index = 0; 9600 ira->old_irb.current_basic_block = old_bb; 9601 ira->const_predecessor_bb = const_predecessor_bb; 9602 } 9603 9604 static void ir_finish_bb(IrAnalyze *ira) { 9605 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); 9606 ira->instruction_index += 1; 9607 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { 9608 IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 9609 if (!next_instruction->is_gen) { 9610 ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); 9611 break; 9612 } 9613 ira->instruction_index += 1; 9614 } 9615 9616 ira->old_bb_index += 1; 9617 9618 bool need_repeat = true; 9619 for (;;) { 9620 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 9621 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 9622 if (old_bb->other == nullptr) { 9623 ira->old_bb_index += 1; 9624 continue; 9625 } 9626 if (old_bb->other->instruction_list.length != 0) { 9627 ira->old_bb_index += 1; 9628 continue; 9629 } 9630 ira->new_irb.current_basic_block = old_bb->other; 9631 9632 ir_start_bb(ira, old_bb, nullptr); 9633 return; 9634 } 9635 if (!need_repeat) 9636 return; 9637 need_repeat = false; 9638 ira->old_bb_index = 0; 9639 continue; 9640 } 9641 } 9642 9643 static ZigType *ir_unreach_error(IrAnalyze *ira) { 9644 ira->old_bb_index = SIZE_MAX; 9645 ira->new_irb.exec->invalid = true; 9646 return ira->codegen->builtin_types.entry_unreachable; 9647 } 9648 9649 static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instruction) { 9650 size_t *bbc = ira->new_irb.exec->backward_branch_count; 9651 size_t quota = ira->new_irb.exec->backward_branch_quota; 9652 9653 // If we're already over quota, we've already given an error message for this. 9654 if (*bbc > quota) { 9655 return false; 9656 } 9657 9658 *bbc += 1; 9659 if (*bbc > quota) { 9660 ir_add_error(ira, source_instruction, buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", quota)); 9661 return false; 9662 } 9663 return true; 9664 } 9665 9666 static ZigType *ir_inline_bb(IrAnalyze *ira, IrInstruction *source_instruction, IrBasicBlock *old_bb) { 9667 if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) { 9668 if (!ir_emit_backward_branch(ira, source_instruction)) 9669 return ir_unreach_error(ira); 9670 } 9671 9672 old_bb->other = ira->old_irb.current_basic_block->other; 9673 ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block); 9674 return ira->codegen->builtin_types.entry_unreachable; 9675 } 9676 9677 static ZigType *ir_finish_anal(IrAnalyze *ira, ZigType *result_type) { 9678 if (result_type->id == ZigTypeIdUnreachable) 9679 ir_finish_bb(ira); 9680 return result_type; 9681 } 9682 9683 static IrInstruction *ir_get_const(IrAnalyze *ira, IrInstruction *old_instruction) { 9684 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 9685 old_instruction->scope, old_instruction->source_node); 9686 IrInstruction *new_instruction = &const_instruction->base; 9687 new_instruction->value.special = ConstValSpecialStatic; 9688 return new_instruction; 9689 } 9690 9691 static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_instruction) { 9692 IrInstruction *new_instruction = ir_get_const(ira, old_instruction); 9693 ir_link_new_instruction(new_instruction, old_instruction); 9694 return &new_instruction->value; 9695 } 9696 9697 static ZigType *ir_analyze_void(IrAnalyze *ira, IrInstruction *instruction) { 9698 ir_build_const_from(ira, instruction); 9699 return ira->codegen->builtin_types.entry_void; 9700 } 9701 9702 static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instruction, 9703 ConstExprValue *pointee, ZigType *pointee_type, 9704 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align) 9705 { 9706 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type, 9707 ptr_is_const, ptr_is_volatile, PtrLenSingle, ptr_align, 0, 0); 9708 IrInstruction *const_instr = ir_get_const(ira, instruction); 9709 ConstExprValue *const_val = &const_instr->value; 9710 const_val->type = ptr_type; 9711 const_val->data.x_ptr.special = ConstPtrSpecialRef; 9712 const_val->data.x_ptr.mut = ptr_mut; 9713 const_val->data.x_ptr.data.ref.pointee = pointee; 9714 return const_instr; 9715 } 9716 9717 static ZigType *ir_analyze_const_ptr(IrAnalyze *ira, IrInstruction *instruction, 9718 ConstExprValue *pointee, ZigType *pointee_type, 9719 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile) 9720 { 9721 IrInstruction *const_instr = ir_get_const_ptr(ira, instruction, pointee, 9722 pointee_type, ptr_mut, ptr_is_const, ptr_is_volatile, 9723 get_abi_alignment(ira->codegen, pointee_type)); 9724 ir_link_new_instruction(const_instr, instruction); 9725 return const_instr->value.type; 9726 } 9727 9728 static ZigType *ir_analyze_const_usize(IrAnalyze *ira, IrInstruction *instruction, uint64_t value) { 9729 ConstExprValue *const_val = ir_build_const_from(ira, instruction); 9730 bigint_init_unsigned(&const_val->data.x_bigint, value); 9731 return ira->codegen->builtin_types.entry_usize; 9732 } 9733 9734 enum UndefAllowed { 9735 UndefOk, 9736 UndefBad, 9737 }; 9738 9739 static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { 9740 switch (value->value.special) { 9741 case ConstValSpecialStatic: 9742 return &value->value; 9743 case ConstValSpecialRuntime: 9744 if (!type_has_bits(value->value.type)) { 9745 return &value->value; 9746 } 9747 ir_add_error(ira, value, buf_sprintf("unable to evaluate constant expression")); 9748 return nullptr; 9749 case ConstValSpecialUndef: 9750 if (undef_allowed == UndefOk) { 9751 return &value->value; 9752 } else { 9753 ir_add_error(ira, value, buf_sprintf("use of undefined value")); 9754 return nullptr; 9755 } 9756 } 9757 zig_unreachable(); 9758 } 9759 9760 IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, 9761 ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, 9762 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, 9763 IrExecutable *parent_exec) 9764 { 9765 if (expected_type != nullptr && type_is_invalid(expected_type)) 9766 return codegen->invalid_instruction; 9767 9768 IrExecutable *ir_executable = allocate<IrExecutable>(1); 9769 ir_executable->source_node = source_node; 9770 ir_executable->parent_exec = parent_exec; 9771 ir_executable->name = exec_name; 9772 ir_executable->is_inline = true; 9773 ir_executable->fn_entry = fn_entry; 9774 ir_executable->c_import_buf = c_import_buf; 9775 ir_executable->begin_scope = scope; 9776 ir_gen(codegen, node, scope, ir_executable); 9777 9778 if (ir_executable->invalid) 9779 return codegen->invalid_instruction; 9780 9781 if (codegen->verbose_ir) { 9782 fprintf(stderr, "\nSource: "); 9783 ast_render(codegen, stderr, node, 4); 9784 fprintf(stderr, "\n{ // (IR)\n"); 9785 ir_print(codegen, stderr, ir_executable, 4); 9786 fprintf(stderr, "}\n"); 9787 } 9788 IrExecutable *analyzed_executable = allocate<IrExecutable>(1); 9789 analyzed_executable->source_node = source_node; 9790 analyzed_executable->parent_exec = parent_exec; 9791 analyzed_executable->source_exec = ir_executable; 9792 analyzed_executable->name = exec_name; 9793 analyzed_executable->is_inline = true; 9794 analyzed_executable->fn_entry = fn_entry; 9795 analyzed_executable->c_import_buf = c_import_buf; 9796 analyzed_executable->backward_branch_count = backward_branch_count; 9797 analyzed_executable->backward_branch_quota = backward_branch_quota; 9798 analyzed_executable->begin_scope = scope; 9799 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, node); 9800 if (type_is_invalid(result_type)) 9801 return codegen->invalid_instruction; 9802 9803 if (codegen->verbose_ir) { 9804 fprintf(stderr, "{ // (analyzed)\n"); 9805 ir_print(codegen, stderr, analyzed_executable, 4); 9806 fprintf(stderr, "}\n"); 9807 } 9808 9809 return ir_exec_const_result(codegen, analyzed_executable); 9810 } 9811 9812 static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { 9813 if (type_is_invalid(type_value->value.type)) 9814 return ira->codegen->builtin_types.entry_invalid; 9815 9816 if (type_value->value.type->id != ZigTypeIdMetaType) { 9817 ir_add_error(ira, type_value, 9818 buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value.type->name))); 9819 return ira->codegen->builtin_types.entry_invalid; 9820 } 9821 9822 ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad); 9823 if (!const_val) 9824 return ira->codegen->builtin_types.entry_invalid; 9825 9826 return const_val->data.x_type; 9827 } 9828 9829 static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { 9830 if (fn_value == ira->codegen->invalid_instruction) 9831 return nullptr; 9832 9833 if (type_is_invalid(fn_value->value.type)) 9834 return nullptr; 9835 9836 if (fn_value->value.type->id != ZigTypeIdFn) { 9837 ir_add_error_node(ira, fn_value->source_node, 9838 buf_sprintf("expected function type, found '%s'", buf_ptr(&fn_value->value.type->name))); 9839 return nullptr; 9840 } 9841 9842 ConstExprValue *const_val = ir_resolve_const(ira, fn_value, UndefBad); 9843 if (!const_val) 9844 return nullptr; 9845 9846 assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction); 9847 return const_val->data.x_ptr.data.fn.fn_entry; 9848 } 9849 9850 static IrInstruction *ir_analyze_maybe_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { 9851 assert(wanted_type->id == ZigTypeIdOptional); 9852 9853 if (instr_is_comptime(value)) { 9854 ZigType *payload_type = wanted_type->data.maybe.child_type; 9855 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); 9856 if (type_is_invalid(casted_payload->value.type)) 9857 return ira->codegen->invalid_instruction; 9858 9859 ConstExprValue *val = ir_resolve_const(ira, casted_payload, UndefOk); 9860 if (!val) 9861 return ira->codegen->invalid_instruction; 9862 9863 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 9864 source_instr->scope, source_instr->source_node); 9865 const_instruction->base.value.special = ConstValSpecialStatic; 9866 if (get_codegen_ptr_type(wanted_type) != nullptr) { 9867 copy_const_val(&const_instruction->base.value, val, val->data.x_ptr.mut == ConstPtrMutComptimeConst); 9868 } else { 9869 const_instruction->base.value.data.x_optional = val; 9870 } 9871 const_instruction->base.value.type = wanted_type; 9872 return &const_instruction->base; 9873 } 9874 9875 IrInstruction *result = ir_build_maybe_wrap(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 9876 result->value.type = wanted_type; 9877 result->value.data.rh_maybe = RuntimeHintOptionalNonNull; 9878 ir_add_alloca(ira, result, wanted_type); 9879 return result; 9880 } 9881 9882 static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, 9883 IrInstruction *value, ZigType *wanted_type) 9884 { 9885 assert(wanted_type->id == ZigTypeIdErrorUnion); 9886 9887 if (instr_is_comptime(value)) { 9888 ZigType *payload_type = wanted_type->data.error_union.payload_type; 9889 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); 9890 if (type_is_invalid(casted_payload->value.type)) 9891 return ira->codegen->invalid_instruction; 9892 9893 ConstExprValue *val = ir_resolve_const(ira, casted_payload, UndefBad); 9894 if (!val) 9895 return ira->codegen->invalid_instruction; 9896 9897 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 9898 source_instr->scope, source_instr->source_node); 9899 const_instruction->base.value.type = wanted_type; 9900 const_instruction->base.value.special = ConstValSpecialStatic; 9901 const_instruction->base.value.data.x_err_union.err = nullptr; 9902 const_instruction->base.value.data.x_err_union.payload = val; 9903 return &const_instruction->base; 9904 } 9905 9906 IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 9907 result->value.type = wanted_type; 9908 result->value.data.rh_error_union = RuntimeHintErrorUnionNonError; 9909 ir_add_alloca(ira, result, wanted_type); 9910 return result; 9911 } 9912 9913 static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 9914 ZigType *wanted_type) 9915 { 9916 assert(value->value.type->id == ZigTypeIdErrorSet); 9917 assert(wanted_type->id == ZigTypeIdErrorSet); 9918 9919 if (instr_is_comptime(value)) { 9920 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 9921 if (!val) 9922 return ira->codegen->invalid_instruction; 9923 9924 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 9925 return ira->codegen->invalid_instruction; 9926 } 9927 if (!type_is_global_error_set(wanted_type)) { 9928 bool subset = false; 9929 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 9930 if (wanted_type->data.error_set.errors[i]->value == val->data.x_err_set->value) { 9931 subset = true; 9932 break; 9933 } 9934 } 9935 if (!subset) { 9936 ir_add_error(ira, source_instr, 9937 buf_sprintf("error.%s not a member of error set '%s'", 9938 buf_ptr(&val->data.x_err_set->name), buf_ptr(&wanted_type->name))); 9939 return ira->codegen->invalid_instruction; 9940 } 9941 } 9942 9943 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 9944 source_instr->scope, source_instr->source_node); 9945 const_instruction->base.value.type = wanted_type; 9946 const_instruction->base.value.special = ConstValSpecialStatic; 9947 const_instruction->base.value.data.x_err_set = val->data.x_err_set; 9948 return &const_instruction->base; 9949 } 9950 9951 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, CastOpErrSet); 9952 result->value.type = wanted_type; 9953 return result; 9954 } 9955 9956 static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { 9957 assert(wanted_type->id == ZigTypeIdErrorUnion); 9958 9959 IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); 9960 9961 if (instr_is_comptime(casted_value)) { 9962 ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad); 9963 if (!val) 9964 return ira->codegen->invalid_instruction; 9965 9966 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 9967 source_instr->scope, source_instr->source_node); 9968 const_instruction->base.value.type = wanted_type; 9969 const_instruction->base.value.special = ConstValSpecialStatic; 9970 const_instruction->base.value.data.x_err_union.err = val->data.x_err_set; 9971 const_instruction->base.value.data.x_err_union.payload = nullptr; 9972 return &const_instruction->base; 9973 } 9974 9975 IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 9976 result->value.type = wanted_type; 9977 result->value.data.rh_error_union = RuntimeHintErrorUnionError; 9978 ir_add_alloca(ira, result, wanted_type); 9979 return result; 9980 } 9981 9982 static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_instr, 9983 IrInstruction *value, ZigType *wanted_type) 9984 { 9985 if (instr_is_comptime(value)) { 9986 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 9987 if (!val) 9988 return ira->codegen->invalid_instruction; 9989 9990 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 9991 source_instr->scope, source_instr->source_node); 9992 const_instruction->base.value.type = wanted_type; 9993 const_instruction->base.value.special = ConstValSpecialStatic; 9994 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialRef; 9995 const_instruction->base.value.data.x_ptr.data.ref.pointee = val; 9996 return &const_instruction->base; 9997 } 9998 9999 if (value->id == IrInstructionIdLoadPtr) { 10000 IrInstructionLoadPtr *load_ptr_inst = (IrInstructionLoadPtr *)value; 10001 return load_ptr_inst->ptr; 10002 } else { 10003 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instr->scope, 10004 source_instr->source_node, value, true, false); 10005 new_instruction->value.type = wanted_type; 10006 10007 ZigType *child_type = wanted_type->data.pointer.child_type; 10008 if (type_has_bits(child_type)) { 10009 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 10010 assert(fn_entry); 10011 fn_entry->alloca_list.append(new_instruction); 10012 } 10013 ir_add_alloca(ira, new_instruction, child_type); 10014 return new_instruction; 10015 } 10016 } 10017 10018 static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { 10019 assert(wanted_type->id == ZigTypeIdOptional); 10020 assert(instr_is_comptime(value)); 10021 10022 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 10023 assert(val); 10024 10025 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, source_instr->scope, source_instr->source_node); 10026 const_instruction->base.value.special = ConstValSpecialStatic; 10027 if (get_codegen_ptr_type(wanted_type) != nullptr) { 10028 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 10029 const_instruction->base.value.data.x_ptr.data.hard_coded_addr.addr = 0; 10030 } else { 10031 const_instruction->base.value.data.x_optional = nullptr; 10032 } 10033 const_instruction->base.value.type = wanted_type; 10034 return &const_instruction->base; 10035 } 10036 10037 static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value, 10038 bool is_const, bool is_volatile) 10039 { 10040 if (type_is_invalid(value->value.type)) 10041 return ira->codegen->invalid_instruction; 10042 10043 if (instr_is_comptime(value)) { 10044 ConstExprValue *val = ir_resolve_const(ira, value, UndefOk); 10045 if (!val) 10046 return ira->codegen->invalid_instruction; 10047 return ir_get_const_ptr(ira, source_instruction, val, value->value.type, 10048 ConstPtrMutComptimeConst, is_const, is_volatile, 10049 get_abi_alignment(ira->codegen, value->value.type)); 10050 } 10051 10052 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, 10053 is_const, is_volatile, PtrLenSingle, get_abi_alignment(ira->codegen, value->value.type), 0, 0); 10054 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope, 10055 source_instruction->source_node, value, is_const, is_volatile); 10056 new_instruction->value.type = ptr_type; 10057 new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; 10058 if (type_has_bits(ptr_type)) { 10059 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 10060 assert(fn_entry); 10061 fn_entry->alloca_list.append(new_instruction); 10062 } 10063 return new_instruction; 10064 } 10065 10066 static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, 10067 IrInstruction *array_arg, ZigType *wanted_type) 10068 { 10069 assert(is_slice(wanted_type)); 10070 // In this function we honor the const-ness of wanted_type, because 10071 // we may be casting [0]T to []const T which is perfectly valid. 10072 10073 IrInstruction *array_ptr = nullptr; 10074 IrInstruction *array; 10075 if (array_arg->value.type->id == ZigTypeIdPointer) { 10076 array = ir_get_deref(ira, source_instr, array_arg); 10077 array_ptr = array_arg; 10078 } else { 10079 array = array_arg; 10080 } 10081 ZigType *array_type = array->value.type; 10082 assert(array_type->id == ZigTypeIdArray); 10083 10084 if (instr_is_comptime(array)) { 10085 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10086 source_instr->source_node, wanted_type); 10087 init_const_slice(ira->codegen, &result->value, &array->value, 0, array_type->data.array.len, true); 10088 result->value.type = wanted_type; 10089 return result; 10090 } 10091 10092 IrInstruction *start = ir_create_const(&ira->new_irb, source_instr->scope, 10093 source_instr->source_node, ira->codegen->builtin_types.entry_usize); 10094 init_const_usize(ira->codegen, &start->value, 0); 10095 10096 IrInstruction *end = ir_create_const(&ira->new_irb, source_instr->scope, 10097 source_instr->source_node, ira->codegen->builtin_types.entry_usize); 10098 init_const_usize(ira->codegen, &end->value, array_type->data.array.len); 10099 10100 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false); 10101 10102 IrInstruction *result = ir_build_slice(&ira->new_irb, source_instr->scope, 10103 source_instr->source_node, array_ptr, start, end, false); 10104 result->value.type = wanted_type; 10105 result->value.data.rh_slice.id = RuntimeHintSliceIdLen; 10106 result->value.data.rh_slice.len = array_type->data.array.len; 10107 ir_add_alloca(ira, result, result->value.type); 10108 10109 return result; 10110 } 10111 10112 static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *source_instr, 10113 IrInstruction *target, ZigType *wanted_type) 10114 { 10115 Error err; 10116 assert(wanted_type->id == ZigTypeIdInt); 10117 10118 ZigType *actual_type = target->value.type; 10119 if ((err = ensure_complete_type(ira->codegen, actual_type))) 10120 return ira->codegen->invalid_instruction; 10121 10122 if (wanted_type != actual_type->data.enumeration.tag_int_type) { 10123 ir_add_error(ira, source_instr, 10124 buf_sprintf("enum to integer cast to '%s' instead of its tag type, '%s'", 10125 buf_ptr(&wanted_type->name), 10126 buf_ptr(&actual_type->data.enumeration.tag_int_type->name))); 10127 return ira->codegen->invalid_instruction; 10128 } 10129 10130 assert(actual_type->id == ZigTypeIdEnum); 10131 10132 if (instr_is_comptime(target)) { 10133 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10134 if (!val) 10135 return ira->codegen->invalid_instruction; 10136 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10137 source_instr->source_node, wanted_type); 10138 init_const_bigint(&result->value, wanted_type, &val->data.x_enum_tag); 10139 return result; 10140 } 10141 10142 IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, 10143 source_instr->source_node, target); 10144 result->value.type = wanted_type; 10145 return result; 10146 } 10147 10148 static IrInstruction *ir_analyze_union_to_tag(IrAnalyze *ira, IrInstruction *source_instr, 10149 IrInstruction *target, ZigType *wanted_type) 10150 { 10151 assert(target->value.type->id == ZigTypeIdUnion); 10152 assert(wanted_type->id == ZigTypeIdEnum); 10153 assert(wanted_type == target->value.type->data.unionation.tag_type); 10154 10155 if (instr_is_comptime(target)) { 10156 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10157 if (!val) 10158 return ira->codegen->invalid_instruction; 10159 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10160 source_instr->source_node, wanted_type); 10161 result->value.special = ConstValSpecialStatic; 10162 result->value.type = wanted_type; 10163 bigint_init_bigint(&result->value.data.x_enum_tag, &val->data.x_union.tag); 10164 return result; 10165 } 10166 10167 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, 10168 source_instr->source_node, target); 10169 result->value.type = wanted_type; 10170 return result; 10171 } 10172 10173 static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruction *source_instr, 10174 IrInstruction *target, ZigType *wanted_type) 10175 { 10176 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10177 source_instr->source_node, wanted_type); 10178 init_const_undefined(ira->codegen, &result->value); 10179 return result; 10180 } 10181 10182 static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *source_instr, 10183 IrInstruction *target, ZigType *wanted_type) 10184 { 10185 Error err; 10186 assert(wanted_type->id == ZigTypeIdUnion); 10187 assert(target->value.type->id == ZigTypeIdEnum); 10188 10189 if (instr_is_comptime(target)) { 10190 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10191 if (!val) 10192 return ira->codegen->invalid_instruction; 10193 TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); 10194 assert(union_field != nullptr); 10195 if ((err = type_ensure_zero_bits_known(ira->codegen, union_field->type_entry))) 10196 return ira->codegen->invalid_instruction; 10197 if (!union_field->type_entry->zero_bits) { 10198 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at( 10199 union_field->enum_field->decl_index); 10200 ErrorMsg *msg = ir_add_error(ira, source_instr, 10201 buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", 10202 buf_ptr(&wanted_type->name), 10203 buf_ptr(&union_field->type_entry->name), 10204 buf_ptr(union_field->name))); 10205 add_error_note(ira->codegen, msg, field_node, 10206 buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); 10207 return ira->codegen->invalid_instruction; 10208 } 10209 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10210 source_instr->source_node, wanted_type); 10211 result->value.special = ConstValSpecialStatic; 10212 result->value.type = wanted_type; 10213 bigint_init_bigint(&result->value.data.x_union.tag, &val->data.x_enum_tag); 10214 return result; 10215 } 10216 10217 // if the union has all fields 0 bits, we can do it 10218 // and in fact it's a noop cast because the union value is just the enum value 10219 if (wanted_type->data.unionation.gen_field_count == 0) { 10220 IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, wanted_type, target, CastOpNoop); 10221 result->value.type = wanted_type; 10222 return result; 10223 } 10224 10225 ErrorMsg *msg = ir_add_error(ira, source_instr, 10226 buf_sprintf("runtime cast to union '%s' which has non-void fields", 10227 buf_ptr(&wanted_type->name))); 10228 for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { 10229 TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; 10230 if (type_has_bits(union_field->type_entry)) { 10231 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); 10232 add_error_note(ira->codegen, msg, field_node, 10233 buf_sprintf("field '%s' has type '%s'", 10234 buf_ptr(union_field->name), 10235 buf_ptr(&union_field->type_entry->name))); 10236 } 10237 } 10238 return ira->codegen->invalid_instruction; 10239 } 10240 10241 static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction *source_instr, 10242 IrInstruction *target, ZigType *wanted_type) 10243 { 10244 assert(wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdFloat); 10245 10246 if (instr_is_comptime(target)) { 10247 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10248 if (!val) 10249 return ira->codegen->invalid_instruction; 10250 if (wanted_type->id == ZigTypeIdInt) { 10251 if (bigint_cmp_zero(&val->data.x_bigint) == CmpLT && !wanted_type->data.integral.is_signed) { 10252 ir_add_error(ira, source_instr, 10253 buf_sprintf("attempt to cast negative value to unsigned integer")); 10254 return ira->codegen->invalid_instruction; 10255 } 10256 if (!bigint_fits_in_bits(&val->data.x_bigint, wanted_type->data.integral.bit_count, 10257 wanted_type->data.integral.is_signed)) 10258 { 10259 ir_add_error(ira, source_instr, 10260 buf_sprintf("cast from '%s' to '%s' truncates bits", 10261 buf_ptr(&target->value.type->name), buf_ptr(&wanted_type->name))); 10262 return ira->codegen->invalid_instruction; 10263 } 10264 } 10265 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10266 source_instr->source_node, wanted_type); 10267 result->value.type = wanted_type; 10268 if (wanted_type->id == ZigTypeIdInt) { 10269 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); 10270 } else { 10271 float_init_float(&result->value, val); 10272 } 10273 return result; 10274 } 10275 10276 IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, 10277 source_instr->source_node, target); 10278 result->value.type = wanted_type; 10279 return result; 10280 } 10281 10282 static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *source_instr, 10283 IrInstruction *target, ZigType *wanted_type) 10284 { 10285 Error err; 10286 assert(wanted_type->id == ZigTypeIdEnum); 10287 10288 ZigType *actual_type = target->value.type; 10289 10290 if ((err = ensure_complete_type(ira->codegen, wanted_type))) 10291 return ira->codegen->invalid_instruction; 10292 10293 if (actual_type != wanted_type->data.enumeration.tag_int_type) { 10294 ir_add_error(ira, source_instr, 10295 buf_sprintf("integer to enum cast from '%s' instead of its tag type, '%s'", 10296 buf_ptr(&actual_type->name), 10297 buf_ptr(&wanted_type->data.enumeration.tag_int_type->name))); 10298 return ira->codegen->invalid_instruction; 10299 } 10300 10301 assert(actual_type->id == ZigTypeIdInt); 10302 10303 if (instr_is_comptime(target)) { 10304 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10305 if (!val) 10306 return ira->codegen->invalid_instruction; 10307 10308 TypeEnumField *field = find_enum_field_by_tag(wanted_type, &val->data.x_bigint); 10309 if (field == nullptr) { 10310 Buf *val_buf = buf_alloc(); 10311 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 10312 ErrorMsg *msg = ir_add_error(ira, source_instr, 10313 buf_sprintf("enum '%s' has no tag matching integer value %s", 10314 buf_ptr(&wanted_type->name), buf_ptr(val_buf))); 10315 add_error_note(ira->codegen, msg, wanted_type->data.enumeration.decl_node, 10316 buf_sprintf("'%s' declared here", buf_ptr(&wanted_type->name))); 10317 return ira->codegen->invalid_instruction; 10318 } 10319 10320 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10321 source_instr->source_node, wanted_type); 10322 bigint_init_bigint(&result->value.data.x_enum_tag, &val->data.x_bigint); 10323 return result; 10324 } 10325 10326 IrInstruction *result = ir_build_int_to_enum(&ira->new_irb, source_instr->scope, 10327 source_instr->source_node, nullptr, target); 10328 result->value.type = wanted_type; 10329 return result; 10330 } 10331 10332 static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction *source_instr, 10333 IrInstruction *target, ZigType *wanted_type) 10334 { 10335 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10336 if (!val) 10337 return ira->codegen->invalid_instruction; 10338 10339 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10340 source_instr->source_node, wanted_type); 10341 if (wanted_type->id == ZigTypeIdComptimeFloat) { 10342 float_init_float(&result->value, val); 10343 } else if (wanted_type->id == ZigTypeIdComptimeInt) { 10344 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); 10345 } else { 10346 zig_unreachable(); 10347 } 10348 return result; 10349 } 10350 10351 static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 10352 ZigType *wanted_type) 10353 { 10354 assert(target->value.type->id == ZigTypeIdInt); 10355 assert(!target->value.type->data.integral.is_signed); 10356 assert(wanted_type->id == ZigTypeIdErrorSet); 10357 10358 if (instr_is_comptime(target)) { 10359 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10360 if (!val) 10361 return ira->codegen->invalid_instruction; 10362 10363 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10364 source_instr->source_node, wanted_type); 10365 10366 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 10367 return ira->codegen->invalid_instruction; 10368 } 10369 10370 if (type_is_global_error_set(wanted_type)) { 10371 BigInt err_count; 10372 bigint_init_unsigned(&err_count, ira->codegen->errors_by_index.length); 10373 10374 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) { 10375 Buf *val_buf = buf_alloc(); 10376 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 10377 ir_add_error(ira, source_instr, 10378 buf_sprintf("integer value %s represents no error", buf_ptr(val_buf))); 10379 return ira->codegen->invalid_instruction; 10380 } 10381 10382 size_t index = bigint_as_unsigned(&val->data.x_bigint); 10383 result->value.data.x_err_set = ira->codegen->errors_by_index.at(index); 10384 return result; 10385 } else { 10386 ErrorTableEntry *err = nullptr; 10387 BigInt err_int; 10388 10389 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 10390 ErrorTableEntry *this_err = wanted_type->data.error_set.errors[i]; 10391 bigint_init_unsigned(&err_int, this_err->value); 10392 if (bigint_cmp(&val->data.x_bigint, &err_int) == CmpEQ) { 10393 err = this_err; 10394 break; 10395 } 10396 } 10397 10398 if (err == nullptr) { 10399 Buf *val_buf = buf_alloc(); 10400 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 10401 ir_add_error(ira, source_instr, 10402 buf_sprintf("integer value %s represents no error in '%s'", buf_ptr(val_buf), buf_ptr(&wanted_type->name))); 10403 return ira->codegen->invalid_instruction; 10404 } 10405 10406 result->value.data.x_err_set = err; 10407 return result; 10408 } 10409 } 10410 10411 IrInstruction *result = ir_build_int_to_err(&ira->new_irb, source_instr->scope, source_instr->source_node, target); 10412 result->value.type = wanted_type; 10413 return result; 10414 } 10415 10416 static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 10417 ZigType *wanted_type) 10418 { 10419 assert(wanted_type->id == ZigTypeIdInt); 10420 10421 ZigType *err_type = target->value.type; 10422 10423 if (instr_is_comptime(target)) { 10424 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10425 if (!val) 10426 return ira->codegen->invalid_instruction; 10427 10428 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10429 source_instr->source_node, wanted_type); 10430 10431 ErrorTableEntry *err; 10432 if (err_type->id == ZigTypeIdErrorUnion) { 10433 err = val->data.x_err_union.err; 10434 } else if (err_type->id == ZigTypeIdErrorSet) { 10435 err = val->data.x_err_set; 10436 } else { 10437 zig_unreachable(); 10438 } 10439 result->value.type = wanted_type; 10440 uint64_t err_value = err ? err->value : 0; 10441 bigint_init_unsigned(&result->value.data.x_bigint, err_value); 10442 10443 if (!bigint_fits_in_bits(&result->value.data.x_bigint, 10444 wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) 10445 { 10446 ir_add_error_node(ira, source_instr->source_node, 10447 buf_sprintf("error code '%s' does not fit in '%s'", 10448 buf_ptr(&err->name), buf_ptr(&wanted_type->name))); 10449 return ira->codegen->invalid_instruction; 10450 } 10451 10452 return result; 10453 } 10454 10455 ZigType *err_set_type; 10456 if (err_type->id == ZigTypeIdErrorUnion) { 10457 err_set_type = err_type->data.error_union.err_set_type; 10458 } else if (err_type->id == ZigTypeIdErrorSet) { 10459 err_set_type = err_type; 10460 } else { 10461 zig_unreachable(); 10462 } 10463 if (!type_is_global_error_set(err_set_type)) { 10464 if (!resolve_inferred_error_set(ira->codegen, err_set_type, source_instr->source_node)) { 10465 return ira->codegen->invalid_instruction; 10466 } 10467 if (err_set_type->data.error_set.err_count == 0) { 10468 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10469 source_instr->source_node, wanted_type); 10470 result->value.type = wanted_type; 10471 bigint_init_unsigned(&result->value.data.x_bigint, 0); 10472 return result; 10473 } else if (err_set_type->data.error_set.err_count == 1) { 10474 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10475 source_instr->source_node, wanted_type); 10476 result->value.type = wanted_type; 10477 ErrorTableEntry *err = err_set_type->data.error_set.errors[0]; 10478 bigint_init_unsigned(&result->value.data.x_bigint, err->value); 10479 return result; 10480 } 10481 } 10482 10483 BigInt bn; 10484 bigint_init_unsigned(&bn, ira->codegen->errors_by_index.length); 10485 if (!bigint_fits_in_bits(&bn, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) { 10486 ir_add_error_node(ira, source_instr->source_node, 10487 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name))); 10488 return ira->codegen->invalid_instruction; 10489 } 10490 10491 IrInstruction *result = ir_build_err_to_int(&ira->new_irb, source_instr->scope, source_instr->source_node, target); 10492 result->value.type = wanted_type; 10493 return result; 10494 } 10495 10496 static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 10497 ZigType *wanted_type) 10498 { 10499 assert(wanted_type->id == ZigTypeIdPointer); 10500 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, target->value.type->data.pointer.alignment); 10501 ZigType *array_type = wanted_type->data.pointer.child_type; 10502 assert(array_type->id == ZigTypeIdArray); 10503 assert(array_type->data.array.len == 1); 10504 10505 if (instr_is_comptime(target)) { 10506 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10507 if (!val) 10508 return ira->codegen->invalid_instruction; 10509 10510 assert(val->type->id == ZigTypeIdPointer); 10511 ConstExprValue *pointee = ir_const_ptr_pointee(ira, val, source_instr->source_node); 10512 if (pointee == nullptr) 10513 return ira->codegen->invalid_instruction; 10514 if (pointee->special != ConstValSpecialRuntime) { 10515 ConstExprValue *array_val = create_const_vals(1); 10516 array_val->special = ConstValSpecialStatic; 10517 array_val->type = array_type; 10518 array_val->data.x_array.special = ConstArraySpecialNone; 10519 array_val->data.x_array.s_none.elements = pointee; 10520 array_val->data.x_array.s_none.parent.id = ConstParentIdScalar; 10521 array_val->data.x_array.s_none.parent.data.p_scalar.scalar_val = pointee; 10522 10523 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 10524 source_instr->scope, source_instr->source_node); 10525 const_instruction->base.value.type = wanted_type; 10526 const_instruction->base.value.special = ConstValSpecialStatic; 10527 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialRef; 10528 const_instruction->base.value.data.x_ptr.data.ref.pointee = array_val; 10529 const_instruction->base.value.data.x_ptr.mut = val->data.x_ptr.mut; 10530 return &const_instruction->base; 10531 } 10532 } 10533 10534 // pointer to array and pointer to single item are represented the same way at runtime 10535 IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, 10536 wanted_type, target, CastOpBitCast); 10537 result->value.type = wanted_type; 10538 return result; 10539 } 10540 10541 static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCastOnly *cast_result, 10542 ErrorMsg *parent_msg) 10543 { 10544 switch (cast_result->id) { 10545 case ConstCastResultIdOk: 10546 zig_unreachable(); 10547 case ConstCastResultIdOptionalChild: { 10548 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 10549 buf_sprintf("optional type child '%s' cannot cast into optional type child '%s'", 10550 buf_ptr(&cast_result->data.optional->actual_child->name), 10551 buf_ptr(&cast_result->data.optional->wanted_child->name))); 10552 report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg); 10553 break; 10554 } 10555 case ConstCastResultIdErrorUnionErrorSet: { 10556 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 10557 buf_sprintf("error set '%s' cannot cast into error set '%s'", 10558 buf_ptr(&cast_result->data.error_union_error_set->actual_err_set->name), 10559 buf_ptr(&cast_result->data.error_union_error_set->wanted_err_set->name))); 10560 report_recursive_error(ira, source_node, &cast_result->data.error_union_error_set->child, msg); 10561 break; 10562 } 10563 case ConstCastResultIdErrSet: { 10564 ZigList<ErrorTableEntry *> *missing_errors = &cast_result->data.error_set_mismatch->missing_errors; 10565 for (size_t i = 0; i < missing_errors->length; i += 1) { 10566 ErrorTableEntry *error_entry = missing_errors->at(i); 10567 add_error_note(ira->codegen, parent_msg, error_entry->decl_node, 10568 buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name))); 10569 } 10570 break; 10571 } 10572 case ConstCastResultIdErrSetGlobal: { 10573 add_error_note(ira->codegen, parent_msg, source_node, 10574 buf_sprintf("cannot cast global error set into smaller set")); 10575 break; 10576 } 10577 case ConstCastResultIdPointerChild: { 10578 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 10579 buf_sprintf("pointer type child '%s' cannot cast into pointer type child '%s'", 10580 buf_ptr(&cast_result->data.pointer_mismatch->actual_child->name), 10581 buf_ptr(&cast_result->data.pointer_mismatch->wanted_child->name))); 10582 report_recursive_error(ira, source_node, &cast_result->data.pointer_mismatch->child, msg); 10583 break; 10584 } 10585 case ConstCastResultIdSliceChild: { 10586 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 10587 buf_sprintf("slice type child '%s' cannot cast into slice type child '%s'", 10588 buf_ptr(&cast_result->data.slice_mismatch->actual_child->name), 10589 buf_ptr(&cast_result->data.slice_mismatch->wanted_child->name))); 10590 report_recursive_error(ira, source_node, &cast_result->data.slice_mismatch->child, msg); 10591 break; 10592 } 10593 case ConstCastResultIdErrorUnionPayload: { 10594 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 10595 buf_sprintf("error union payload '%s' cannot cast into error union payload '%s'", 10596 buf_ptr(&cast_result->data.error_union_payload->actual_payload->name), 10597 buf_ptr(&cast_result->data.error_union_payload->wanted_payload->name))); 10598 report_recursive_error(ira, source_node, &cast_result->data.error_union_payload->child, msg); 10599 break; 10600 } 10601 case ConstCastResultIdType: { 10602 AstNode *wanted_decl_node = type_decl_node(cast_result->data.type_mismatch->wanted_type); 10603 AstNode *actual_decl_node = type_decl_node(cast_result->data.type_mismatch->actual_type); 10604 if (wanted_decl_node != nullptr) { 10605 add_error_note(ira->codegen, parent_msg, wanted_decl_node, 10606 buf_sprintf("%s declared here", 10607 buf_ptr(&cast_result->data.type_mismatch->wanted_type->name))); 10608 } 10609 if (actual_decl_node != nullptr) { 10610 add_error_note(ira->codegen, parent_msg, actual_decl_node, 10611 buf_sprintf("%s declared here", 10612 buf_ptr(&cast_result->data.type_mismatch->actual_type->name))); 10613 } 10614 break; 10615 } 10616 case ConstCastResultIdFnAlign: // TODO 10617 case ConstCastResultIdFnCC: // TODO 10618 case ConstCastResultIdFnVarArgs: // TODO 10619 case ConstCastResultIdFnIsGeneric: // TODO 10620 case ConstCastResultIdFnReturnType: // TODO 10621 case ConstCastResultIdFnArgCount: // TODO 10622 case ConstCastResultIdFnGenericArgCount: // TODO 10623 case ConstCastResultIdFnArg: // TODO 10624 case ConstCastResultIdFnArgNoAlias: // TODO 10625 case ConstCastResultIdUnresolvedInferredErrSet: // TODO 10626 case ConstCastResultIdAsyncAllocatorType: // TODO 10627 case ConstCastResultIdNullWrapPtr: // TODO 10628 break; 10629 } 10630 } 10631 10632 static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, 10633 ZigType *wanted_type, IrInstruction *value) 10634 { 10635 Error err; 10636 ZigType *actual_type = value->value.type; 10637 AstNode *source_node = source_instr->source_node; 10638 10639 if (type_is_invalid(wanted_type) || type_is_invalid(actual_type)) { 10640 return ira->codegen->invalid_instruction; 10641 } 10642 10643 // perfect match or non-const to const 10644 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, 10645 source_node, false); 10646 if (const_cast_result.id == ConstCastResultIdOk) { 10647 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); 10648 } 10649 10650 // widening conversion 10651 if (wanted_type->id == ZigTypeIdInt && 10652 actual_type->id == ZigTypeIdInt && 10653 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed && 10654 wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count) 10655 { 10656 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 10657 } 10658 10659 // small enough unsigned ints can get casted to large enough signed ints 10660 if (wanted_type->id == ZigTypeIdInt && wanted_type->data.integral.is_signed && 10661 actual_type->id == ZigTypeIdInt && !actual_type->data.integral.is_signed && 10662 wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count) 10663 { 10664 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 10665 } 10666 10667 // float widening conversion 10668 if (wanted_type->id == ZigTypeIdFloat && 10669 actual_type->id == ZigTypeIdFloat && 10670 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count) 10671 { 10672 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 10673 } 10674 10675 10676 // cast from [N]T to []const T 10677 if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) { 10678 ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 10679 assert(ptr_type->id == ZigTypeIdPointer); 10680 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 10681 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 10682 source_node, false).id == ConstCastResultIdOk) 10683 { 10684 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type); 10685 } 10686 } 10687 10688 // cast from *const [N]T to []const T 10689 if (is_slice(wanted_type) && 10690 actual_type->id == ZigTypeIdPointer && 10691 actual_type->data.pointer.is_const && 10692 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 10693 { 10694 ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 10695 assert(ptr_type->id == ZigTypeIdPointer); 10696 10697 ZigType *array_type = actual_type->data.pointer.child_type; 10698 10699 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) && 10700 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, array_type->data.array.child_type, 10701 source_node, false).id == ConstCastResultIdOk) 10702 { 10703 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type); 10704 } 10705 } 10706 10707 // cast from [N]T to *const []const T 10708 if (wanted_type->id == ZigTypeIdPointer && 10709 wanted_type->data.pointer.is_const && 10710 is_slice(wanted_type->data.pointer.child_type) && 10711 actual_type->id == ZigTypeIdArray) 10712 { 10713 ZigType *ptr_type = 10714 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry; 10715 assert(ptr_type->id == ZigTypeIdPointer); 10716 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 10717 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 10718 source_node, false).id == ConstCastResultIdOk) 10719 { 10720 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value); 10721 if (type_is_invalid(cast1->value.type)) 10722 return ira->codegen->invalid_instruction; 10723 10724 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 10725 if (type_is_invalid(cast2->value.type)) 10726 return ira->codegen->invalid_instruction; 10727 10728 return cast2; 10729 } 10730 } 10731 10732 // cast from [N]T to ?[]const T 10733 if (wanted_type->id == ZigTypeIdOptional && 10734 is_slice(wanted_type->data.maybe.child_type) && 10735 actual_type->id == ZigTypeIdArray) 10736 { 10737 ZigType *ptr_type = 10738 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry; 10739 assert(ptr_type->id == ZigTypeIdPointer); 10740 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 10741 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 10742 source_node, false).id == ConstCastResultIdOk) 10743 { 10744 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); 10745 if (type_is_invalid(cast1->value.type)) 10746 return ira->codegen->invalid_instruction; 10747 10748 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 10749 if (type_is_invalid(cast2->value.type)) 10750 return ira->codegen->invalid_instruction; 10751 10752 return cast2; 10753 } 10754 } 10755 10756 // *[N]T to [*]T 10757 if (wanted_type->id == ZigTypeIdPointer && 10758 wanted_type->data.pointer.ptr_len == PtrLenUnknown && 10759 actual_type->id == ZigTypeIdPointer && 10760 actual_type->data.pointer.ptr_len == PtrLenSingle && 10761 actual_type->data.pointer.child_type->id == ZigTypeIdArray && 10762 actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment && 10763 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 10764 actual_type->data.pointer.child_type->data.array.child_type, source_node, 10765 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 10766 { 10767 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type); 10768 } 10769 10770 // *[N]T to []T 10771 if (is_slice(wanted_type) && 10772 actual_type->id == ZigTypeIdPointer && 10773 actual_type->data.pointer.ptr_len == PtrLenSingle && 10774 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 10775 { 10776 ZigType *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 10777 assert(slice_ptr_type->id == ZigTypeIdPointer); 10778 if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 10779 actual_type->data.pointer.child_type->data.array.child_type, source_node, 10780 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) 10781 { 10782 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type); 10783 } 10784 } 10785 10786 10787 // cast from T to ?T 10788 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism 10789 if (wanted_type->id == ZigTypeIdOptional) { 10790 ZigType *wanted_child_type = wanted_type->data.maybe.child_type; 10791 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, 10792 false).id == ConstCastResultIdOk) 10793 { 10794 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); 10795 } else if (actual_type->id == ZigTypeIdComptimeInt || 10796 actual_type->id == ZigTypeIdComptimeFloat) 10797 { 10798 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { 10799 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); 10800 } else { 10801 return ira->codegen->invalid_instruction; 10802 } 10803 } else if (wanted_child_type->id == ZigTypeIdPointer && 10804 wanted_child_type->data.pointer.is_const && 10805 (actual_type->id == ZigTypeIdPointer || is_container(actual_type))) 10806 { 10807 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_child_type, value); 10808 if (type_is_invalid(cast1->value.type)) 10809 return ira->codegen->invalid_instruction; 10810 10811 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 10812 if (type_is_invalid(cast2->value.type)) 10813 return ira->codegen->invalid_instruction; 10814 10815 return cast2; 10816 } else if ( 10817 wanted_child_type->id == ZigTypeIdPointer && 10818 wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && 10819 actual_type->id == ZigTypeIdPointer && 10820 actual_type->data.pointer.ptr_len == PtrLenSingle && 10821 actual_type->data.pointer.child_type->id == ZigTypeIdArray && 10822 actual_type->data.pointer.alignment >= wanted_child_type->data.pointer.alignment && 10823 types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, 10824 actual_type->data.pointer.child_type->data.array.child_type, source_node, 10825 !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) 10826 { 10827 IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_child_type); 10828 if (type_is_invalid(cast1->value.type)) 10829 return ira->codegen->invalid_instruction; 10830 return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type); 10831 } 10832 } 10833 10834 // cast from null literal to maybe type 10835 if (wanted_type->id == ZigTypeIdOptional && 10836 actual_type->id == ZigTypeIdNull) 10837 { 10838 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); 10839 } 10840 10841 // cast from child type of error type to error type 10842 if (wanted_type->id == ZigTypeIdErrorUnion) { 10843 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, 10844 source_node, false).id == ConstCastResultIdOk) 10845 { 10846 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); 10847 } else if (actual_type->id == ZigTypeIdComptimeInt || 10848 actual_type->id == ZigTypeIdComptimeFloat) 10849 { 10850 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { 10851 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); 10852 } else { 10853 return ira->codegen->invalid_instruction; 10854 } 10855 } 10856 } 10857 10858 // cast from [N]T to E![]const T 10859 if (wanted_type->id == ZigTypeIdErrorUnion && 10860 is_slice(wanted_type->data.error_union.payload_type) && 10861 actual_type->id == ZigTypeIdArray) 10862 { 10863 ZigType *ptr_type = 10864 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry; 10865 assert(ptr_type->id == ZigTypeIdPointer); 10866 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 10867 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 10868 source_node, false).id == ConstCastResultIdOk) 10869 { 10870 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); 10871 if (type_is_invalid(cast1->value.type)) 10872 return ira->codegen->invalid_instruction; 10873 10874 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 10875 if (type_is_invalid(cast2->value.type)) 10876 return ira->codegen->invalid_instruction; 10877 10878 return cast2; 10879 } 10880 } 10881 10882 // cast from error set to error union type 10883 if (wanted_type->id == ZigTypeIdErrorUnion && 10884 actual_type->id == ZigTypeIdErrorSet) 10885 { 10886 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type); 10887 } 10888 10889 // cast from T to E!?T 10890 if (wanted_type->id == ZigTypeIdErrorUnion && 10891 wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && 10892 actual_type->id != ZigTypeIdOptional) 10893 { 10894 ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; 10895 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || 10896 actual_type->id == ZigTypeIdNull || 10897 actual_type->id == ZigTypeIdComptimeInt || 10898 actual_type->id == ZigTypeIdComptimeFloat) 10899 { 10900 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); 10901 if (type_is_invalid(cast1->value.type)) 10902 return ira->codegen->invalid_instruction; 10903 10904 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 10905 if (type_is_invalid(cast2->value.type)) 10906 return ira->codegen->invalid_instruction; 10907 10908 return cast2; 10909 } 10910 } 10911 10912 // cast from number literal to another type 10913 // cast from number literal to *const integer 10914 if (actual_type->id == ZigTypeIdComptimeFloat || 10915 actual_type->id == ZigTypeIdComptimeInt) 10916 { 10917 if ((err = ensure_complete_type(ira->codegen, wanted_type))) 10918 return ira->codegen->invalid_instruction; 10919 if (wanted_type->id == ZigTypeIdEnum) { 10920 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.enumeration.tag_int_type, value); 10921 if (type_is_invalid(cast1->value.type)) 10922 return ira->codegen->invalid_instruction; 10923 10924 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 10925 if (type_is_invalid(cast2->value.type)) 10926 return ira->codegen->invalid_instruction; 10927 10928 return cast2; 10929 } else if (wanted_type->id == ZigTypeIdPointer && 10930 wanted_type->data.pointer.is_const) 10931 { 10932 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value); 10933 if (type_is_invalid(cast1->value.type)) 10934 return ira->codegen->invalid_instruction; 10935 10936 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 10937 if (type_is_invalid(cast2->value.type)) 10938 return ira->codegen->invalid_instruction; 10939 10940 return cast2; 10941 } else if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { 10942 CastOp op; 10943 if ((actual_type->id == ZigTypeIdComptimeFloat && 10944 wanted_type->id == ZigTypeIdFloat) || 10945 (actual_type->id == ZigTypeIdComptimeInt && 10946 wanted_type->id == ZigTypeIdInt)) 10947 { 10948 op = CastOpNumLitToConcrete; 10949 } else if (wanted_type->id == ZigTypeIdInt) { 10950 op = CastOpFloatToInt; 10951 } else if (wanted_type->id == ZigTypeIdFloat) { 10952 op = CastOpIntToFloat; 10953 } else { 10954 zig_unreachable(); 10955 } 10956 return ir_resolve_cast(ira, source_instr, value, wanted_type, op, false); 10957 } else { 10958 return ira->codegen->invalid_instruction; 10959 } 10960 } 10961 10962 // cast from typed number to integer or float literal. 10963 // works when the number is known at compile time 10964 if (instr_is_comptime(value) && 10965 ((actual_type->id == ZigTypeIdInt && wanted_type->id == ZigTypeIdComptimeInt) || 10966 (actual_type->id == ZigTypeIdFloat && wanted_type->id == ZigTypeIdComptimeFloat))) 10967 { 10968 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type); 10969 } 10970 10971 // cast from union to the enum type of the union 10972 if (actual_type->id == ZigTypeIdUnion && wanted_type->id == ZigTypeIdEnum) { 10973 if ((err = type_ensure_zero_bits_known(ira->codegen, actual_type))) 10974 return ira->codegen->invalid_instruction; 10975 10976 if (actual_type->data.unionation.tag_type == wanted_type) { 10977 return ir_analyze_union_to_tag(ira, source_instr, value, wanted_type); 10978 } 10979 } 10980 10981 // enum to union which has the enum as the tag type 10982 if (wanted_type->id == ZigTypeIdUnion && actual_type->id == ZigTypeIdEnum && 10983 (wanted_type->data.unionation.decl_node->data.container_decl.auto_enum || 10984 wanted_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 10985 { 10986 if ((err = type_ensure_zero_bits_known(ira->codegen, wanted_type))) 10987 return ira->codegen->invalid_instruction; 10988 10989 if (wanted_type->data.unionation.tag_type == actual_type) { 10990 return ir_analyze_enum_to_union(ira, source_instr, value, wanted_type); 10991 } 10992 } 10993 10994 // enum to &const union which has the enum as the tag type 10995 if (actual_type->id == ZigTypeIdEnum && wanted_type->id == ZigTypeIdPointer) { 10996 ZigType *union_type = wanted_type->data.pointer.child_type; 10997 if (union_type->data.unionation.decl_node->data.container_decl.auto_enum || 10998 union_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr) 10999 { 11000 if ((err = type_ensure_zero_bits_known(ira->codegen, union_type))) 11001 return ira->codegen->invalid_instruction; 11002 11003 if (union_type->data.unionation.tag_type == actual_type) { 11004 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, union_type, value); 11005 if (type_is_invalid(cast1->value.type)) 11006 return ira->codegen->invalid_instruction; 11007 11008 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 11009 if (type_is_invalid(cast2->value.type)) 11010 return ira->codegen->invalid_instruction; 11011 11012 return cast2; 11013 } 11014 } 11015 } 11016 11017 // cast from *T to *[1]T 11018 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 11019 actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle) 11020 { 11021 ZigType *array_type = wanted_type->data.pointer.child_type; 11022 if (array_type->id == ZigTypeIdArray && array_type->data.array.len == 1 && 11023 types_match_const_cast_only(ira, array_type->data.array.child_type, 11024 actual_type->data.pointer.child_type, source_node, 11025 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 11026 { 11027 if (wanted_type->data.pointer.alignment > actual_type->data.pointer.alignment) { 11028 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 11029 add_error_note(ira->codegen, msg, value->source_node, 11030 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&actual_type->name), 11031 actual_type->data.pointer.alignment)); 11032 add_error_note(ira->codegen, msg, source_instr->source_node, 11033 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&wanted_type->name), 11034 wanted_type->data.pointer.alignment)); 11035 return ira->codegen->invalid_instruction; 11036 } 11037 return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type); 11038 } 11039 } 11040 11041 // cast from T to *T where T is zero bits 11042 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 11043 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 11044 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 11045 { 11046 if ((err = type_ensure_zero_bits_known(ira->codegen, actual_type))) { 11047 return ira->codegen->invalid_instruction; 11048 } 11049 if (!type_has_bits(actual_type)) { 11050 return ir_get_ref(ira, source_instr, value, false, false); 11051 } 11052 } 11053 11054 11055 // cast from undefined to anything 11056 if (actual_type->id == ZigTypeIdUndefined) { 11057 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); 11058 } 11059 11060 // cast from something to const pointer of it 11061 if (!type_requires_comptime(actual_type)) { 11062 ZigType *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true); 11063 if (types_match_const_cast_only(ira, wanted_type, const_ptr_actual, source_node, false).id == ConstCastResultIdOk) { 11064 return ir_analyze_cast_ref(ira, source_instr, value, wanted_type); 11065 } 11066 } 11067 11068 ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, 11069 buf_sprintf("expected type '%s', found '%s'", 11070 buf_ptr(&wanted_type->name), 11071 buf_ptr(&actual_type->name))); 11072 report_recursive_error(ira, source_instr->source_node, &const_cast_result, parent_msg); 11073 return ira->codegen->invalid_instruction; 11074 } 11075 11076 static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { 11077 assert(value); 11078 assert(value != ira->codegen->invalid_instruction); 11079 assert(!expected_type || !type_is_invalid(expected_type)); 11080 assert(value->value.type); 11081 assert(!type_is_invalid(value->value.type)); 11082 if (expected_type == nullptr) 11083 return value; // anything will do 11084 if (expected_type == value->value.type) 11085 return value; // match 11086 if (value->value.type->id == ZigTypeIdUnreachable) 11087 return value; 11088 11089 return ir_analyze_cast(ira, value, expected_type, value); 11090 } 11091 11092 static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) { 11093 ZigType *type_entry = ptr->value.type; 11094 if (type_is_invalid(type_entry)) { 11095 return ira->codegen->invalid_instruction; 11096 } else if (type_entry->id == ZigTypeIdPointer) { 11097 ZigType *child_type = type_entry->data.pointer.child_type; 11098 if (instr_is_comptime(ptr)) { 11099 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst || 11100 ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) 11101 { 11102 ConstExprValue *pointee = ir_const_ptr_pointee(ira, &ptr->value, source_instruction->source_node); 11103 if (pointee == nullptr) 11104 return ira->codegen->invalid_instruction; 11105 if (pointee->special != ConstValSpecialRuntime) { 11106 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope, 11107 source_instruction->source_node, child_type); 11108 copy_const_val(&result->value, pointee, ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst); 11109 result->value.type = child_type; 11110 return result; 11111 } 11112 } 11113 } 11114 // TODO if the instruction is a const ref instruction we can skip it 11115 IrInstruction *load_ptr_instruction = ir_build_load_ptr(&ira->new_irb, source_instruction->scope, 11116 source_instruction->source_node, ptr); 11117 load_ptr_instruction->value.type = child_type; 11118 return load_ptr_instruction; 11119 } else { 11120 ir_add_error_node(ira, source_instruction->source_node, 11121 buf_sprintf("attempt to dereference non pointer type '%s'", 11122 buf_ptr(&type_entry->name))); 11123 return ira->codegen->invalid_instruction; 11124 } 11125 } 11126 11127 static ZigType *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value, 11128 bool is_const, bool is_volatile) 11129 { 11130 IrInstruction *result = ir_get_ref(ira, source_instruction, value, is_const, is_volatile); 11131 ir_link_new_instruction(result, source_instruction); 11132 return result->value.type; 11133 } 11134 11135 static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { 11136 if (type_is_invalid(value->value.type)) 11137 return false; 11138 11139 IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); 11140 if (type_is_invalid(casted_value->value.type)) 11141 return false; 11142 11143 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 11144 if (!const_val) 11145 return false; 11146 11147 uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint); 11148 if (align_bytes == 0) { 11149 ir_add_error(ira, value, buf_sprintf("alignment must be >= 1")); 11150 return false; 11151 } 11152 11153 if (!is_power_of_2(align_bytes)) { 11154 ir_add_error(ira, value, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); 11155 return false; 11156 } 11157 11158 *out = align_bytes; 11159 return true; 11160 } 11161 11162 static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { 11163 if (type_is_invalid(value->value.type)) 11164 return false; 11165 11166 IrInstruction *casted_value = ir_implicit_cast(ira, value, int_type); 11167 if (type_is_invalid(casted_value->value.type)) 11168 return false; 11169 11170 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 11171 if (!const_val) 11172 return false; 11173 11174 *out = bigint_as_unsigned(&const_val->data.x_bigint); 11175 return true; 11176 } 11177 11178 static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) { 11179 return ir_resolve_unsigned(ira, value, ira->codegen->builtin_types.entry_usize, out); 11180 } 11181 11182 static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) { 11183 if (type_is_invalid(value->value.type)) 11184 return false; 11185 11186 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_bool); 11187 if (type_is_invalid(casted_value->value.type)) 11188 return false; 11189 11190 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 11191 if (!const_val) 11192 return false; 11193 11194 *out = const_val->data.x_bool; 11195 return true; 11196 } 11197 11198 static bool ir_resolve_comptime(IrAnalyze *ira, IrInstruction *value, bool *out) { 11199 if (!value) { 11200 *out = false; 11201 return true; 11202 } 11203 return ir_resolve_bool(ira, value, out); 11204 } 11205 11206 static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, AtomicOrder *out) { 11207 if (type_is_invalid(value->value.type)) 11208 return false; 11209 11210 ConstExprValue *atomic_order_val = get_builtin_value(ira->codegen, "AtomicOrder"); 11211 assert(atomic_order_val->type->id == ZigTypeIdMetaType); 11212 ZigType *atomic_order_type = atomic_order_val->data.x_type; 11213 11214 IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_order_type); 11215 if (type_is_invalid(casted_value->value.type)) 11216 return false; 11217 11218 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 11219 if (!const_val) 11220 return false; 11221 11222 *out = (AtomicOrder)bigint_as_unsigned(&const_val->data.x_enum_tag); 11223 return true; 11224 } 11225 11226 static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstruction *value, AtomicRmwOp *out) { 11227 if (type_is_invalid(value->value.type)) 11228 return false; 11229 11230 ConstExprValue *atomic_rmw_op_val = get_builtin_value(ira->codegen, "AtomicRmwOp"); 11231 assert(atomic_rmw_op_val->type->id == ZigTypeIdMetaType); 11232 ZigType *atomic_rmw_op_type = atomic_rmw_op_val->data.x_type; 11233 11234 IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_rmw_op_type); 11235 if (type_is_invalid(casted_value->value.type)) 11236 return false; 11237 11238 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 11239 if (!const_val) 11240 return false; 11241 11242 *out = (AtomicRmwOp)bigint_as_unsigned(&const_val->data.x_enum_tag); 11243 return true; 11244 } 11245 11246 static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstruction *value, GlobalLinkageId *out) { 11247 if (type_is_invalid(value->value.type)) 11248 return false; 11249 11250 ConstExprValue *global_linkage_val = get_builtin_value(ira->codegen, "GlobalLinkage"); 11251 assert(global_linkage_val->type->id == ZigTypeIdMetaType); 11252 ZigType *global_linkage_type = global_linkage_val->data.x_type; 11253 11254 IrInstruction *casted_value = ir_implicit_cast(ira, value, global_linkage_type); 11255 if (type_is_invalid(casted_value->value.type)) 11256 return false; 11257 11258 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 11259 if (!const_val) 11260 return false; 11261 11262 *out = (GlobalLinkageId)bigint_as_unsigned(&const_val->data.x_enum_tag); 11263 return true; 11264 } 11265 11266 static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMode *out) { 11267 if (type_is_invalid(value->value.type)) 11268 return false; 11269 11270 ConstExprValue *float_mode_val = get_builtin_value(ira->codegen, "FloatMode"); 11271 assert(float_mode_val->type->id == ZigTypeIdMetaType); 11272 ZigType *float_mode_type = float_mode_val->data.x_type; 11273 11274 IrInstruction *casted_value = ir_implicit_cast(ira, value, float_mode_type); 11275 if (type_is_invalid(casted_value->value.type)) 11276 return false; 11277 11278 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 11279 if (!const_val) 11280 return false; 11281 11282 *out = (FloatMode)bigint_as_unsigned(&const_val->data.x_enum_tag); 11283 return true; 11284 } 11285 11286 11287 static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { 11288 if (type_is_invalid(value->value.type)) 11289 return nullptr; 11290 11291 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 11292 true, false, PtrLenUnknown, 11293 get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0); 11294 ZigType *str_type = get_slice_type(ira->codegen, ptr_type); 11295 IrInstruction *casted_value = ir_implicit_cast(ira, value, str_type); 11296 if (type_is_invalid(casted_value->value.type)) 11297 return nullptr; 11298 11299 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 11300 if (!const_val) 11301 return nullptr; 11302 11303 ConstExprValue *ptr_field = &const_val->data.x_struct.fields[slice_ptr_index]; 11304 ConstExprValue *len_field = &const_val->data.x_struct.fields[slice_len_index]; 11305 11306 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); 11307 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; 11308 expand_undef_array(ira->codegen, array_val); 11309 size_t len = bigint_as_unsigned(&len_field->data.x_bigint); 11310 Buf *result = buf_alloc(); 11311 buf_resize(result, len); 11312 for (size_t i = 0; i < len; i += 1) { 11313 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; 11314 ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index]; 11315 if (char_val->special == ConstValSpecialUndef) { 11316 ir_add_error(ira, casted_value, buf_sprintf("use of undefined value")); 11317 return nullptr; 11318 } 11319 uint64_t big_c = bigint_as_unsigned(&char_val->data.x_bigint); 11320 assert(big_c <= UINT8_MAX); 11321 uint8_t c = (uint8_t)big_c; 11322 buf_ptr(result)[i] = c; 11323 } 11324 return result; 11325 } 11326 11327 static ZigType *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, 11328 IrInstructionAddImplicitReturnType *instruction) 11329 { 11330 IrInstruction *value = instruction->value->other; 11331 if (type_is_invalid(value->value.type)) 11332 return ir_unreach_error(ira); 11333 11334 ira->src_implicit_return_type_list.append(value); 11335 11336 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 11337 out_val->type = ira->codegen->builtin_types.entry_void; 11338 return out_val->type; 11339 } 11340 11341 static ZigType *ir_analyze_instruction_return(IrAnalyze *ira, 11342 IrInstructionReturn *return_instruction) 11343 { 11344 IrInstruction *value = return_instruction->value->other; 11345 if (type_is_invalid(value->value.type)) 11346 return ir_unreach_error(ira); 11347 11348 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type); 11349 if (casted_value == ira->codegen->invalid_instruction) 11350 return ir_unreach_error(ira); 11351 11352 if (casted_value->value.special == ConstValSpecialRuntime && 11353 casted_value->value.type->id == ZigTypeIdPointer && 11354 casted_value->value.data.rh_ptr == RuntimeHintPtrStack) 11355 { 11356 ir_add_error(ira, casted_value, buf_sprintf("function returns address of local variable")); 11357 return ir_unreach_error(ira); 11358 } 11359 IrInstruction *result = ir_build_return(&ira->new_irb, return_instruction->base.scope, 11360 return_instruction->base.source_node, casted_value); 11361 result->value.type = ira->codegen->builtin_types.entry_unreachable; 11362 ir_link_new_instruction(result, &return_instruction->base); 11363 return ir_finish_anal(ira, result->value.type); 11364 } 11365 11366 static ZigType *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *const_instruction) { 11367 ConstExprValue *out_val = ir_build_const_from(ira, &const_instruction->base); 11368 *out_val = const_instruction->base.value; 11369 return const_instruction->base.value.type; 11370 } 11371 11372 static ZigType *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 11373 IrInstruction *op1 = bin_op_instruction->op1->other; 11374 if (type_is_invalid(op1->value.type)) 11375 return ira->codegen->builtin_types.entry_invalid; 11376 11377 IrInstruction *op2 = bin_op_instruction->op2->other; 11378 if (type_is_invalid(op2->value.type)) 11379 return ira->codegen->builtin_types.entry_invalid; 11380 11381 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 11382 11383 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, bool_type); 11384 if (casted_op1 == ira->codegen->invalid_instruction) 11385 return ira->codegen->builtin_types.entry_invalid; 11386 11387 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, bool_type); 11388 if (casted_op2 == ira->codegen->invalid_instruction) 11389 return ira->codegen->builtin_types.entry_invalid; 11390 11391 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 11392 ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base); 11393 ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 11394 if (op1_val == nullptr) 11395 return ira->codegen->builtin_types.entry_invalid; 11396 11397 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 11398 if (op2_val == nullptr) 11399 return ira->codegen->builtin_types.entry_invalid; 11400 11401 assert(casted_op1->value.type->id == ZigTypeIdBool); 11402 assert(casted_op2->value.type->id == ZigTypeIdBool); 11403 if (bin_op_instruction->op_id == IrBinOpBoolOr) { 11404 out_val->data.x_bool = op1_val->data.x_bool || op2_val->data.x_bool; 11405 } else if (bin_op_instruction->op_id == IrBinOpBoolAnd) { 11406 out_val->data.x_bool = op1_val->data.x_bool && op2_val->data.x_bool; 11407 } else { 11408 zig_unreachable(); 11409 } 11410 return bool_type; 11411 } 11412 11413 ir_build_bin_op_from(&ira->new_irb, &bin_op_instruction->base, bin_op_instruction->op_id, 11414 casted_op1, casted_op2, bin_op_instruction->safety_check_on); 11415 return bool_type; 11416 } 11417 11418 static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) { 11419 if (op_id == IrBinOpCmpEq) { 11420 return cmp == CmpEQ; 11421 } else if (op_id == IrBinOpCmpNotEq) { 11422 return cmp != CmpEQ; 11423 } else if (op_id == IrBinOpCmpLessThan) { 11424 return cmp == CmpLT; 11425 } else if (op_id == IrBinOpCmpGreaterThan) { 11426 return cmp == CmpGT; 11427 } else if (op_id == IrBinOpCmpLessOrEq) { 11428 return cmp != CmpGT; 11429 } else if (op_id == IrBinOpCmpGreaterOrEq) { 11430 return cmp != CmpLT; 11431 } else { 11432 zig_unreachable(); 11433 } 11434 } 11435 11436 static bool optional_value_is_null(ConstExprValue *val) { 11437 assert(val->special == ConstValSpecialStatic); 11438 if (get_codegen_ptr_type(val->type) != nullptr) { 11439 return val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 11440 val->data.x_ptr.data.hard_coded_addr.addr == 0; 11441 } else { 11442 return val->data.x_optional == nullptr; 11443 } 11444 } 11445 11446 static ZigType *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 11447 Error err; 11448 IrInstruction *op1 = bin_op_instruction->op1->other; 11449 IrInstruction *op2 = bin_op_instruction->op2->other; 11450 AstNode *source_node = bin_op_instruction->base.source_node; 11451 11452 IrBinOp op_id = bin_op_instruction->op_id; 11453 bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 11454 if (is_equality_cmp && 11455 ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdOptional) || 11456 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdOptional) || 11457 (op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull))) 11458 { 11459 if (op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull) { 11460 ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base); 11461 out_val->data.x_bool = (op_id == IrBinOpCmpEq); 11462 return ira->codegen->builtin_types.entry_bool; 11463 } 11464 IrInstruction *maybe_op; 11465 if (op1->value.type->id == ZigTypeIdNull) { 11466 maybe_op = op2; 11467 } else if (op2->value.type->id == ZigTypeIdNull) { 11468 maybe_op = op1; 11469 } else { 11470 zig_unreachable(); 11471 } 11472 if (instr_is_comptime(maybe_op)) { 11473 ConstExprValue *maybe_val = ir_resolve_const(ira, maybe_op, UndefBad); 11474 if (!maybe_val) 11475 return ira->codegen->builtin_types.entry_invalid; 11476 bool is_null = optional_value_is_null(maybe_val); 11477 ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base); 11478 out_val->data.x_bool = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 11479 return ira->codegen->builtin_types.entry_bool; 11480 } 11481 11482 IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope, 11483 source_node, maybe_op); 11484 is_non_null->value.type = ira->codegen->builtin_types.entry_bool; 11485 11486 if (op_id == IrBinOpCmpEq) { 11487 ir_build_bool_not_from(&ira->new_irb, &bin_op_instruction->base, is_non_null); 11488 } else { 11489 ir_link_new_instruction(is_non_null, &bin_op_instruction->base); 11490 } 11491 return ira->codegen->builtin_types.entry_bool; 11492 } 11493 11494 if (op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) { 11495 if (!is_equality_cmp) { 11496 ir_add_error_node(ira, source_node, buf_sprintf("operator not allowed for errors")); 11497 return ira->codegen->builtin_types.entry_invalid; 11498 } 11499 ZigType *intersect_type = get_error_set_intersection(ira, op1->value.type, op2->value.type, source_node); 11500 if (type_is_invalid(intersect_type)) { 11501 return ira->codegen->builtin_types.entry_invalid; 11502 } 11503 11504 if (!resolve_inferred_error_set(ira->codegen, intersect_type, source_node)) { 11505 return ira->codegen->builtin_types.entry_invalid; 11506 } 11507 11508 // exception if one of the operators has the type of the empty error set, we allow the comparison 11509 // (and make it comptime known) 11510 // this is a function which is evaluated at comptime and returns an inferred error set will have an empty 11511 // error set. 11512 if (op1->value.type->data.error_set.err_count == 0 || op2->value.type->data.error_set.err_count == 0) { 11513 bool are_equal = false; 11514 bool answer; 11515 if (op_id == IrBinOpCmpEq) { 11516 answer = are_equal; 11517 } else if (op_id == IrBinOpCmpNotEq) { 11518 answer = !are_equal; 11519 } else { 11520 zig_unreachable(); 11521 } 11522 ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base); 11523 out_val->data.x_bool = answer; 11524 return ira->codegen->builtin_types.entry_bool; 11525 } 11526 11527 if (!type_is_global_error_set(intersect_type)) { 11528 if (intersect_type->data.error_set.err_count == 0) { 11529 ir_add_error_node(ira, source_node, 11530 buf_sprintf("error sets '%s' and '%s' have no common errors", 11531 buf_ptr(&op1->value.type->name), buf_ptr(&op2->value.type->name))); 11532 return ira->codegen->builtin_types.entry_invalid; 11533 } 11534 if (op1->value.type->data.error_set.err_count == 1 && op2->value.type->data.error_set.err_count == 1) { 11535 bool are_equal = true; 11536 bool answer; 11537 if (op_id == IrBinOpCmpEq) { 11538 answer = are_equal; 11539 } else if (op_id == IrBinOpCmpNotEq) { 11540 answer = !are_equal; 11541 } else { 11542 zig_unreachable(); 11543 } 11544 ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base); 11545 out_val->data.x_bool = answer; 11546 return ira->codegen->builtin_types.entry_bool; 11547 } 11548 } 11549 11550 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 11551 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 11552 if (op1_val == nullptr) 11553 return ira->codegen->builtin_types.entry_invalid; 11554 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 11555 if (op2_val == nullptr) 11556 return ira->codegen->builtin_types.entry_invalid; 11557 11558 bool answer; 11559 bool are_equal = op1_val->data.x_err_set->value == op2_val->data.x_err_set->value; 11560 if (op_id == IrBinOpCmpEq) { 11561 answer = are_equal; 11562 } else if (op_id == IrBinOpCmpNotEq) { 11563 answer = !are_equal; 11564 } else { 11565 zig_unreachable(); 11566 } 11567 11568 ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base); 11569 out_val->data.x_bool = answer; 11570 return ira->codegen->builtin_types.entry_bool; 11571 } 11572 11573 ir_build_bin_op_from(&ira->new_irb, &bin_op_instruction->base, op_id, 11574 op1, op2, bin_op_instruction->safety_check_on); 11575 11576 return ira->codegen->builtin_types.entry_bool; 11577 } 11578 11579 IrInstruction *instructions[] = {op1, op2}; 11580 ZigType *resolved_type = ir_resolve_peer_types(ira, source_node, nullptr, instructions, 2); 11581 if (type_is_invalid(resolved_type)) 11582 return resolved_type; 11583 if ((err = type_ensure_zero_bits_known(ira->codegen, resolved_type))) 11584 return resolved_type; 11585 11586 bool operator_allowed; 11587 switch (resolved_type->id) { 11588 case ZigTypeIdInvalid: 11589 zig_unreachable(); // handled above 11590 11591 case ZigTypeIdComptimeFloat: 11592 case ZigTypeIdComptimeInt: 11593 case ZigTypeIdInt: 11594 case ZigTypeIdFloat: 11595 operator_allowed = true; 11596 break; 11597 11598 case ZigTypeIdBool: 11599 case ZigTypeIdMetaType: 11600 case ZigTypeIdVoid: 11601 case ZigTypeIdPointer: 11602 case ZigTypeIdErrorSet: 11603 case ZigTypeIdFn: 11604 case ZigTypeIdOpaque: 11605 case ZigTypeIdNamespace: 11606 case ZigTypeIdBlock: 11607 case ZigTypeIdBoundFn: 11608 case ZigTypeIdArgTuple: 11609 case ZigTypeIdPromise: 11610 case ZigTypeIdEnum: 11611 operator_allowed = is_equality_cmp; 11612 break; 11613 11614 case ZigTypeIdUnreachable: 11615 case ZigTypeIdArray: 11616 case ZigTypeIdStruct: 11617 case ZigTypeIdUndefined: 11618 case ZigTypeIdNull: 11619 case ZigTypeIdErrorUnion: 11620 case ZigTypeIdUnion: 11621 operator_allowed = false; 11622 break; 11623 case ZigTypeIdOptional: 11624 operator_allowed = is_equality_cmp && get_codegen_ptr_type(resolved_type) != nullptr; 11625 break; 11626 } 11627 if (!operator_allowed) { 11628 ir_add_error_node(ira, source_node, 11629 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); 11630 return ira->codegen->builtin_types.entry_invalid; 11631 } 11632 11633 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 11634 if (casted_op1 == ira->codegen->invalid_instruction) 11635 return ira->codegen->builtin_types.entry_invalid; 11636 11637 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 11638 if (casted_op2 == ira->codegen->invalid_instruction) 11639 return ira->codegen->builtin_types.entry_invalid; 11640 11641 bool one_possible_value = !type_requires_comptime(resolved_type) && !type_has_bits(resolved_type); 11642 if (one_possible_value || (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2))) { 11643 ConstExprValue *op1_val = one_possible_value ? &casted_op1->value : ir_resolve_const(ira, casted_op1, UndefBad); 11644 if (op1_val == nullptr) 11645 return ira->codegen->builtin_types.entry_invalid; 11646 ConstExprValue *op2_val = one_possible_value ? &casted_op2->value : ir_resolve_const(ira, casted_op2, UndefBad); 11647 if (op2_val == nullptr) 11648 return ira->codegen->builtin_types.entry_invalid; 11649 11650 bool answer; 11651 if (resolved_type->id == ZigTypeIdComptimeFloat || resolved_type->id == ZigTypeIdFloat) { 11652 Cmp cmp_result = float_cmp(op1_val, op2_val); 11653 answer = resolve_cmp_op_id(op_id, cmp_result); 11654 } else if (resolved_type->id == ZigTypeIdComptimeInt || resolved_type->id == ZigTypeIdInt) { 11655 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); 11656 answer = resolve_cmp_op_id(op_id, cmp_result); 11657 } else { 11658 bool are_equal = one_possible_value || const_values_equal(op1_val, op2_val); 11659 if (op_id == IrBinOpCmpEq) { 11660 answer = are_equal; 11661 } else if (op_id == IrBinOpCmpNotEq) { 11662 answer = !are_equal; 11663 } else { 11664 zig_unreachable(); 11665 } 11666 } 11667 11668 ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base); 11669 out_val->data.x_bool = answer; 11670 return ira->codegen->builtin_types.entry_bool; 11671 } 11672 11673 // some comparisons with unsigned numbers can be evaluated 11674 if (resolved_type->id == ZigTypeIdInt && !resolved_type->data.integral.is_signed) { 11675 ConstExprValue *known_left_val; 11676 IrBinOp flipped_op_id; 11677 if (instr_is_comptime(casted_op1)) { 11678 known_left_val = ir_resolve_const(ira, casted_op1, UndefBad); 11679 if (known_left_val == nullptr) 11680 return ira->codegen->builtin_types.entry_invalid; 11681 11682 flipped_op_id = op_id; 11683 } else if (instr_is_comptime(casted_op2)) { 11684 known_left_val = ir_resolve_const(ira, casted_op2, UndefBad); 11685 if (known_left_val == nullptr) 11686 return ira->codegen->builtin_types.entry_invalid; 11687 11688 if (op_id == IrBinOpCmpLessThan) { 11689 flipped_op_id = IrBinOpCmpGreaterThan; 11690 } else if (op_id == IrBinOpCmpGreaterThan) { 11691 flipped_op_id = IrBinOpCmpLessThan; 11692 } else if (op_id == IrBinOpCmpLessOrEq) { 11693 flipped_op_id = IrBinOpCmpGreaterOrEq; 11694 } else if (op_id == IrBinOpCmpGreaterOrEq) { 11695 flipped_op_id = IrBinOpCmpLessOrEq; 11696 } else { 11697 flipped_op_id = op_id; 11698 } 11699 } else { 11700 known_left_val = nullptr; 11701 } 11702 if (known_left_val != nullptr && bigint_cmp_zero(&known_left_val->data.x_bigint) == CmpEQ && 11703 (flipped_op_id == IrBinOpCmpLessOrEq || flipped_op_id == IrBinOpCmpGreaterThan)) 11704 { 11705 bool answer = (flipped_op_id == IrBinOpCmpLessOrEq); 11706 ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base); 11707 out_val->data.x_bool = answer; 11708 return ira->codegen->builtin_types.entry_bool; 11709 } 11710 } 11711 11712 ir_build_bin_op_from(&ira->new_irb, &bin_op_instruction->base, op_id, 11713 casted_op1, casted_op2, bin_op_instruction->safety_check_on); 11714 11715 return ira->codegen->builtin_types.entry_bool; 11716 } 11717 11718 static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val, 11719 IrBinOp op_id, ConstExprValue *op2_val, ConstExprValue *out_val) 11720 { 11721 bool is_int; 11722 bool is_float; 11723 Cmp op2_zcmp; 11724 if (type_entry->id == ZigTypeIdInt || type_entry->id == ZigTypeIdComptimeInt) { 11725 is_int = true; 11726 is_float = false; 11727 op2_zcmp = bigint_cmp_zero(&op2_val->data.x_bigint); 11728 } else if (type_entry->id == ZigTypeIdFloat || 11729 type_entry->id == ZigTypeIdComptimeFloat) 11730 { 11731 is_int = false; 11732 is_float = true; 11733 op2_zcmp = float_cmp_zero(op2_val); 11734 } else { 11735 zig_unreachable(); 11736 } 11737 11738 if ((op_id == IrBinOpDivUnspecified || op_id == IrBinOpRemRem || op_id == IrBinOpRemMod || 11739 op_id == IrBinOpDivTrunc || op_id == IrBinOpDivFloor) && op2_zcmp == CmpEQ) 11740 { 11741 return ErrorDivByZero; 11742 } 11743 if ((op_id == IrBinOpRemRem || op_id == IrBinOpRemMod) && op2_zcmp == CmpLT) { 11744 return ErrorNegativeDenominator; 11745 } 11746 11747 switch (op_id) { 11748 case IrBinOpInvalid: 11749 case IrBinOpBoolOr: 11750 case IrBinOpBoolAnd: 11751 case IrBinOpCmpEq: 11752 case IrBinOpCmpNotEq: 11753 case IrBinOpCmpLessThan: 11754 case IrBinOpCmpGreaterThan: 11755 case IrBinOpCmpLessOrEq: 11756 case IrBinOpCmpGreaterOrEq: 11757 case IrBinOpArrayCat: 11758 case IrBinOpArrayMult: 11759 case IrBinOpRemUnspecified: 11760 case IrBinOpMergeErrorSets: 11761 zig_unreachable(); 11762 case IrBinOpBinOr: 11763 assert(is_int); 11764 bigint_or(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11765 break; 11766 case IrBinOpBinXor: 11767 assert(is_int); 11768 bigint_xor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11769 break; 11770 case IrBinOpBinAnd: 11771 assert(is_int); 11772 bigint_and(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11773 break; 11774 case IrBinOpBitShiftLeftExact: 11775 assert(is_int); 11776 bigint_shl(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11777 break; 11778 case IrBinOpBitShiftLeftLossy: 11779 assert(type_entry->id == ZigTypeIdInt); 11780 bigint_shl_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 11781 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 11782 break; 11783 case IrBinOpBitShiftRightExact: 11784 { 11785 assert(is_int); 11786 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11787 BigInt orig_bigint; 11788 bigint_shl(&orig_bigint, &out_val->data.x_bigint, &op2_val->data.x_bigint); 11789 if (bigint_cmp(&op1_val->data.x_bigint, &orig_bigint) != CmpEQ) { 11790 return ErrorShiftedOutOneBits; 11791 } 11792 break; 11793 } 11794 case IrBinOpBitShiftRightLossy: 11795 assert(is_int); 11796 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11797 break; 11798 case IrBinOpAdd: 11799 if (is_int) { 11800 bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11801 } else { 11802 float_add(out_val, op1_val, op2_val); 11803 } 11804 break; 11805 case IrBinOpAddWrap: 11806 assert(type_entry->id == ZigTypeIdInt); 11807 bigint_add_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 11808 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 11809 break; 11810 case IrBinOpSub: 11811 if (is_int) { 11812 bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11813 } else { 11814 float_sub(out_val, op1_val, op2_val); 11815 } 11816 break; 11817 case IrBinOpSubWrap: 11818 assert(type_entry->id == ZigTypeIdInt); 11819 bigint_sub_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 11820 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 11821 break; 11822 case IrBinOpMult: 11823 if (is_int) { 11824 bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11825 } else { 11826 float_mul(out_val, op1_val, op2_val); 11827 } 11828 break; 11829 case IrBinOpMultWrap: 11830 assert(type_entry->id == ZigTypeIdInt); 11831 bigint_mul_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 11832 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 11833 break; 11834 case IrBinOpDivUnspecified: 11835 assert(is_float); 11836 float_div(out_val, op1_val, op2_val); 11837 break; 11838 case IrBinOpDivTrunc: 11839 if (is_int) { 11840 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11841 } else { 11842 float_div_trunc(out_val, op1_val, op2_val); 11843 } 11844 break; 11845 case IrBinOpDivFloor: 11846 if (is_int) { 11847 bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11848 } else { 11849 float_div_floor(out_val, op1_val, op2_val); 11850 } 11851 break; 11852 case IrBinOpDivExact: 11853 if (is_int) { 11854 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11855 BigInt remainder; 11856 bigint_rem(&remainder, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11857 if (bigint_cmp_zero(&remainder) != CmpEQ) { 11858 return ErrorExactDivRemainder; 11859 } 11860 } else { 11861 float_div_trunc(out_val, op1_val, op2_val); 11862 ConstExprValue remainder; 11863 float_rem(&remainder, op1_val, op2_val); 11864 if (float_cmp_zero(&remainder) != CmpEQ) { 11865 return ErrorExactDivRemainder; 11866 } 11867 } 11868 break; 11869 case IrBinOpRemRem: 11870 if (is_int) { 11871 bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11872 } else { 11873 float_rem(out_val, op1_val, op2_val); 11874 } 11875 break; 11876 case IrBinOpRemMod: 11877 if (is_int) { 11878 bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11879 } else { 11880 float_mod(out_val, op1_val, op2_val); 11881 } 11882 break; 11883 } 11884 11885 if (type_entry->id == ZigTypeIdInt) { 11886 if (!bigint_fits_in_bits(&out_val->data.x_bigint, type_entry->data.integral.bit_count, 11887 type_entry->data.integral.is_signed)) 11888 { 11889 return ErrorOverflow; 11890 } 11891 } 11892 11893 out_val->type = type_entry; 11894 out_val->special = ConstValSpecialStatic; 11895 return 0; 11896 } 11897 11898 static ZigType *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 11899 IrInstruction *op1 = bin_op_instruction->op1->other; 11900 if (type_is_invalid(op1->value.type)) 11901 return ira->codegen->builtin_types.entry_invalid; 11902 11903 if (op1->value.type->id != ZigTypeIdInt && op1->value.type->id != ZigTypeIdComptimeInt) { 11904 ir_add_error(ira, &bin_op_instruction->base, 11905 buf_sprintf("bit shifting operation expected integer type, found '%s'", 11906 buf_ptr(&op1->value.type->name))); 11907 return ira->codegen->builtin_types.entry_invalid; 11908 } 11909 11910 IrInstruction *op2 = bin_op_instruction->op2->other; 11911 if (type_is_invalid(op2->value.type)) 11912 return ira->codegen->builtin_types.entry_invalid; 11913 11914 IrInstruction *casted_op2; 11915 IrBinOp op_id = bin_op_instruction->op_id; 11916 if (op1->value.type->id == ZigTypeIdComptimeInt) { 11917 casted_op2 = op2; 11918 11919 if (op_id == IrBinOpBitShiftLeftLossy) { 11920 op_id = IrBinOpBitShiftLeftExact; 11921 } 11922 11923 if (casted_op2->value.data.x_bigint.is_negative) { 11924 Buf *val_buf = buf_alloc(); 11925 bigint_append_buf(val_buf, &casted_op2->value.data.x_bigint, 10); 11926 ir_add_error(ira, casted_op2, buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); 11927 return ira->codegen->builtin_types.entry_invalid; 11928 } 11929 } else { 11930 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 11931 op1->value.type->data.integral.bit_count - 1); 11932 if (bin_op_instruction->op_id == IrBinOpBitShiftLeftLossy && 11933 op2->value.type->id == ZigTypeIdComptimeInt) { 11934 if (!bigint_fits_in_bits(&op2->value.data.x_bigint, 11935 shift_amt_type->data.integral.bit_count, 11936 op2->value.data.x_bigint.is_negative)) { 11937 Buf *val_buf = buf_alloc(); 11938 bigint_append_buf(val_buf, &op2->value.data.x_bigint, 10); 11939 ErrorMsg* msg = ir_add_error(ira, 11940 &bin_op_instruction->base, 11941 buf_sprintf("RHS of shift is too large for LHS type")); 11942 add_error_note( 11943 ira->codegen, 11944 msg, 11945 op2->source_node, 11946 buf_sprintf("value %s cannot fit into type %s", 11947 buf_ptr(val_buf), 11948 buf_ptr(&shift_amt_type->name))); 11949 return ira->codegen->builtin_types.entry_invalid; 11950 } 11951 } 11952 11953 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 11954 if (casted_op2 == ira->codegen->invalid_instruction) 11955 return ira->codegen->builtin_types.entry_invalid; 11956 } 11957 11958 if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { 11959 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 11960 if (op1_val == nullptr) 11961 return ira->codegen->builtin_types.entry_invalid; 11962 11963 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 11964 if (op2_val == nullptr) 11965 return ira->codegen->builtin_types.entry_invalid; 11966 11967 IrInstruction *result_instruction = ir_get_const(ira, &bin_op_instruction->base); 11968 ir_link_new_instruction(result_instruction, &bin_op_instruction->base); 11969 ConstExprValue *out_val = &result_instruction->value; 11970 11971 int err; 11972 if ((err = ir_eval_math_op(op1->value.type, op1_val, op_id, op2_val, out_val))) { 11973 if (err == ErrorOverflow) { 11974 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("operation caused overflow")); 11975 return ira->codegen->builtin_types.entry_invalid; 11976 } else if (err == ErrorShiftedOutOneBits) { 11977 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("exact shift shifted out 1 bits")); 11978 return ira->codegen->builtin_types.entry_invalid; 11979 } else { 11980 zig_unreachable(); 11981 } 11982 return ira->codegen->builtin_types.entry_invalid; 11983 } 11984 11985 ir_num_lit_fits_in_other_type(ira, result_instruction, op1->value.type, false); 11986 return op1->value.type; 11987 } else if (op1->value.type->id == ZigTypeIdComptimeInt) { 11988 ir_add_error(ira, &bin_op_instruction->base, 11989 buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known")); 11990 return ira->codegen->builtin_types.entry_invalid; 11991 } 11992 11993 ir_build_bin_op_from(&ira->new_irb, &bin_op_instruction->base, op_id, 11994 op1, casted_op2, bin_op_instruction->safety_check_on); 11995 return op1->value.type; 11996 } 11997 11998 static ZigType *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 11999 IrInstruction *op1 = bin_op_instruction->op1->other; 12000 if (type_is_invalid(op1->value.type)) 12001 return ira->codegen->builtin_types.entry_invalid; 12002 12003 IrInstruction *op2 = bin_op_instruction->op2->other; 12004 if (type_is_invalid(op2->value.type)) 12005 return ira->codegen->builtin_types.entry_invalid; 12006 12007 IrBinOp op_id = bin_op_instruction->op_id; 12008 12009 // look for pointer math 12010 if (op1->value.type->id == ZigTypeIdPointer && op1->value.type->data.pointer.ptr_len == PtrLenUnknown && 12011 (op_id == IrBinOpAdd || op_id == IrBinOpSub)) 12012 { 12013 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize); 12014 if (casted_op2 == ira->codegen->invalid_instruction) 12015 return ira->codegen->builtin_types.entry_invalid; 12016 12017 IrInstruction *result = ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.scope, 12018 bin_op_instruction->base.source_node, op_id, op1, casted_op2, true); 12019 result->value.type = op1->value.type; 12020 ir_link_new_instruction(result, &bin_op_instruction->base); 12021 return result->value.type; 12022 } 12023 12024 IrInstruction *instructions[] = {op1, op2}; 12025 ZigType *resolved_type = ir_resolve_peer_types(ira, bin_op_instruction->base.source_node, nullptr, instructions, 2); 12026 if (type_is_invalid(resolved_type)) 12027 return resolved_type; 12028 12029 bool is_int = resolved_type->id == ZigTypeIdInt || resolved_type->id == ZigTypeIdComptimeInt; 12030 bool is_float = resolved_type->id == ZigTypeIdFloat || resolved_type->id == ZigTypeIdComptimeFloat; 12031 bool is_signed_div = ( 12032 (resolved_type->id == ZigTypeIdInt && resolved_type->data.integral.is_signed) || 12033 resolved_type->id == ZigTypeIdFloat || 12034 (resolved_type->id == ZigTypeIdComptimeFloat && 12035 ((bigfloat_cmp_zero(&op1->value.data.x_bigfloat) != CmpGT) != 12036 (bigfloat_cmp_zero(&op2->value.data.x_bigfloat) != CmpGT))) || 12037 (resolved_type->id == ZigTypeIdComptimeInt && 12038 ((bigint_cmp_zero(&op1->value.data.x_bigint) != CmpGT) != 12039 (bigint_cmp_zero(&op2->value.data.x_bigint) != CmpGT))) 12040 ); 12041 if (op_id == IrBinOpDivUnspecified && is_int) { 12042 if (is_signed_div) { 12043 bool ok = false; 12044 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 12045 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 12046 if (op1_val == nullptr) 12047 return ira->codegen->builtin_types.entry_invalid; 12048 12049 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 12050 if (op2_val == nullptr) 12051 return ira->codegen->builtin_types.entry_invalid; 12052 12053 if (bigint_cmp_zero(&op2_val->data.x_bigint) == CmpEQ) { 12054 // the division by zero error will be caught later, but we don't have a 12055 // division function ambiguity problem. 12056 op_id = IrBinOpDivTrunc; 12057 ok = true; 12058 } else { 12059 BigInt trunc_result; 12060 BigInt floor_result; 12061 bigint_div_trunc(&trunc_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12062 bigint_div_floor(&floor_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12063 if (bigint_cmp(&trunc_result, &floor_result) == CmpEQ) { 12064 ok = true; 12065 op_id = IrBinOpDivTrunc; 12066 } 12067 } 12068 } 12069 if (!ok) { 12070 ir_add_error(ira, &bin_op_instruction->base, 12071 buf_sprintf("division with '%s' and '%s': signed integers must use @divTrunc, @divFloor, or @divExact", 12072 buf_ptr(&op1->value.type->name), 12073 buf_ptr(&op2->value.type->name))); 12074 return ira->codegen->builtin_types.entry_invalid; 12075 } 12076 } else { 12077 op_id = IrBinOpDivTrunc; 12078 } 12079 } else if (op_id == IrBinOpRemUnspecified) { 12080 if (is_signed_div && (is_int || is_float)) { 12081 bool ok = false; 12082 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 12083 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 12084 if (op1_val == nullptr) 12085 return ira->codegen->builtin_types.entry_invalid; 12086 12087 if (is_int) { 12088 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 12089 if (op2_val == nullptr) 12090 return ira->codegen->builtin_types.entry_invalid; 12091 12092 if (bigint_cmp_zero(&op2->value.data.x_bigint) == CmpEQ) { 12093 // the division by zero error will be caught later, but we don't 12094 // have a remainder function ambiguity problem 12095 ok = true; 12096 } else { 12097 BigInt rem_result; 12098 BigInt mod_result; 12099 bigint_rem(&rem_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12100 bigint_mod(&mod_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12101 ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ; 12102 } 12103 } else { 12104 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 12105 if (casted_op2 == ira->codegen->invalid_instruction) 12106 return ira->codegen->builtin_types.entry_invalid; 12107 12108 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 12109 if (op2_val == nullptr) 12110 return ira->codegen->builtin_types.entry_invalid; 12111 12112 if (float_cmp_zero(&casted_op2->value) == CmpEQ) { 12113 // the division by zero error will be caught later, but we don't 12114 // have a remainder function ambiguity problem 12115 ok = true; 12116 } else { 12117 ConstExprValue rem_result; 12118 ConstExprValue mod_result; 12119 float_rem(&rem_result, op1_val, op2_val); 12120 float_mod(&mod_result, op1_val, op2_val); 12121 ok = float_cmp(&rem_result, &mod_result) == CmpEQ; 12122 } 12123 } 12124 } 12125 if (!ok) { 12126 ir_add_error(ira, &bin_op_instruction->base, 12127 buf_sprintf("remainder division with '%s' and '%s': signed integers and floats must use @rem or @mod", 12128 buf_ptr(&op1->value.type->name), 12129 buf_ptr(&op2->value.type->name))); 12130 return ira->codegen->builtin_types.entry_invalid; 12131 } 12132 } 12133 op_id = IrBinOpRemRem; 12134 } 12135 12136 if (is_int) { 12137 // int 12138 } else if (is_float && 12139 (op_id == IrBinOpAdd || 12140 op_id == IrBinOpSub || 12141 op_id == IrBinOpMult || 12142 op_id == IrBinOpDivUnspecified || 12143 op_id == IrBinOpDivTrunc || 12144 op_id == IrBinOpDivFloor || 12145 op_id == IrBinOpDivExact || 12146 op_id == IrBinOpRemRem || 12147 op_id == IrBinOpRemMod)) 12148 { 12149 // float 12150 } else { 12151 AstNode *source_node = bin_op_instruction->base.source_node; 12152 ir_add_error_node(ira, source_node, 12153 buf_sprintf("invalid operands to binary expression: '%s' and '%s'", 12154 buf_ptr(&op1->value.type->name), 12155 buf_ptr(&op2->value.type->name))); 12156 return ira->codegen->builtin_types.entry_invalid; 12157 } 12158 12159 if (resolved_type->id == ZigTypeIdComptimeInt) { 12160 if (op_id == IrBinOpAddWrap) { 12161 op_id = IrBinOpAdd; 12162 } else if (op_id == IrBinOpSubWrap) { 12163 op_id = IrBinOpSub; 12164 } else if (op_id == IrBinOpMultWrap) { 12165 op_id = IrBinOpMult; 12166 } 12167 } 12168 12169 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 12170 if (casted_op1 == ira->codegen->invalid_instruction) 12171 return ira->codegen->builtin_types.entry_invalid; 12172 12173 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 12174 if (casted_op2 == ira->codegen->invalid_instruction) 12175 return ira->codegen->builtin_types.entry_invalid; 12176 12177 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 12178 ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 12179 if (op1_val == nullptr) 12180 return ira->codegen->builtin_types.entry_invalid; 12181 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 12182 if (op2_val == nullptr) 12183 return ira->codegen->builtin_types.entry_invalid; 12184 12185 IrInstruction *result_instruction = ir_get_const(ira, &bin_op_instruction->base); 12186 ir_link_new_instruction(result_instruction, &bin_op_instruction->base); 12187 ConstExprValue *out_val = &result_instruction->value; 12188 12189 int err; 12190 if ((err = ir_eval_math_op(resolved_type, op1_val, op_id, op2_val, out_val))) { 12191 if (err == ErrorDivByZero) { 12192 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("division by zero")); 12193 return ira->codegen->builtin_types.entry_invalid; 12194 } else if (err == ErrorOverflow) { 12195 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("operation caused overflow")); 12196 return ira->codegen->builtin_types.entry_invalid; 12197 } else if (err == ErrorExactDivRemainder) { 12198 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("exact division had a remainder")); 12199 return ira->codegen->builtin_types.entry_invalid; 12200 } else if (err == ErrorNegativeDenominator) { 12201 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("negative denominator")); 12202 return ira->codegen->builtin_types.entry_invalid; 12203 } else { 12204 zig_unreachable(); 12205 } 12206 return ira->codegen->builtin_types.entry_invalid; 12207 } 12208 12209 ir_num_lit_fits_in_other_type(ira, result_instruction, resolved_type, false); 12210 return resolved_type; 12211 } 12212 12213 ir_build_bin_op_from(&ira->new_irb, &bin_op_instruction->base, op_id, 12214 casted_op1, casted_op2, bin_op_instruction->safety_check_on); 12215 return resolved_type; 12216 } 12217 12218 12219 static ZigType *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruction) { 12220 IrInstruction *op1 = instruction->op1->other; 12221 ZigType *op1_type = op1->value.type; 12222 if (type_is_invalid(op1_type)) 12223 return ira->codegen->builtin_types.entry_invalid; 12224 12225 IrInstruction *op2 = instruction->op2->other; 12226 ZigType *op2_type = op2->value.type; 12227 if (type_is_invalid(op2_type)) 12228 return ira->codegen->builtin_types.entry_invalid; 12229 12230 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 12231 if (!op1_val) 12232 return ira->codegen->builtin_types.entry_invalid; 12233 12234 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 12235 if (!op2_val) 12236 return ira->codegen->builtin_types.entry_invalid; 12237 12238 ConstExprValue *op1_array_val; 12239 size_t op1_array_index; 12240 size_t op1_array_end; 12241 ZigType *child_type; 12242 if (op1_type->id == ZigTypeIdArray) { 12243 child_type = op1_type->data.array.child_type; 12244 op1_array_val = op1_val; 12245 op1_array_index = 0; 12246 op1_array_end = op1_type->data.array.len; 12247 } else if (op1_type->id == ZigTypeIdPointer && 12248 op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 12249 op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray && 12250 op1_val->data.x_ptr.data.base_array.is_cstr) 12251 { 12252 child_type = op1_type->data.pointer.child_type; 12253 op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; 12254 op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; 12255 op1_array_end = op1_array_val->type->data.array.len - 1; 12256 } else if (is_slice(op1_type)) { 12257 ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index].type_entry; 12258 child_type = ptr_type->data.pointer.child_type; 12259 ConstExprValue *ptr_val = &op1_val->data.x_struct.fields[slice_ptr_index]; 12260 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 12261 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 12262 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 12263 op1_array_end = op1_array_val->type->data.array.len; 12264 } else { 12265 ir_add_error(ira, op1, 12266 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name))); 12267 return ira->codegen->builtin_types.entry_invalid; 12268 } 12269 12270 ConstExprValue *op2_array_val; 12271 size_t op2_array_index; 12272 size_t op2_array_end; 12273 if (op2_type->id == ZigTypeIdArray) { 12274 if (op2_type->data.array.child_type != child_type) { 12275 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", 12276 buf_ptr(&child_type->name), 12277 buf_ptr(&op2->value.type->name))); 12278 return ira->codegen->builtin_types.entry_invalid; 12279 } 12280 op2_array_val = op2_val; 12281 op2_array_index = 0; 12282 op2_array_end = op2_array_val->type->data.array.len; 12283 } else if (op2_type->id == ZigTypeIdPointer && 12284 op2_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 12285 op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray && 12286 op2_val->data.x_ptr.data.base_array.is_cstr) 12287 { 12288 if (child_type != ira->codegen->builtin_types.entry_u8) { 12289 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", 12290 buf_ptr(&child_type->name), 12291 buf_ptr(&op2->value.type->name))); 12292 return ira->codegen->builtin_types.entry_invalid; 12293 } 12294 op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; 12295 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; 12296 op2_array_end = op2_array_val->type->data.array.len - 1; 12297 } else if (is_slice(op2_type)) { 12298 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry; 12299 if (ptr_type->data.pointer.child_type != child_type) { 12300 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", 12301 buf_ptr(&child_type->name), 12302 buf_ptr(&op2->value.type->name))); 12303 return ira->codegen->builtin_types.entry_invalid; 12304 } 12305 ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index]; 12306 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 12307 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 12308 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 12309 op2_array_end = op2_array_val->type->data.array.len; 12310 } else { 12311 ir_add_error(ira, op2, 12312 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name))); 12313 return ira->codegen->builtin_types.entry_invalid; 12314 } 12315 12316 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 12317 12318 ZigType *result_type; 12319 ConstExprValue *out_array_val; 12320 size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); 12321 if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { 12322 result_type = get_array_type(ira->codegen, child_type, new_len); 12323 12324 out_array_val = out_val; 12325 } else if (is_slice(op1_type) || is_slice(op2_type)) { 12326 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, 12327 true, false, PtrLenUnknown, get_abi_alignment(ira->codegen, child_type), 0, 0); 12328 result_type = get_slice_type(ira->codegen, ptr_type); 12329 out_array_val = create_const_vals(1); 12330 out_array_val->special = ConstValSpecialStatic; 12331 out_array_val->type = get_array_type(ira->codegen, child_type, new_len); 12332 12333 out_val->data.x_struct.fields = create_const_vals(2); 12334 12335 out_val->data.x_struct.fields[slice_ptr_index].type = ptr_type; 12336 out_val->data.x_struct.fields[slice_ptr_index].special = ConstValSpecialStatic; 12337 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.special = ConstPtrSpecialBaseArray; 12338 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.array_val = out_array_val; 12339 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.elem_index = 0; 12340 12341 out_val->data.x_struct.fields[slice_len_index].type = ira->codegen->builtin_types.entry_usize; 12342 out_val->data.x_struct.fields[slice_len_index].special = ConstValSpecialStatic; 12343 bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index].data.x_bigint, new_len); 12344 } else { 12345 new_len += 1; // null byte 12346 12347 // TODO make this `[*]null T` instead of `[*]T` 12348 result_type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, 12349 PtrLenUnknown, get_abi_alignment(ira->codegen, child_type), 0, 0); 12350 12351 out_array_val = create_const_vals(1); 12352 out_array_val->special = ConstValSpecialStatic; 12353 out_array_val->type = get_array_type(ira->codegen, child_type, new_len); 12354 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 12355 out_val->data.x_ptr.data.base_array.is_cstr = true; 12356 out_val->data.x_ptr.data.base_array.array_val = out_array_val; 12357 out_val->data.x_ptr.data.base_array.elem_index = 0; 12358 } 12359 12360 if (op1_array_val->data.x_array.special == ConstArraySpecialUndef && 12361 op2_array_val->data.x_array.special == ConstArraySpecialUndef) { 12362 out_array_val->data.x_array.special = ConstArraySpecialUndef; 12363 return result_type; 12364 } 12365 12366 out_array_val->data.x_array.s_none.elements = create_const_vals(new_len); 12367 expand_undef_array(ira->codegen, op1_array_val); 12368 expand_undef_array(ira->codegen, op2_array_val); 12369 12370 size_t next_index = 0; 12371 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { 12372 out_array_val->data.x_array.s_none.elements[next_index] = op1_array_val->data.x_array.s_none.elements[i]; 12373 } 12374 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { 12375 out_array_val->data.x_array.s_none.elements[next_index] = op2_array_val->data.x_array.s_none.elements[i]; 12376 } 12377 if (next_index < new_len) { 12378 ConstExprValue *null_byte = &out_array_val->data.x_array.s_none.elements[next_index]; 12379 init_const_unsigned_negative(null_byte, child_type, 0, false); 12380 next_index += 1; 12381 } 12382 assert(next_index == new_len); 12383 12384 return result_type; 12385 } 12386 12387 static ZigType *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instruction) { 12388 IrInstruction *op1 = instruction->op1->other; 12389 if (type_is_invalid(op1->value.type)) 12390 return ira->codegen->builtin_types.entry_invalid; 12391 12392 IrInstruction *op2 = instruction->op2->other; 12393 if (type_is_invalid(op2->value.type)) 12394 return ira->codegen->builtin_types.entry_invalid; 12395 12396 ConstExprValue *array_val = ir_resolve_const(ira, op1, UndefBad); 12397 if (!array_val) 12398 return ira->codegen->builtin_types.entry_invalid; 12399 12400 uint64_t mult_amt; 12401 if (!ir_resolve_usize(ira, op2, &mult_amt)) 12402 return ira->codegen->builtin_types.entry_invalid; 12403 12404 ZigType *array_type = op1->value.type; 12405 if (array_type->id != ZigTypeIdArray) { 12406 ir_add_error(ira, op1, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value.type->name))); 12407 return ira->codegen->builtin_types.entry_invalid; 12408 } 12409 12410 uint64_t old_array_len = array_type->data.array.len; 12411 uint64_t new_array_len; 12412 12413 if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) 12414 { 12415 ir_add_error(ira, &instruction->base, buf_sprintf("operation results in overflow")); 12416 return ira->codegen->builtin_types.entry_invalid; 12417 } 12418 12419 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 12420 if (array_val->data.x_array.special == ConstArraySpecialUndef) { 12421 out_val->data.x_array.special = ConstArraySpecialUndef; 12422 12423 ZigType *child_type = array_type->data.array.child_type; 12424 return get_array_type(ira->codegen, child_type, new_array_len); 12425 } 12426 12427 out_val->data.x_array.s_none.elements = create_const_vals(new_array_len); 12428 12429 uint64_t i = 0; 12430 for (uint64_t x = 0; x < mult_amt; x += 1) { 12431 for (uint64_t y = 0; y < old_array_len; y += 1) { 12432 out_val->data.x_array.s_none.elements[i] = array_val->data.x_array.s_none.elements[y]; 12433 i += 1; 12434 } 12435 } 12436 assert(i == new_array_len); 12437 12438 ZigType *child_type = array_type->data.array.child_type; 12439 return get_array_type(ira->codegen, child_type, new_array_len); 12440 } 12441 12442 static ZigType *ir_analyze_merge_error_sets(IrAnalyze *ira, IrInstructionBinOp *instruction) { 12443 ZigType *op1_type = ir_resolve_type(ira, instruction->op1->other); 12444 if (type_is_invalid(op1_type)) 12445 return ira->codegen->builtin_types.entry_invalid; 12446 12447 ZigType *op2_type = ir_resolve_type(ira, instruction->op2->other); 12448 if (type_is_invalid(op2_type)) 12449 return ira->codegen->builtin_types.entry_invalid; 12450 12451 if (type_is_global_error_set(op1_type) || 12452 type_is_global_error_set(op2_type)) 12453 { 12454 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 12455 out_val->data.x_type = ira->codegen->builtin_types.entry_global_error_set; 12456 return ira->codegen->builtin_types.entry_type; 12457 } 12458 12459 if (!resolve_inferred_error_set(ira->codegen, op1_type, instruction->op1->other->source_node)) { 12460 return ira->codegen->builtin_types.entry_invalid; 12461 } 12462 12463 if (!resolve_inferred_error_set(ira->codegen, op2_type, instruction->op2->other->source_node)) { 12464 return ira->codegen->builtin_types.entry_invalid; 12465 } 12466 12467 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 12468 for (uint32_t i = 0, count = op1_type->data.error_set.err_count; i < count; i += 1) { 12469 ErrorTableEntry *error_entry = op1_type->data.error_set.errors[i]; 12470 assert(errors[error_entry->value] == nullptr); 12471 errors[error_entry->value] = error_entry; 12472 } 12473 ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type); 12474 free(errors); 12475 12476 12477 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 12478 out_val->data.x_type = result_type; 12479 return ira->codegen->builtin_types.entry_type; 12480 } 12481 12482 static ZigType *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 12483 IrBinOp op_id = bin_op_instruction->op_id; 12484 switch (op_id) { 12485 case IrBinOpInvalid: 12486 zig_unreachable(); 12487 case IrBinOpBoolOr: 12488 case IrBinOpBoolAnd: 12489 return ir_analyze_bin_op_bool(ira, bin_op_instruction); 12490 case IrBinOpCmpEq: 12491 case IrBinOpCmpNotEq: 12492 case IrBinOpCmpLessThan: 12493 case IrBinOpCmpGreaterThan: 12494 case IrBinOpCmpLessOrEq: 12495 case IrBinOpCmpGreaterOrEq: 12496 return ir_analyze_bin_op_cmp(ira, bin_op_instruction); 12497 case IrBinOpBitShiftLeftLossy: 12498 case IrBinOpBitShiftLeftExact: 12499 case IrBinOpBitShiftRightLossy: 12500 case IrBinOpBitShiftRightExact: 12501 return ir_analyze_bit_shift(ira, bin_op_instruction); 12502 case IrBinOpBinOr: 12503 case IrBinOpBinXor: 12504 case IrBinOpBinAnd: 12505 case IrBinOpAdd: 12506 case IrBinOpAddWrap: 12507 case IrBinOpSub: 12508 case IrBinOpSubWrap: 12509 case IrBinOpMult: 12510 case IrBinOpMultWrap: 12511 case IrBinOpDivUnspecified: 12512 case IrBinOpDivTrunc: 12513 case IrBinOpDivFloor: 12514 case IrBinOpDivExact: 12515 case IrBinOpRemUnspecified: 12516 case IrBinOpRemRem: 12517 case IrBinOpRemMod: 12518 return ir_analyze_bin_op_math(ira, bin_op_instruction); 12519 case IrBinOpArrayCat: 12520 return ir_analyze_array_cat(ira, bin_op_instruction); 12521 case IrBinOpArrayMult: 12522 return ir_analyze_array_mult(ira, bin_op_instruction); 12523 case IrBinOpMergeErrorSets: 12524 return ir_analyze_merge_error_sets(ira, bin_op_instruction); 12525 } 12526 zig_unreachable(); 12527 } 12528 12529 static ZigType *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDeclVar *decl_var_instruction) { 12530 Error err; 12531 ZigVar *var = decl_var_instruction->var; 12532 12533 IrInstruction *init_value = decl_var_instruction->init_value->other; 12534 if (type_is_invalid(init_value->value.type)) { 12535 var->value->type = ira->codegen->builtin_types.entry_invalid; 12536 return var->value->type; 12537 } 12538 12539 ZigType *explicit_type = nullptr; 12540 IrInstruction *var_type = nullptr; 12541 if (decl_var_instruction->var_type != nullptr) { 12542 var_type = decl_var_instruction->var_type->other; 12543 ZigType *proposed_type = ir_resolve_type(ira, var_type); 12544 explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type); 12545 if (type_is_invalid(explicit_type)) { 12546 var->value->type = ira->codegen->builtin_types.entry_invalid; 12547 return var->value->type; 12548 } 12549 } 12550 12551 AstNode *source_node = decl_var_instruction->base.source_node; 12552 12553 IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); 12554 bool is_comptime_var = ir_get_var_is_comptime(var); 12555 12556 bool var_class_requires_const = false; 12557 12558 ZigType *result_type = casted_init_value->value.type; 12559 if (type_is_invalid(result_type)) { 12560 result_type = ira->codegen->builtin_types.entry_invalid; 12561 } else { 12562 if ((err = type_ensure_zero_bits_known(ira->codegen, result_type))) { 12563 result_type = ira->codegen->builtin_types.entry_invalid; 12564 } 12565 } 12566 12567 if (!type_is_invalid(result_type)) { 12568 if (result_type->id == ZigTypeIdUnreachable || 12569 result_type->id == ZigTypeIdOpaque) 12570 { 12571 ir_add_error_node(ira, source_node, 12572 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); 12573 result_type = ira->codegen->builtin_types.entry_invalid; 12574 } else if (type_requires_comptime(result_type)) { 12575 var_class_requires_const = true; 12576 if (!var->gen_is_const && !is_comptime_var) { 12577 ir_add_error_node(ira, source_node, 12578 buf_sprintf("variable of type '%s' must be const or comptime", 12579 buf_ptr(&result_type->name))); 12580 result_type = ira->codegen->builtin_types.entry_invalid; 12581 } 12582 } else { 12583 if (casted_init_value->value.special == ConstValSpecialStatic && 12584 casted_init_value->value.type->id == ZigTypeIdFn && 12585 casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) 12586 { 12587 var_class_requires_const = true; 12588 if (!var->src_is_const && !is_comptime_var) { 12589 ErrorMsg *msg = ir_add_error_node(ira, source_node, 12590 buf_sprintf("functions marked inline must be stored in const or comptime var")); 12591 AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node; 12592 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); 12593 result_type = ira->codegen->builtin_types.entry_invalid; 12594 } 12595 } 12596 } 12597 } 12598 12599 if (var->value->type != nullptr && !is_comptime_var) { 12600 // This is at least the second time we've seen this variable declaration during analysis. 12601 // This means that this is actually a different variable due to, e.g. an inline while loop. 12602 // We make a new variable so that it can hold a different type, and so the debug info can 12603 // be distinct. 12604 ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope, 12605 &var->name, var->src_is_const, var->gen_is_const, var->shadowable, var->is_comptime, true); 12606 new_var->owner_exec = var->owner_exec; 12607 new_var->align_bytes = var->align_bytes; 12608 if (var->mem_slot_index != SIZE_MAX) { 12609 ConstExprValue *vals = create_const_vals(1); 12610 new_var->mem_slot_index = ira->exec_context.mem_slot_list.length; 12611 ira->exec_context.mem_slot_list.append(vals); 12612 } 12613 12614 var->next_var = new_var; 12615 var = new_var; 12616 } 12617 12618 // This must be done after possibly creating a new variable above 12619 var->ref_count = 0; 12620 12621 var->value->type = result_type; 12622 assert(var->value->type); 12623 12624 if (type_is_invalid(result_type)) { 12625 decl_var_instruction->base.other = &decl_var_instruction->base; 12626 return ira->codegen->builtin_types.entry_void; 12627 } 12628 12629 if (decl_var_instruction->align_value == nullptr) { 12630 var->align_bytes = get_abi_alignment(ira->codegen, result_type); 12631 } else { 12632 if (!ir_resolve_align(ira, decl_var_instruction->align_value->other, &var->align_bytes)) { 12633 var->value->type = ira->codegen->builtin_types.entry_invalid; 12634 } 12635 } 12636 12637 if (casted_init_value->value.special != ConstValSpecialRuntime) { 12638 if (var->mem_slot_index != SIZE_MAX) { 12639 assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); 12640 ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); 12641 copy_const_val(mem_slot, &casted_init_value->value, !is_comptime_var || var->gen_is_const); 12642 12643 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { 12644 ir_build_const_from(ira, &decl_var_instruction->base); 12645 return ira->codegen->builtin_types.entry_void; 12646 } 12647 } 12648 } else if (is_comptime_var) { 12649 ir_add_error(ira, &decl_var_instruction->base, 12650 buf_sprintf("cannot store runtime value in compile time variable")); 12651 var->value->type = ira->codegen->builtin_types.entry_invalid; 12652 return ira->codegen->builtin_types.entry_invalid; 12653 } 12654 12655 ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, nullptr, casted_init_value); 12656 12657 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 12658 if (fn_entry) 12659 fn_entry->variable_list.append(var); 12660 12661 return ira->codegen->builtin_types.entry_void; 12662 } 12663 12664 static ZigType *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { 12665 IrInstruction *name = instruction->name->other; 12666 Buf *symbol_name = ir_resolve_str(ira, name); 12667 if (symbol_name == nullptr) { 12668 return ira->codegen->builtin_types.entry_invalid; 12669 } 12670 12671 IrInstruction *target = instruction->target->other; 12672 if (type_is_invalid(target->value.type)) { 12673 return ira->codegen->builtin_types.entry_invalid; 12674 } 12675 12676 GlobalLinkageId global_linkage_id = GlobalLinkageIdStrong; 12677 if (instruction->linkage != nullptr) { 12678 IrInstruction *linkage_value = instruction->linkage->other; 12679 if (!ir_resolve_global_linkage(ira, linkage_value, &global_linkage_id)) { 12680 return ira->codegen->builtin_types.entry_invalid; 12681 } 12682 } 12683 12684 auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, instruction->base.source_node); 12685 if (entry) { 12686 AstNode *other_export_node = entry->value; 12687 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 12688 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name))); 12689 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); 12690 } 12691 12692 switch (target->value.type->id) { 12693 case ZigTypeIdInvalid: 12694 case ZigTypeIdUnreachable: 12695 zig_unreachable(); 12696 case ZigTypeIdFn: { 12697 assert(target->value.data.x_ptr.special == ConstPtrSpecialFunction); 12698 ZigFn *fn_entry = target->value.data.x_ptr.data.fn.fn_entry; 12699 CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc; 12700 switch (cc) { 12701 case CallingConventionUnspecified: { 12702 ErrorMsg *msg = ir_add_error(ira, target, 12703 buf_sprintf("exported function must specify calling convention")); 12704 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 12705 } break; 12706 case CallingConventionAsync: { 12707 ErrorMsg *msg = ir_add_error(ira, target, 12708 buf_sprintf("exported function cannot be async")); 12709 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 12710 } break; 12711 case CallingConventionC: 12712 case CallingConventionNaked: 12713 case CallingConventionCold: 12714 case CallingConventionStdcall: 12715 add_fn_export(ira->codegen, fn_entry, symbol_name, global_linkage_id, cc == CallingConventionC); 12716 break; 12717 } 12718 } break; 12719 case ZigTypeIdStruct: 12720 if (is_slice(target->value.type)) { 12721 ir_add_error(ira, target, 12722 buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value.type->name))); 12723 } else if (target->value.type->data.structure.layout != ContainerLayoutExtern) { 12724 ErrorMsg *msg = ir_add_error(ira, target, 12725 buf_sprintf("exported struct value must be declared extern")); 12726 add_error_note(ira->codegen, msg, target->value.type->data.structure.decl_node, buf_sprintf("declared here")); 12727 } 12728 break; 12729 case ZigTypeIdUnion: 12730 if (target->value.type->data.unionation.layout != ContainerLayoutExtern) { 12731 ErrorMsg *msg = ir_add_error(ira, target, 12732 buf_sprintf("exported union value must be declared extern")); 12733 add_error_note(ira->codegen, msg, target->value.type->data.unionation.decl_node, buf_sprintf("declared here")); 12734 } 12735 break; 12736 case ZigTypeIdEnum: 12737 if (target->value.type->data.enumeration.layout != ContainerLayoutExtern) { 12738 ErrorMsg *msg = ir_add_error(ira, target, 12739 buf_sprintf("exported enum value must be declared extern")); 12740 add_error_note(ira->codegen, msg, target->value.type->data.enumeration.decl_node, buf_sprintf("declared here")); 12741 } 12742 break; 12743 case ZigTypeIdMetaType: { 12744 ZigType *type_value = target->value.data.x_type; 12745 switch (type_value->id) { 12746 case ZigTypeIdInvalid: 12747 zig_unreachable(); 12748 case ZigTypeIdStruct: 12749 if (is_slice(type_value)) { 12750 ir_add_error(ira, target, 12751 buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name))); 12752 } else if (type_value->data.structure.layout != ContainerLayoutExtern) { 12753 ErrorMsg *msg = ir_add_error(ira, target, 12754 buf_sprintf("exported struct must be declared extern")); 12755 add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here")); 12756 } 12757 break; 12758 case ZigTypeIdUnion: 12759 if (type_value->data.unionation.layout != ContainerLayoutExtern) { 12760 ErrorMsg *msg = ir_add_error(ira, target, 12761 buf_sprintf("exported union must be declared extern")); 12762 add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here")); 12763 } 12764 break; 12765 case ZigTypeIdEnum: 12766 if (type_value->data.enumeration.layout != ContainerLayoutExtern) { 12767 ErrorMsg *msg = ir_add_error(ira, target, 12768 buf_sprintf("exported enum must be declared extern")); 12769 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); 12770 } 12771 break; 12772 case ZigTypeIdFn: { 12773 if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 12774 ir_add_error(ira, target, 12775 buf_sprintf("exported function type must specify calling convention")); 12776 } 12777 } break; 12778 case ZigTypeIdInt: 12779 case ZigTypeIdFloat: 12780 case ZigTypeIdPointer: 12781 case ZigTypeIdArray: 12782 case ZigTypeIdBool: 12783 break; 12784 case ZigTypeIdMetaType: 12785 case ZigTypeIdVoid: 12786 case ZigTypeIdUnreachable: 12787 case ZigTypeIdComptimeFloat: 12788 case ZigTypeIdComptimeInt: 12789 case ZigTypeIdUndefined: 12790 case ZigTypeIdNull: 12791 case ZigTypeIdOptional: 12792 case ZigTypeIdErrorUnion: 12793 case ZigTypeIdErrorSet: 12794 case ZigTypeIdNamespace: 12795 case ZigTypeIdBlock: 12796 case ZigTypeIdBoundFn: 12797 case ZigTypeIdArgTuple: 12798 case ZigTypeIdOpaque: 12799 case ZigTypeIdPromise: 12800 ir_add_error(ira, target, 12801 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); 12802 break; 12803 } 12804 } break; 12805 case ZigTypeIdVoid: 12806 case ZigTypeIdBool: 12807 case ZigTypeIdInt: 12808 case ZigTypeIdFloat: 12809 case ZigTypeIdPointer: 12810 case ZigTypeIdArray: 12811 case ZigTypeIdComptimeFloat: 12812 case ZigTypeIdComptimeInt: 12813 case ZigTypeIdUndefined: 12814 case ZigTypeIdNull: 12815 case ZigTypeIdOptional: 12816 case ZigTypeIdErrorUnion: 12817 case ZigTypeIdErrorSet: 12818 zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name)); 12819 case ZigTypeIdNamespace: 12820 case ZigTypeIdBlock: 12821 case ZigTypeIdBoundFn: 12822 case ZigTypeIdArgTuple: 12823 case ZigTypeIdOpaque: 12824 case ZigTypeIdPromise: 12825 ir_add_error(ira, target, 12826 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name))); 12827 break; 12828 } 12829 12830 ir_build_const_from(ira, &instruction->base); 12831 return ira->codegen->builtin_types.entry_void; 12832 } 12833 12834 static bool exec_has_err_ret_trace(CodeGen *g, IrExecutable *exec) { 12835 ZigFn *fn_entry = exec_fn_entry(exec); 12836 return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing; 12837 } 12838 12839 static ZigType *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, 12840 IrInstructionErrorReturnTrace *instruction) 12841 { 12842 if (instruction->optional == IrInstructionErrorReturnTrace::Null) { 12843 ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(ira->codegen); 12844 ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type); 12845 if (!exec_has_err_ret_trace(ira->codegen, ira->new_irb.exec)) { 12846 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 12847 assert(get_codegen_ptr_type(optional_type) != nullptr); 12848 out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 12849 out_val->data.x_ptr.data.hard_coded_addr.addr = 0; 12850 return optional_type; 12851 } 12852 IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, 12853 instruction->base.source_node, instruction->optional); 12854 ir_link_new_instruction(new_instruction, &instruction->base); 12855 return optional_type; 12856 } else { 12857 assert(ira->codegen->have_err_ret_tracing); 12858 IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, 12859 instruction->base.source_node, instruction->optional); 12860 ir_link_new_instruction(new_instruction, &instruction->base); 12861 return get_ptr_to_stack_trace_type(ira->codegen); 12862 } 12863 } 12864 12865 static ZigType *ir_analyze_instruction_error_union(IrAnalyze *ira, 12866 IrInstructionErrorUnion *instruction) 12867 { 12868 ZigType *err_set_type = ir_resolve_type(ira, instruction->err_set->other); 12869 if (type_is_invalid(err_set_type)) 12870 return ira->codegen->builtin_types.entry_invalid; 12871 12872 ZigType *payload_type = ir_resolve_type(ira, instruction->payload->other); 12873 if (type_is_invalid(payload_type)) 12874 return ira->codegen->builtin_types.entry_invalid; 12875 12876 if (err_set_type->id != ZigTypeIdErrorSet) { 12877 ir_add_error(ira, instruction->err_set->other, 12878 buf_sprintf("expected error set type, found type '%s'", 12879 buf_ptr(&err_set_type->name))); 12880 return ira->codegen->builtin_types.entry_invalid; 12881 } 12882 12883 ZigType *result_type = get_error_union_type(ira->codegen, err_set_type, payload_type); 12884 12885 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 12886 out_val->data.x_type = result_type; 12887 return ira->codegen->builtin_types.entry_type; 12888 } 12889 12890 IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_instr, ImplicitAllocatorId id) { 12891 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 12892 if (parent_fn_entry == nullptr) { 12893 ir_add_error(ira, source_instr, buf_sprintf("no implicit allocator available")); 12894 return ira->codegen->invalid_instruction; 12895 } 12896 12897 FnTypeId *parent_fn_type = &parent_fn_entry->type_entry->data.fn.fn_type_id; 12898 if (parent_fn_type->cc != CallingConventionAsync) { 12899 ir_add_error(ira, source_instr, buf_sprintf("async function call from non-async caller requires allocator parameter")); 12900 return ira->codegen->invalid_instruction; 12901 } 12902 12903 assert(parent_fn_type->async_allocator_type != nullptr); 12904 12905 switch (id) { 12906 case ImplicitAllocatorIdArg: 12907 { 12908 IrInstruction *result = ir_build_get_implicit_allocator(&ira->new_irb, source_instr->scope, 12909 source_instr->source_node, ImplicitAllocatorIdArg); 12910 result->value.type = parent_fn_type->async_allocator_type; 12911 return result; 12912 } 12913 case ImplicitAllocatorIdLocalVar: 12914 { 12915 ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; 12916 assert(coro_allocator_var != nullptr); 12917 IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var); 12918 IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst); 12919 assert(result->value.type != nullptr); 12920 return result; 12921 } 12922 } 12923 zig_unreachable(); 12924 } 12925 12926 static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry, ZigType *fn_type, 12927 IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, IrInstruction *async_allocator_inst) 12928 { 12929 Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME); 12930 //Buf *free_field_name = buf_create_from_str("freeFn"); 12931 assert(async_allocator_inst->value.type->id == ZigTypeIdPointer); 12932 ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; 12933 IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, alloc_field_name, &call_instruction->base, 12934 async_allocator_inst, container_type); 12935 if (type_is_invalid(field_ptr_inst->value.type)) { 12936 return ira->codegen->invalid_instruction; 12937 } 12938 ZigType *ptr_to_alloc_fn_type = field_ptr_inst->value.type; 12939 assert(ptr_to_alloc_fn_type->id == ZigTypeIdPointer); 12940 12941 ZigType *alloc_fn_type = ptr_to_alloc_fn_type->data.pointer.child_type; 12942 if (alloc_fn_type->id != ZigTypeIdFn) { 12943 ir_add_error(ira, &call_instruction->base, 12944 buf_sprintf("expected allocation function, found '%s'", buf_ptr(&alloc_fn_type->name))); 12945 return ira->codegen->invalid_instruction; 12946 } 12947 12948 ZigType *alloc_fn_return_type = alloc_fn_type->data.fn.fn_type_id.return_type; 12949 if (alloc_fn_return_type->id != ZigTypeIdErrorUnion) { 12950 ir_add_error(ira, fn_ref, 12951 buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&alloc_fn_return_type->name))); 12952 return ira->codegen->invalid_instruction; 12953 } 12954 ZigType *alloc_fn_error_set_type = alloc_fn_return_type->data.error_union.err_set_type; 12955 ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; 12956 ZigType *promise_type = get_promise_type(ira->codegen, return_type); 12957 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); 12958 12959 IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node, 12960 fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr); 12961 result->value.type = async_return_type; 12962 return result; 12963 } 12964 12965 static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, 12966 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) 12967 { 12968 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 12969 assert(param_decl_node->type == NodeTypeParamDecl); 12970 12971 IrInstruction *casted_arg; 12972 if (param_decl_node->data.param_decl.var_token == nullptr) { 12973 AstNode *param_type_node = param_decl_node->data.param_decl.type; 12974 ZigType *param_type = analyze_type_expr(ira->codegen, *exec_scope, param_type_node); 12975 if (type_is_invalid(param_type)) 12976 return false; 12977 12978 casted_arg = ir_implicit_cast(ira, arg, param_type); 12979 if (type_is_invalid(casted_arg->value.type)) 12980 return false; 12981 } else { 12982 casted_arg = arg; 12983 } 12984 12985 ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad); 12986 if (!arg_val) 12987 return false; 12988 12989 Buf *param_name = param_decl_node->data.param_decl.name; 12990 ZigVar *var = add_variable(ira->codegen, param_decl_node, 12991 *exec_scope, param_name, true, arg_val, nullptr); 12992 *exec_scope = var->child_scope; 12993 *next_proto_i += 1; 12994 12995 return true; 12996 } 12997 12998 static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, 12999 IrInstruction *arg, Scope **child_scope, size_t *next_proto_i, 13000 GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args, 13001 ZigFn *impl_fn) 13002 { 13003 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 13004 assert(param_decl_node->type == NodeTypeParamDecl); 13005 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 13006 bool arg_part_of_generic_id = false; 13007 IrInstruction *casted_arg; 13008 if (is_var_args) { 13009 arg_part_of_generic_id = true; 13010 casted_arg = arg; 13011 } else { 13012 if (param_decl_node->data.param_decl.var_token == nullptr) { 13013 AstNode *param_type_node = param_decl_node->data.param_decl.type; 13014 ZigType *param_type = analyze_type_expr(ira->codegen, *child_scope, param_type_node); 13015 if (type_is_invalid(param_type)) 13016 return false; 13017 13018 casted_arg = ir_implicit_cast(ira, arg, param_type); 13019 if (type_is_invalid(casted_arg->value.type)) 13020 return false; 13021 } else { 13022 arg_part_of_generic_id = true; 13023 casted_arg = arg; 13024 } 13025 } 13026 13027 bool comptime_arg = param_decl_node->data.param_decl.is_inline || 13028 casted_arg->value.type->id == ZigTypeIdComptimeInt || casted_arg->value.type->id == ZigTypeIdComptimeFloat; 13029 13030 ConstExprValue *arg_val; 13031 13032 if (comptime_arg) { 13033 arg_part_of_generic_id = true; 13034 arg_val = ir_resolve_const(ira, casted_arg, UndefBad); 13035 if (!arg_val) 13036 return false; 13037 } else { 13038 arg_val = create_const_runtime(casted_arg->value.type); 13039 } 13040 if (arg_part_of_generic_id) { 13041 generic_id->params[generic_id->param_count] = *arg_val; 13042 generic_id->param_count += 1; 13043 } 13044 13045 Buf *param_name = param_decl_node->data.param_decl.name; 13046 if (!param_name) return false; 13047 if (!is_var_args) { 13048 ZigVar *var = add_variable(ira->codegen, param_decl_node, 13049 *child_scope, param_name, true, arg_val, nullptr); 13050 *child_scope = var->child_scope; 13051 var->shadowable = !comptime_arg; 13052 13053 *next_proto_i += 1; 13054 } else if (casted_arg->value.type->id == ZigTypeIdComptimeInt || 13055 casted_arg->value.type->id == ZigTypeIdComptimeFloat) 13056 { 13057 ir_add_error(ira, casted_arg, 13058 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557")); 13059 return false; 13060 } 13061 13062 if (!comptime_arg) { 13063 if (type_requires_comptime(casted_arg->value.type)) { 13064 ir_add_error(ira, casted_arg, 13065 buf_sprintf("parameter of type '%s' requires comptime", buf_ptr(&casted_arg->value.type->name))); 13066 return false; 13067 } 13068 13069 casted_args[fn_type_id->param_count] = casted_arg; 13070 FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count]; 13071 param_info->type = casted_arg->value.type; 13072 param_info->is_noalias = param_decl_node->data.param_decl.is_noalias; 13073 impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node; 13074 fn_type_id->param_count += 1; 13075 } 13076 13077 return true; 13078 } 13079 13080 static ZigVar *get_fn_var_by_index(ZigFn *fn_entry, size_t index) { 13081 size_t next_var_i = 0; 13082 FnGenParamInfo *gen_param_info = fn_entry->type_entry->data.fn.gen_param_info; 13083 assert(gen_param_info != nullptr); 13084 for (size_t param_i = 0; param_i < index; param_i += 1) { 13085 FnGenParamInfo *info = &gen_param_info[param_i]; 13086 if (info->gen_index == SIZE_MAX) 13087 continue; 13088 13089 next_var_i += 1; 13090 } 13091 FnGenParamInfo *info = &gen_param_info[index]; 13092 if (info->gen_index == SIZE_MAX) 13093 return nullptr; 13094 13095 return fn_entry->variable_list.at(next_var_i); 13096 } 13097 13098 static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, 13099 ZigVar *var) 13100 { 13101 Error err; 13102 while (var->next_var != nullptr) { 13103 var = var->next_var; 13104 } 13105 13106 if (var->mem_slot_index != SIZE_MAX && var->owner_exec->analysis == nullptr) { 13107 assert(ira->codegen->errors.length != 0); 13108 return ira->codegen->invalid_instruction; 13109 } 13110 assert(var->value->type); 13111 if (type_is_invalid(var->value->type)) 13112 return ira->codegen->invalid_instruction; 13113 13114 bool comptime_var_mem = ir_get_var_is_comptime(var); 13115 13116 ConstExprValue *mem_slot = nullptr; 13117 if (var->value->special == ConstValSpecialStatic) { 13118 mem_slot = var->value; 13119 } else { 13120 if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { 13121 // find the relevant exec_context 13122 assert(var->owner_exec != nullptr); 13123 assert(var->owner_exec->analysis != nullptr); 13124 IrExecContext *exec_context = &var->owner_exec->analysis->exec_context; 13125 assert(var->mem_slot_index < exec_context->mem_slot_list.length); 13126 mem_slot = exec_context->mem_slot_list.at(var->mem_slot_index); 13127 } 13128 } 13129 13130 bool is_const = var->src_is_const; 13131 bool is_volatile = false; 13132 if (mem_slot != nullptr) { 13133 switch (mem_slot->special) { 13134 case ConstValSpecialRuntime: 13135 goto no_mem_slot; 13136 case ConstValSpecialStatic: // fallthrough 13137 case ConstValSpecialUndef: { 13138 ConstPtrMut ptr_mut; 13139 if (comptime_var_mem) { 13140 ptr_mut = ConstPtrMutComptimeVar; 13141 } else if (var->gen_is_const) { 13142 ptr_mut = ConstPtrMutComptimeConst; 13143 } else { 13144 assert(!comptime_var_mem); 13145 ptr_mut = ConstPtrMutRuntimeVar; 13146 } 13147 return ir_get_const_ptr(ira, instruction, mem_slot, var->value->type, 13148 ptr_mut, is_const, is_volatile, var->align_bytes); 13149 } 13150 } 13151 zig_unreachable(); 13152 } 13153 13154 no_mem_slot: 13155 13156 IrInstruction *var_ptr_instruction = ir_build_var_ptr(&ira->new_irb, 13157 instruction->scope, instruction->source_node, var); 13158 var_ptr_instruction->value.type = get_pointer_to_type_extra(ira->codegen, var->value->type, 13159 var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0); 13160 if ((err = type_ensure_zero_bits_known(ira->codegen, var->value->type))) 13161 return ira->codegen->invalid_instruction; 13162 13163 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr); 13164 var_ptr_instruction->value.data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack; 13165 13166 return var_ptr_instruction; 13167 } 13168 13169 static ZigType *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction, 13170 ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, 13171 IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) 13172 { 13173 Error err; 13174 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 13175 size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0; 13176 13177 // for extern functions, the var args argument is not counted. 13178 // for zig functions, it is. 13179 size_t var_args_1_or_0; 13180 if (fn_type_id->cc == CallingConventionC) { 13181 var_args_1_or_0 = 0; 13182 } else { 13183 var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0; 13184 } 13185 size_t src_param_count = fn_type_id->param_count - var_args_1_or_0; 13186 13187 size_t call_param_count = call_instruction->arg_count + first_arg_1_or_0; 13188 for (size_t i = 0; i < call_instruction->arg_count; i += 1) { 13189 ConstExprValue *arg_tuple_value = &call_instruction->args[i]->other->value; 13190 if (arg_tuple_value->type->id == ZigTypeIdArgTuple) { 13191 call_param_count -= 1; 13192 call_param_count += arg_tuple_value->data.x_arg_tuple.end_index - 13193 arg_tuple_value->data.x_arg_tuple.start_index; 13194 } 13195 } 13196 AstNode *source_node = call_instruction->base.source_node; 13197 13198 AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;; 13199 13200 if (fn_type_id->cc == CallingConventionNaked) { 13201 ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("unable to call function with naked calling convention")); 13202 if (fn_proto_node) { 13203 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 13204 } 13205 return ira->codegen->builtin_types.entry_invalid; 13206 } 13207 if (fn_type_id->cc == CallingConventionAsync && !call_instruction->is_async) { 13208 ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("must use async keyword to call async function")); 13209 if (fn_proto_node) { 13210 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 13211 } 13212 return ira->codegen->builtin_types.entry_invalid; 13213 } 13214 if (fn_type_id->cc != CallingConventionAsync && call_instruction->is_async) { 13215 ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("cannot use async keyword to call non-async function")); 13216 if (fn_proto_node) { 13217 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 13218 } 13219 return ira->codegen->builtin_types.entry_invalid; 13220 } 13221 13222 13223 if (fn_type_id->is_var_args) { 13224 if (call_param_count < src_param_count) { 13225 ErrorMsg *msg = ir_add_error_node(ira, source_node, 13226 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 13227 if (fn_proto_node) { 13228 add_error_note(ira->codegen, msg, fn_proto_node, 13229 buf_sprintf("declared here")); 13230 } 13231 return ira->codegen->builtin_types.entry_invalid; 13232 } 13233 } else if (src_param_count != call_param_count) { 13234 ErrorMsg *msg = ir_add_error_node(ira, source_node, 13235 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 13236 if (fn_proto_node) { 13237 add_error_note(ira->codegen, msg, fn_proto_node, 13238 buf_sprintf("declared here")); 13239 } 13240 return ira->codegen->builtin_types.entry_invalid; 13241 } 13242 13243 if (comptime_fn_call) { 13244 // No special handling is needed for compile time evaluation of generic functions. 13245 if (!fn_entry || fn_entry->body_node == nullptr) { 13246 ir_add_error(ira, fn_ref, buf_sprintf("unable to evaluate constant expression")); 13247 return ira->codegen->builtin_types.entry_invalid; 13248 } 13249 13250 if (!ir_emit_backward_branch(ira, &call_instruction->base)) 13251 return ira->codegen->builtin_types.entry_invalid; 13252 13253 // Fork a scope of the function with known values for the parameters. 13254 Scope *exec_scope = &fn_entry->fndef_scope->base; 13255 13256 size_t next_proto_i = 0; 13257 if (first_arg_ptr) { 13258 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 13259 13260 bool first_arg_known_bare = false; 13261 if (fn_type_id->next_param_index >= 1) { 13262 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 13263 if (type_is_invalid(param_type)) 13264 return ira->codegen->builtin_types.entry_invalid; 13265 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 13266 } 13267 13268 IrInstruction *first_arg; 13269 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { 13270 first_arg = first_arg_ptr; 13271 } else { 13272 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); 13273 if (type_is_invalid(first_arg->value.type)) 13274 return ira->codegen->builtin_types.entry_invalid; 13275 } 13276 13277 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, first_arg, &exec_scope, &next_proto_i)) 13278 return ira->codegen->builtin_types.entry_invalid; 13279 } 13280 13281 if (fn_proto_node->data.fn_proto.is_var_args) { 13282 ir_add_error(ira, &call_instruction->base, 13283 buf_sprintf("compiler bug: unable to call var args function at compile time. https://github.com/ziglang/zig/issues/313")); 13284 return ira->codegen->builtin_types.entry_invalid; 13285 } 13286 13287 13288 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 13289 IrInstruction *old_arg = call_instruction->args[call_i]->other; 13290 if (type_is_invalid(old_arg->value.type)) 13291 return ira->codegen->builtin_types.entry_invalid; 13292 13293 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i)) 13294 return ira->codegen->builtin_types.entry_invalid; 13295 } 13296 13297 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 13298 ZigType *specified_return_type = analyze_type_expr(ira->codegen, exec_scope, return_type_node); 13299 if (type_is_invalid(specified_return_type)) 13300 return ira->codegen->builtin_types.entry_invalid; 13301 ZigType *return_type; 13302 ZigType *inferred_err_set_type = nullptr; 13303 if (fn_proto_node->data.fn_proto.auto_err_set) { 13304 inferred_err_set_type = get_auto_err_set_type(ira->codegen, fn_entry); 13305 return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 13306 } else { 13307 return_type = specified_return_type; 13308 } 13309 13310 bool cacheable = fn_eval_cacheable(exec_scope, return_type); 13311 IrInstruction *result = nullptr; 13312 if (cacheable) { 13313 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope); 13314 if (entry) 13315 result = entry->value; 13316 } 13317 13318 if (result == nullptr) { 13319 // Analyze the fn body block like any other constant expression. 13320 AstNode *body_node = fn_entry->body_node; 13321 result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, 13322 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, 13323 nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec); 13324 13325 if (inferred_err_set_type != nullptr) { 13326 inferred_err_set_type->data.error_set.infer_fn = nullptr; 13327 if (result->value.type->id == ZigTypeIdErrorUnion) { 13328 if (result->value.data.x_err_union.err != nullptr) { 13329 inferred_err_set_type->data.error_set.err_count = 1; 13330 inferred_err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1); 13331 inferred_err_set_type->data.error_set.errors[0] = result->value.data.x_err_union.err; 13332 } 13333 ZigType *fn_inferred_err_set_type = result->value.type->data.error_union.err_set_type; 13334 inferred_err_set_type->data.error_set.err_count = fn_inferred_err_set_type->data.error_set.err_count; 13335 inferred_err_set_type->data.error_set.errors = fn_inferred_err_set_type->data.error_set.errors; 13336 } else if (result->value.type->id == ZigTypeIdErrorSet) { 13337 inferred_err_set_type->data.error_set.err_count = result->value.type->data.error_set.err_count; 13338 inferred_err_set_type->data.error_set.errors = result->value.type->data.error_set.errors; 13339 } 13340 } 13341 13342 if (cacheable) { 13343 ira->codegen->memoized_fn_eval_table.put(exec_scope, result); 13344 } 13345 13346 if (type_is_invalid(result->value.type)) 13347 return ira->codegen->builtin_types.entry_invalid; 13348 } 13349 13350 ConstExprValue *out_val = ir_build_const_from(ira, &call_instruction->base); 13351 *out_val = result->value; 13352 return ir_finish_anal(ira, return_type); 13353 } 13354 13355 IrInstruction *casted_new_stack = nullptr; 13356 if (call_instruction->new_stack != nullptr) { 13357 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 13358 false, false, PtrLenUnknown, 13359 get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0); 13360 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 13361 IrInstruction *new_stack = call_instruction->new_stack->other; 13362 if (type_is_invalid(new_stack->value.type)) 13363 return ira->codegen->builtin_types.entry_invalid; 13364 13365 casted_new_stack = ir_implicit_cast(ira, new_stack, u8_slice); 13366 if (type_is_invalid(casted_new_stack->value.type)) 13367 return ira->codegen->builtin_types.entry_invalid; 13368 } 13369 13370 if (fn_type->data.fn.is_generic) { 13371 if (!fn_entry) { 13372 ir_add_error(ira, call_instruction->fn_ref, 13373 buf_sprintf("calling a generic function requires compile-time known function value")); 13374 return ira->codegen->builtin_types.entry_invalid; 13375 } 13376 13377 // Count the arguments of the function type id we are creating 13378 size_t new_fn_arg_count = first_arg_1_or_0; 13379 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 13380 IrInstruction *arg = call_instruction->args[call_i]->other; 13381 if (type_is_invalid(arg->value.type)) 13382 return ira->codegen->builtin_types.entry_invalid; 13383 13384 if (arg->value.type->id == ZigTypeIdArgTuple) { 13385 new_fn_arg_count += arg->value.data.x_arg_tuple.end_index - arg->value.data.x_arg_tuple.start_index; 13386 } else { 13387 new_fn_arg_count += 1; 13388 } 13389 } 13390 13391 IrInstruction **casted_args = allocate<IrInstruction *>(new_fn_arg_count); 13392 13393 // Fork a scope of the function with known values for the parameters. 13394 Scope *parent_scope = fn_entry->fndef_scope->base.parent; 13395 ZigFn *impl_fn = create_fn(fn_proto_node); 13396 impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count); 13397 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); 13398 impl_fn->fndef_scope = create_fndef_scope(impl_fn->body_node, parent_scope, impl_fn); 13399 impl_fn->child_scope = &impl_fn->fndef_scope->base; 13400 FnTypeId inst_fn_type_id = {0}; 13401 init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count); 13402 inst_fn_type_id.param_count = 0; 13403 inst_fn_type_id.is_var_args = false; 13404 13405 // TODO maybe GenericFnTypeId can be replaced with using the child_scope directly 13406 // as the key in generic_table 13407 GenericFnTypeId *generic_id = allocate<GenericFnTypeId>(1); 13408 generic_id->fn_entry = fn_entry; 13409 generic_id->param_count = 0; 13410 generic_id->params = create_const_vals(new_fn_arg_count); 13411 size_t next_proto_i = 0; 13412 13413 if (first_arg_ptr) { 13414 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 13415 13416 bool first_arg_known_bare = false; 13417 if (fn_type_id->next_param_index >= 1) { 13418 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 13419 if (type_is_invalid(param_type)) 13420 return ira->codegen->builtin_types.entry_invalid; 13421 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 13422 } 13423 13424 IrInstruction *first_arg; 13425 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { 13426 first_arg = first_arg_ptr; 13427 } else { 13428 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); 13429 if (type_is_invalid(first_arg->value.type)) 13430 return ira->codegen->builtin_types.entry_invalid; 13431 } 13432 13433 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, &impl_fn->child_scope, 13434 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 13435 { 13436 return ira->codegen->builtin_types.entry_invalid; 13437 } 13438 } 13439 13440 bool found_first_var_arg = false; 13441 size_t first_var_arg; 13442 13443 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 13444 assert(parent_fn_entry); 13445 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 13446 IrInstruction *arg = call_instruction->args[call_i]->other; 13447 if (type_is_invalid(arg->value.type)) 13448 return ira->codegen->builtin_types.entry_invalid; 13449 13450 if (arg->value.type->id == ZigTypeIdArgTuple) { 13451 for (size_t arg_tuple_i = arg->value.data.x_arg_tuple.start_index; 13452 arg_tuple_i < arg->value.data.x_arg_tuple.end_index; arg_tuple_i += 1) 13453 { 13454 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 13455 assert(param_decl_node->type == NodeTypeParamDecl); 13456 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 13457 if (is_var_args && !found_first_var_arg) { 13458 first_var_arg = inst_fn_type_id.param_count; 13459 found_first_var_arg = true; 13460 } 13461 13462 ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i); 13463 if (arg_var == nullptr) { 13464 ir_add_error(ira, arg, 13465 buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557")); 13466 return ira->codegen->builtin_types.entry_invalid; 13467 } 13468 IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, arg, arg_var); 13469 if (type_is_invalid(arg_var_ptr_inst->value.type)) 13470 return ira->codegen->builtin_types.entry_invalid; 13471 13472 IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst); 13473 if (type_is_invalid(arg_tuple_arg->value.type)) 13474 return ira->codegen->builtin_types.entry_invalid; 13475 13476 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg_tuple_arg, &impl_fn->child_scope, 13477 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 13478 { 13479 return ira->codegen->builtin_types.entry_invalid; 13480 } 13481 } 13482 } else { 13483 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 13484 assert(param_decl_node->type == NodeTypeParamDecl); 13485 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 13486 if (is_var_args && !found_first_var_arg) { 13487 first_var_arg = inst_fn_type_id.param_count; 13488 found_first_var_arg = true; 13489 } 13490 13491 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope, 13492 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 13493 { 13494 return ira->codegen->builtin_types.entry_invalid; 13495 } 13496 } 13497 } 13498 13499 if (fn_proto_node->data.fn_proto.is_var_args) { 13500 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 13501 Buf *param_name = param_decl_node->data.param_decl.name; 13502 13503 if (!found_first_var_arg) { 13504 first_var_arg = inst_fn_type_id.param_count; 13505 } 13506 13507 ConstExprValue *var_args_val = create_const_arg_tuple(ira->codegen, 13508 first_var_arg, inst_fn_type_id.param_count); 13509 ZigVar *var = add_variable(ira->codegen, param_decl_node, 13510 impl_fn->child_scope, param_name, true, var_args_val, nullptr); 13511 impl_fn->child_scope = var->child_scope; 13512 } 13513 13514 if (fn_proto_node->data.fn_proto.align_expr != nullptr) { 13515 IrInstruction *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, 13516 fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), 13517 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 13518 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec); 13519 13520 uint32_t align_bytes = 0; 13521 ir_resolve_align(ira, align_result, &align_bytes); 13522 impl_fn->align_bytes = align_bytes; 13523 inst_fn_type_id.alignment = align_bytes; 13524 } 13525 13526 if (fn_proto_node->data.fn_proto.return_var_token == nullptr) { 13527 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 13528 ZigType *specified_return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node); 13529 if (type_is_invalid(specified_return_type)) 13530 return ira->codegen->builtin_types.entry_invalid; 13531 if (fn_proto_node->data.fn_proto.auto_err_set) { 13532 ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn); 13533 inst_fn_type_id.return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 13534 } else { 13535 inst_fn_type_id.return_type = specified_return_type; 13536 } 13537 13538 if ((err = type_ensure_zero_bits_known(ira->codegen, specified_return_type))) 13539 return ira->codegen->builtin_types.entry_invalid; 13540 13541 if (type_requires_comptime(specified_return_type)) { 13542 // Throw out our work and call the function as if it were comptime. 13543 return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, true, FnInlineAuto); 13544 } 13545 } 13546 IrInstruction *async_allocator_inst = nullptr; 13547 if (call_instruction->is_async) { 13548 AstNode *async_allocator_type_node = fn_proto_node->data.fn_proto.async_allocator_type; 13549 if (async_allocator_type_node != nullptr) { 13550 ZigType *async_allocator_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, async_allocator_type_node); 13551 if (type_is_invalid(async_allocator_type)) 13552 return ira->codegen->builtin_types.entry_invalid; 13553 inst_fn_type_id.async_allocator_type = async_allocator_type; 13554 } 13555 IrInstruction *uncasted_async_allocator_inst; 13556 if (call_instruction->async_allocator == nullptr) { 13557 uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, 13558 ImplicitAllocatorIdLocalVar); 13559 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 13560 return ira->codegen->builtin_types.entry_invalid; 13561 } else { 13562 uncasted_async_allocator_inst = call_instruction->async_allocator->other; 13563 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 13564 return ira->codegen->builtin_types.entry_invalid; 13565 } 13566 if (inst_fn_type_id.async_allocator_type == nullptr) { 13567 inst_fn_type_id.async_allocator_type = uncasted_async_allocator_inst->value.type; 13568 } 13569 async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type); 13570 if (type_is_invalid(async_allocator_inst->value.type)) 13571 return ira->codegen->builtin_types.entry_invalid; 13572 } 13573 13574 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn); 13575 if (existing_entry) { 13576 // throw away all our work and use the existing function 13577 impl_fn = existing_entry->value; 13578 } else { 13579 // finish instantiating the function 13580 impl_fn->type_entry = get_fn_type(ira->codegen, &inst_fn_type_id); 13581 if (type_is_invalid(impl_fn->type_entry)) 13582 return ira->codegen->builtin_types.entry_invalid; 13583 13584 impl_fn->ir_executable.source_node = call_instruction->base.source_node; 13585 impl_fn->ir_executable.parent_exec = ira->new_irb.exec; 13586 impl_fn->analyzed_executable.source_node = call_instruction->base.source_node; 13587 impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; 13588 impl_fn->analyzed_executable.backward_branch_quota = ira->new_irb.exec->backward_branch_quota; 13589 impl_fn->analyzed_executable.is_generic_instantiation = true; 13590 13591 ira->codegen->fn_defs.append(impl_fn); 13592 } 13593 13594 ZigType *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type; 13595 if (fn_type_can_fail(&impl_fn->type_entry->data.fn.fn_type_id)) { 13596 parent_fn_entry->calls_or_awaits_errorable_fn = true; 13597 } 13598 13599 size_t impl_param_count = impl_fn->type_entry->data.fn.fn_type_id.param_count; 13600 if (call_instruction->is_async) { 13601 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, fn_ref, casted_args, impl_param_count, 13602 async_allocator_inst); 13603 ir_link_new_instruction(result, &call_instruction->base); 13604 ir_add_alloca(ira, result, result->value.type); 13605 return ir_finish_anal(ira, result->value.type); 13606 } 13607 13608 assert(async_allocator_inst == nullptr); 13609 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base, 13610 impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline, 13611 call_instruction->is_async, nullptr, casted_new_stack); 13612 13613 ir_add_alloca(ira, new_call_instruction, return_type); 13614 13615 return ir_finish_anal(ira, return_type); 13616 } 13617 13618 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 13619 assert(fn_type_id->return_type != nullptr); 13620 assert(parent_fn_entry != nullptr); 13621 if (fn_type_can_fail(fn_type_id)) { 13622 parent_fn_entry->calls_or_awaits_errorable_fn = true; 13623 } 13624 13625 13626 IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count); 13627 size_t next_arg_index = 0; 13628 if (first_arg_ptr) { 13629 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 13630 13631 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 13632 if (type_is_invalid(param_type)) 13633 return ira->codegen->builtin_types.entry_invalid; 13634 13635 IrInstruction *first_arg; 13636 if (param_type->id == ZigTypeIdPointer && 13637 handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) 13638 { 13639 first_arg = first_arg_ptr; 13640 } else { 13641 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); 13642 if (type_is_invalid(first_arg->value.type)) 13643 return ira->codegen->builtin_types.entry_invalid; 13644 } 13645 13646 IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type); 13647 if (type_is_invalid(casted_arg->value.type)) 13648 return ira->codegen->builtin_types.entry_invalid; 13649 13650 casted_args[next_arg_index] = casted_arg; 13651 next_arg_index += 1; 13652 } 13653 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 13654 IrInstruction *old_arg = call_instruction->args[call_i]->other; 13655 if (type_is_invalid(old_arg->value.type)) 13656 return ira->codegen->builtin_types.entry_invalid; 13657 IrInstruction *casted_arg; 13658 if (next_arg_index < src_param_count) { 13659 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 13660 if (type_is_invalid(param_type)) 13661 return ira->codegen->builtin_types.entry_invalid; 13662 casted_arg = ir_implicit_cast(ira, old_arg, param_type); 13663 if (type_is_invalid(casted_arg->value.type)) 13664 return ira->codegen->builtin_types.entry_invalid; 13665 } else { 13666 casted_arg = old_arg; 13667 } 13668 13669 casted_args[next_arg_index] = casted_arg; 13670 next_arg_index += 1; 13671 } 13672 13673 assert(next_arg_index == call_param_count); 13674 13675 ZigType *return_type = fn_type_id->return_type; 13676 if (type_is_invalid(return_type)) 13677 return ira->codegen->builtin_types.entry_invalid; 13678 13679 if (call_instruction->is_async) { 13680 IrInstruction *uncasted_async_allocator_inst; 13681 if (call_instruction->async_allocator == nullptr) { 13682 uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, 13683 ImplicitAllocatorIdLocalVar); 13684 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 13685 return ira->codegen->builtin_types.entry_invalid; 13686 } else { 13687 uncasted_async_allocator_inst = call_instruction->async_allocator->other; 13688 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 13689 return ira->codegen->builtin_types.entry_invalid; 13690 13691 } 13692 IrInstruction *async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, fn_type_id->async_allocator_type); 13693 if (type_is_invalid(async_allocator_inst->value.type)) 13694 return ira->codegen->builtin_types.entry_invalid; 13695 13696 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, casted_args, call_param_count, 13697 async_allocator_inst); 13698 ir_link_new_instruction(result, &call_instruction->base); 13699 ir_add_alloca(ira, result, result->value.type); 13700 return ir_finish_anal(ira, result->value.type); 13701 } 13702 13703 if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) { 13704 ir_add_error(ira, &call_instruction->base, 13705 buf_sprintf("no-inline call of inline function")); 13706 return ira->codegen->builtin_types.entry_invalid; 13707 } 13708 13709 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base, 13710 fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack); 13711 13712 ir_add_alloca(ira, new_call_instruction, return_type); 13713 return ir_finish_anal(ira, return_type); 13714 } 13715 13716 static ZigType *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) { 13717 IrInstruction *fn_ref = call_instruction->fn_ref->other; 13718 if (type_is_invalid(fn_ref->value.type)) 13719 return ira->codegen->builtin_types.entry_invalid; 13720 13721 bool is_comptime = call_instruction->is_comptime || 13722 ir_should_inline(ira->new_irb.exec, call_instruction->base.scope); 13723 13724 if (is_comptime || instr_is_comptime(fn_ref)) { 13725 if (fn_ref->value.type->id == ZigTypeIdMetaType) { 13726 ZigType *dest_type = ir_resolve_type(ira, fn_ref); 13727 if (type_is_invalid(dest_type)) 13728 return ira->codegen->builtin_types.entry_invalid; 13729 13730 size_t actual_param_count = call_instruction->arg_count; 13731 13732 if (actual_param_count != 1) { 13733 ir_add_error_node(ira, call_instruction->base.source_node, 13734 buf_sprintf("cast expression expects exactly one parameter")); 13735 return ira->codegen->builtin_types.entry_invalid; 13736 } 13737 13738 IrInstruction *arg = call_instruction->args[0]->other; 13739 13740 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg); 13741 if (type_is_invalid(cast_instruction->value.type)) 13742 return ira->codegen->builtin_types.entry_invalid; 13743 13744 ir_link_new_instruction(cast_instruction, &call_instruction->base); 13745 return ir_finish_anal(ira, cast_instruction->value.type); 13746 } else if (fn_ref->value.type->id == ZigTypeIdFn) { 13747 ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); 13748 if (fn_table_entry == nullptr) 13749 return ira->codegen->builtin_types.entry_invalid; 13750 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 13751 fn_ref, nullptr, is_comptime, call_instruction->fn_inline); 13752 } else if (fn_ref->value.type->id == ZigTypeIdBoundFn) { 13753 assert(fn_ref->value.special == ConstValSpecialStatic); 13754 ZigFn *fn_table_entry = fn_ref->value.data.x_bound_fn.fn; 13755 IrInstruction *first_arg_ptr = fn_ref->value.data.x_bound_fn.first_arg; 13756 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 13757 fn_ref, first_arg_ptr, is_comptime, call_instruction->fn_inline); 13758 } else { 13759 ir_add_error_node(ira, fn_ref->source_node, 13760 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value.type->name))); 13761 return ira->codegen->builtin_types.entry_invalid; 13762 } 13763 } 13764 13765 if (fn_ref->value.type->id == ZigTypeIdFn) { 13766 return ir_analyze_fn_call(ira, call_instruction, nullptr, fn_ref->value.type, 13767 fn_ref, nullptr, false, FnInlineAuto); 13768 } else { 13769 ir_add_error_node(ira, fn_ref->source_node, 13770 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value.type->name))); 13771 return ira->codegen->builtin_types.entry_invalid; 13772 } 13773 } 13774 13775 // out_val->type must be the type to read the pointer as 13776 // if the type is different than the actual type then it does a comptime byte reinterpretation 13777 static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, 13778 ConstExprValue *out_val, ConstExprValue *ptr_val) 13779 { 13780 assert(out_val->type != nullptr); 13781 13782 ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, ptr_val); 13783 13784 size_t src_size = type_size(ira->codegen, pointee->type); 13785 size_t dst_size = type_size(ira->codegen, out_val->type); 13786 13787 if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { 13788 copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst); 13789 return ErrorNone; 13790 } 13791 13792 if (dst_size > src_size) { 13793 ir_add_error_node(ira, source_node, 13794 buf_sprintf("attempt to read %zu bytes from pointer to %s which is %zu bytes", 13795 dst_size, buf_ptr(&pointee->type->name), src_size)); 13796 return ErrorSemanticAnalyzeFail; 13797 } 13798 13799 Buf buf = BUF_INIT; 13800 buf_resize(&buf, src_size); 13801 buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee); 13802 buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val); 13803 return ErrorNone; 13804 } 13805 13806 static ZigType *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { 13807 Error err; 13808 IrInstruction *value = un_op_instruction->value->other; 13809 13810 ZigType *ptr_type = value->value.type; 13811 ZigType *child_type; 13812 if (type_is_invalid(ptr_type)) { 13813 return ira->codegen->builtin_types.entry_invalid; 13814 } else if (ptr_type->id == ZigTypeIdPointer) { 13815 if (ptr_type->data.pointer.ptr_len == PtrLenUnknown) { 13816 ir_add_error_node(ira, un_op_instruction->base.source_node, 13817 buf_sprintf("index syntax required for unknown-length pointer type '%s'", 13818 buf_ptr(&ptr_type->name))); 13819 return ira->codegen->builtin_types.entry_invalid; 13820 } 13821 child_type = ptr_type->data.pointer.child_type; 13822 } else { 13823 ir_add_error_node(ira, un_op_instruction->base.source_node, 13824 buf_sprintf("attempt to dereference non-pointer type '%s'", 13825 buf_ptr(&ptr_type->name))); 13826 return ira->codegen->builtin_types.entry_invalid; 13827 } 13828 13829 // this dereference is always an rvalue because in the IR gen we identify lvalue and emit 13830 // one of the ptr instructions 13831 13832 if (instr_is_comptime(value)) { 13833 ConstExprValue *comptime_value = ir_resolve_const(ira, value, UndefBad); 13834 if (comptime_value == nullptr) 13835 return ira->codegen->builtin_types.entry_invalid; 13836 13837 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); 13838 out_val->type = child_type; 13839 if ((err = ir_read_const_ptr(ira, un_op_instruction->base.source_node, out_val, comptime_value))) 13840 return ira->codegen->builtin_types.entry_invalid; 13841 return child_type; 13842 } 13843 13844 ir_build_load_ptr_from(&ira->new_irb, &un_op_instruction->base, value); 13845 return child_type; 13846 } 13847 13848 static ZigType *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { 13849 Error err; 13850 IrInstruction *value = un_op_instruction->value->other; 13851 ZigType *type_entry = ir_resolve_type(ira, value); 13852 if (type_is_invalid(type_entry)) 13853 return ira->codegen->builtin_types.entry_invalid; 13854 if ((err = ensure_complete_type(ira->codegen, type_entry))) 13855 return ira->codegen->builtin_types.entry_invalid; 13856 13857 switch (type_entry->id) { 13858 case ZigTypeIdInvalid: 13859 zig_unreachable(); 13860 case ZigTypeIdMetaType: 13861 case ZigTypeIdVoid: 13862 case ZigTypeIdBool: 13863 case ZigTypeIdInt: 13864 case ZigTypeIdFloat: 13865 case ZigTypeIdPointer: 13866 case ZigTypeIdArray: 13867 case ZigTypeIdStruct: 13868 case ZigTypeIdComptimeFloat: 13869 case ZigTypeIdComptimeInt: 13870 case ZigTypeIdUndefined: 13871 case ZigTypeIdNull: 13872 case ZigTypeIdOptional: 13873 case ZigTypeIdErrorUnion: 13874 case ZigTypeIdErrorSet: 13875 case ZigTypeIdEnum: 13876 case ZigTypeIdUnion: 13877 case ZigTypeIdFn: 13878 case ZigTypeIdNamespace: 13879 case ZigTypeIdBlock: 13880 case ZigTypeIdBoundFn: 13881 case ZigTypeIdArgTuple: 13882 case ZigTypeIdPromise: 13883 { 13884 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); 13885 out_val->data.x_type = get_optional_type(ira->codegen, type_entry); 13886 return ira->codegen->builtin_types.entry_type; 13887 } 13888 case ZigTypeIdUnreachable: 13889 case ZigTypeIdOpaque: 13890 ir_add_error_node(ira, un_op_instruction->base.source_node, 13891 buf_sprintf("type '%s' not optional", buf_ptr(&type_entry->name))); 13892 return ira->codegen->builtin_types.entry_invalid; 13893 } 13894 zig_unreachable(); 13895 } 13896 13897 static ZigType *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { 13898 IrInstruction *value = un_op_instruction->value->other; 13899 ZigType *expr_type = value->value.type; 13900 if (type_is_invalid(expr_type)) 13901 return ira->codegen->builtin_types.entry_invalid; 13902 13903 bool is_wrap_op = (un_op_instruction->op_id == IrUnOpNegationWrap); 13904 13905 bool is_float = (expr_type->id == ZigTypeIdFloat || expr_type->id == ZigTypeIdComptimeFloat); 13906 13907 if ((expr_type->id == ZigTypeIdInt && expr_type->data.integral.is_signed) || 13908 expr_type->id == ZigTypeIdComptimeInt || (is_float && !is_wrap_op)) 13909 { 13910 if (instr_is_comptime(value)) { 13911 ConstExprValue *target_const_val = ir_resolve_const(ira, value, UndefBad); 13912 if (!target_const_val) 13913 return ira->codegen->builtin_types.entry_invalid; 13914 13915 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); 13916 if (is_float) { 13917 float_negate(out_val, target_const_val); 13918 } else if (is_wrap_op) { 13919 bigint_negate_wrap(&out_val->data.x_bigint, &target_const_val->data.x_bigint, 13920 expr_type->data.integral.bit_count); 13921 } else { 13922 bigint_negate(&out_val->data.x_bigint, &target_const_val->data.x_bigint); 13923 } 13924 if (is_wrap_op || is_float || expr_type->id == ZigTypeIdComptimeInt) { 13925 return expr_type; 13926 } 13927 13928 if (!bigint_fits_in_bits(&out_val->data.x_bigint, expr_type->data.integral.bit_count, true)) { 13929 ir_add_error(ira, &un_op_instruction->base, buf_sprintf("negation caused overflow")); 13930 return ira->codegen->builtin_types.entry_invalid; 13931 } 13932 return expr_type; 13933 } 13934 13935 ir_build_un_op_from(&ira->new_irb, &un_op_instruction->base, un_op_instruction->op_id, value); 13936 return expr_type; 13937 } 13938 13939 const char *fmt = is_wrap_op ? "invalid wrapping negation type: '%s'" : "invalid negation type: '%s'"; 13940 ir_add_error(ira, &un_op_instruction->base, buf_sprintf(fmt, buf_ptr(&expr_type->name))); 13941 return ira->codegen->builtin_types.entry_invalid; 13942 } 13943 13944 static ZigType *ir_analyze_bin_not(IrAnalyze *ira, IrInstructionUnOp *instruction) { 13945 IrInstruction *value = instruction->value->other; 13946 ZigType *expr_type = value->value.type; 13947 if (type_is_invalid(expr_type)) 13948 return ira->codegen->builtin_types.entry_invalid; 13949 13950 if (expr_type->id == ZigTypeIdInt) { 13951 if (instr_is_comptime(value)) { 13952 ConstExprValue *target_const_val = ir_resolve_const(ira, value, UndefBad); 13953 if (target_const_val == nullptr) 13954 return ira->codegen->builtin_types.entry_invalid; 13955 13956 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 13957 bigint_not(&out_val->data.x_bigint, &target_const_val->data.x_bigint, 13958 expr_type->data.integral.bit_count, expr_type->data.integral.is_signed); 13959 return expr_type; 13960 } 13961 13962 ir_build_un_op_from(&ira->new_irb, &instruction->base, IrUnOpBinNot, value); 13963 return expr_type; 13964 } 13965 13966 ir_add_error(ira, &instruction->base, 13967 buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name))); 13968 return ira->codegen->builtin_types.entry_invalid; 13969 } 13970 13971 static ZigType *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { 13972 IrUnOp op_id = un_op_instruction->op_id; 13973 switch (op_id) { 13974 case IrUnOpInvalid: 13975 zig_unreachable(); 13976 case IrUnOpBinNot: 13977 return ir_analyze_bin_not(ira, un_op_instruction); 13978 case IrUnOpNegation: 13979 case IrUnOpNegationWrap: 13980 return ir_analyze_negation(ira, un_op_instruction); 13981 case IrUnOpDereference: 13982 return ir_analyze_dereference(ira, un_op_instruction); 13983 case IrUnOpOptional: 13984 return ir_analyze_maybe(ira, un_op_instruction); 13985 } 13986 zig_unreachable(); 13987 } 13988 13989 static ZigType *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { 13990 IrBasicBlock *old_dest_block = br_instruction->dest_block; 13991 13992 bool is_comptime; 13993 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->other, &is_comptime)) 13994 return ir_unreach_error(ira); 13995 13996 if (is_comptime || old_dest_block->ref_count == 1) 13997 return ir_inline_bb(ira, &br_instruction->base, old_dest_block); 13998 13999 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); 14000 if (new_bb == nullptr) 14001 return ir_unreach_error(ira); 14002 14003 ir_build_br_from(&ira->new_irb, &br_instruction->base, new_bb); 14004 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); 14005 } 14006 14007 static ZigType *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) { 14008 IrInstruction *condition = cond_br_instruction->condition->other; 14009 if (type_is_invalid(condition->value.type)) 14010 return ir_unreach_error(ira); 14011 14012 bool is_comptime; 14013 if (!ir_resolve_comptime(ira, cond_br_instruction->is_comptime->other, &is_comptime)) 14014 return ir_unreach_error(ira); 14015 14016 if (is_comptime || instr_is_comptime(condition)) { 14017 bool cond_is_true; 14018 if (!ir_resolve_bool(ira, condition, &cond_is_true)) 14019 return ir_unreach_error(ira); 14020 14021 IrBasicBlock *old_dest_block = cond_is_true ? 14022 cond_br_instruction->then_block : cond_br_instruction->else_block; 14023 14024 if (is_comptime || old_dest_block->ref_count == 1) 14025 return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); 14026 14027 IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); 14028 if (new_dest_block == nullptr) 14029 return ir_unreach_error(ira); 14030 14031 ir_build_br_from(&ira->new_irb, &cond_br_instruction->base, new_dest_block); 14032 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); 14033 } 14034 14035 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 14036 IrInstruction *casted_condition = ir_implicit_cast(ira, condition, bool_type); 14037 if (casted_condition == ira->codegen->invalid_instruction) 14038 return ir_unreach_error(ira); 14039 14040 assert(cond_br_instruction->then_block != cond_br_instruction->else_block); 14041 IrBasicBlock *new_then_block = ir_get_new_bb_runtime(ira, cond_br_instruction->then_block, &cond_br_instruction->base); 14042 if (new_then_block == nullptr) 14043 return ir_unreach_error(ira); 14044 14045 IrBasicBlock *new_else_block = ir_get_new_bb_runtime(ira, cond_br_instruction->else_block, &cond_br_instruction->base); 14046 if (new_else_block == nullptr) 14047 return ir_unreach_error(ira); 14048 14049 ir_build_cond_br_from(&ira->new_irb, &cond_br_instruction->base, 14050 casted_condition, new_then_block, new_else_block, nullptr); 14051 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); 14052 } 14053 14054 static ZigType *ir_analyze_instruction_unreachable(IrAnalyze *ira, 14055 IrInstructionUnreachable *unreachable_instruction) 14056 { 14057 ir_build_unreachable_from(&ira->new_irb, &unreachable_instruction->base); 14058 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); 14059 } 14060 14061 static ZigType *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) { 14062 if (ira->const_predecessor_bb) { 14063 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 14064 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; 14065 if (predecessor != ira->const_predecessor_bb) 14066 continue; 14067 IrInstruction *value = phi_instruction->incoming_values[i]->other; 14068 assert(value->value.type); 14069 if (type_is_invalid(value->value.type)) 14070 return ira->codegen->builtin_types.entry_invalid; 14071 14072 if (value->value.special != ConstValSpecialRuntime) { 14073 ConstExprValue *out_val = ir_build_const_from(ira, &phi_instruction->base); 14074 *out_val = value->value; 14075 } else { 14076 phi_instruction->base.other = value; 14077 } 14078 return value->value.type; 14079 } 14080 zig_unreachable(); 14081 } 14082 14083 ZigList<IrBasicBlock*> new_incoming_blocks = {0}; 14084 ZigList<IrInstruction*> new_incoming_values = {0}; 14085 14086 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 14087 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; 14088 if (predecessor->ref_count == 0) 14089 continue; 14090 14091 14092 IrInstruction *old_value = phi_instruction->incoming_values[i]; 14093 assert(old_value); 14094 IrInstruction *new_value = old_value->other; 14095 if (!new_value || new_value->value.type->id == ZigTypeIdUnreachable || predecessor->other == nullptr) 14096 continue; 14097 14098 if (type_is_invalid(new_value->value.type)) 14099 return ira->codegen->builtin_types.entry_invalid; 14100 14101 14102 assert(predecessor->other); 14103 new_incoming_blocks.append(predecessor->other); 14104 new_incoming_values.append(new_value); 14105 } 14106 14107 if (new_incoming_blocks.length == 0) { 14108 ir_build_unreachable_from(&ira->new_irb, &phi_instruction->base); 14109 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); 14110 } 14111 14112 if (new_incoming_blocks.length == 1) { 14113 IrInstruction *first_value = new_incoming_values.at(0); 14114 phi_instruction->base.other = first_value; 14115 return first_value->value.type; 14116 } 14117 14118 ZigType *resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, 14119 new_incoming_values.items, new_incoming_values.length); 14120 if (type_is_invalid(resolved_type)) 14121 return resolved_type; 14122 14123 if (resolved_type->id == ZigTypeIdComptimeFloat || 14124 resolved_type->id == ZigTypeIdComptimeInt || 14125 resolved_type->id == ZigTypeIdNull || 14126 resolved_type->id == ZigTypeIdUndefined) 14127 { 14128 ir_add_error_node(ira, phi_instruction->base.source_node, 14129 buf_sprintf("unable to infer expression type")); 14130 return ira->codegen->builtin_types.entry_invalid; 14131 } 14132 14133 bool all_stack_ptrs = (resolved_type->id == ZigTypeIdPointer); 14134 14135 // cast all values to the resolved type. however we can't put cast instructions in front of the phi instruction. 14136 // so we go back and insert the casts as the last instruction in the corresponding predecessor blocks, and 14137 // then make sure the branch instruction is preserved. 14138 IrBasicBlock *cur_bb = ira->new_irb.current_basic_block; 14139 for (size_t i = 0; i < new_incoming_values.length; i += 1) { 14140 IrInstruction *new_value = new_incoming_values.at(i); 14141 IrBasicBlock *predecessor = new_incoming_blocks.at(i); 14142 IrInstruction *branch_instruction = predecessor->instruction_list.pop(); 14143 ir_set_cursor_at_end(&ira->new_irb, predecessor); 14144 IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); 14145 if (casted_value == ira->codegen->invalid_instruction) { 14146 return ira->codegen->builtin_types.entry_invalid; 14147 } 14148 new_incoming_values.items[i] = casted_value; 14149 predecessor->instruction_list.append(branch_instruction); 14150 14151 if (all_stack_ptrs && (casted_value->value.special != ConstValSpecialRuntime || 14152 casted_value->value.data.rh_ptr != RuntimeHintPtrStack)) 14153 { 14154 all_stack_ptrs = false; 14155 } 14156 } 14157 ir_set_cursor_at_end(&ira->new_irb, cur_bb); 14158 14159 IrInstruction *result = ir_build_phi_from(&ira->new_irb, &phi_instruction->base, new_incoming_blocks.length, 14160 new_incoming_blocks.items, new_incoming_values.items); 14161 14162 if (all_stack_ptrs) { 14163 assert(result->value.special == ConstValSpecialRuntime); 14164 result->value.data.rh_ptr = RuntimeHintPtrStack; 14165 } 14166 14167 return resolved_type; 14168 } 14169 14170 static ZigType *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var) { 14171 IrInstruction *result = ir_get_var_ptr(ira, instruction, var); 14172 ir_link_new_instruction(result, instruction); 14173 return result->value.type; 14174 } 14175 14176 static ZigType *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *instruction) { 14177 ZigVar *var = instruction->var; 14178 IrInstruction *result = ir_get_var_ptr(ira, &instruction->base, var); 14179 if (instruction->crossed_fndef_scope != nullptr && !instr_is_comptime(result)) { 14180 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 14181 buf_sprintf("'%s' not accessible from inner function", buf_ptr(&var->name))); 14182 add_error_note(ira->codegen, msg, instruction->crossed_fndef_scope->base.source_node, 14183 buf_sprintf("crossed function definition here")); 14184 add_error_note(ira->codegen, msg, var->decl_node, 14185 buf_sprintf("declared here")); 14186 return ira->codegen->builtin_types.entry_invalid; 14187 } 14188 ir_link_new_instruction(result, &instruction->base); 14189 return result->value.type; 14190 } 14191 14192 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align) { 14193 assert(ptr_type->id == ZigTypeIdPointer); 14194 return get_pointer_to_type_extra(g, 14195 ptr_type->data.pointer.child_type, 14196 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 14197 ptr_type->data.pointer.ptr_len, 14198 new_align, 14199 ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count); 14200 } 14201 14202 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) { 14203 assert(is_slice(slice_type)); 14204 ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index].type_entry, 14205 new_align); 14206 return get_slice_type(g, ptr_type); 14207 } 14208 14209 static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) { 14210 assert(ptr_type->id == ZigTypeIdPointer); 14211 return get_pointer_to_type_extra(g, 14212 ptr_type->data.pointer.child_type, 14213 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 14214 ptr_len, 14215 ptr_type->data.pointer.alignment, 14216 ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count); 14217 } 14218 14219 static ZigType *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { 14220 Error err; 14221 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other; 14222 if (type_is_invalid(array_ptr->value.type)) 14223 return ira->codegen->builtin_types.entry_invalid; 14224 14225 ConstExprValue *orig_array_ptr_val = &array_ptr->value; 14226 14227 IrInstruction *elem_index = elem_ptr_instruction->elem_index->other; 14228 if (type_is_invalid(elem_index->value.type)) 14229 return ira->codegen->builtin_types.entry_invalid; 14230 14231 ZigType *ptr_type = orig_array_ptr_val->type; 14232 assert(ptr_type->id == ZigTypeIdPointer); 14233 14234 ZigType *array_type = ptr_type->data.pointer.child_type; 14235 14236 // At first return_type will be the pointer type we want to return, except with an optimistic alignment. 14237 // We will adjust return_type's alignment before returning it. 14238 ZigType *return_type; 14239 14240 if (type_is_invalid(array_type)) { 14241 return array_type; 14242 } else if (array_type->id == ZigTypeIdArray || 14243 (array_type->id == ZigTypeIdPointer && 14244 array_type->data.pointer.ptr_len == PtrLenSingle && 14245 array_type->data.pointer.child_type->id == ZigTypeIdArray)) 14246 { 14247 if (array_type->id == ZigTypeIdPointer) { 14248 array_type = array_type->data.pointer.child_type; 14249 ptr_type = ptr_type->data.pointer.child_type; 14250 if (orig_array_ptr_val->special != ConstValSpecialRuntime) { 14251 orig_array_ptr_val = ir_const_ptr_pointee(ira, orig_array_ptr_val, 14252 elem_ptr_instruction->base.source_node); 14253 if (orig_array_ptr_val == nullptr) 14254 return ira->codegen->builtin_types.entry_invalid; 14255 } 14256 } 14257 if (array_type->data.array.len == 0) { 14258 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 14259 buf_sprintf("index 0 outside array of size 0")); 14260 return ira->codegen->builtin_types.entry_invalid; 14261 } 14262 ZigType *child_type = array_type->data.array.child_type; 14263 if (ptr_type->data.pointer.unaligned_bit_count == 0) { 14264 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 14265 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 14266 elem_ptr_instruction->ptr_len, 14267 ptr_type->data.pointer.alignment, 0, 0); 14268 } else { 14269 uint64_t elem_val_scalar; 14270 if (!ir_resolve_usize(ira, elem_index, &elem_val_scalar)) 14271 return ira->codegen->builtin_types.entry_invalid; 14272 14273 size_t bit_width = type_size_bits(ira->codegen, child_type); 14274 size_t bit_offset = bit_width * elem_val_scalar; 14275 14276 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 14277 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 14278 elem_ptr_instruction->ptr_len, 14279 1, (uint32_t)bit_offset, (uint32_t)bit_width); 14280 } 14281 } else if (array_type->id == ZigTypeIdPointer) { 14282 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 14283 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 14284 buf_sprintf("index of single-item pointer")); 14285 return ira->codegen->builtin_types.entry_invalid; 14286 } 14287 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len); 14288 } else if (is_slice(array_type)) { 14289 return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index].type_entry, 14290 elem_ptr_instruction->ptr_len); 14291 } else if (array_type->id == ZigTypeIdArgTuple) { 14292 ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); 14293 if (!ptr_val) 14294 return ira->codegen->builtin_types.entry_invalid; 14295 ConstExprValue *args_val = ir_const_ptr_pointee(ira, ptr_val, elem_ptr_instruction->base.source_node); 14296 if (args_val == nullptr) 14297 return ira->codegen->builtin_types.entry_invalid; 14298 size_t start = args_val->data.x_arg_tuple.start_index; 14299 size_t end = args_val->data.x_arg_tuple.end_index; 14300 uint64_t elem_index_val; 14301 if (!ir_resolve_usize(ira, elem_index, &elem_index_val)) 14302 return ira->codegen->builtin_types.entry_invalid; 14303 size_t index = elem_index_val; 14304 size_t len = end - start; 14305 if (index >= len) { 14306 ir_add_error(ira, &elem_ptr_instruction->base, 14307 buf_sprintf("index %" ZIG_PRI_usize " outside argument list of size %" ZIG_PRI_usize "", index, len)); 14308 return ira->codegen->builtin_types.entry_invalid; 14309 } 14310 size_t abs_index = start + index; 14311 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 14312 assert(fn_entry); 14313 ZigVar *var = get_fn_var_by_index(fn_entry, abs_index); 14314 bool is_const = true; 14315 bool is_volatile = false; 14316 if (var) { 14317 return ir_analyze_var_ptr(ira, &elem_ptr_instruction->base, var); 14318 } else { 14319 return ir_analyze_const_ptr(ira, &elem_ptr_instruction->base, &ira->codegen->const_void_val, 14320 ira->codegen->builtin_types.entry_void, ConstPtrMutComptimeConst, is_const, is_volatile); 14321 } 14322 } else { 14323 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 14324 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name))); 14325 return ira->codegen->builtin_types.entry_invalid; 14326 } 14327 14328 ZigType *usize = ira->codegen->builtin_types.entry_usize; 14329 IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 14330 if (casted_elem_index == ira->codegen->invalid_instruction) 14331 return ira->codegen->builtin_types.entry_invalid; 14332 14333 bool safety_check_on = elem_ptr_instruction->safety_check_on; 14334 if ((err = ensure_complete_type(ira->codegen, return_type->data.pointer.child_type))) 14335 return ira->codegen->builtin_types.entry_invalid; 14336 14337 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); 14338 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); 14339 uint64_t ptr_align = return_type->data.pointer.alignment; 14340 if (instr_is_comptime(casted_elem_index)) { 14341 uint64_t index = bigint_as_unsigned(&casted_elem_index->value.data.x_bigint); 14342 if (array_type->id == ZigTypeIdArray) { 14343 uint64_t array_len = array_type->data.array.len; 14344 if (index >= array_len) { 14345 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 14346 buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, 14347 index, array_len)); 14348 return ira->codegen->builtin_types.entry_invalid; 14349 } 14350 safety_check_on = false; 14351 } 14352 14353 { 14354 // figure out the largest alignment possible 14355 uint64_t chosen_align = abi_align; 14356 if (ptr_align >= abi_align) { 14357 while (ptr_align > abi_align) { 14358 if ((index * elem_size) % ptr_align == 0) { 14359 chosen_align = ptr_align; 14360 break; 14361 } 14362 ptr_align >>= 1; 14363 } 14364 } else if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 14365 chosen_align = ptr_align; 14366 } else { 14367 // can't get here because guaranteed elem_size >= abi_align 14368 zig_unreachable(); 14369 } 14370 return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align); 14371 } 14372 14373 if (orig_array_ptr_val->special != ConstValSpecialRuntime && 14374 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || 14375 array_type->id == ZigTypeIdArray)) 14376 { 14377 ConstExprValue *array_ptr_val = ir_const_ptr_pointee(ira, orig_array_ptr_val, 14378 elem_ptr_instruction->base.source_node); 14379 if (array_ptr_val == nullptr) 14380 return ira->codegen->builtin_types.entry_invalid; 14381 14382 if (array_ptr_val->special != ConstValSpecialRuntime && 14383 (array_type->id != ZigTypeIdPointer || 14384 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) 14385 { 14386 if (array_type->id == ZigTypeIdPointer) { 14387 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base); 14388 out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 14389 size_t new_index; 14390 size_t mem_size; 14391 size_t old_size; 14392 switch (array_ptr_val->data.x_ptr.special) { 14393 case ConstPtrSpecialInvalid: 14394 case ConstPtrSpecialDiscard: 14395 zig_unreachable(); 14396 case ConstPtrSpecialRef: 14397 mem_size = 1; 14398 old_size = 1; 14399 new_index = index; 14400 14401 out_val->data.x_ptr.special = ConstPtrSpecialRef; 14402 out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee; 14403 break; 14404 case ConstPtrSpecialBaseArray: 14405 { 14406 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; 14407 new_index = offset + index; 14408 mem_size = array_ptr_val->data.x_ptr.data.base_array.array_val->type->data.array.len; 14409 old_size = mem_size - offset; 14410 14411 assert(array_ptr_val->data.x_ptr.data.base_array.array_val); 14412 14413 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 14414 out_val->data.x_ptr.data.base_array.array_val = 14415 array_ptr_val->data.x_ptr.data.base_array.array_val; 14416 out_val->data.x_ptr.data.base_array.elem_index = new_index; 14417 out_val->data.x_ptr.data.base_array.is_cstr = 14418 array_ptr_val->data.x_ptr.data.base_array.is_cstr; 14419 14420 break; 14421 } 14422 case ConstPtrSpecialBaseStruct: 14423 zig_panic("TODO elem ptr on a const inner struct"); 14424 case ConstPtrSpecialHardCodedAddr: 14425 zig_unreachable(); 14426 case ConstPtrSpecialFunction: 14427 zig_panic("TODO element ptr of a function casted to a ptr"); 14428 } 14429 if (new_index >= mem_size) { 14430 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 14431 buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size)); 14432 return ira->codegen->builtin_types.entry_invalid; 14433 } 14434 return return_type; 14435 } else if (is_slice(array_type)) { 14436 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; 14437 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 14438 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, 14439 array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len); 14440 result->value.type = return_type; 14441 ir_link_new_instruction(result, &elem_ptr_instruction->base); 14442 return return_type; 14443 } 14444 ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index]; 14445 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base); 14446 uint64_t slice_len = bigint_as_unsigned(&len_field->data.x_bigint); 14447 if (index >= slice_len) { 14448 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 14449 buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64, 14450 index, slice_len)); 14451 return ira->codegen->builtin_types.entry_invalid; 14452 } 14453 out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut; 14454 switch (ptr_field->data.x_ptr.special) { 14455 case ConstPtrSpecialInvalid: 14456 case ConstPtrSpecialDiscard: 14457 zig_unreachable(); 14458 case ConstPtrSpecialRef: 14459 out_val->data.x_ptr.special = ConstPtrSpecialRef; 14460 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee; 14461 break; 14462 case ConstPtrSpecialBaseArray: 14463 { 14464 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index; 14465 uint64_t new_index = offset + index; 14466 assert(new_index < ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len); 14467 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 14468 out_val->data.x_ptr.data.base_array.array_val = 14469 ptr_field->data.x_ptr.data.base_array.array_val; 14470 out_val->data.x_ptr.data.base_array.elem_index = new_index; 14471 out_val->data.x_ptr.data.base_array.is_cstr = 14472 ptr_field->data.x_ptr.data.base_array.is_cstr; 14473 break; 14474 } 14475 case ConstPtrSpecialBaseStruct: 14476 zig_panic("TODO elem ptr on a slice backed by const inner struct"); 14477 case ConstPtrSpecialHardCodedAddr: 14478 zig_unreachable(); 14479 case ConstPtrSpecialFunction: 14480 zig_panic("TODO elem ptr on a slice that was ptrcast from a function"); 14481 } 14482 return return_type; 14483 } else if (array_type->id == ZigTypeIdArray) { 14484 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base); 14485 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 14486 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; 14487 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val; 14488 out_val->data.x_ptr.data.base_array.elem_index = index; 14489 return return_type; 14490 } else { 14491 zig_unreachable(); 14492 } 14493 } 14494 } 14495 14496 } else { 14497 // runtime known element index 14498 if (ptr_align < abi_align) { 14499 if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 14500 return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align); 14501 } else { 14502 // can't get here because guaranteed elem_size >= abi_align 14503 zig_unreachable(); 14504 } 14505 } else { 14506 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align); 14507 } 14508 } 14509 14510 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, 14511 array_ptr, casted_elem_index, safety_check_on, elem_ptr_instruction->ptr_len); 14512 result->value.type = return_type; 14513 ir_link_new_instruction(result, &elem_ptr_instruction->base); 14514 return return_type; 14515 } 14516 14517 static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, 14518 ZigType *bare_struct_type, Buf *field_name, IrInstruction *source_instr, 14519 IrInstruction *container_ptr, ZigType *container_type) 14520 { 14521 if (!is_slice(bare_struct_type)) { 14522 ScopeDecls *container_scope = get_container_scope(bare_struct_type); 14523 assert(container_scope != nullptr); 14524 auto entry = container_scope->decl_table.maybe_get(field_name); 14525 Tld *tld = entry ? entry->value : nullptr; 14526 if (tld && tld->id == TldIdFn) { 14527 resolve_top_level_decl(ira->codegen, tld, false, source_instr->source_node); 14528 if (tld->resolution == TldResolutionInvalid) 14529 return ira->codegen->invalid_instruction; 14530 TldFn *tld_fn = (TldFn *)tld; 14531 ZigFn *fn_entry = tld_fn->fn_entry; 14532 if (type_is_invalid(fn_entry->type_entry)) 14533 return ira->codegen->invalid_instruction; 14534 14535 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope, 14536 source_instr->source_node, fn_entry, container_ptr); 14537 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 14538 } 14539 } 14540 const char *prefix_name; 14541 if (is_slice(bare_struct_type)) { 14542 prefix_name = ""; 14543 } else if (bare_struct_type->id == ZigTypeIdStruct) { 14544 prefix_name = "struct "; 14545 } else if (bare_struct_type->id == ZigTypeIdEnum) { 14546 prefix_name = "enum "; 14547 } else if (bare_struct_type->id == ZigTypeIdUnion) { 14548 prefix_name = "union "; 14549 } else { 14550 prefix_name = ""; 14551 } 14552 ir_add_error_node(ira, source_instr->source_node, 14553 buf_sprintf("no member named '%s' in %s'%s'", buf_ptr(field_name), prefix_name, buf_ptr(&bare_struct_type->name))); 14554 return ira->codegen->invalid_instruction; 14555 } 14556 14557 static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 14558 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type) 14559 { 14560 Error err; 14561 14562 ZigType *bare_type = container_ref_type(container_type); 14563 if ((err = ensure_complete_type(ira->codegen, bare_type))) 14564 return ira->codegen->invalid_instruction; 14565 14566 assert(container_ptr->value.type->id == ZigTypeIdPointer); 14567 bool is_const = container_ptr->value.type->data.pointer.is_const; 14568 bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; 14569 if (bare_type->id == ZigTypeIdStruct) { 14570 TypeStructField *field = find_struct_type_field(bare_type, field_name); 14571 if (field) { 14572 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked); 14573 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 14574 size_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset; 14575 size_t ptr_unaligned_bit_count = container_ptr->value.type->data.pointer.unaligned_bit_count; 14576 size_t unaligned_bit_count_for_result_type = (ptr_unaligned_bit_count == 0) ? 14577 field->unaligned_bit_count : type_size_bits(ira->codegen, field->type_entry); 14578 if (instr_is_comptime(container_ptr)) { 14579 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 14580 if (!ptr_val) 14581 return ira->codegen->invalid_instruction; 14582 14583 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 14584 ConstExprValue *struct_val = ir_const_ptr_pointee(ira, ptr_val, source_instr->source_node); 14585 if (struct_val == nullptr) 14586 return ira->codegen->invalid_instruction; 14587 if (type_is_invalid(struct_val->type)) 14588 return ira->codegen->invalid_instruction; 14589 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index]; 14590 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type, 14591 is_const, is_volatile, PtrLenSingle, align_bytes, 14592 (uint32_t)(ptr_bit_offset + field->packed_bits_offset), 14593 (uint32_t)unaligned_bit_count_for_result_type); 14594 IrInstruction *result = ir_get_const(ira, source_instr); 14595 ConstExprValue *const_val = &result->value; 14596 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; 14597 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; 14598 const_val->data.x_ptr.data.base_struct.struct_val = struct_val; 14599 const_val->data.x_ptr.data.base_struct.field_index = field->src_index; 14600 const_val->type = ptr_type; 14601 return result; 14602 } 14603 } 14604 IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, 14605 container_ptr, field); 14606 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, 14607 PtrLenSingle, 14608 align_bytes, 14609 (uint32_t)(ptr_bit_offset + field->packed_bits_offset), 14610 (uint32_t)unaligned_bit_count_for_result_type); 14611 return result; 14612 } else { 14613 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 14614 source_instr, container_ptr, container_type); 14615 } 14616 } else if (bare_type->id == ZigTypeIdEnum) { 14617 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 14618 source_instr, container_ptr, container_type); 14619 } else if (bare_type->id == ZigTypeIdUnion) { 14620 TypeUnionField *field = find_union_type_field(bare_type, field_name); 14621 if (field) { 14622 if (instr_is_comptime(container_ptr)) { 14623 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 14624 if (!ptr_val) 14625 return ira->codegen->invalid_instruction; 14626 14627 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 14628 ConstExprValue *union_val = ir_const_ptr_pointee(ira, ptr_val, source_instr->source_node); 14629 if (union_val == nullptr) 14630 return ira->codegen->invalid_instruction; 14631 if (type_is_invalid(union_val->type)) 14632 return ira->codegen->invalid_instruction; 14633 14634 TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); 14635 if (actual_field == nullptr) 14636 zig_unreachable(); 14637 14638 if (field != actual_field) { 14639 ir_add_error_node(ira, source_instr->source_node, 14640 buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), 14641 buf_ptr(actual_field->name))); 14642 return ira->codegen->invalid_instruction; 14643 } 14644 14645 ConstExprValue *payload_val = union_val->data.x_union.payload; 14646 14647 ZigType *field_type = field->type_entry; 14648 if (field_type->id == ZigTypeIdVoid) { 14649 assert(payload_val == nullptr); 14650 payload_val = create_const_vals(1); 14651 payload_val->special = ConstValSpecialStatic; 14652 payload_val->type = field_type; 14653 } 14654 14655 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 14656 is_const, is_volatile, 14657 PtrLenSingle, 14658 get_abi_alignment(ira->codegen, field_type), 0, 0); 14659 14660 IrInstruction *result = ir_get_const(ira, source_instr); 14661 ConstExprValue *const_val = &result->value; 14662 const_val->data.x_ptr.special = ConstPtrSpecialRef; 14663 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; 14664 const_val->data.x_ptr.data.ref.pointee = payload_val; 14665 const_val->type = ptr_type; 14666 return result; 14667 } 14668 } 14669 14670 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); 14671 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, 14672 PtrLenSingle, get_abi_alignment(ira->codegen, field->type_entry), 0, 0); 14673 return result; 14674 } else { 14675 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 14676 source_instr, container_ptr, container_type); 14677 } 14678 } else { 14679 zig_unreachable(); 14680 } 14681 } 14682 14683 static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { 14684 LinkLib *link_lib = add_link_lib(ira->codegen, lib_name); 14685 for (size_t i = 0; i < link_lib->symbols.length; i += 1) { 14686 Buf *existing_symbol_name = link_lib->symbols.at(i); 14687 if (buf_eql_buf(existing_symbol_name, symbol_name)) { 14688 return; 14689 } 14690 } 14691 for (size_t i = 0; i < ira->codegen->forbidden_libs.length; i += 1) { 14692 Buf *forbidden_lib_name = ira->codegen->forbidden_libs.at(i); 14693 if (buf_eql_buf(lib_name, forbidden_lib_name)) { 14694 ir_add_error_node(ira, source_node, 14695 buf_sprintf("linking against forbidden library '%s'", buf_ptr(symbol_name))); 14696 } 14697 } 14698 link_lib->symbols.append(symbol_name); 14699 } 14700 14701 14702 static ZigType *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { 14703 bool pointer_only = false; 14704 resolve_top_level_decl(ira->codegen, tld, pointer_only, source_instruction->source_node); 14705 if (tld->resolution == TldResolutionInvalid) 14706 return ira->codegen->builtin_types.entry_invalid; 14707 14708 switch (tld->id) { 14709 case TldIdContainer: 14710 case TldIdCompTime: 14711 zig_unreachable(); 14712 case TldIdVar: 14713 { 14714 TldVar *tld_var = (TldVar *)tld; 14715 ZigVar *var = tld_var->var; 14716 if (tld_var->extern_lib_name != nullptr) { 14717 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node); 14718 } 14719 14720 return ir_analyze_var_ptr(ira, source_instruction, var); 14721 } 14722 case TldIdFn: 14723 { 14724 TldFn *tld_fn = (TldFn *)tld; 14725 ZigFn *fn_entry = tld_fn->fn_entry; 14726 assert(fn_entry->type_entry); 14727 14728 if (type_is_invalid(fn_entry->type_entry)) 14729 return ira->codegen->builtin_types.entry_invalid; 14730 14731 // TODO instead of allocating this every time, put it in the tld value and we can reference 14732 // the same one every time 14733 ConstExprValue *const_val = create_const_vals(1); 14734 const_val->special = ConstValSpecialStatic; 14735 const_val->type = fn_entry->type_entry; 14736 const_val->data.x_ptr.data.fn.fn_entry = fn_entry; 14737 const_val->data.x_ptr.special = ConstPtrSpecialFunction; 14738 const_val->data.x_ptr.mut = ConstPtrMutComptimeConst; 14739 14740 if (tld_fn->extern_lib_name != nullptr) { 14741 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); 14742 } 14743 14744 bool ptr_is_const = true; 14745 bool ptr_is_volatile = false; 14746 return ir_analyze_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, 14747 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 14748 } 14749 } 14750 zig_unreachable(); 14751 } 14752 14753 static ErrorTableEntry *find_err_table_entry(ZigType *err_set_type, Buf *field_name) { 14754 assert(err_set_type->id == ZigTypeIdErrorSet); 14755 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 14756 ErrorTableEntry *err_table_entry = err_set_type->data.error_set.errors[i]; 14757 if (buf_eql_buf(&err_table_entry->name, field_name)) { 14758 return err_table_entry; 14759 } 14760 } 14761 return nullptr; 14762 } 14763 14764 static ZigType *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) { 14765 Error err; 14766 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->other; 14767 if (type_is_invalid(container_ptr->value.type)) 14768 return ira->codegen->builtin_types.entry_invalid; 14769 14770 ZigType *container_type = container_ptr->value.type->data.pointer.child_type; 14771 assert(container_ptr->value.type->id == ZigTypeIdPointer); 14772 14773 Buf *field_name = field_ptr_instruction->field_name_buffer; 14774 if (!field_name) { 14775 IrInstruction *field_name_expr = field_ptr_instruction->field_name_expr->other; 14776 field_name = ir_resolve_str(ira, field_name_expr); 14777 if (!field_name) 14778 return ira->codegen->builtin_types.entry_invalid; 14779 } 14780 14781 14782 AstNode *source_node = field_ptr_instruction->base.source_node; 14783 14784 if (type_is_invalid(container_type)) { 14785 return container_type; 14786 } else if (is_container_ref(container_type)) { 14787 assert(container_ptr->value.type->id == ZigTypeIdPointer); 14788 if (container_type->id == ZigTypeIdPointer) { 14789 ZigType *bare_type = container_ref_type(container_type); 14790 IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr); 14791 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type); 14792 ir_link_new_instruction(result, &field_ptr_instruction->base); 14793 return result->value.type; 14794 } else { 14795 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type); 14796 ir_link_new_instruction(result, &field_ptr_instruction->base); 14797 return result->value.type; 14798 } 14799 } else if (is_array_ref(container_type)) { 14800 if (buf_eql_str(field_name, "len")) { 14801 ConstExprValue *len_val = create_const_vals(1); 14802 if (container_type->id == ZigTypeIdPointer) { 14803 init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len); 14804 } else { 14805 init_const_usize(ira->codegen, len_val, container_type->data.array.len); 14806 } 14807 14808 ZigType *usize = ira->codegen->builtin_types.entry_usize; 14809 bool ptr_is_const = true; 14810 bool ptr_is_volatile = false; 14811 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, len_val, 14812 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 14813 } else { 14814 ir_add_error_node(ira, source_node, 14815 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), 14816 buf_ptr(&container_type->name))); 14817 return ira->codegen->builtin_types.entry_invalid; 14818 } 14819 } else if (container_type->id == ZigTypeIdArgTuple) { 14820 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 14821 if (!container_ptr_val) 14822 return ira->codegen->builtin_types.entry_invalid; 14823 14824 assert(container_ptr->value.type->id == ZigTypeIdPointer); 14825 ConstExprValue *child_val = ir_const_ptr_pointee(ira, container_ptr_val, source_node); 14826 if (child_val == nullptr) 14827 return ira->codegen->builtin_types.entry_invalid; 14828 14829 if (buf_eql_str(field_name, "len")) { 14830 ConstExprValue *len_val = create_const_vals(1); 14831 size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index; 14832 init_const_usize(ira->codegen, len_val, len); 14833 14834 ZigType *usize = ira->codegen->builtin_types.entry_usize; 14835 bool ptr_is_const = true; 14836 bool ptr_is_volatile = false; 14837 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, len_val, 14838 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 14839 } else { 14840 ir_add_error_node(ira, source_node, 14841 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), 14842 buf_ptr(&container_type->name))); 14843 return ira->codegen->builtin_types.entry_invalid; 14844 } 14845 } else if (container_type->id == ZigTypeIdMetaType) { 14846 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 14847 if (!container_ptr_val) 14848 return ira->codegen->builtin_types.entry_invalid; 14849 14850 assert(container_ptr->value.type->id == ZigTypeIdPointer); 14851 ConstExprValue *child_val = ir_const_ptr_pointee(ira, container_ptr_val, source_node); 14852 if (child_val == nullptr) 14853 return ira->codegen->builtin_types.entry_invalid; 14854 ZigType *child_type = child_val->data.x_type; 14855 14856 if (type_is_invalid(child_type)) { 14857 return ira->codegen->builtin_types.entry_invalid; 14858 } else if (is_container(child_type)) { 14859 if (is_slice(child_type) && buf_eql_str(field_name, "Child")) { 14860 bool ptr_is_const = true; 14861 bool ptr_is_volatile = false; 14862 TypeStructField *ptr_field = &child_type->data.structure.fields[slice_ptr_index]; 14863 assert(ptr_field->type_entry->id == ZigTypeIdPointer); 14864 ZigType *child_type = ptr_field->type_entry->data.pointer.child_type; 14865 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 14866 create_const_type(ira->codegen, child_type), 14867 ira->codegen->builtin_types.entry_type, 14868 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 14869 } 14870 if (child_type->id == ZigTypeIdEnum) { 14871 if ((err = ensure_complete_type(ira->codegen, child_type))) 14872 return ira->codegen->builtin_types.entry_invalid; 14873 14874 TypeEnumField *field = find_enum_type_field(child_type, field_name); 14875 if (field) { 14876 bool ptr_is_const = true; 14877 bool ptr_is_volatile = false; 14878 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 14879 create_const_enum(child_type, &field->value), child_type, 14880 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 14881 } 14882 } 14883 ScopeDecls *container_scope = get_container_scope(child_type); 14884 if (container_scope != nullptr) { 14885 auto entry = container_scope->decl_table.maybe_get(field_name); 14886 Tld *tld = entry ? entry->value : nullptr; 14887 if (tld) { 14888 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld); 14889 } 14890 } 14891 if (child_type->id == ZigTypeIdUnion && 14892 (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr || 14893 child_type->data.unionation.decl_node->data.container_decl.auto_enum)) 14894 { 14895 if ((err = ensure_complete_type(ira->codegen, child_type))) 14896 return ira->codegen->builtin_types.entry_invalid; 14897 TypeUnionField *field = find_union_type_field(child_type, field_name); 14898 if (field) { 14899 ZigType *enum_type = child_type->data.unionation.tag_type; 14900 bool ptr_is_const = true; 14901 bool ptr_is_volatile = false; 14902 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 14903 create_const_enum(enum_type, &field->enum_field->value), enum_type, 14904 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 14905 } 14906 } 14907 ir_add_error(ira, &field_ptr_instruction->base, 14908 buf_sprintf("container '%s' has no member called '%s'", 14909 buf_ptr(&child_type->name), buf_ptr(field_name))); 14910 return ira->codegen->builtin_types.entry_invalid; 14911 } else if (child_type->id == ZigTypeIdErrorSet) { 14912 ErrorTableEntry *err_entry; 14913 ZigType *err_set_type; 14914 if (type_is_global_error_set(child_type)) { 14915 auto existing_entry = ira->codegen->error_table.maybe_get(field_name); 14916 if (existing_entry) { 14917 err_entry = existing_entry->value; 14918 } else { 14919 err_entry = allocate<ErrorTableEntry>(1); 14920 err_entry->decl_node = field_ptr_instruction->base.source_node; 14921 buf_init_from_buf(&err_entry->name, field_name); 14922 size_t error_value_count = ira->codegen->errors_by_index.length; 14923 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); 14924 err_entry->value = error_value_count; 14925 ira->codegen->errors_by_index.append(err_entry); 14926 ira->codegen->err_enumerators.append(ZigLLVMCreateDebugEnumerator(ira->codegen->dbuilder, 14927 buf_ptr(field_name), error_value_count)); 14928 ira->codegen->error_table.put(field_name, err_entry); 14929 } 14930 if (err_entry->set_with_only_this_in_it == nullptr) { 14931 err_entry->set_with_only_this_in_it = make_err_set_with_one_item(ira->codegen, 14932 field_ptr_instruction->base.scope, field_ptr_instruction->base.source_node, 14933 err_entry); 14934 } 14935 err_set_type = err_entry->set_with_only_this_in_it; 14936 } else { 14937 if (!resolve_inferred_error_set(ira->codegen, child_type, field_ptr_instruction->base.source_node)) { 14938 return ira->codegen->builtin_types.entry_invalid; 14939 } 14940 err_entry = find_err_table_entry(child_type, field_name); 14941 if (err_entry == nullptr) { 14942 ir_add_error(ira, &field_ptr_instruction->base, 14943 buf_sprintf("no error named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&child_type->name))); 14944 return ira->codegen->builtin_types.entry_invalid; 14945 } 14946 err_set_type = child_type; 14947 } 14948 ConstExprValue *const_val = create_const_vals(1); 14949 const_val->special = ConstValSpecialStatic; 14950 const_val->type = err_set_type; 14951 const_val->data.x_err_set = err_entry; 14952 14953 bool ptr_is_const = true; 14954 bool ptr_is_volatile = false; 14955 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, const_val, 14956 err_set_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 14957 } else if (child_type->id == ZigTypeIdInt) { 14958 if (buf_eql_str(field_name, "bit_count")) { 14959 bool ptr_is_const = true; 14960 bool ptr_is_volatile = false; 14961 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 14962 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 14963 child_type->data.integral.bit_count, false), 14964 ira->codegen->builtin_types.entry_num_lit_int, 14965 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 14966 } else if (buf_eql_str(field_name, "is_signed")) { 14967 bool ptr_is_const = true; 14968 bool ptr_is_volatile = false; 14969 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 14970 create_const_bool(ira->codegen, child_type->data.integral.is_signed), 14971 ira->codegen->builtin_types.entry_bool, 14972 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 14973 } else { 14974 ir_add_error(ira, &field_ptr_instruction->base, 14975 buf_sprintf("type '%s' has no member called '%s'", 14976 buf_ptr(&child_type->name), buf_ptr(field_name))); 14977 return ira->codegen->builtin_types.entry_invalid; 14978 } 14979 } else if (child_type->id == ZigTypeIdFloat) { 14980 if (buf_eql_str(field_name, "bit_count")) { 14981 bool ptr_is_const = true; 14982 bool ptr_is_volatile = false; 14983 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 14984 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 14985 child_type->data.floating.bit_count, false), 14986 ira->codegen->builtin_types.entry_num_lit_int, 14987 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 14988 } else { 14989 ir_add_error(ira, &field_ptr_instruction->base, 14990 buf_sprintf("type '%s' has no member called '%s'", 14991 buf_ptr(&child_type->name), buf_ptr(field_name))); 14992 return ira->codegen->builtin_types.entry_invalid; 14993 } 14994 } else if (child_type->id == ZigTypeIdPointer) { 14995 if (buf_eql_str(field_name, "Child")) { 14996 bool ptr_is_const = true; 14997 bool ptr_is_volatile = false; 14998 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 14999 create_const_type(ira->codegen, child_type->data.pointer.child_type), 15000 ira->codegen->builtin_types.entry_type, 15001 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 15002 } else if (buf_eql_str(field_name, "alignment")) { 15003 bool ptr_is_const = true; 15004 bool ptr_is_volatile = false; 15005 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 15006 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 15007 child_type->data.pointer.alignment, false), 15008 ira->codegen->builtin_types.entry_num_lit_int, 15009 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 15010 } else { 15011 ir_add_error(ira, &field_ptr_instruction->base, 15012 buf_sprintf("type '%s' has no member called '%s'", 15013 buf_ptr(&child_type->name), buf_ptr(field_name))); 15014 return ira->codegen->builtin_types.entry_invalid; 15015 } 15016 } else if (child_type->id == ZigTypeIdArray) { 15017 if (buf_eql_str(field_name, "Child")) { 15018 bool ptr_is_const = true; 15019 bool ptr_is_volatile = false; 15020 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 15021 create_const_type(ira->codegen, child_type->data.array.child_type), 15022 ira->codegen->builtin_types.entry_type, 15023 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 15024 } else if (buf_eql_str(field_name, "len")) { 15025 bool ptr_is_const = true; 15026 bool ptr_is_volatile = false; 15027 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 15028 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 15029 child_type->data.array.len, false), 15030 ira->codegen->builtin_types.entry_num_lit_int, 15031 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 15032 } else { 15033 ir_add_error(ira, &field_ptr_instruction->base, 15034 buf_sprintf("type '%s' has no member called '%s'", 15035 buf_ptr(&child_type->name), buf_ptr(field_name))); 15036 return ira->codegen->builtin_types.entry_invalid; 15037 } 15038 } else if (child_type->id == ZigTypeIdErrorUnion) { 15039 if (buf_eql_str(field_name, "Payload")) { 15040 bool ptr_is_const = true; 15041 bool ptr_is_volatile = false; 15042 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 15043 create_const_type(ira->codegen, child_type->data.error_union.payload_type), 15044 ira->codegen->builtin_types.entry_type, 15045 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 15046 } else if (buf_eql_str(field_name, "ErrorSet")) { 15047 bool ptr_is_const = true; 15048 bool ptr_is_volatile = false; 15049 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 15050 create_const_type(ira->codegen, child_type->data.error_union.err_set_type), 15051 ira->codegen->builtin_types.entry_type, 15052 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 15053 } else { 15054 ir_add_error(ira, &field_ptr_instruction->base, 15055 buf_sprintf("type '%s' has no member called '%s'", 15056 buf_ptr(&child_type->name), buf_ptr(field_name))); 15057 return ira->codegen->builtin_types.entry_invalid; 15058 } 15059 } else if (child_type->id == ZigTypeIdOptional) { 15060 if (buf_eql_str(field_name, "Child")) { 15061 bool ptr_is_const = true; 15062 bool ptr_is_volatile = false; 15063 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 15064 create_const_type(ira->codegen, child_type->data.maybe.child_type), 15065 ira->codegen->builtin_types.entry_type, 15066 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 15067 } else { 15068 ir_add_error(ira, &field_ptr_instruction->base, 15069 buf_sprintf("type '%s' has no member called '%s'", 15070 buf_ptr(&child_type->name), buf_ptr(field_name))); 15071 return ira->codegen->builtin_types.entry_invalid; 15072 } 15073 } else if (child_type->id == ZigTypeIdFn) { 15074 if (buf_eql_str(field_name, "ReturnType")) { 15075 if (child_type->data.fn.fn_type_id.return_type == nullptr) { 15076 // Return type can only ever be null, if the function is generic 15077 assert(child_type->data.fn.is_generic); 15078 15079 ir_add_error(ira, &field_ptr_instruction->base, 15080 buf_sprintf("ReturnType has not been resolved because '%s' is generic", buf_ptr(&child_type->name))); 15081 return ira->codegen->builtin_types.entry_invalid; 15082 } 15083 15084 bool ptr_is_const = true; 15085 bool ptr_is_volatile = false; 15086 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 15087 create_const_type(ira->codegen, child_type->data.fn.fn_type_id.return_type), 15088 ira->codegen->builtin_types.entry_type, 15089 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 15090 } else if (buf_eql_str(field_name, "is_var_args")) { 15091 bool ptr_is_const = true; 15092 bool ptr_is_volatile = false; 15093 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 15094 create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), 15095 ira->codegen->builtin_types.entry_bool, 15096 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 15097 } else if (buf_eql_str(field_name, "arg_count")) { 15098 bool ptr_is_const = true; 15099 bool ptr_is_volatile = false; 15100 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, 15101 create_const_usize(ira->codegen, child_type->data.fn.fn_type_id.param_count), 15102 ira->codegen->builtin_types.entry_usize, 15103 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); 15104 } else { 15105 ir_add_error(ira, &field_ptr_instruction->base, 15106 buf_sprintf("type '%s' has no member called '%s'", 15107 buf_ptr(&child_type->name), buf_ptr(field_name))); 15108 return ira->codegen->builtin_types.entry_invalid; 15109 } 15110 } else { 15111 ir_add_error(ira, &field_ptr_instruction->base, 15112 buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); 15113 return ira->codegen->builtin_types.entry_invalid; 15114 } 15115 } else if (container_type->id == ZigTypeIdNamespace) { 15116 assert(container_ptr->value.type->id == ZigTypeIdPointer); 15117 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 15118 if (!container_ptr_val) 15119 return ira->codegen->builtin_types.entry_invalid; 15120 15121 ConstExprValue *namespace_val = ir_const_ptr_pointee(ira, container_ptr_val, 15122 field_ptr_instruction->base.source_node); 15123 if (namespace_val == nullptr) 15124 return ira->codegen->builtin_types.entry_invalid; 15125 assert(namespace_val->special == ConstValSpecialStatic); 15126 15127 ImportTableEntry *namespace_import = namespace_val->data.x_import; 15128 15129 Tld *tld = find_decl(ira->codegen, &namespace_import->decls_scope->base, field_name); 15130 if (tld) { 15131 if (tld->visib_mod == VisibModPrivate && 15132 tld->import != source_node->owner) 15133 { 15134 ErrorMsg *msg = ir_add_error_node(ira, source_node, 15135 buf_sprintf("'%s' is private", buf_ptr(field_name))); 15136 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); 15137 return ira->codegen->builtin_types.entry_invalid; 15138 } 15139 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld); 15140 } else { 15141 const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)"; 15142 ir_add_error_node(ira, source_node, 15143 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), import_name)); 15144 return ira->codegen->builtin_types.entry_invalid; 15145 } 15146 } else { 15147 ir_add_error_node(ira, field_ptr_instruction->base.source_node, 15148 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); 15149 return ira->codegen->builtin_types.entry_invalid; 15150 } 15151 } 15152 15153 static ZigType *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *load_ptr_instruction) { 15154 IrInstruction *ptr = load_ptr_instruction->ptr->other; 15155 if (type_is_invalid(ptr->value.type)) 15156 return ira->codegen->builtin_types.entry_invalid; 15157 15158 IrInstruction *result = ir_get_deref(ira, &load_ptr_instruction->base, ptr); 15159 ir_link_new_instruction(result, &load_ptr_instruction->base); 15160 assert(result->value.type); 15161 return result->value.type; 15162 } 15163 15164 static ZigType *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstructionStorePtr *store_ptr_instruction) { 15165 IrInstruction *ptr = store_ptr_instruction->ptr->other; 15166 if (type_is_invalid(ptr->value.type)) 15167 return ptr->value.type; 15168 15169 IrInstruction *value = store_ptr_instruction->value->other; 15170 if (type_is_invalid(value->value.type)) 15171 return value->value.type; 15172 15173 if (ptr->value.type->id != ZigTypeIdPointer) { 15174 ir_add_error(ira, ptr, 15175 buf_sprintf("attempt to dereference non pointer type '%s'", buf_ptr(&ptr->value.type->name))); 15176 return ira->codegen->builtin_types.entry_invalid; 15177 } 15178 15179 if (ptr->value.data.x_ptr.special == ConstPtrSpecialDiscard) { 15180 return ir_analyze_void(ira, &store_ptr_instruction->base); 15181 } 15182 15183 if (ptr->value.type->data.pointer.is_const && !store_ptr_instruction->base.is_gen) { 15184 ir_add_error(ira, &store_ptr_instruction->base, buf_sprintf("cannot assign to constant")); 15185 return ira->codegen->builtin_types.entry_invalid; 15186 } 15187 15188 ZigType *child_type = ptr->value.type->data.pointer.child_type; 15189 IrInstruction *casted_value = ir_implicit_cast(ira, value, child_type); 15190 if (casted_value == ira->codegen->invalid_instruction) 15191 return ira->codegen->builtin_types.entry_invalid; 15192 15193 if (instr_is_comptime(ptr) && ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 15194 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst) { 15195 ir_add_error(ira, &store_ptr_instruction->base, buf_sprintf("cannot assign to constant")); 15196 return ira->codegen->builtin_types.entry_invalid; 15197 } 15198 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) { 15199 if (instr_is_comptime(casted_value)) { 15200 ConstExprValue *dest_val = ir_const_ptr_pointee(ira, &ptr->value, store_ptr_instruction->base.source_node); 15201 if (dest_val == nullptr) 15202 return ira->codegen->builtin_types.entry_invalid; 15203 if (dest_val->special != ConstValSpecialRuntime) { 15204 *dest_val = casted_value->value; 15205 if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) { 15206 ira->new_irb.current_basic_block->must_be_comptime_source_instr = &store_ptr_instruction->base; 15207 } 15208 return ir_analyze_void(ira, &store_ptr_instruction->base); 15209 } 15210 } 15211 ir_add_error(ira, &store_ptr_instruction->base, 15212 buf_sprintf("cannot store runtime value in compile time variable")); 15213 ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); 15214 dest_val->type = ira->codegen->builtin_types.entry_invalid; 15215 15216 return ira->codegen->builtin_types.entry_invalid; 15217 } 15218 } 15219 15220 ir_build_store_ptr_from(&ira->new_irb, &store_ptr_instruction->base, ptr, casted_value); 15221 return ira->codegen->builtin_types.entry_void; 15222 } 15223 15224 static ZigType *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { 15225 IrInstruction *expr_value = typeof_instruction->value->other; 15226 ZigType *type_entry = expr_value->value.type; 15227 if (type_is_invalid(type_entry)) 15228 return ira->codegen->builtin_types.entry_invalid; 15229 switch (type_entry->id) { 15230 case ZigTypeIdInvalid: 15231 zig_unreachable(); // handled above 15232 case ZigTypeIdComptimeFloat: 15233 case ZigTypeIdComptimeInt: 15234 case ZigTypeIdUndefined: 15235 case ZigTypeIdNull: 15236 case ZigTypeIdNamespace: 15237 case ZigTypeIdBlock: 15238 case ZigTypeIdBoundFn: 15239 case ZigTypeIdMetaType: 15240 case ZigTypeIdVoid: 15241 case ZigTypeIdBool: 15242 case ZigTypeIdUnreachable: 15243 case ZigTypeIdInt: 15244 case ZigTypeIdFloat: 15245 case ZigTypeIdPointer: 15246 case ZigTypeIdArray: 15247 case ZigTypeIdStruct: 15248 case ZigTypeIdOptional: 15249 case ZigTypeIdErrorUnion: 15250 case ZigTypeIdErrorSet: 15251 case ZigTypeIdEnum: 15252 case ZigTypeIdUnion: 15253 case ZigTypeIdFn: 15254 case ZigTypeIdArgTuple: 15255 case ZigTypeIdOpaque: 15256 case ZigTypeIdPromise: 15257 { 15258 ConstExprValue *out_val = ir_build_const_from(ira, &typeof_instruction->base); 15259 out_val->data.x_type = type_entry; 15260 15261 return ira->codegen->builtin_types.entry_type; 15262 } 15263 } 15264 15265 zig_unreachable(); 15266 } 15267 15268 static ZigType *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, 15269 IrInstructionToPtrType *to_ptr_type_instruction) 15270 { 15271 IrInstruction *value = to_ptr_type_instruction->value->other; 15272 ZigType *type_entry = value->value.type; 15273 if (type_is_invalid(type_entry)) 15274 return type_entry; 15275 15276 ZigType *ptr_type; 15277 if (type_entry->id == ZigTypeIdArray) { 15278 ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, false); 15279 } else if (is_slice(type_entry)) { 15280 ptr_type = adjust_ptr_len(ira->codegen, type_entry->data.structure.fields[0].type_entry, PtrLenSingle); 15281 } else if (type_entry->id == ZigTypeIdArgTuple) { 15282 ConstExprValue *arg_tuple_val = ir_resolve_const(ira, value, UndefBad); 15283 if (!arg_tuple_val) 15284 return ira->codegen->builtin_types.entry_invalid; 15285 zig_panic("TODO for loop on var args"); 15286 } else { 15287 ir_add_error_node(ira, to_ptr_type_instruction->base.source_node, 15288 buf_sprintf("expected array type, found '%s'", buf_ptr(&type_entry->name))); 15289 return ira->codegen->builtin_types.entry_invalid; 15290 } 15291 15292 ConstExprValue *out_val = ir_build_const_from(ira, &to_ptr_type_instruction->base); 15293 out_val->data.x_type = ptr_type; 15294 return ira->codegen->builtin_types.entry_type; 15295 } 15296 15297 static ZigType *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, 15298 IrInstructionPtrTypeChild *ptr_type_child_instruction) 15299 { 15300 IrInstruction *type_value = ptr_type_child_instruction->value->other; 15301 ZigType *type_entry = ir_resolve_type(ira, type_value); 15302 if (type_is_invalid(type_entry)) 15303 return type_entry; 15304 15305 if (type_entry->id != ZigTypeIdPointer) { 15306 ir_add_error_node(ira, ptr_type_child_instruction->base.source_node, 15307 buf_sprintf("expected pointer type, found '%s'", buf_ptr(&type_entry->name))); 15308 return ira->codegen->builtin_types.entry_invalid; 15309 } 15310 15311 ConstExprValue *out_val = ir_build_const_from(ira, &ptr_type_child_instruction->base); 15312 out_val->data.x_type = type_entry->data.pointer.child_type; 15313 return ira->codegen->builtin_types.entry_type; 15314 } 15315 15316 static ZigType *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { 15317 if (ira->new_irb.exec->is_inline) { 15318 // ignore setCold when running functions at compile time 15319 ir_build_const_from(ira, &instruction->base); 15320 return ira->codegen->builtin_types.entry_void; 15321 } 15322 15323 IrInstruction *is_cold_value = instruction->is_cold->other; 15324 bool want_cold; 15325 if (!ir_resolve_bool(ira, is_cold_value, &want_cold)) 15326 return ira->codegen->builtin_types.entry_invalid; 15327 15328 ZigFn *fn_entry = scope_fn_entry(instruction->base.scope); 15329 if (fn_entry == nullptr) { 15330 ir_add_error(ira, &instruction->base, buf_sprintf("@setCold outside function")); 15331 return ira->codegen->builtin_types.entry_invalid; 15332 } 15333 15334 if (fn_entry->set_cold_node != nullptr) { 15335 ErrorMsg *msg = ir_add_error(ira, &instruction->base, buf_sprintf("cold set twice in same function")); 15336 add_error_note(ira->codegen, msg, fn_entry->set_cold_node, buf_sprintf("first set here")); 15337 return ira->codegen->builtin_types.entry_invalid; 15338 } 15339 15340 fn_entry->set_cold_node = instruction->base.source_node; 15341 fn_entry->is_cold = want_cold; 15342 15343 ir_build_const_from(ira, &instruction->base); 15344 return ira->codegen->builtin_types.entry_void; 15345 } 15346 static ZigType *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira, 15347 IrInstructionSetRuntimeSafety *set_runtime_safety_instruction) 15348 { 15349 if (ira->new_irb.exec->is_inline) { 15350 // ignore setRuntimeSafety when running functions at compile time 15351 ir_build_const_from(ira, &set_runtime_safety_instruction->base); 15352 return ira->codegen->builtin_types.entry_void; 15353 } 15354 15355 bool *safety_off_ptr; 15356 AstNode **safety_set_node_ptr; 15357 15358 Scope *scope = set_runtime_safety_instruction->base.scope; 15359 while (scope != nullptr) { 15360 if (scope->id == ScopeIdBlock) { 15361 ScopeBlock *block_scope = (ScopeBlock *)scope; 15362 safety_off_ptr = &block_scope->safety_off; 15363 safety_set_node_ptr = &block_scope->safety_set_node; 15364 break; 15365 } else if (scope->id == ScopeIdFnDef) { 15366 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 15367 ZigFn *target_fn = def_scope->fn_entry; 15368 assert(target_fn->def_scope != nullptr); 15369 safety_off_ptr = &target_fn->def_scope->safety_off; 15370 safety_set_node_ptr = &target_fn->def_scope->safety_set_node; 15371 break; 15372 } else if (scope->id == ScopeIdDecls) { 15373 ScopeDecls *decls_scope = (ScopeDecls *)scope; 15374 safety_off_ptr = &decls_scope->safety_off; 15375 safety_set_node_ptr = &decls_scope->safety_set_node; 15376 break; 15377 } else { 15378 scope = scope->parent; 15379 continue; 15380 } 15381 } 15382 assert(scope != nullptr); 15383 15384 IrInstruction *safety_on_value = set_runtime_safety_instruction->safety_on->other; 15385 bool want_runtime_safety; 15386 if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety)) 15387 return ira->codegen->builtin_types.entry_invalid; 15388 15389 AstNode *source_node = set_runtime_safety_instruction->base.source_node; 15390 if (*safety_set_node_ptr) { 15391 ErrorMsg *msg = ir_add_error_node(ira, source_node, 15392 buf_sprintf("runtime safety set twice for same scope")); 15393 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here")); 15394 return ira->codegen->builtin_types.entry_invalid; 15395 } 15396 *safety_set_node_ptr = source_node; 15397 *safety_off_ptr = !want_runtime_safety; 15398 15399 ir_build_const_from(ira, &set_runtime_safety_instruction->base); 15400 return ira->codegen->builtin_types.entry_void; 15401 } 15402 15403 static ZigType *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, 15404 IrInstructionSetFloatMode *instruction) 15405 { 15406 IrInstruction *target_instruction = instruction->scope_value->other; 15407 ZigType *target_type = target_instruction->value.type; 15408 if (type_is_invalid(target_type)) 15409 return ira->codegen->builtin_types.entry_invalid; 15410 ConstExprValue *target_val = ir_resolve_const(ira, target_instruction, UndefBad); 15411 if (!target_val) 15412 return ira->codegen->builtin_types.entry_invalid; 15413 15414 if (ira->new_irb.exec->is_inline) { 15415 // ignore setFloatMode when running functions at compile time 15416 ir_build_const_from(ira, &instruction->base); 15417 return ira->codegen->builtin_types.entry_void; 15418 } 15419 15420 bool *fast_math_on_ptr; 15421 AstNode **fast_math_set_node_ptr; 15422 if (target_type->id == ZigTypeIdBlock) { 15423 ScopeBlock *block_scope = (ScopeBlock *)target_val->data.x_block; 15424 fast_math_on_ptr = &block_scope->fast_math_on; 15425 fast_math_set_node_ptr = &block_scope->fast_math_set_node; 15426 } else if (target_type->id == ZigTypeIdFn) { 15427 assert(target_val->data.x_ptr.special == ConstPtrSpecialFunction); 15428 ZigFn *target_fn = target_val->data.x_ptr.data.fn.fn_entry; 15429 assert(target_fn->def_scope); 15430 fast_math_on_ptr = &target_fn->def_scope->fast_math_on; 15431 fast_math_set_node_ptr = &target_fn->def_scope->fast_math_set_node; 15432 } else if (target_type->id == ZigTypeIdMetaType) { 15433 ScopeDecls *decls_scope; 15434 ZigType *type_arg = target_val->data.x_type; 15435 if (type_arg->id == ZigTypeIdStruct) { 15436 decls_scope = type_arg->data.structure.decls_scope; 15437 } else if (type_arg->id == ZigTypeIdEnum) { 15438 decls_scope = type_arg->data.enumeration.decls_scope; 15439 } else if (type_arg->id == ZigTypeIdUnion) { 15440 decls_scope = type_arg->data.unionation.decls_scope; 15441 } else { 15442 ir_add_error_node(ira, target_instruction->source_node, 15443 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name))); 15444 return ira->codegen->builtin_types.entry_invalid; 15445 } 15446 fast_math_on_ptr = &decls_scope->fast_math_on; 15447 fast_math_set_node_ptr = &decls_scope->fast_math_set_node; 15448 } else { 15449 ir_add_error_node(ira, target_instruction->source_node, 15450 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&target_type->name))); 15451 return ira->codegen->builtin_types.entry_invalid; 15452 } 15453 15454 IrInstruction *float_mode_value = instruction->mode_value->other; 15455 15456 FloatMode float_mode_scalar; 15457 if (!ir_resolve_float_mode(ira, float_mode_value, &float_mode_scalar)) 15458 return ira->codegen->builtin_types.entry_invalid; 15459 15460 AstNode *source_node = instruction->base.source_node; 15461 if (*fast_math_set_node_ptr) { 15462 ErrorMsg *msg = ir_add_error_node(ira, source_node, 15463 buf_sprintf("float mode set twice for same scope")); 15464 add_error_note(ira->codegen, msg, *fast_math_set_node_ptr, buf_sprintf("first set here")); 15465 return ira->codegen->builtin_types.entry_invalid; 15466 } 15467 *fast_math_set_node_ptr = source_node; 15468 *fast_math_on_ptr = (float_mode_scalar == FloatModeOptimized); 15469 15470 ir_build_const_from(ira, &instruction->base); 15471 return ira->codegen->builtin_types.entry_void; 15472 } 15473 15474 static ZigType *ir_analyze_instruction_slice_type(IrAnalyze *ira, 15475 IrInstructionSliceType *slice_type_instruction) 15476 { 15477 Error err; 15478 uint32_t align_bytes; 15479 if (slice_type_instruction->align_value != nullptr) { 15480 if (!ir_resolve_align(ira, slice_type_instruction->align_value->other, &align_bytes)) 15481 return ira->codegen->builtin_types.entry_invalid; 15482 } 15483 15484 ZigType *child_type = ir_resolve_type(ira, slice_type_instruction->child_type->other); 15485 if (type_is_invalid(child_type)) 15486 return ira->codegen->builtin_types.entry_invalid; 15487 15488 if (slice_type_instruction->align_value == nullptr) { 15489 if ((err = type_ensure_zero_bits_known(ira->codegen, child_type))) 15490 return ira->codegen->builtin_types.entry_invalid; 15491 align_bytes = get_abi_alignment(ira->codegen, child_type); 15492 } 15493 15494 bool is_const = slice_type_instruction->is_const; 15495 bool is_volatile = slice_type_instruction->is_volatile; 15496 15497 switch (child_type->id) { 15498 case ZigTypeIdInvalid: // handled above 15499 zig_unreachable(); 15500 case ZigTypeIdUnreachable: 15501 case ZigTypeIdUndefined: 15502 case ZigTypeIdNull: 15503 case ZigTypeIdBlock: 15504 case ZigTypeIdArgTuple: 15505 case ZigTypeIdOpaque: 15506 ir_add_error_node(ira, slice_type_instruction->base.source_node, 15507 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&child_type->name))); 15508 return ira->codegen->builtin_types.entry_invalid; 15509 case ZigTypeIdMetaType: 15510 case ZigTypeIdVoid: 15511 case ZigTypeIdBool: 15512 case ZigTypeIdInt: 15513 case ZigTypeIdFloat: 15514 case ZigTypeIdPointer: 15515 case ZigTypeIdArray: 15516 case ZigTypeIdStruct: 15517 case ZigTypeIdComptimeFloat: 15518 case ZigTypeIdComptimeInt: 15519 case ZigTypeIdOptional: 15520 case ZigTypeIdErrorUnion: 15521 case ZigTypeIdErrorSet: 15522 case ZigTypeIdEnum: 15523 case ZigTypeIdUnion: 15524 case ZigTypeIdFn: 15525 case ZigTypeIdNamespace: 15526 case ZigTypeIdBoundFn: 15527 case ZigTypeIdPromise: 15528 { 15529 if ((err = type_ensure_zero_bits_known(ira->codegen, child_type))) 15530 return ira->codegen->builtin_types.entry_invalid; 15531 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, 15532 is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0); 15533 ZigType *result_type = get_slice_type(ira->codegen, slice_ptr_type); 15534 ConstExprValue *out_val = ir_build_const_from(ira, &slice_type_instruction->base); 15535 out_val->data.x_type = result_type; 15536 return ira->codegen->builtin_types.entry_type; 15537 } 15538 } 15539 zig_unreachable(); 15540 } 15541 15542 static ZigType *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsm *asm_instruction) { 15543 assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr); 15544 15545 AstNodeAsmExpr *asm_expr = &asm_instruction->base.source_node->data.asm_expr; 15546 15547 bool global_scope = (scope_fn_entry(asm_instruction->base.scope) == nullptr); 15548 if (global_scope) { 15549 if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 || 15550 asm_expr->clobber_list.length != 0) 15551 { 15552 ir_add_error(ira, &asm_instruction->base, 15553 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers")); 15554 return ira->codegen->builtin_types.entry_invalid; 15555 } 15556 15557 buf_append_char(&ira->codegen->global_asm, '\n'); 15558 buf_append_buf(&ira->codegen->global_asm, asm_expr->asm_template); 15559 15560 ir_build_const_from(ira, &asm_instruction->base); 15561 return ira->codegen->builtin_types.entry_void; 15562 } 15563 15564 if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base)) 15565 return ira->codegen->builtin_types.entry_invalid; 15566 15567 // TODO validate the output types and variable types 15568 15569 IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length); 15570 IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length); 15571 15572 ZigType *return_type = ira->codegen->builtin_types.entry_void; 15573 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 15574 AsmOutput *asm_output = asm_expr->output_list.at(i); 15575 if (asm_output->return_type) { 15576 output_types[i] = asm_instruction->output_types[i]->other; 15577 return_type = ir_resolve_type(ira, output_types[i]); 15578 if (type_is_invalid(return_type)) 15579 return ira->codegen->builtin_types.entry_invalid; 15580 } 15581 } 15582 15583 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 15584 input_list[i] = asm_instruction->input_list[i]->other; 15585 if (type_is_invalid(input_list[i]->value.type)) 15586 return ira->codegen->builtin_types.entry_invalid; 15587 } 15588 15589 ir_build_asm_from(&ira->new_irb, &asm_instruction->base, input_list, output_types, 15590 asm_instruction->output_vars, asm_instruction->return_count, asm_instruction->has_side_effects); 15591 return return_type; 15592 } 15593 15594 static ZigType *ir_analyze_instruction_array_type(IrAnalyze *ira, 15595 IrInstructionArrayType *array_type_instruction) 15596 { 15597 Error err; 15598 15599 IrInstruction *size_value = array_type_instruction->size->other; 15600 uint64_t size; 15601 if (!ir_resolve_usize(ira, size_value, &size)) 15602 return ira->codegen->builtin_types.entry_invalid; 15603 15604 IrInstruction *child_type_value = array_type_instruction->child_type->other; 15605 ZigType *child_type = ir_resolve_type(ira, child_type_value); 15606 if (type_is_invalid(child_type)) 15607 return ira->codegen->builtin_types.entry_invalid; 15608 switch (child_type->id) { 15609 case ZigTypeIdInvalid: // handled above 15610 zig_unreachable(); 15611 case ZigTypeIdUnreachable: 15612 case ZigTypeIdUndefined: 15613 case ZigTypeIdNull: 15614 case ZigTypeIdBlock: 15615 case ZigTypeIdArgTuple: 15616 case ZigTypeIdOpaque: 15617 ir_add_error_node(ira, array_type_instruction->base.source_node, 15618 buf_sprintf("array of type '%s' not allowed", buf_ptr(&child_type->name))); 15619 return ira->codegen->builtin_types.entry_invalid; 15620 case ZigTypeIdMetaType: 15621 case ZigTypeIdVoid: 15622 case ZigTypeIdBool: 15623 case ZigTypeIdInt: 15624 case ZigTypeIdFloat: 15625 case ZigTypeIdPointer: 15626 case ZigTypeIdArray: 15627 case ZigTypeIdStruct: 15628 case ZigTypeIdComptimeFloat: 15629 case ZigTypeIdComptimeInt: 15630 case ZigTypeIdOptional: 15631 case ZigTypeIdErrorUnion: 15632 case ZigTypeIdErrorSet: 15633 case ZigTypeIdEnum: 15634 case ZigTypeIdUnion: 15635 case ZigTypeIdFn: 15636 case ZigTypeIdNamespace: 15637 case ZigTypeIdBoundFn: 15638 case ZigTypeIdPromise: 15639 { 15640 if ((err = ensure_complete_type(ira->codegen, child_type))) 15641 return ira->codegen->builtin_types.entry_invalid; 15642 ZigType *result_type = get_array_type(ira->codegen, child_type, size); 15643 ConstExprValue *out_val = ir_build_const_from(ira, &array_type_instruction->base); 15644 out_val->data.x_type = result_type; 15645 return ira->codegen->builtin_types.entry_type; 15646 } 15647 } 15648 zig_unreachable(); 15649 } 15650 15651 static ZigType *ir_analyze_instruction_promise_type(IrAnalyze *ira, IrInstructionPromiseType *instruction) { 15652 ZigType *promise_type; 15653 15654 if (instruction->payload_type == nullptr) { 15655 promise_type = ira->codegen->builtin_types.entry_promise; 15656 } else { 15657 ZigType *payload_type = ir_resolve_type(ira, instruction->payload_type->other); 15658 if (type_is_invalid(payload_type)) 15659 return ira->codegen->builtin_types.entry_invalid; 15660 15661 promise_type = get_promise_type(ira->codegen, payload_type); 15662 } 15663 15664 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 15665 out_val->data.x_type = promise_type; 15666 return ira->codegen->builtin_types.entry_type; 15667 } 15668 15669 static ZigType *ir_analyze_instruction_size_of(IrAnalyze *ira, 15670 IrInstructionSizeOf *size_of_instruction) 15671 { 15672 Error err; 15673 IrInstruction *type_value = size_of_instruction->type_value->other; 15674 ZigType *type_entry = ir_resolve_type(ira, type_value); 15675 15676 if ((err = ensure_complete_type(ira->codegen, type_entry))) 15677 return ira->codegen->builtin_types.entry_invalid; 15678 15679 switch (type_entry->id) { 15680 case ZigTypeIdInvalid: // handled above 15681 zig_unreachable(); 15682 case ZigTypeIdUnreachable: 15683 case ZigTypeIdUndefined: 15684 case ZigTypeIdNull: 15685 case ZigTypeIdBlock: 15686 case ZigTypeIdComptimeFloat: 15687 case ZigTypeIdComptimeInt: 15688 case ZigTypeIdBoundFn: 15689 case ZigTypeIdMetaType: 15690 case ZigTypeIdNamespace: 15691 case ZigTypeIdArgTuple: 15692 case ZigTypeIdOpaque: 15693 ir_add_error_node(ira, size_of_instruction->base.source_node, 15694 buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name))); 15695 return ira->codegen->builtin_types.entry_invalid; 15696 case ZigTypeIdVoid: 15697 case ZigTypeIdBool: 15698 case ZigTypeIdInt: 15699 case ZigTypeIdFloat: 15700 case ZigTypeIdPointer: 15701 case ZigTypeIdArray: 15702 case ZigTypeIdStruct: 15703 case ZigTypeIdOptional: 15704 case ZigTypeIdErrorUnion: 15705 case ZigTypeIdErrorSet: 15706 case ZigTypeIdEnum: 15707 case ZigTypeIdUnion: 15708 case ZigTypeIdFn: 15709 case ZigTypeIdPromise: 15710 { 15711 uint64_t size_in_bytes = type_size(ira->codegen, type_entry); 15712 ConstExprValue *out_val = ir_build_const_from(ira, &size_of_instruction->base); 15713 bigint_init_unsigned(&out_val->data.x_bigint, size_in_bytes); 15714 return ira->codegen->builtin_types.entry_num_lit_int; 15715 } 15716 } 15717 zig_unreachable(); 15718 } 15719 15720 static ZigType *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrInstructionTestNonNull *instruction) { 15721 IrInstruction *value = instruction->value->other; 15722 if (type_is_invalid(value->value.type)) 15723 return ira->codegen->builtin_types.entry_invalid; 15724 15725 ZigType *type_entry = value->value.type; 15726 15727 if (type_entry->id == ZigTypeIdOptional) { 15728 if (instr_is_comptime(value)) { 15729 ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefBad); 15730 if (!maybe_val) 15731 return ira->codegen->builtin_types.entry_invalid; 15732 15733 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 15734 out_val->data.x_bool = !optional_value_is_null(maybe_val); 15735 return ira->codegen->builtin_types.entry_bool; 15736 } 15737 15738 ir_build_test_nonnull_from(&ira->new_irb, &instruction->base, value); 15739 return ira->codegen->builtin_types.entry_bool; 15740 } else if (type_entry->id == ZigTypeIdNull) { 15741 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 15742 out_val->data.x_bool = false; 15743 return ira->codegen->builtin_types.entry_bool; 15744 } else { 15745 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 15746 out_val->data.x_bool = true; 15747 return ira->codegen->builtin_types.entry_bool; 15748 } 15749 } 15750 15751 static ZigType *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira, 15752 IrInstructionUnwrapOptional *unwrap_maybe_instruction) 15753 { 15754 IrInstruction *value = unwrap_maybe_instruction->value->other; 15755 if (type_is_invalid(value->value.type)) 15756 return ira->codegen->builtin_types.entry_invalid; 15757 15758 ZigType *ptr_type = value->value.type; 15759 assert(ptr_type->id == ZigTypeIdPointer); 15760 15761 ZigType *type_entry = ptr_type->data.pointer.child_type; 15762 if (type_is_invalid(type_entry)) { 15763 return ira->codegen->builtin_types.entry_invalid; 15764 } else if (type_entry->id != ZigTypeIdOptional) { 15765 ir_add_error_node(ira, unwrap_maybe_instruction->value->source_node, 15766 buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name))); 15767 return ira->codegen->builtin_types.entry_invalid; 15768 } 15769 ZigType *child_type = type_entry->data.maybe.child_type; 15770 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, 15771 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 15772 PtrLenSingle, 15773 get_abi_alignment(ira->codegen, child_type), 0, 0); 15774 15775 if (instr_is_comptime(value)) { 15776 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 15777 if (!val) 15778 return ira->codegen->builtin_types.entry_invalid; 15779 ConstExprValue *maybe_val = ir_const_ptr_pointee(ira, val, unwrap_maybe_instruction->base.source_node); 15780 if (maybe_val == nullptr) 15781 return ira->codegen->builtin_types.entry_invalid; 15782 15783 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 15784 if (optional_value_is_null(maybe_val)) { 15785 ir_add_error(ira, &unwrap_maybe_instruction->base, buf_sprintf("unable to unwrap null")); 15786 return ira->codegen->builtin_types.entry_invalid; 15787 } 15788 ConstExprValue *out_val = ir_build_const_from(ira, &unwrap_maybe_instruction->base); 15789 out_val->data.x_ptr.special = ConstPtrSpecialRef; 15790 out_val->data.x_ptr.mut = val->data.x_ptr.mut; 15791 if (type_is_codegen_pointer(child_type)) { 15792 out_val->data.x_ptr.data.ref.pointee = maybe_val; 15793 } else { 15794 out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_optional; 15795 } 15796 return result_type; 15797 } 15798 } 15799 15800 ir_build_unwrap_maybe_from(&ira->new_irb, &unwrap_maybe_instruction->base, value, 15801 unwrap_maybe_instruction->safety_check_on); 15802 return result_type; 15803 } 15804 15805 static ZigType *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *ctz_instruction) { 15806 IrInstruction *value = ctz_instruction->value->other; 15807 if (type_is_invalid(value->value.type)) { 15808 return ira->codegen->builtin_types.entry_invalid; 15809 } else if (value->value.type->id == ZigTypeIdInt) { 15810 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, 15811 value->value.type->data.integral.bit_count); 15812 if (value->value.special != ConstValSpecialRuntime) { 15813 size_t result = bigint_ctz(&value->value.data.x_bigint, 15814 value->value.type->data.integral.bit_count); 15815 ConstExprValue *out_val = ir_build_const_from(ira, &ctz_instruction->base); 15816 bigint_init_unsigned(&out_val->data.x_bigint, result); 15817 return return_type; 15818 } 15819 15820 ir_build_ctz_from(&ira->new_irb, &ctz_instruction->base, value); 15821 return return_type; 15822 } else { 15823 ir_add_error_node(ira, ctz_instruction->base.source_node, 15824 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); 15825 return ira->codegen->builtin_types.entry_invalid; 15826 } 15827 } 15828 15829 static ZigType *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *clz_instruction) { 15830 IrInstruction *value = clz_instruction->value->other; 15831 if (type_is_invalid(value->value.type)) { 15832 return ira->codegen->builtin_types.entry_invalid; 15833 } else if (value->value.type->id == ZigTypeIdInt) { 15834 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, 15835 value->value.type->data.integral.bit_count); 15836 if (value->value.special != ConstValSpecialRuntime) { 15837 size_t result = bigint_clz(&value->value.data.x_bigint, 15838 value->value.type->data.integral.bit_count); 15839 ConstExprValue *out_val = ir_build_const_from(ira, &clz_instruction->base); 15840 bigint_init_unsigned(&out_val->data.x_bigint, result); 15841 return return_type; 15842 } 15843 15844 ir_build_clz_from(&ira->new_irb, &clz_instruction->base, value); 15845 return return_type; 15846 } else { 15847 ir_add_error_node(ira, clz_instruction->base.source_node, 15848 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); 15849 return ira->codegen->builtin_types.entry_invalid; 15850 } 15851 } 15852 15853 static ZigType *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) { 15854 IrInstruction *value = instruction->value->other; 15855 if (type_is_invalid(value->value.type)) 15856 return ira->codegen->builtin_types.entry_invalid; 15857 15858 if (value->value.type->id != ZigTypeIdInt && value->value.type->id != ZigTypeIdComptimeInt) { 15859 ir_add_error(ira, value, 15860 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); 15861 return ira->codegen->builtin_types.entry_invalid; 15862 } 15863 15864 if (instr_is_comptime(value)) { 15865 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 15866 if (!val) 15867 return ira->codegen->builtin_types.entry_invalid; 15868 if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { 15869 size_t result = bigint_popcount_unsigned(&val->data.x_bigint); 15870 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 15871 bigint_init_unsigned(&out_val->data.x_bigint, result); 15872 return ira->codegen->builtin_types.entry_num_lit_int; 15873 } 15874 if (value->value.type->id == ZigTypeIdComptimeInt) { 15875 Buf *val_buf = buf_alloc(); 15876 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 15877 ir_add_error(ira, &instruction->base, 15878 buf_sprintf("@popCount on negative %s value %s", 15879 buf_ptr(&value->value.type->name), buf_ptr(val_buf))); 15880 return ira->codegen->builtin_types.entry_invalid; 15881 } 15882 size_t result = bigint_popcount_signed(&val->data.x_bigint, value->value.type->data.integral.bit_count); 15883 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 15884 bigint_init_unsigned(&out_val->data.x_bigint, result); 15885 return ira->codegen->builtin_types.entry_num_lit_int; 15886 } 15887 15888 IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope, 15889 instruction->base.source_node, value); 15890 result->value.type = get_smallest_unsigned_int_type(ira->codegen, value->value.type->data.integral.bit_count); 15891 ir_link_new_instruction(result, &instruction->base); 15892 return result->value.type; 15893 } 15894 15895 static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value) { 15896 if (type_is_invalid(value->value.type)) 15897 return ira->codegen->invalid_instruction; 15898 15899 if (value->value.type->id == ZigTypeIdEnum) { 15900 return value; 15901 } 15902 15903 if (value->value.type->id != ZigTypeIdUnion) { 15904 ir_add_error(ira, value, 15905 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value.type->name))); 15906 return ira->codegen->invalid_instruction; 15907 } 15908 if (!value->value.type->data.unionation.have_explicit_tag_type && !source_instr->is_gen) { 15909 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum")); 15910 if (value->value.type->data.unionation.decl_node != nullptr) { 15911 add_error_note(ira->codegen, msg, value->value.type->data.unionation.decl_node, 15912 buf_sprintf("declared here")); 15913 } 15914 return ira->codegen->invalid_instruction; 15915 } 15916 15917 ZigType *tag_type = value->value.type->data.unionation.tag_type; 15918 assert(tag_type->id == ZigTypeIdEnum); 15919 15920 if (instr_is_comptime(value)) { 15921 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 15922 if (!val) 15923 return ira->codegen->invalid_instruction; 15924 15925 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 15926 source_instr->scope, source_instr->source_node); 15927 const_instruction->base.value.type = tag_type; 15928 const_instruction->base.value.special = ConstValSpecialStatic; 15929 bigint_init_bigint(&const_instruction->base.value.data.x_enum_tag, &val->data.x_union.tag); 15930 return &const_instruction->base; 15931 } 15932 15933 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 15934 result->value.type = tag_type; 15935 return result; 15936 } 15937 15938 static ZigType *ir_analyze_instruction_switch_br(IrAnalyze *ira, 15939 IrInstructionSwitchBr *switch_br_instruction) 15940 { 15941 IrInstruction *target_value = switch_br_instruction->target_value->other; 15942 if (type_is_invalid(target_value->value.type)) 15943 return ir_unreach_error(ira); 15944 15945 if (switch_br_instruction->switch_prongs_void != nullptr) { 15946 if (type_is_invalid(switch_br_instruction->switch_prongs_void->other->value.type)) { 15947 return ir_unreach_error(ira); 15948 } 15949 } 15950 15951 15952 size_t case_count = switch_br_instruction->case_count; 15953 15954 bool is_comptime; 15955 if (!ir_resolve_comptime(ira, switch_br_instruction->is_comptime->other, &is_comptime)) 15956 return ira->codegen->builtin_types.entry_invalid; 15957 15958 if (is_comptime || instr_is_comptime(target_value)) { 15959 ConstExprValue *target_val = ir_resolve_const(ira, target_value, UndefBad); 15960 if (!target_val) 15961 return ir_unreach_error(ira); 15962 15963 IrBasicBlock *old_dest_block = switch_br_instruction->else_block; 15964 for (size_t i = 0; i < case_count; i += 1) { 15965 IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 15966 IrInstruction *case_value = old_case->value->other; 15967 if (type_is_invalid(case_value->value.type)) 15968 return ir_unreach_error(ira); 15969 15970 if (case_value->value.type->id == ZigTypeIdEnum) { 15971 case_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, case_value); 15972 if (type_is_invalid(case_value->value.type)) 15973 return ir_unreach_error(ira); 15974 } 15975 15976 IrInstruction *casted_case_value = ir_implicit_cast(ira, case_value, target_value->value.type); 15977 if (type_is_invalid(casted_case_value->value.type)) 15978 return ir_unreach_error(ira); 15979 15980 ConstExprValue *case_val = ir_resolve_const(ira, casted_case_value, UndefBad); 15981 if (!case_val) 15982 return ir_unreach_error(ira); 15983 15984 if (const_values_equal(target_val, case_val)) { 15985 old_dest_block = old_case->block; 15986 break; 15987 } 15988 } 15989 15990 if (is_comptime || old_dest_block->ref_count == 1) { 15991 return ir_inline_bb(ira, &switch_br_instruction->base, old_dest_block); 15992 } else { 15993 IrBasicBlock *new_dest_block = ir_get_new_bb(ira, old_dest_block, &switch_br_instruction->base); 15994 ir_build_br_from(&ira->new_irb, &switch_br_instruction->base, new_dest_block); 15995 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); 15996 } 15997 } 15998 15999 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(case_count); 16000 for (size_t i = 0; i < case_count; i += 1) { 16001 IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 16002 IrInstructionSwitchBrCase *new_case = &cases[i]; 16003 new_case->block = ir_get_new_bb(ira, old_case->block, &switch_br_instruction->base); 16004 new_case->value = ira->codegen->invalid_instruction; 16005 16006 // Calling ir_get_new_bb set the ref_instruction on the new basic block. 16007 // However a switch br may branch to the same basic block which would trigger an 16008 // incorrect re-generation of the block. So we set it to null here and assign 16009 // it back after the loop. 16010 new_case->block->ref_instruction = nullptr; 16011 16012 IrInstruction *old_value = old_case->value; 16013 IrInstruction *new_value = old_value->other; 16014 if (type_is_invalid(new_value->value.type)) 16015 continue; 16016 16017 if (new_value->value.type->id == ZigTypeIdEnum) { 16018 new_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, new_value); 16019 if (type_is_invalid(new_value->value.type)) 16020 continue; 16021 } 16022 16023 IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, target_value->value.type); 16024 if (type_is_invalid(casted_new_value->value.type)) 16025 continue; 16026 16027 if (!ir_resolve_const(ira, casted_new_value, UndefBad)) 16028 continue; 16029 16030 new_case->value = casted_new_value; 16031 } 16032 16033 for (size_t i = 0; i < case_count; i += 1) { 16034 IrInstructionSwitchBrCase *new_case = &cases[i]; 16035 if (new_case->value == ira->codegen->invalid_instruction) 16036 return ir_unreach_error(ira); 16037 new_case->block->ref_instruction = &switch_br_instruction->base; 16038 } 16039 16040 IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); 16041 ir_build_switch_br_from(&ira->new_irb, &switch_br_instruction->base, 16042 target_value, new_else_block, case_count, cases, nullptr, nullptr); 16043 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); 16044 } 16045 16046 static ZigType *ir_analyze_instruction_switch_target(IrAnalyze *ira, 16047 IrInstructionSwitchTarget *switch_target_instruction) 16048 { 16049 Error err; 16050 IrInstruction *target_value_ptr = switch_target_instruction->target_value_ptr->other; 16051 if (type_is_invalid(target_value_ptr->value.type)) 16052 return ira->codegen->builtin_types.entry_invalid; 16053 16054 if (target_value_ptr->value.type->id == ZigTypeIdMetaType) { 16055 assert(instr_is_comptime(target_value_ptr)); 16056 ZigType *ptr_type = target_value_ptr->value.data.x_type; 16057 assert(ptr_type->id == ZigTypeIdPointer); 16058 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); 16059 out_val->type = ira->codegen->builtin_types.entry_type; 16060 out_val->data.x_type = ptr_type->data.pointer.child_type; 16061 return out_val->type; 16062 } 16063 16064 if (target_value_ptr->value.type->id != ZigTypeIdPointer) { 16065 ir_add_error(ira, target_value_ptr, buf_sprintf("invalid deref on switch target")); 16066 return ira->codegen->builtin_types.entry_invalid; 16067 } 16068 16069 ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type; 16070 ConstExprValue *pointee_val = nullptr; 16071 if (instr_is_comptime(target_value_ptr)) { 16072 pointee_val = ir_const_ptr_pointee(ira, &target_value_ptr->value, target_value_ptr->source_node); 16073 if (pointee_val == nullptr) 16074 return ira->codegen->builtin_types.entry_invalid; 16075 16076 if (pointee_val->special == ConstValSpecialRuntime) 16077 pointee_val = nullptr; 16078 } 16079 if ((err = ensure_complete_type(ira->codegen, target_type))) 16080 return ira->codegen->builtin_types.entry_invalid; 16081 16082 switch (target_type->id) { 16083 case ZigTypeIdInvalid: 16084 zig_unreachable(); 16085 case ZigTypeIdMetaType: 16086 case ZigTypeIdVoid: 16087 case ZigTypeIdBool: 16088 case ZigTypeIdInt: 16089 case ZigTypeIdFloat: 16090 case ZigTypeIdComptimeFloat: 16091 case ZigTypeIdComptimeInt: 16092 case ZigTypeIdPointer: 16093 case ZigTypeIdPromise: 16094 case ZigTypeIdFn: 16095 case ZigTypeIdNamespace: 16096 case ZigTypeIdErrorSet: 16097 if (pointee_val) { 16098 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); 16099 copy_const_val(out_val, pointee_val, true); 16100 out_val->type = target_type; 16101 return target_type; 16102 } 16103 16104 ir_build_load_ptr_from(&ira->new_irb, &switch_target_instruction->base, target_value_ptr); 16105 return target_type; 16106 case ZigTypeIdUnion: { 16107 AstNode *decl_node = target_type->data.unionation.decl_node; 16108 if (!decl_node->data.container_decl.auto_enum && 16109 decl_node->data.container_decl.init_arg_expr == nullptr) 16110 { 16111 ErrorMsg *msg = ir_add_error(ira, target_value_ptr, 16112 buf_sprintf("switch on union which has no attached enum")); 16113 add_error_note(ira->codegen, msg, decl_node, 16114 buf_sprintf("consider 'union(enum)' here")); 16115 return ira->codegen->builtin_types.entry_invalid; 16116 } 16117 ZigType *tag_type = target_type->data.unionation.tag_type; 16118 assert(tag_type != nullptr); 16119 assert(tag_type->id == ZigTypeIdEnum); 16120 if (pointee_val) { 16121 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); 16122 bigint_init_bigint(&out_val->data.x_enum_tag, &pointee_val->data.x_union.tag); 16123 return tag_type; 16124 } 16125 if (tag_type->data.enumeration.src_field_count == 1) { 16126 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); 16127 TypeEnumField *only_field = &tag_type->data.enumeration.fields[0]; 16128 bigint_init_bigint(&out_val->data.x_enum_tag, &only_field->value); 16129 return tag_type; 16130 } 16131 16132 IrInstruction *union_value = ir_build_load_ptr(&ira->new_irb, switch_target_instruction->base.scope, 16133 switch_target_instruction->base.source_node, target_value_ptr); 16134 union_value->value.type = target_type; 16135 16136 IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, 16137 switch_target_instruction->base.source_node, union_value); 16138 union_tag_inst->value.type = tag_type; 16139 ir_link_new_instruction(union_tag_inst, &switch_target_instruction->base); 16140 return tag_type; 16141 } 16142 case ZigTypeIdEnum: { 16143 if ((err = type_ensure_zero_bits_known(ira->codegen, target_type))) 16144 return ira->codegen->builtin_types.entry_invalid; 16145 if (target_type->data.enumeration.src_field_count < 2) { 16146 TypeEnumField *only_field = &target_type->data.enumeration.fields[0]; 16147 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); 16148 bigint_init_bigint(&out_val->data.x_enum_tag, &only_field->value); 16149 return target_type; 16150 } 16151 16152 if (pointee_val) { 16153 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); 16154 bigint_init_bigint(&out_val->data.x_enum_tag, &pointee_val->data.x_enum_tag); 16155 return target_type; 16156 } 16157 16158 IrInstruction *enum_value = ir_build_load_ptr(&ira->new_irb, switch_target_instruction->base.scope, 16159 switch_target_instruction->base.source_node, target_value_ptr); 16160 enum_value->value.type = target_type; 16161 ir_link_new_instruction(enum_value, &switch_target_instruction->base); 16162 return target_type; 16163 } 16164 case ZigTypeIdErrorUnion: 16165 case ZigTypeIdUnreachable: 16166 case ZigTypeIdArray: 16167 case ZigTypeIdStruct: 16168 case ZigTypeIdUndefined: 16169 case ZigTypeIdNull: 16170 case ZigTypeIdOptional: 16171 case ZigTypeIdBlock: 16172 case ZigTypeIdBoundFn: 16173 case ZigTypeIdArgTuple: 16174 case ZigTypeIdOpaque: 16175 ir_add_error(ira, &switch_target_instruction->base, 16176 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); 16177 return ira->codegen->builtin_types.entry_invalid; 16178 } 16179 zig_unreachable(); 16180 } 16181 16182 static ZigType *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstructionSwitchVar *instruction) { 16183 IrInstruction *target_value_ptr = instruction->target_value_ptr->other; 16184 if (type_is_invalid(target_value_ptr->value.type)) 16185 return ira->codegen->builtin_types.entry_invalid; 16186 16187 IrInstruction *prong_value = instruction->prong_value->other; 16188 if (type_is_invalid(prong_value->value.type)) 16189 return ira->codegen->builtin_types.entry_invalid; 16190 16191 assert(target_value_ptr->value.type->id == ZigTypeIdPointer); 16192 ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type; 16193 if (target_type->id == ZigTypeIdUnion) { 16194 ConstExprValue *prong_val = ir_resolve_const(ira, prong_value, UndefBad); 16195 if (!prong_val) 16196 return ira->codegen->builtin_types.entry_invalid; 16197 16198 assert(prong_value->value.type->id == ZigTypeIdEnum); 16199 TypeUnionField *field = find_union_field_by_tag(target_type, &prong_val->data.x_enum_tag); 16200 16201 if (instr_is_comptime(target_value_ptr)) { 16202 ConstExprValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad); 16203 if (!target_value_ptr) 16204 return ira->codegen->builtin_types.entry_invalid; 16205 16206 ConstExprValue *pointee_val = ir_const_ptr_pointee(ira, target_val_ptr, instruction->base.source_node); 16207 if (pointee_val == nullptr) 16208 return ira->codegen->builtin_types.entry_invalid; 16209 16210 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 16211 out_val->data.x_ptr.special = ConstPtrSpecialRef; 16212 out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut; 16213 out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_union.payload; 16214 return get_pointer_to_type(ira->codegen, field->type_entry, target_val_ptr->type->data.pointer.is_const); 16215 } 16216 16217 ir_build_union_field_ptr_from(&ira->new_irb, &instruction->base, target_value_ptr, field); 16218 return get_pointer_to_type(ira->codegen, field->type_entry, 16219 target_value_ptr->value.type->data.pointer.is_const); 16220 } else { 16221 ir_add_error(ira, &instruction->base, 16222 buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); 16223 return ira->codegen->builtin_types.entry_invalid; 16224 } 16225 } 16226 16227 static ZigType *ir_analyze_instruction_union_tag(IrAnalyze *ira, IrInstructionUnionTag *instruction) { 16228 IrInstruction *value = instruction->value->other; 16229 IrInstruction *new_instruction = ir_analyze_union_tag(ira, &instruction->base, value); 16230 ir_link_new_instruction(new_instruction, &instruction->base); 16231 return new_instruction->value.type; 16232 } 16233 16234 static ZigType *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) { 16235 IrInstruction *name_value = import_instruction->name->other; 16236 Buf *import_target_str = ir_resolve_str(ira, name_value); 16237 if (!import_target_str) 16238 return ira->codegen->builtin_types.entry_invalid; 16239 16240 AstNode *source_node = import_instruction->base.source_node; 16241 ImportTableEntry *import = source_node->owner; 16242 16243 Buf *import_target_path; 16244 Buf *search_dir; 16245 assert(import->package); 16246 PackageTableEntry *target_package; 16247 auto package_entry = import->package->package_table.maybe_get(import_target_str); 16248 if (package_entry) { 16249 target_package = package_entry->value; 16250 import_target_path = &target_package->root_src_path; 16251 search_dir = &target_package->root_src_dir; 16252 } else { 16253 // try it as a filename 16254 target_package = import->package; 16255 import_target_path = import_target_str; 16256 16257 // search relative to importing file 16258 search_dir = buf_alloc(); 16259 os_path_dirname(import->path, search_dir); 16260 } 16261 16262 Buf full_path = BUF_INIT; 16263 os_path_join(search_dir, import_target_path, &full_path); 16264 16265 Buf *import_code = buf_alloc(); 16266 Buf *resolved_path = buf_alloc(); 16267 16268 Buf *resolve_paths[] = { &full_path, }; 16269 *resolved_path = os_path_resolve(resolve_paths, 1); 16270 16271 auto import_entry = ira->codegen->import_table.maybe_get(resolved_path); 16272 if (import_entry) { 16273 ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base); 16274 out_val->data.x_import = import_entry->value; 16275 return ira->codegen->builtin_types.entry_namespace; 16276 } 16277 16278 int err; 16279 if ((err = os_fetch_file_path(resolved_path, import_code, true))) { 16280 if (err == ErrorFileNotFound) { 16281 ir_add_error_node(ira, source_node, 16282 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); 16283 return ira->codegen->builtin_types.entry_invalid; 16284 } else { 16285 ir_add_error_node(ira, source_node, 16286 buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); 16287 return ira->codegen->builtin_types.entry_invalid; 16288 } 16289 } 16290 ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, resolved_path, import_code); 16291 16292 scan_import(ira->codegen, target_import); 16293 16294 ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base); 16295 out_val->data.x_import = target_import; 16296 return ira->codegen->builtin_types.entry_namespace; 16297 16298 } 16299 16300 static ZigType *ir_analyze_instruction_array_len(IrAnalyze *ira, 16301 IrInstructionArrayLen *array_len_instruction) 16302 { 16303 IrInstruction *array_value = array_len_instruction->array_value->other; 16304 ZigType *type_entry = array_value->value.type; 16305 if (type_is_invalid(type_entry)) { 16306 return ira->codegen->builtin_types.entry_invalid; 16307 } else if (type_entry->id == ZigTypeIdArray) { 16308 return ir_analyze_const_usize(ira, &array_len_instruction->base, 16309 type_entry->data.array.len); 16310 } else if (is_slice(type_entry)) { 16311 if (array_value->value.special != ConstValSpecialRuntime) { 16312 ConstExprValue *len_val = &array_value->value.data.x_struct.fields[slice_len_index]; 16313 if (len_val->special != ConstValSpecialRuntime) { 16314 return ir_analyze_const_usize(ira, &array_len_instruction->base, 16315 bigint_as_unsigned(&len_val->data.x_bigint)); 16316 } 16317 } 16318 TypeStructField *field = &type_entry->data.structure.fields[slice_len_index]; 16319 IrInstruction *len_ptr = ir_build_struct_field_ptr(&ira->new_irb, array_len_instruction->base.scope, 16320 array_len_instruction->base.source_node, array_value, field); 16321 len_ptr->value.type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_usize, true); 16322 ir_build_load_ptr_from(&ira->new_irb, &array_len_instruction->base, len_ptr); 16323 return ira->codegen->builtin_types.entry_usize; 16324 } else { 16325 ir_add_error_node(ira, array_len_instruction->base.source_node, 16326 buf_sprintf("type '%s' has no field 'len'", buf_ptr(&array_value->value.type->name))); 16327 return ira->codegen->builtin_types.entry_invalid; 16328 } 16329 } 16330 16331 static ZigType *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) { 16332 IrInstruction *value = ref_instruction->value->other; 16333 return ir_analyze_ref(ira, &ref_instruction->base, value, ref_instruction->is_const, ref_instruction->is_volatile); 16334 } 16335 16336 static ZigType *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, 16337 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) 16338 { 16339 Error err; 16340 assert(container_type->id == ZigTypeIdUnion); 16341 16342 if ((err = ensure_complete_type(ira->codegen, container_type))) 16343 return ira->codegen->builtin_types.entry_invalid; 16344 16345 if (instr_field_count != 1) { 16346 ir_add_error(ira, instruction, 16347 buf_sprintf("union initialization expects exactly one field")); 16348 return ira->codegen->builtin_types.entry_invalid; 16349 } 16350 16351 IrInstructionContainerInitFieldsField *field = &fields[0]; 16352 IrInstruction *field_value = field->value->other; 16353 if (type_is_invalid(field_value->value.type)) 16354 return ira->codegen->builtin_types.entry_invalid; 16355 16356 TypeUnionField *type_field = find_union_type_field(container_type, field->name); 16357 if (!type_field) { 16358 ir_add_error_node(ira, field->source_node, 16359 buf_sprintf("no member named '%s' in union '%s'", 16360 buf_ptr(field->name), buf_ptr(&container_type->name))); 16361 return ira->codegen->builtin_types.entry_invalid; 16362 } 16363 16364 if (type_is_invalid(type_field->type_entry)) 16365 return ira->codegen->builtin_types.entry_invalid; 16366 16367 IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); 16368 if (casted_field_value == ira->codegen->invalid_instruction) 16369 return ira->codegen->builtin_types.entry_invalid; 16370 16371 if ((err = type_ensure_zero_bits_known(ira->codegen, casted_field_value->value.type))) 16372 return ira->codegen->builtin_types.entry_invalid; 16373 16374 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope); 16375 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime || 16376 !type_has_bits(casted_field_value->value.type)) 16377 { 16378 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); 16379 if (!field_val) 16380 return ira->codegen->builtin_types.entry_invalid; 16381 16382 ConstExprValue *out_val = ir_build_const_from(ira, instruction); 16383 out_val->data.x_union.payload = field_val; 16384 out_val->data.x_union.tag = type_field->enum_field->value; 16385 16386 ConstParent *parent = get_const_val_parent(ira->codegen, field_val); 16387 if (parent != nullptr) { 16388 parent->id = ConstParentIdUnion; 16389 parent->data.p_union.union_val = out_val; 16390 } 16391 16392 return container_type; 16393 } 16394 16395 IrInstruction *new_instruction = ir_build_union_init_from(&ira->new_irb, instruction, 16396 container_type, type_field, casted_field_value); 16397 16398 ir_add_alloca(ira, new_instruction, container_type); 16399 return container_type; 16400 } 16401 16402 static ZigType *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, 16403 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) 16404 { 16405 Error err; 16406 if (container_type->id == ZigTypeIdUnion) { 16407 return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, fields); 16408 } 16409 if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { 16410 ir_add_error(ira, instruction, 16411 buf_sprintf("type '%s' does not support struct initialization syntax", 16412 buf_ptr(&container_type->name))); 16413 return ira->codegen->builtin_types.entry_invalid; 16414 } 16415 16416 if ((err = ensure_complete_type(ira->codegen, container_type))) 16417 return ira->codegen->builtin_types.entry_invalid; 16418 16419 size_t actual_field_count = container_type->data.structure.src_field_count; 16420 16421 IrInstruction *first_non_const_instruction = nullptr; 16422 16423 AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); 16424 16425 IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count); 16426 16427 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope); 16428 16429 ConstExprValue const_val = {}; 16430 const_val.special = ConstValSpecialStatic; 16431 const_val.type = container_type; 16432 const_val.data.x_struct.fields = create_const_vals(actual_field_count); 16433 for (size_t i = 0; i < instr_field_count; i += 1) { 16434 IrInstructionContainerInitFieldsField *field = &fields[i]; 16435 16436 IrInstruction *field_value = field->value->other; 16437 if (type_is_invalid(field_value->value.type)) 16438 return ira->codegen->builtin_types.entry_invalid; 16439 16440 TypeStructField *type_field = find_struct_type_field(container_type, field->name); 16441 if (!type_field) { 16442 ir_add_error_node(ira, field->source_node, 16443 buf_sprintf("no member named '%s' in struct '%s'", 16444 buf_ptr(field->name), buf_ptr(&container_type->name))); 16445 return ira->codegen->builtin_types.entry_invalid; 16446 } 16447 16448 if (type_is_invalid(type_field->type_entry)) 16449 return ira->codegen->builtin_types.entry_invalid; 16450 16451 IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); 16452 if (casted_field_value == ira->codegen->invalid_instruction) 16453 return ira->codegen->builtin_types.entry_invalid; 16454 16455 size_t field_index = type_field->src_index; 16456 AstNode *existing_assign_node = field_assign_nodes[field_index]; 16457 if (existing_assign_node) { 16458 ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field")); 16459 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); 16460 return ira->codegen->builtin_types.entry_invalid; 16461 } 16462 field_assign_nodes[field_index] = field->source_node; 16463 16464 new_fields[field_index].value = casted_field_value; 16465 new_fields[field_index].type_struct_field = type_field; 16466 16467 if (const_val.special == ConstValSpecialStatic) { 16468 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) { 16469 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); 16470 if (!field_val) 16471 return ira->codegen->builtin_types.entry_invalid; 16472 16473 copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true); 16474 } else { 16475 first_non_const_instruction = casted_field_value; 16476 const_val.special = ConstValSpecialRuntime; 16477 } 16478 } 16479 } 16480 16481 bool any_missing = false; 16482 for (size_t i = 0; i < actual_field_count; i += 1) { 16483 if (!field_assign_nodes[i]) { 16484 ir_add_error_node(ira, instruction->source_node, 16485 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name))); 16486 any_missing = true; 16487 } 16488 } 16489 if (any_missing) 16490 return ira->codegen->builtin_types.entry_invalid; 16491 16492 if (const_val.special == ConstValSpecialStatic) { 16493 ConstExprValue *out_val = ir_build_const_from(ira, instruction); 16494 *out_val = const_val; 16495 16496 for (size_t i = 0; i < instr_field_count; i += 1) { 16497 ConstExprValue *field_val = &out_val->data.x_struct.fields[i]; 16498 ConstParent *parent = get_const_val_parent(ira->codegen, field_val); 16499 if (parent != nullptr) { 16500 parent->id = ConstParentIdStruct; 16501 parent->data.p_struct.field_index = i; 16502 parent->data.p_struct.struct_val = out_val; 16503 } 16504 } 16505 16506 return container_type; 16507 } 16508 16509 if (is_comptime) { 16510 ir_add_error_node(ira, first_non_const_instruction->source_node, 16511 buf_sprintf("unable to evaluate constant expression")); 16512 return ira->codegen->builtin_types.entry_invalid; 16513 } 16514 16515 IrInstruction *new_instruction = ir_build_struct_init_from(&ira->new_irb, instruction, 16516 container_type, actual_field_count, new_fields); 16517 16518 ir_add_alloca(ira, new_instruction, container_type); 16519 return container_type; 16520 } 16521 16522 static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira, 16523 IrInstructionContainerInitList *instruction) 16524 { 16525 IrInstruction *container_type_value = instruction->container_type->other; 16526 if (type_is_invalid(container_type_value->value.type)) 16527 return ira->codegen->builtin_types.entry_invalid; 16528 16529 size_t elem_count = instruction->item_count; 16530 if (container_type_value->value.type->id == ZigTypeIdMetaType) { 16531 ZigType *container_type = ir_resolve_type(ira, container_type_value); 16532 if (type_is_invalid(container_type)) 16533 return ira->codegen->builtin_types.entry_invalid; 16534 16535 if (container_type->id == ZigTypeIdStruct && !is_slice(container_type) && elem_count == 0) { 16536 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 16537 0, nullptr); 16538 } else if (is_slice(container_type) || container_type->id == ZigTypeIdArray) { 16539 // array is same as slice init but we make a compile error if the length is wrong 16540 ZigType *child_type; 16541 if (container_type->id == ZigTypeIdArray) { 16542 child_type = container_type->data.array.child_type; 16543 if (container_type->data.array.len != elem_count) { 16544 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); 16545 16546 ir_add_error(ira, &instruction->base, 16547 buf_sprintf("expected %s literal, found %s literal", 16548 buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); 16549 return ira->codegen->builtin_types.entry_invalid; 16550 } 16551 } else { 16552 ZigType *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry; 16553 assert(pointer_type->id == ZigTypeIdPointer); 16554 child_type = pointer_type->data.pointer.child_type; 16555 } 16556 16557 ZigType *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count); 16558 16559 ConstExprValue const_val = {}; 16560 const_val.special = ConstValSpecialStatic; 16561 const_val.type = fixed_size_array_type; 16562 const_val.data.x_array.s_none.elements = create_const_vals(elem_count); 16563 16564 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); 16565 16566 IrInstruction **new_items = allocate<IrInstruction *>(elem_count); 16567 16568 IrInstruction *first_non_const_instruction = nullptr; 16569 16570 for (size_t i = 0; i < elem_count; i += 1) { 16571 IrInstruction *arg_value = instruction->items[i]->other; 16572 if (type_is_invalid(arg_value->value.type)) 16573 return ira->codegen->builtin_types.entry_invalid; 16574 16575 IrInstruction *casted_arg = ir_implicit_cast(ira, arg_value, child_type); 16576 if (casted_arg == ira->codegen->invalid_instruction) 16577 return ira->codegen->builtin_types.entry_invalid; 16578 16579 new_items[i] = casted_arg; 16580 16581 if (const_val.special == ConstValSpecialStatic) { 16582 if (is_comptime || casted_arg->value.special != ConstValSpecialRuntime) { 16583 ConstExprValue *elem_val = ir_resolve_const(ira, casted_arg, UndefBad); 16584 if (!elem_val) 16585 return ira->codegen->builtin_types.entry_invalid; 16586 16587 copy_const_val(&const_val.data.x_array.s_none.elements[i], elem_val, true); 16588 } else { 16589 first_non_const_instruction = casted_arg; 16590 const_val.special = ConstValSpecialRuntime; 16591 } 16592 } 16593 } 16594 16595 if (const_val.special == ConstValSpecialStatic) { 16596 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 16597 *out_val = const_val; 16598 for (size_t i = 0; i < elem_count; i += 1) { 16599 ConstExprValue *elem_val = &out_val->data.x_array.s_none.elements[i]; 16600 ConstParent *parent = get_const_val_parent(ira->codegen, elem_val); 16601 if (parent != nullptr) { 16602 parent->id = ConstParentIdArray; 16603 parent->data.p_array.array_val = out_val; 16604 parent->data.p_array.elem_index = i; 16605 } 16606 } 16607 return fixed_size_array_type; 16608 } 16609 16610 if (is_comptime) { 16611 ir_add_error_node(ira, first_non_const_instruction->source_node, 16612 buf_sprintf("unable to evaluate constant expression")); 16613 return ira->codegen->builtin_types.entry_invalid; 16614 } 16615 16616 IrInstruction *new_instruction = ir_build_container_init_list_from(&ira->new_irb, &instruction->base, 16617 container_type_value, elem_count, new_items); 16618 ir_add_alloca(ira, new_instruction, fixed_size_array_type); 16619 return fixed_size_array_type; 16620 } else if (container_type->id == ZigTypeIdVoid) { 16621 if (elem_count != 0) { 16622 ir_add_error_node(ira, instruction->base.source_node, 16623 buf_sprintf("void expression expects no arguments")); 16624 return ira->codegen->builtin_types.entry_invalid; 16625 } 16626 return ir_analyze_void(ira, &instruction->base); 16627 } else { 16628 ir_add_error_node(ira, instruction->base.source_node, 16629 buf_sprintf("type '%s' does not support array initialization", 16630 buf_ptr(&container_type->name))); 16631 return ira->codegen->builtin_types.entry_invalid; 16632 } 16633 } else { 16634 ir_add_error(ira, container_type_value, 16635 buf_sprintf("expected type, found '%s' value", buf_ptr(&container_type_value->value.type->name))); 16636 return ira->codegen->builtin_types.entry_invalid; 16637 } 16638 } 16639 16640 static ZigType *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, IrInstructionContainerInitFields *instruction) { 16641 IrInstruction *container_type_value = instruction->container_type->other; 16642 ZigType *container_type = ir_resolve_type(ira, container_type_value); 16643 if (type_is_invalid(container_type)) 16644 return ira->codegen->builtin_types.entry_invalid; 16645 16646 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 16647 instruction->field_count, instruction->fields); 16648 } 16649 16650 static ZigType *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_instruction, 16651 IrInstruction *target_type_value, bool is_max) 16652 { 16653 ZigType *target_type = ir_resolve_type(ira, target_type_value); 16654 if (type_is_invalid(target_type)) 16655 return ira->codegen->builtin_types.entry_invalid; 16656 switch (target_type->id) { 16657 case ZigTypeIdInvalid: 16658 zig_unreachable(); 16659 case ZigTypeIdInt: 16660 { 16661 ConstExprValue *out_val = ir_build_const_from(ira, source_instruction); 16662 eval_min_max_value(ira->codegen, target_type, out_val, is_max); 16663 return ira->codegen->builtin_types.entry_num_lit_int; 16664 } 16665 case ZigTypeIdBool: 16666 case ZigTypeIdVoid: 16667 { 16668 ConstExprValue *out_val = ir_build_const_from(ira, source_instruction); 16669 eval_min_max_value(ira->codegen, target_type, out_val, is_max); 16670 return target_type; 16671 } 16672 case ZigTypeIdEnum: 16673 case ZigTypeIdFloat: 16674 case ZigTypeIdMetaType: 16675 case ZigTypeIdUnreachable: 16676 case ZigTypeIdPointer: 16677 case ZigTypeIdPromise: 16678 case ZigTypeIdArray: 16679 case ZigTypeIdStruct: 16680 case ZigTypeIdComptimeFloat: 16681 case ZigTypeIdComptimeInt: 16682 case ZigTypeIdUndefined: 16683 case ZigTypeIdNull: 16684 case ZigTypeIdOptional: 16685 case ZigTypeIdErrorUnion: 16686 case ZigTypeIdErrorSet: 16687 case ZigTypeIdUnion: 16688 case ZigTypeIdFn: 16689 case ZigTypeIdNamespace: 16690 case ZigTypeIdBlock: 16691 case ZigTypeIdBoundFn: 16692 case ZigTypeIdArgTuple: 16693 case ZigTypeIdOpaque: 16694 { 16695 const char *err_format = is_max ? 16696 "no max value available for type '%s'" : 16697 "no min value available for type '%s'"; 16698 ir_add_error(ira, source_instruction, 16699 buf_sprintf(err_format, buf_ptr(&target_type->name))); 16700 return ira->codegen->builtin_types.entry_invalid; 16701 } 16702 } 16703 zig_unreachable(); 16704 } 16705 16706 static ZigType *ir_analyze_instruction_min_value(IrAnalyze *ira, 16707 IrInstructionMinValue *instruction) 16708 { 16709 return ir_analyze_min_max(ira, &instruction->base, instruction->value->other, false); 16710 } 16711 16712 static ZigType *ir_analyze_instruction_max_value(IrAnalyze *ira, 16713 IrInstructionMaxValue *instruction) 16714 { 16715 return ir_analyze_min_max(ira, &instruction->base, instruction->value->other, true); 16716 } 16717 16718 static ZigType *ir_analyze_instruction_compile_err(IrAnalyze *ira, 16719 IrInstructionCompileErr *instruction) 16720 { 16721 IrInstruction *msg_value = instruction->msg->other; 16722 Buf *msg_buf = ir_resolve_str(ira, msg_value); 16723 if (!msg_buf) 16724 return ira->codegen->builtin_types.entry_invalid; 16725 16726 ErrorMsg *msg = ir_add_error(ira, &instruction->base, msg_buf); 16727 size_t i = ira->codegen->tld_ref_source_node_stack.length; 16728 for (;;) { 16729 if (i == 0) 16730 break; 16731 i -= 1; 16732 AstNode *source_node = ira->codegen->tld_ref_source_node_stack.at(i); 16733 if (source_node) { 16734 add_error_note(ira->codegen, msg, source_node, 16735 buf_sprintf("referenced here")); 16736 } 16737 } 16738 16739 return ira->codegen->builtin_types.entry_invalid; 16740 } 16741 16742 static ZigType *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstructionCompileLog *instruction) { 16743 Buf buf = BUF_INIT; 16744 fprintf(stderr, "| "); 16745 for (size_t i = 0; i < instruction->msg_count; i += 1) { 16746 IrInstruction *msg = instruction->msg_list[i]->other; 16747 if (type_is_invalid(msg->value.type)) 16748 return ira->codegen->builtin_types.entry_invalid; 16749 buf_resize(&buf, 0); 16750 render_const_value(ira->codegen, &buf, &msg->value); 16751 const char *comma_str = (i != 0) ? ", " : ""; 16752 fprintf(stderr, "%s%s", comma_str, buf_ptr(&buf)); 16753 } 16754 fprintf(stderr, "\n"); 16755 16756 ir_add_error(ira, &instruction->base, buf_sprintf("found compile log statement")); 16757 16758 ir_build_const_from(ira, &instruction->base); 16759 return ira->codegen->builtin_types.entry_void; 16760 } 16761 16762 static ZigType *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstructionErrName *instruction) { 16763 IrInstruction *value = instruction->value->other; 16764 if (type_is_invalid(value->value.type)) 16765 return ira->codegen->builtin_types.entry_invalid; 16766 16767 IrInstruction *casted_value = ir_implicit_cast(ira, value, value->value.type); 16768 if (type_is_invalid(casted_value->value.type)) 16769 return ira->codegen->builtin_types.entry_invalid; 16770 16771 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 16772 true, false, PtrLenUnknown, get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0); 16773 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 16774 if (casted_value->value.special == ConstValSpecialStatic) { 16775 ErrorTableEntry *err = casted_value->value.data.x_err_set; 16776 if (!err->cached_error_name_val) { 16777 ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name); 16778 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); 16779 } 16780 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 16781 copy_const_val(out_val, err->cached_error_name_val, true); 16782 return str_type; 16783 } 16784 16785 ira->codegen->generate_error_name_table = true; 16786 ir_build_err_name_from(&ira->new_irb, &instruction->base, value); 16787 return str_type; 16788 } 16789 16790 static ZigType *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionTagName *instruction) { 16791 Error err; 16792 IrInstruction *target = instruction->target->other; 16793 if (type_is_invalid(target->value.type)) 16794 return ira->codegen->builtin_types.entry_invalid; 16795 16796 assert(target->value.type->id == ZigTypeIdEnum); 16797 16798 if (instr_is_comptime(target)) { 16799 if ((err = type_ensure_zero_bits_known(ira->codegen, target->value.type))) 16800 return ira->codegen->builtin_types.entry_invalid; 16801 TypeEnumField *field = find_enum_field_by_tag(target->value.type, &target->value.data.x_bigint); 16802 ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name); 16803 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 16804 init_const_slice(ira->codegen, out_val, array_val, 0, buf_len(field->name), true); 16805 return out_val->type; 16806 } 16807 16808 IrInstruction *result = ir_build_tag_name(&ira->new_irb, instruction->base.scope, 16809 instruction->base.source_node, target); 16810 ir_link_new_instruction(result, &instruction->base); 16811 ZigType *u8_ptr_type = get_pointer_to_type_extra( 16812 ira->codegen, ira->codegen->builtin_types.entry_u8, 16813 true, false, PtrLenUnknown, 16814 get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 16815 0, 0); 16816 result->value.type = get_slice_type(ira->codegen, u8_ptr_type); 16817 return result->value.type; 16818 } 16819 16820 static ZigType *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, 16821 IrInstructionFieldParentPtr *instruction) 16822 { 16823 Error err; 16824 IrInstruction *type_value = instruction->type_value->other; 16825 ZigType *container_type = ir_resolve_type(ira, type_value); 16826 if (type_is_invalid(container_type)) 16827 return ira->codegen->builtin_types.entry_invalid; 16828 16829 IrInstruction *field_name_value = instruction->field_name->other; 16830 Buf *field_name = ir_resolve_str(ira, field_name_value); 16831 if (!field_name) 16832 return ira->codegen->builtin_types.entry_invalid; 16833 16834 IrInstruction *field_ptr = instruction->field_ptr->other; 16835 if (type_is_invalid(field_ptr->value.type)) 16836 return ira->codegen->builtin_types.entry_invalid; 16837 16838 if (container_type->id != ZigTypeIdStruct) { 16839 ir_add_error(ira, type_value, 16840 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 16841 return ira->codegen->builtin_types.entry_invalid; 16842 } 16843 16844 if ((err = ensure_complete_type(ira->codegen, container_type))) 16845 return ira->codegen->builtin_types.entry_invalid; 16846 16847 TypeStructField *field = find_struct_type_field(container_type, field_name); 16848 if (field == nullptr) { 16849 ir_add_error(ira, field_name_value, 16850 buf_sprintf("struct '%s' has no field '%s'", 16851 buf_ptr(&container_type->name), buf_ptr(field_name))); 16852 return ira->codegen->builtin_types.entry_invalid; 16853 } 16854 16855 if (field_ptr->value.type->id != ZigTypeIdPointer) { 16856 ir_add_error(ira, field_ptr, 16857 buf_sprintf("expected pointer, found '%s'", buf_ptr(&field_ptr->value.type->name))); 16858 return ira->codegen->builtin_types.entry_invalid; 16859 } 16860 16861 bool is_packed = (container_type->data.structure.layout == ContainerLayoutPacked); 16862 uint32_t field_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 16863 uint32_t parent_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, container_type); 16864 16865 ZigType *field_ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, 16866 field_ptr->value.type->data.pointer.is_const, 16867 field_ptr->value.type->data.pointer.is_volatile, 16868 PtrLenSingle, 16869 field_ptr_align, 0, 0); 16870 IrInstruction *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type); 16871 if (type_is_invalid(casted_field_ptr->value.type)) 16872 return ira->codegen->builtin_types.entry_invalid; 16873 16874 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, container_type, 16875 casted_field_ptr->value.type->data.pointer.is_const, 16876 casted_field_ptr->value.type->data.pointer.is_volatile, 16877 PtrLenSingle, 16878 parent_ptr_align, 0, 0); 16879 16880 if (instr_is_comptime(casted_field_ptr)) { 16881 ConstExprValue *field_ptr_val = ir_resolve_const(ira, casted_field_ptr, UndefBad); 16882 if (!field_ptr_val) 16883 return ira->codegen->builtin_types.entry_invalid; 16884 16885 if (field_ptr_val->data.x_ptr.special != ConstPtrSpecialBaseStruct) { 16886 ir_add_error(ira, field_ptr, buf_sprintf("pointer value not based on parent struct")); 16887 return ira->codegen->builtin_types.entry_invalid; 16888 } 16889 16890 size_t ptr_field_index = field_ptr_val->data.x_ptr.data.base_struct.field_index; 16891 if (ptr_field_index != field->src_index) { 16892 ir_add_error(ira, &instruction->base, 16893 buf_sprintf("field '%s' has index %" ZIG_PRI_usize " but pointer value is index %" ZIG_PRI_usize " of struct '%s'", 16894 buf_ptr(field->name), field->src_index, 16895 ptr_field_index, buf_ptr(&container_type->name))); 16896 return ira->codegen->builtin_types.entry_invalid; 16897 } 16898 16899 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 16900 out_val->data.x_ptr.special = ConstPtrSpecialRef; 16901 out_val->data.x_ptr.data.ref.pointee = field_ptr_val->data.x_ptr.data.base_struct.struct_val; 16902 out_val->data.x_ptr.mut = field_ptr_val->data.x_ptr.mut; 16903 16904 return result_type; 16905 } 16906 16907 IrInstruction *result = ir_build_field_parent_ptr(&ira->new_irb, instruction->base.scope, 16908 instruction->base.source_node, type_value, field_name_value, casted_field_ptr, field); 16909 ir_link_new_instruction(result, &instruction->base); 16910 return result_type; 16911 } 16912 16913 static ZigType *ir_analyze_instruction_offset_of(IrAnalyze *ira, 16914 IrInstructionOffsetOf *instruction) 16915 { 16916 Error err; 16917 IrInstruction *type_value = instruction->type_value->other; 16918 ZigType *container_type = ir_resolve_type(ira, type_value); 16919 if (type_is_invalid(container_type)) 16920 return ira->codegen->builtin_types.entry_invalid; 16921 16922 if ((err = ensure_complete_type(ira->codegen, container_type))) 16923 return ira->codegen->builtin_types.entry_invalid; 16924 16925 IrInstruction *field_name_value = instruction->field_name->other; 16926 Buf *field_name = ir_resolve_str(ira, field_name_value); 16927 if (!field_name) 16928 return ira->codegen->builtin_types.entry_invalid; 16929 16930 if (container_type->id != ZigTypeIdStruct) { 16931 ir_add_error(ira, type_value, 16932 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 16933 return ira->codegen->builtin_types.entry_invalid; 16934 } 16935 16936 TypeStructField *field = find_struct_type_field(container_type, field_name); 16937 if (field == nullptr) { 16938 ir_add_error(ira, field_name_value, 16939 buf_sprintf("struct '%s' has no field '%s'", 16940 buf_ptr(&container_type->name), buf_ptr(field_name))); 16941 return ira->codegen->builtin_types.entry_invalid; 16942 } 16943 16944 if (!type_has_bits(field->type_entry)) { 16945 ir_add_error(ira, field_name_value, 16946 buf_sprintf("zero-bit field '%s' in struct '%s' has no offset", 16947 buf_ptr(field_name), buf_ptr(&container_type->name))); 16948 return ira->codegen->builtin_types.entry_invalid; 16949 } 16950 size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, container_type->type_ref, field->gen_index); 16951 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 16952 bigint_init_unsigned(&out_val->data.x_bigint, byte_offset); 16953 return ira->codegen->builtin_types.entry_num_lit_int; 16954 } 16955 16956 static void ensure_field_index(ZigType *type, const char *field_name, size_t index) 16957 { 16958 Buf *field_name_buf; 16959 16960 assert(type != nullptr && !type_is_invalid(type)); 16961 // Check for our field by creating a buffer in place then using the comma operator to free it so that we don't 16962 // leak memory in debug mode. 16963 assert(find_struct_type_field(type, field_name_buf = buf_create_from_str(field_name))->src_index == index && 16964 (buf_deinit(field_name_buf), true)); 16965 } 16966 16967 static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) { 16968 Error err; 16969 static ConstExprValue *type_info_var = nullptr; 16970 static ZigType *type_info_type = nullptr; 16971 if (type_info_var == nullptr) { 16972 type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); 16973 assert(type_info_var->type->id == ZigTypeIdMetaType); 16974 16975 assertNoError(ensure_complete_type(ira->codegen, type_info_var->data.x_type)); 16976 type_info_type = type_info_var->data.x_type; 16977 assert(type_info_type->id == ZigTypeIdUnion); 16978 } 16979 16980 if (type_name == nullptr && root == nullptr) 16981 return type_info_type; 16982 else if (type_name == nullptr) 16983 return root; 16984 16985 ZigType *root_type = (root == nullptr) ? type_info_type : root; 16986 16987 ScopeDecls *type_info_scope = get_container_scope(root_type); 16988 assert(type_info_scope != nullptr); 16989 16990 Buf field_name = BUF_INIT; 16991 buf_init_from_str(&field_name, type_name); 16992 auto entry = type_info_scope->decl_table.get(&field_name); 16993 buf_deinit(&field_name); 16994 16995 TldVar *tld = (TldVar *)entry; 16996 assert(tld->base.id == TldIdVar); 16997 16998 ZigVar *var = tld->var; 16999 17000 if ((err = ensure_complete_type(ira->codegen, var->value->type))) 17001 return ira->codegen->builtin_types.entry_invalid; 17002 assert(var->value->type->id == ZigTypeIdMetaType); 17003 return var->value->data.x_type; 17004 } 17005 17006 static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, ScopeDecls *decls_scope) { 17007 Error err; 17008 ZigType *type_info_definition_type = ir_type_info_get_type(ira, "Definition", nullptr); 17009 if ((err = ensure_complete_type(ira->codegen, type_info_definition_type))) 17010 return err; 17011 17012 ensure_field_index(type_info_definition_type, "name", 0); 17013 ensure_field_index(type_info_definition_type, "is_pub", 1); 17014 ensure_field_index(type_info_definition_type, "data", 2); 17015 17016 ZigType *type_info_definition_data_type = ir_type_info_get_type(ira, "Data", type_info_definition_type); 17017 if ((err = ensure_complete_type(ira->codegen, type_info_definition_data_type))) 17018 return err; 17019 17020 ZigType *type_info_fn_def_type = ir_type_info_get_type(ira, "FnDef", type_info_definition_data_type); 17021 if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_type))) 17022 return err; 17023 17024 ZigType *type_info_fn_def_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_def_type); 17025 if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_inline_type))) 17026 return err; 17027 17028 // Loop through our definitions once to figure out how many definitions we will generate info for. 17029 auto decl_it = decls_scope->decl_table.entry_iterator(); 17030 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; 17031 int definition_count = 0; 17032 17033 while ((curr_entry = decl_it.next()) != nullptr) { 17034 // If the definition is unresolved, force it to be resolved again. 17035 if (curr_entry->value->resolution == TldResolutionUnresolved) { 17036 resolve_top_level_decl(ira->codegen, curr_entry->value, false, curr_entry->value->source_node); 17037 if (curr_entry->value->resolution != TldResolutionOk) { 17038 return ErrorSemanticAnalyzeFail; 17039 } 17040 } 17041 17042 // Skip comptime blocks and test functions. 17043 if (curr_entry->value->id != TldIdCompTime) { 17044 if (curr_entry->value->id == TldIdFn) { 17045 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 17046 if (fn_entry->is_test) 17047 continue; 17048 } 17049 17050 definition_count += 1; 17051 } 17052 } 17053 17054 ConstExprValue *definition_array = create_const_vals(1); 17055 definition_array->special = ConstValSpecialStatic; 17056 definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count); 17057 definition_array->data.x_array.special = ConstArraySpecialNone; 17058 definition_array->data.x_array.s_none.parent.id = ConstParentIdNone; 17059 definition_array->data.x_array.s_none.elements = create_const_vals(definition_count); 17060 init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false); 17061 17062 // Loop through the definitions and generate info. 17063 decl_it = decls_scope->decl_table.entry_iterator(); 17064 curr_entry = nullptr; 17065 int definition_index = 0; 17066 while ((curr_entry = decl_it.next()) != nullptr) { 17067 // Skip comptime blocks and test functions. 17068 if (curr_entry->value->id == TldIdCompTime) { 17069 continue; 17070 } else if (curr_entry->value->id == TldIdFn) { 17071 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 17072 if (fn_entry->is_test) 17073 continue; 17074 } 17075 17076 ConstExprValue *definition_val = &definition_array->data.x_array.s_none.elements[definition_index]; 17077 17078 definition_val->special = ConstValSpecialStatic; 17079 definition_val->type = type_info_definition_type; 17080 17081 ConstExprValue *inner_fields = create_const_vals(3); 17082 ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key); 17083 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(curr_entry->key), true); 17084 inner_fields[1].special = ConstValSpecialStatic; 17085 inner_fields[1].type = ira->codegen->builtin_types.entry_bool; 17086 inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub; 17087 inner_fields[2].special = ConstValSpecialStatic; 17088 inner_fields[2].type = type_info_definition_data_type; 17089 inner_fields[2].data.x_union.parent.id = ConstParentIdStruct; 17090 inner_fields[2].data.x_union.parent.data.p_struct.struct_val = definition_val; 17091 inner_fields[2].data.x_union.parent.data.p_struct.field_index = 1; 17092 17093 switch (curr_entry->value->id) { 17094 case TldIdVar: 17095 { 17096 ZigVar *var = ((TldVar *)curr_entry->value)->var; 17097 if ((err = ensure_complete_type(ira->codegen, var->value->type))) 17098 return ErrorSemanticAnalyzeFail; 17099 17100 if (var->value->type->id == ZigTypeIdMetaType) 17101 { 17102 // We have a variable of type 'type', so it's actually a type definition. 17103 // 0: Data.Type: type 17104 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); 17105 inner_fields[2].data.x_union.payload = var->value; 17106 } 17107 else 17108 { 17109 // We have a variable of another type, so we store the type of the variable. 17110 // 1: Data.Var: type 17111 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 1); 17112 17113 ConstExprValue *payload = create_const_vals(1); 17114 payload->type = ira->codegen->builtin_types.entry_type; 17115 payload->data.x_type = var->value->type; 17116 17117 inner_fields[2].data.x_union.payload = payload; 17118 } 17119 17120 break; 17121 } 17122 case TldIdFn: 17123 { 17124 // 2: Data.Fn: Data.FnDef 17125 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2); 17126 17127 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 17128 assert(!fn_entry->is_test); 17129 17130 AstNodeFnProto *fn_node = (AstNodeFnProto *)(fn_entry->proto_node); 17131 17132 ConstExprValue *fn_def_val = create_const_vals(1); 17133 fn_def_val->special = ConstValSpecialStatic; 17134 fn_def_val->type = type_info_fn_def_type; 17135 fn_def_val->data.x_struct.parent.id = ConstParentIdUnion; 17136 fn_def_val->data.x_struct.parent.data.p_union.union_val = &inner_fields[2]; 17137 17138 ConstExprValue *fn_def_fields = create_const_vals(9); 17139 fn_def_val->data.x_struct.fields = fn_def_fields; 17140 17141 // fn_type: type 17142 ensure_field_index(fn_def_val->type, "fn_type", 0); 17143 fn_def_fields[0].special = ConstValSpecialStatic; 17144 fn_def_fields[0].type = ira->codegen->builtin_types.entry_type; 17145 fn_def_fields[0].data.x_type = fn_entry->type_entry; 17146 // inline_type: Data.FnDef.Inline 17147 ensure_field_index(fn_def_val->type, "inline_type", 1); 17148 fn_def_fields[1].special = ConstValSpecialStatic; 17149 fn_def_fields[1].type = type_info_fn_def_inline_type; 17150 bigint_init_unsigned(&fn_def_fields[1].data.x_enum_tag, fn_entry->fn_inline); 17151 // calling_convention: TypeInfo.CallingConvention 17152 ensure_field_index(fn_def_val->type, "calling_convention", 2); 17153 fn_def_fields[2].special = ConstValSpecialStatic; 17154 fn_def_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); 17155 bigint_init_unsigned(&fn_def_fields[2].data.x_enum_tag, fn_node->cc); 17156 // is_var_args: bool 17157 ensure_field_index(fn_def_val->type, "is_var_args", 3); 17158 bool is_varargs = fn_node->is_var_args; 17159 fn_def_fields[3].special = ConstValSpecialStatic; 17160 fn_def_fields[3].type = ira->codegen->builtin_types.entry_bool; 17161 fn_def_fields[3].data.x_bool = is_varargs; 17162 // is_extern: bool 17163 ensure_field_index(fn_def_val->type, "is_extern", 4); 17164 fn_def_fields[4].special = ConstValSpecialStatic; 17165 fn_def_fields[4].type = ira->codegen->builtin_types.entry_bool; 17166 fn_def_fields[4].data.x_bool = fn_node->is_extern; 17167 // is_export: bool 17168 ensure_field_index(fn_def_val->type, "is_export", 5); 17169 fn_def_fields[5].special = ConstValSpecialStatic; 17170 fn_def_fields[5].type = ira->codegen->builtin_types.entry_bool; 17171 fn_def_fields[5].data.x_bool = fn_node->is_export; 17172 // lib_name: ?[]const u8 17173 ensure_field_index(fn_def_val->type, "lib_name", 6); 17174 fn_def_fields[6].special = ConstValSpecialStatic; 17175 ZigType *u8_ptr = get_pointer_to_type_extra( 17176 ira->codegen, ira->codegen->builtin_types.entry_u8, 17177 true, false, PtrLenUnknown, 17178 get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 17179 0, 0); 17180 fn_def_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); 17181 if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) { 17182 fn_def_fields[6].data.x_optional = create_const_vals(1); 17183 ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name); 17184 init_const_slice(ira->codegen, fn_def_fields[6].data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true); 17185 } else { 17186 fn_def_fields[6].data.x_optional = nullptr; 17187 } 17188 // return_type: type 17189 ensure_field_index(fn_def_val->type, "return_type", 7); 17190 fn_def_fields[7].special = ConstValSpecialStatic; 17191 fn_def_fields[7].type = ira->codegen->builtin_types.entry_type; 17192 if (fn_entry->src_implicit_return_type != nullptr) 17193 fn_def_fields[7].data.x_type = fn_entry->src_implicit_return_type; 17194 else if (fn_entry->type_entry->data.fn.gen_return_type != nullptr) 17195 fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.gen_return_type; 17196 else 17197 fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; 17198 // arg_names: [][] const u8 17199 ensure_field_index(fn_def_val->type, "arg_names", 8); 17200 size_t fn_arg_count = fn_entry->variable_list.length; 17201 ConstExprValue *fn_arg_name_array = create_const_vals(1); 17202 fn_arg_name_array->special = ConstValSpecialStatic; 17203 fn_arg_name_array->type = get_array_type(ira->codegen, 17204 get_slice_type(ira->codegen, u8_ptr), fn_arg_count); 17205 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; 17206 fn_arg_name_array->data.x_array.s_none.parent.id = ConstParentIdNone; 17207 fn_arg_name_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count); 17208 17209 init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false); 17210 17211 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) 17212 { 17213 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); 17214 ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.s_none.elements[fn_arg_index]; 17215 ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name); 17216 init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true); 17217 fn_arg_name_val->data.x_struct.parent.id = ConstParentIdArray; 17218 fn_arg_name_val->data.x_struct.parent.data.p_array.array_val = fn_arg_name_array; 17219 fn_arg_name_val->data.x_struct.parent.data.p_array.elem_index = fn_arg_index; 17220 } 17221 17222 inner_fields[2].data.x_union.payload = fn_def_val; 17223 break; 17224 } 17225 case TldIdContainer: 17226 { 17227 ZigType *type_entry = ((TldContainer *)curr_entry->value)->type_entry; 17228 if ((err = ensure_complete_type(ira->codegen, type_entry))) 17229 return ErrorSemanticAnalyzeFail; 17230 17231 // This is a type. 17232 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); 17233 17234 ConstExprValue *payload = create_const_vals(1); 17235 payload->type = ira->codegen->builtin_types.entry_type; 17236 payload->data.x_type = type_entry; 17237 17238 inner_fields[2].data.x_union.payload = payload; 17239 17240 break; 17241 } 17242 default: 17243 zig_unreachable(); 17244 } 17245 17246 definition_val->data.x_struct.fields = inner_fields; 17247 definition_index++; 17248 } 17249 17250 assert(definition_index == definition_count); 17251 return ErrorNone; 17252 } 17253 17254 static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) { 17255 ZigType *attrs_type; 17256 uint32_t size_enum_index; 17257 if (is_slice(ptr_type_entry)) { 17258 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index].type_entry; 17259 size_enum_index = 2; 17260 } else if (ptr_type_entry->id == ZigTypeIdPointer) { 17261 attrs_type = ptr_type_entry; 17262 size_enum_index = (ptr_type_entry->data.pointer.ptr_len == PtrLenSingle) ? 0 : 1; 17263 } else { 17264 zig_unreachable(); 17265 } 17266 17267 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 17268 assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_type)); 17269 17270 ConstExprValue *result = create_const_vals(1); 17271 result->special = ConstValSpecialStatic; 17272 result->type = type_info_pointer_type; 17273 17274 ConstExprValue *fields = create_const_vals(5); 17275 result->data.x_struct.fields = fields; 17276 17277 // size: Size 17278 ensure_field_index(result->type, "size", 0); 17279 ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); 17280 assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_size_type)); 17281 fields[0].special = ConstValSpecialStatic; 17282 fields[0].type = type_info_pointer_size_type; 17283 bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index); 17284 17285 // is_const: bool 17286 ensure_field_index(result->type, "is_const", 1); 17287 fields[1].special = ConstValSpecialStatic; 17288 fields[1].type = ira->codegen->builtin_types.entry_bool; 17289 fields[1].data.x_bool = attrs_type->data.pointer.is_const; 17290 // is_volatile: bool 17291 ensure_field_index(result->type, "is_volatile", 2); 17292 fields[2].special = ConstValSpecialStatic; 17293 fields[2].type = ira->codegen->builtin_types.entry_bool; 17294 fields[2].data.x_bool = attrs_type->data.pointer.is_volatile; 17295 // alignment: u32 17296 ensure_field_index(result->type, "alignment", 3); 17297 fields[3].special = ConstValSpecialStatic; 17298 fields[3].type = get_int_type(ira->codegen, false, 29); 17299 bigint_init_unsigned(&fields[3].data.x_bigint, attrs_type->data.pointer.alignment); 17300 // child: type 17301 ensure_field_index(result->type, "child", 4); 17302 fields[4].special = ConstValSpecialStatic; 17303 fields[4].type = ira->codegen->builtin_types.entry_type; 17304 fields[4].data.x_type = attrs_type->data.pointer.child_type; 17305 17306 return result; 17307 }; 17308 17309 static void make_enum_field_val(IrAnalyze *ira, ConstExprValue *enum_field_val, TypeEnumField *enum_field, 17310 ZigType *type_info_enum_field_type) 17311 { 17312 enum_field_val->special = ConstValSpecialStatic; 17313 enum_field_val->type = type_info_enum_field_type; 17314 17315 ConstExprValue *inner_fields = create_const_vals(2); 17316 inner_fields[1].special = ConstValSpecialStatic; 17317 inner_fields[1].type = ira->codegen->builtin_types.entry_usize; 17318 17319 ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name); 17320 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(enum_field->name), true); 17321 17322 bigint_init_bigint(&inner_fields[1].data.x_bigint, &enum_field->value); 17323 17324 enum_field_val->data.x_struct.fields = inner_fields; 17325 } 17326 17327 static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstExprValue **out) { 17328 Error err; 17329 assert(type_entry != nullptr); 17330 assert(!type_is_invalid(type_entry)); 17331 17332 if ((err = ensure_complete_type(ira->codegen, type_entry))) 17333 return err; 17334 17335 if (type_entry == ira->codegen->builtin_types.entry_global_error_set) { 17336 zig_panic("TODO implement @typeInfo for global error set"); 17337 } 17338 17339 ConstExprValue *result = nullptr; 17340 switch (type_entry->id) 17341 { 17342 case ZigTypeIdInvalid: 17343 zig_unreachable(); 17344 case ZigTypeIdMetaType: 17345 case ZigTypeIdVoid: 17346 case ZigTypeIdBool: 17347 case ZigTypeIdUnreachable: 17348 case ZigTypeIdComptimeFloat: 17349 case ZigTypeIdComptimeInt: 17350 case ZigTypeIdUndefined: 17351 case ZigTypeIdNull: 17352 case ZigTypeIdNamespace: 17353 case ZigTypeIdBlock: 17354 case ZigTypeIdArgTuple: 17355 case ZigTypeIdOpaque: 17356 *out = nullptr; 17357 return ErrorNone; 17358 default: 17359 { 17360 // Lookup an available value in our cache. 17361 auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); 17362 if (entry != nullptr) { 17363 *out = entry->value; 17364 return ErrorNone; 17365 } 17366 17367 // Fallthrough if we don't find one. 17368 } 17369 case ZigTypeIdInt: 17370 { 17371 result = create_const_vals(1); 17372 result->special = ConstValSpecialStatic; 17373 result->type = ir_type_info_get_type(ira, "Int", nullptr); 17374 17375 ConstExprValue *fields = create_const_vals(2); 17376 result->data.x_struct.fields = fields; 17377 17378 // is_signed: bool 17379 ensure_field_index(result->type, "is_signed", 0); 17380 fields[0].special = ConstValSpecialStatic; 17381 fields[0].type = ira->codegen->builtin_types.entry_bool; 17382 fields[0].data.x_bool = type_entry->data.integral.is_signed; 17383 // bits: u8 17384 ensure_field_index(result->type, "bits", 1); 17385 fields[1].special = ConstValSpecialStatic; 17386 fields[1].type = ira->codegen->builtin_types.entry_u8; 17387 bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); 17388 17389 break; 17390 } 17391 case ZigTypeIdFloat: 17392 { 17393 result = create_const_vals(1); 17394 result->special = ConstValSpecialStatic; 17395 result->type = ir_type_info_get_type(ira, "Float", nullptr); 17396 17397 ConstExprValue *fields = create_const_vals(1); 17398 result->data.x_struct.fields = fields; 17399 17400 // bits: u8 17401 ensure_field_index(result->type, "bits", 0); 17402 fields[0].special = ConstValSpecialStatic; 17403 fields[0].type = ira->codegen->builtin_types.entry_u8; 17404 bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); 17405 17406 break; 17407 } 17408 case ZigTypeIdPointer: 17409 { 17410 result = create_ptr_like_type_info(ira, type_entry); 17411 break; 17412 } 17413 case ZigTypeIdArray: 17414 { 17415 result = create_const_vals(1); 17416 result->special = ConstValSpecialStatic; 17417 result->type = ir_type_info_get_type(ira, "Array", nullptr); 17418 17419 ConstExprValue *fields = create_const_vals(2); 17420 result->data.x_struct.fields = fields; 17421 17422 // len: usize 17423 ensure_field_index(result->type, "len", 0); 17424 fields[0].special = ConstValSpecialStatic; 17425 fields[0].type = ira->codegen->builtin_types.entry_usize; 17426 bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); 17427 // child: type 17428 ensure_field_index(result->type, "child", 1); 17429 fields[1].special = ConstValSpecialStatic; 17430 fields[1].type = ira->codegen->builtin_types.entry_type; 17431 fields[1].data.x_type = type_entry->data.array.child_type; 17432 17433 break; 17434 } 17435 case ZigTypeIdOptional: 17436 { 17437 result = create_const_vals(1); 17438 result->special = ConstValSpecialStatic; 17439 result->type = ir_type_info_get_type(ira, "Optional", nullptr); 17440 17441 ConstExprValue *fields = create_const_vals(1); 17442 result->data.x_struct.fields = fields; 17443 17444 // child: type 17445 ensure_field_index(result->type, "child", 0); 17446 fields[0].special = ConstValSpecialStatic; 17447 fields[0].type = ira->codegen->builtin_types.entry_type; 17448 fields[0].data.x_type = type_entry->data.maybe.child_type; 17449 17450 break; 17451 } 17452 case ZigTypeIdPromise: 17453 { 17454 result = create_const_vals(1); 17455 result->special = ConstValSpecialStatic; 17456 result->type = ir_type_info_get_type(ira, "Promise", nullptr); 17457 17458 ConstExprValue *fields = create_const_vals(1); 17459 result->data.x_struct.fields = fields; 17460 17461 // child: ?type 17462 ensure_field_index(result->type, "child", 0); 17463 fields[0].special = ConstValSpecialStatic; 17464 fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 17465 17466 if (type_entry->data.promise.result_type == nullptr) 17467 fields[0].data.x_optional = nullptr; 17468 else { 17469 ConstExprValue *child_type = create_const_vals(1); 17470 child_type->special = ConstValSpecialStatic; 17471 child_type->type = ira->codegen->builtin_types.entry_type; 17472 child_type->data.x_type = type_entry->data.promise.result_type; 17473 fields[0].data.x_optional = child_type; 17474 } 17475 17476 break; 17477 } 17478 case ZigTypeIdEnum: 17479 { 17480 result = create_const_vals(1); 17481 result->special = ConstValSpecialStatic; 17482 result->type = ir_type_info_get_type(ira, "Enum", nullptr); 17483 17484 ConstExprValue *fields = create_const_vals(4); 17485 result->data.x_struct.fields = fields; 17486 17487 // layout: ContainerLayout 17488 ensure_field_index(result->type, "layout", 0); 17489 fields[0].special = ConstValSpecialStatic; 17490 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 17491 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.enumeration.layout); 17492 // tag_type: type 17493 ensure_field_index(result->type, "tag_type", 1); 17494 fields[1].special = ConstValSpecialStatic; 17495 fields[1].type = ira->codegen->builtin_types.entry_type; 17496 fields[1].data.x_type = type_entry->data.enumeration.tag_int_type; 17497 // fields: []TypeInfo.EnumField 17498 ensure_field_index(result->type, "fields", 2); 17499 17500 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 17501 uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; 17502 17503 ConstExprValue *enum_field_array = create_const_vals(1); 17504 enum_field_array->special = ConstValSpecialStatic; 17505 enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count); 17506 enum_field_array->data.x_array.special = ConstArraySpecialNone; 17507 enum_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; 17508 enum_field_array->data.x_array.s_none.elements = create_const_vals(enum_field_count); 17509 17510 init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false); 17511 17512 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) 17513 { 17514 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; 17515 ConstExprValue *enum_field_val = &enum_field_array->data.x_array.s_none.elements[enum_field_index]; 17516 make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type); 17517 enum_field_val->data.x_struct.parent.id = ConstParentIdArray; 17518 enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array; 17519 enum_field_val->data.x_struct.parent.data.p_array.elem_index = enum_field_index; 17520 } 17521 // defs: []TypeInfo.Definition 17522 ensure_field_index(result->type, "defs", 3); 17523 if ((err = ir_make_type_info_defs(ira, &fields[3], type_entry->data.enumeration.decls_scope))) 17524 return err; 17525 17526 break; 17527 } 17528 case ZigTypeIdErrorSet: 17529 { 17530 result = create_const_vals(1); 17531 result->special = ConstValSpecialStatic; 17532 result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr); 17533 17534 ConstExprValue *fields = create_const_vals(1); 17535 result->data.x_struct.fields = fields; 17536 17537 // errors: []TypeInfo.Error 17538 ensure_field_index(result->type, "errors", 0); 17539 17540 ZigType *type_info_error_type = ir_type_info_get_type(ira, "Error", nullptr); 17541 uint32_t error_count = type_entry->data.error_set.err_count; 17542 ConstExprValue *error_array = create_const_vals(1); 17543 error_array->special = ConstValSpecialStatic; 17544 error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count); 17545 error_array->data.x_array.special = ConstArraySpecialNone; 17546 error_array->data.x_array.s_none.parent.id = ConstParentIdNone; 17547 error_array->data.x_array.s_none.elements = create_const_vals(error_count); 17548 17549 init_const_slice(ira->codegen, &fields[0], error_array, 0, error_count, false); 17550 for (uint32_t error_index = 0; error_index < error_count; error_index++) { 17551 ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; 17552 ConstExprValue *error_val = &error_array->data.x_array.s_none.elements[error_index]; 17553 17554 error_val->special = ConstValSpecialStatic; 17555 error_val->type = type_info_error_type; 17556 17557 ConstExprValue *inner_fields = create_const_vals(2); 17558 inner_fields[1].special = ConstValSpecialStatic; 17559 inner_fields[1].type = ira->codegen->builtin_types.entry_usize; 17560 17561 ConstExprValue *name = nullptr; 17562 if (error->cached_error_name_val != nullptr) 17563 name = error->cached_error_name_val; 17564 if (name == nullptr) 17565 name = create_const_str_lit(ira->codegen, &error->name); 17566 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(&error->name), true); 17567 bigint_init_unsigned(&inner_fields[1].data.x_bigint, error->value); 17568 17569 error_val->data.x_struct.fields = inner_fields; 17570 error_val->data.x_struct.parent.id = ConstParentIdArray; 17571 error_val->data.x_struct.parent.data.p_array.array_val = error_array; 17572 error_val->data.x_struct.parent.data.p_array.elem_index = error_index; 17573 } 17574 17575 break; 17576 } 17577 case ZigTypeIdErrorUnion: 17578 { 17579 result = create_const_vals(1); 17580 result->special = ConstValSpecialStatic; 17581 result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr); 17582 17583 ConstExprValue *fields = create_const_vals(2); 17584 result->data.x_struct.fields = fields; 17585 17586 // error_set: type 17587 ensure_field_index(result->type, "error_set", 0); 17588 fields[0].special = ConstValSpecialStatic; 17589 fields[0].type = ira->codegen->builtin_types.entry_type; 17590 fields[0].data.x_type = type_entry->data.error_union.err_set_type; 17591 17592 // payload: type 17593 ensure_field_index(result->type, "payload", 1); 17594 fields[1].special = ConstValSpecialStatic; 17595 fields[1].type = ira->codegen->builtin_types.entry_type; 17596 fields[1].data.x_type = type_entry->data.error_union.payload_type; 17597 17598 break; 17599 } 17600 case ZigTypeIdUnion: 17601 { 17602 result = create_const_vals(1); 17603 result->special = ConstValSpecialStatic; 17604 result->type = ir_type_info_get_type(ira, "Union", nullptr); 17605 17606 ConstExprValue *fields = create_const_vals(4); 17607 result->data.x_struct.fields = fields; 17608 17609 // layout: ContainerLayout 17610 ensure_field_index(result->type, "layout", 0); 17611 fields[0].special = ConstValSpecialStatic; 17612 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 17613 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout); 17614 // tag_type: ?type 17615 ensure_field_index(result->type, "tag_type", 1); 17616 fields[1].special = ConstValSpecialStatic; 17617 fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 17618 17619 AstNode *union_decl_node = type_entry->data.unionation.decl_node; 17620 if (union_decl_node->data.container_decl.auto_enum || 17621 union_decl_node->data.container_decl.init_arg_expr != nullptr) 17622 { 17623 ConstExprValue *tag_type = create_const_vals(1); 17624 tag_type->special = ConstValSpecialStatic; 17625 tag_type->type = ira->codegen->builtin_types.entry_type; 17626 tag_type->data.x_type = type_entry->data.unionation.tag_type; 17627 fields[1].data.x_optional = tag_type; 17628 } else { 17629 fields[1].data.x_optional = nullptr; 17630 } 17631 // fields: []TypeInfo.UnionField 17632 ensure_field_index(result->type, "fields", 2); 17633 17634 ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); 17635 uint32_t union_field_count = type_entry->data.unionation.src_field_count; 17636 17637 ConstExprValue *union_field_array = create_const_vals(1); 17638 union_field_array->special = ConstValSpecialStatic; 17639 union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count); 17640 union_field_array->data.x_array.special = ConstArraySpecialNone; 17641 union_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; 17642 union_field_array->data.x_array.s_none.elements = create_const_vals(union_field_count); 17643 17644 init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false); 17645 17646 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 17647 17648 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { 17649 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; 17650 ConstExprValue *union_field_val = &union_field_array->data.x_array.s_none.elements[union_field_index]; 17651 17652 union_field_val->special = ConstValSpecialStatic; 17653 union_field_val->type = type_info_union_field_type; 17654 17655 ConstExprValue *inner_fields = create_const_vals(3); 17656 inner_fields[1].special = ConstValSpecialStatic; 17657 inner_fields[1].type = get_optional_type(ira->codegen, type_info_enum_field_type); 17658 17659 if (fields[1].data.x_optional == nullptr) { 17660 inner_fields[1].data.x_optional = nullptr; 17661 } else { 17662 inner_fields[1].data.x_optional = create_const_vals(1); 17663 make_enum_field_val(ira, inner_fields[1].data.x_optional, union_field->enum_field, type_info_enum_field_type); 17664 } 17665 17666 inner_fields[2].special = ConstValSpecialStatic; 17667 inner_fields[2].type = ira->codegen->builtin_types.entry_type; 17668 inner_fields[2].data.x_type = union_field->type_entry; 17669 17670 ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name); 17671 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(union_field->name), true); 17672 17673 union_field_val->data.x_struct.fields = inner_fields; 17674 union_field_val->data.x_struct.parent.id = ConstParentIdArray; 17675 union_field_val->data.x_struct.parent.data.p_array.array_val = union_field_array; 17676 union_field_val->data.x_struct.parent.data.p_array.elem_index = union_field_index; 17677 } 17678 // defs: []TypeInfo.Definition 17679 ensure_field_index(result->type, "defs", 3); 17680 if ((err = ir_make_type_info_defs(ira, &fields[3], type_entry->data.unionation.decls_scope))) 17681 return err; 17682 17683 break; 17684 } 17685 case ZigTypeIdStruct: 17686 { 17687 if (type_entry->data.structure.is_slice) { 17688 result = create_ptr_like_type_info(ira, type_entry); 17689 break; 17690 } 17691 17692 result = create_const_vals(1); 17693 result->special = ConstValSpecialStatic; 17694 result->type = ir_type_info_get_type(ira, "Struct", nullptr); 17695 17696 ConstExprValue *fields = create_const_vals(3); 17697 result->data.x_struct.fields = fields; 17698 17699 // layout: ContainerLayout 17700 ensure_field_index(result->type, "layout", 0); 17701 fields[0].special = ConstValSpecialStatic; 17702 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 17703 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.structure.layout); 17704 // fields: []TypeInfo.StructField 17705 ensure_field_index(result->type, "fields", 1); 17706 17707 ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); 17708 uint32_t struct_field_count = type_entry->data.structure.src_field_count; 17709 17710 ConstExprValue *struct_field_array = create_const_vals(1); 17711 struct_field_array->special = ConstValSpecialStatic; 17712 struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count); 17713 struct_field_array->data.x_array.special = ConstArraySpecialNone; 17714 struct_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; 17715 struct_field_array->data.x_array.s_none.elements = create_const_vals(struct_field_count); 17716 17717 init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false); 17718 17719 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { 17720 TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index]; 17721 ConstExprValue *struct_field_val = &struct_field_array->data.x_array.s_none.elements[struct_field_index]; 17722 17723 struct_field_val->special = ConstValSpecialStatic; 17724 struct_field_val->type = type_info_struct_field_type; 17725 17726 ConstExprValue *inner_fields = create_const_vals(3); 17727 inner_fields[1].special = ConstValSpecialStatic; 17728 inner_fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_usize); 17729 17730 if (!type_has_bits(struct_field->type_entry)) { 17731 inner_fields[1].data.x_optional = nullptr; 17732 } else { 17733 size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, type_entry->type_ref, struct_field->gen_index); 17734 inner_fields[1].data.x_optional = create_const_vals(1); 17735 inner_fields[1].data.x_optional->special = ConstValSpecialStatic; 17736 inner_fields[1].data.x_optional->type = ira->codegen->builtin_types.entry_usize; 17737 bigint_init_unsigned(&inner_fields[1].data.x_optional->data.x_bigint, byte_offset); 17738 } 17739 17740 inner_fields[2].special = ConstValSpecialStatic; 17741 inner_fields[2].type = ira->codegen->builtin_types.entry_type; 17742 inner_fields[2].data.x_type = struct_field->type_entry; 17743 17744 ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name); 17745 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(struct_field->name), true); 17746 17747 struct_field_val->data.x_struct.fields = inner_fields; 17748 struct_field_val->data.x_struct.parent.id = ConstParentIdArray; 17749 struct_field_val->data.x_struct.parent.data.p_array.array_val = struct_field_array; 17750 struct_field_val->data.x_struct.parent.data.p_array.elem_index = struct_field_index; 17751 } 17752 // defs: []TypeInfo.Definition 17753 ensure_field_index(result->type, "defs", 2); 17754 if ((err = ir_make_type_info_defs(ira, &fields[2], type_entry->data.structure.decls_scope))) 17755 return err; 17756 17757 break; 17758 } 17759 case ZigTypeIdFn: 17760 { 17761 result = create_const_vals(1); 17762 result->special = ConstValSpecialStatic; 17763 result->type = ir_type_info_get_type(ira, "Fn", nullptr); 17764 17765 ConstExprValue *fields = create_const_vals(6); 17766 result->data.x_struct.fields = fields; 17767 17768 // calling_convention: TypeInfo.CallingConvention 17769 ensure_field_index(result->type, "calling_convention", 0); 17770 fields[0].special = ConstValSpecialStatic; 17771 fields[0].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); 17772 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); 17773 // is_generic: bool 17774 ensure_field_index(result->type, "is_generic", 1); 17775 bool is_generic = type_entry->data.fn.is_generic; 17776 fields[1].special = ConstValSpecialStatic; 17777 fields[1].type = ira->codegen->builtin_types.entry_bool; 17778 fields[1].data.x_bool = is_generic; 17779 // is_varargs: bool 17780 ensure_field_index(result->type, "is_var_args", 2); 17781 bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; 17782 fields[2].special = ConstValSpecialStatic; 17783 fields[2].type = ira->codegen->builtin_types.entry_bool; 17784 fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; 17785 // return_type: ?type 17786 ensure_field_index(result->type, "return_type", 3); 17787 fields[3].special = ConstValSpecialStatic; 17788 fields[3].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 17789 if (type_entry->data.fn.fn_type_id.return_type == nullptr) 17790 fields[3].data.x_optional = nullptr; 17791 else { 17792 ConstExprValue *return_type = create_const_vals(1); 17793 return_type->special = ConstValSpecialStatic; 17794 return_type->type = ira->codegen->builtin_types.entry_type; 17795 return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; 17796 fields[3].data.x_optional = return_type; 17797 } 17798 // async_allocator_type: type 17799 ensure_field_index(result->type, "async_allocator_type", 4); 17800 fields[4].special = ConstValSpecialStatic; 17801 fields[4].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 17802 if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr) 17803 fields[4].data.x_optional = nullptr; 17804 else { 17805 ConstExprValue *async_alloc_type = create_const_vals(1); 17806 async_alloc_type->special = ConstValSpecialStatic; 17807 async_alloc_type->type = ira->codegen->builtin_types.entry_type; 17808 async_alloc_type->data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type; 17809 fields[4].data.x_optional = async_alloc_type; 17810 } 17811 // args: []TypeInfo.FnArg 17812 ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); 17813 size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - 17814 (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); 17815 17816 ConstExprValue *fn_arg_array = create_const_vals(1); 17817 fn_arg_array->special = ConstValSpecialStatic; 17818 fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count); 17819 fn_arg_array->data.x_array.special = ConstArraySpecialNone; 17820 fn_arg_array->data.x_array.s_none.parent.id = ConstParentIdNone; 17821 fn_arg_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count); 17822 17823 init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false); 17824 17825 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) 17826 { 17827 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; 17828 ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.s_none.elements[fn_arg_index]; 17829 17830 fn_arg_val->special = ConstValSpecialStatic; 17831 fn_arg_val->type = type_info_fn_arg_type; 17832 17833 bool arg_is_generic = fn_param_info->type == nullptr; 17834 if (arg_is_generic) assert(is_generic); 17835 17836 ConstExprValue *inner_fields = create_const_vals(3); 17837 inner_fields[0].special = ConstValSpecialStatic; 17838 inner_fields[0].type = ira->codegen->builtin_types.entry_bool; 17839 inner_fields[0].data.x_bool = arg_is_generic; 17840 inner_fields[1].special = ConstValSpecialStatic; 17841 inner_fields[1].type = ira->codegen->builtin_types.entry_bool; 17842 inner_fields[1].data.x_bool = fn_param_info->is_noalias; 17843 inner_fields[2].special = ConstValSpecialStatic; 17844 inner_fields[2].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 17845 17846 if (arg_is_generic) 17847 inner_fields[2].data.x_optional = nullptr; 17848 else { 17849 ConstExprValue *arg_type = create_const_vals(1); 17850 arg_type->special = ConstValSpecialStatic; 17851 arg_type->type = ira->codegen->builtin_types.entry_type; 17852 arg_type->data.x_type = fn_param_info->type; 17853 inner_fields[2].data.x_optional = arg_type; 17854 } 17855 17856 fn_arg_val->data.x_struct.fields = inner_fields; 17857 fn_arg_val->data.x_struct.parent.id = ConstParentIdArray; 17858 fn_arg_val->data.x_struct.parent.data.p_array.array_val = fn_arg_array; 17859 fn_arg_val->data.x_struct.parent.data.p_array.elem_index = fn_arg_index; 17860 } 17861 17862 break; 17863 } 17864 case ZigTypeIdBoundFn: 17865 { 17866 ZigType *fn_type = type_entry->data.bound_fn.fn_type; 17867 assert(fn_type->id == ZigTypeIdFn); 17868 if ((err = ir_make_type_info_value(ira, fn_type, &result))) 17869 return err; 17870 17871 break; 17872 } 17873 } 17874 17875 assert(result != nullptr); 17876 ira->codegen->type_info_cache.put(type_entry, result); 17877 *out = result; 17878 return ErrorNone; 17879 } 17880 17881 static ZigType *ir_analyze_instruction_type_info(IrAnalyze *ira, 17882 IrInstructionTypeInfo *instruction) 17883 { 17884 Error err; 17885 IrInstruction *type_value = instruction->type_value->other; 17886 ZigType *type_entry = ir_resolve_type(ira, type_value); 17887 if (type_is_invalid(type_entry)) 17888 return ira->codegen->builtin_types.entry_invalid; 17889 17890 ZigType *result_type = ir_type_info_get_type(ira, nullptr, nullptr); 17891 17892 ConstExprValue *payload; 17893 if ((err = ir_make_type_info_value(ira, type_entry, &payload))) 17894 return ira->codegen->builtin_types.entry_invalid; 17895 17896 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 17897 out_val->type = result_type; 17898 bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry)); 17899 out_val->data.x_union.payload = payload; 17900 17901 if (payload != nullptr) { 17902 assert(payload->type->id == ZigTypeIdStruct); 17903 payload->data.x_struct.parent.id = ConstParentIdUnion; 17904 payload->data.x_struct.parent.data.p_union.union_val = out_val; 17905 } 17906 17907 return result_type; 17908 } 17909 17910 static ZigType *ir_analyze_instruction_type_id(IrAnalyze *ira, 17911 IrInstructionTypeId *instruction) 17912 { 17913 IrInstruction *type_value = instruction->type_value->other; 17914 ZigType *type_entry = ir_resolve_type(ira, type_value); 17915 if (type_is_invalid(type_entry)) 17916 return ira->codegen->builtin_types.entry_invalid; 17917 17918 ConstExprValue *var_value = get_builtin_value(ira->codegen, "TypeId"); 17919 assert(var_value->type->id == ZigTypeIdMetaType); 17920 ZigType *result_type = var_value->data.x_type; 17921 17922 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 17923 bigint_init_unsigned(&out_val->data.x_enum_tag, type_id_index(type_entry)); 17924 return result_type; 17925 } 17926 17927 static ZigType *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira, 17928 IrInstructionSetEvalBranchQuota *instruction) 17929 { 17930 if (ira->new_irb.exec->parent_exec != nullptr && !ira->new_irb.exec->is_generic_instantiation) { 17931 ir_add_error(ira, &instruction->base, 17932 buf_sprintf("@setEvalBranchQuota must be called from the top of the comptime stack")); 17933 return ira->codegen->builtin_types.entry_invalid; 17934 } 17935 17936 uint64_t new_quota; 17937 if (!ir_resolve_usize(ira, instruction->new_quota->other, &new_quota)) 17938 return ira->codegen->builtin_types.entry_invalid; 17939 17940 if (new_quota > ira->new_irb.exec->backward_branch_quota) { 17941 ira->new_irb.exec->backward_branch_quota = new_quota; 17942 } 17943 17944 ir_build_const_from(ira, &instruction->base); 17945 return ira->codegen->builtin_types.entry_void; 17946 } 17947 17948 static ZigType *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) { 17949 IrInstruction *type_value = instruction->type_value->other; 17950 ZigType *type_entry = ir_resolve_type(ira, type_value); 17951 if (type_is_invalid(type_entry)) 17952 return ira->codegen->builtin_types.entry_invalid; 17953 17954 if (!type_entry->cached_const_name_val) { 17955 type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, &type_entry->name); 17956 } 17957 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 17958 copy_const_val(out_val, type_entry->cached_const_name_val, true); 17959 return out_val->type; 17960 } 17961 17962 static ZigType *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCImport *instruction) { 17963 AstNode *node = instruction->base.source_node; 17964 assert(node->type == NodeTypeFnCallExpr); 17965 AstNode *block_node = node->data.fn_call_expr.params.at(0); 17966 17967 ScopeCImport *cimport_scope = create_cimport_scope(node, instruction->base.scope); 17968 17969 // Execute the C import block like an inline function 17970 ZigType *void_type = ira->codegen->builtin_types.entry_void; 17971 IrInstruction *result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, 17972 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, 17973 &cimport_scope->buf, block_node, nullptr, nullptr); 17974 if (type_is_invalid(result->value.type)) 17975 return ira->codegen->builtin_types.entry_invalid; 17976 17977 find_libc_include_path(ira->codegen); 17978 17979 ImportTableEntry *child_import = allocate<ImportTableEntry>(1); 17980 child_import->decls_scope = create_decls_scope(node, nullptr, nullptr, child_import); 17981 child_import->c_import_node = node; 17982 child_import->package = new_anonymous_package(); 17983 child_import->package->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package); 17984 child_import->package->package_table.put(buf_create_from_str("std"), ira->codegen->std_package); 17985 child_import->di_file = ZigLLVMCreateFile(ira->codegen->dbuilder, 17986 buf_ptr(buf_create_from_str("cimport.h")), buf_ptr(buf_create_from_str("."))); 17987 17988 ZigList<ErrorMsg *> errors = {0}; 17989 17990 int err; 17991 if ((err = parse_h_buf(child_import, &errors, &cimport_scope->buf, ira->codegen, node))) { 17992 if (err != ErrorCCompileErrors) { 17993 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); 17994 return ira->codegen->builtin_types.entry_invalid; 17995 } 17996 } 17997 17998 if (errors.length > 0) { 17999 ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed")); 18000 for (size_t i = 0; i < errors.length; i += 1) { 18001 ErrorMsg *err_msg = errors.at(i); 18002 err_msg_add_note(parent_err_msg, err_msg); 18003 } 18004 18005 return ira->codegen->builtin_types.entry_invalid; 18006 } 18007 18008 if (ira->codegen->verbose_cimport) { 18009 fprintf(stderr, "\nC imports:\n"); 18010 fprintf(stderr, "-----------\n"); 18011 ast_render(ira->codegen, stderr, child_import->root, 4); 18012 } 18013 18014 scan_decls(ira->codegen, child_import->decls_scope, child_import->root); 18015 18016 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 18017 out_val->data.x_import = child_import; 18018 return ira->codegen->builtin_types.entry_namespace; 18019 } 18020 18021 static ZigType *ir_analyze_instruction_c_include(IrAnalyze *ira, IrInstructionCInclude *instruction) { 18022 IrInstruction *name_value = instruction->name->other; 18023 if (type_is_invalid(name_value->value.type)) 18024 return ira->codegen->builtin_types.entry_invalid; 18025 18026 Buf *include_name = ir_resolve_str(ira, name_value); 18027 if (!include_name) 18028 return ira->codegen->builtin_types.entry_invalid; 18029 18030 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 18031 // We check for this error in pass1 18032 assert(c_import_buf); 18033 18034 buf_appendf(c_import_buf, "#include <%s>\n", buf_ptr(include_name)); 18035 18036 ir_build_const_from(ira, &instruction->base); 18037 return ira->codegen->builtin_types.entry_void; 18038 } 18039 18040 static ZigType *ir_analyze_instruction_c_define(IrAnalyze *ira, IrInstructionCDefine *instruction) { 18041 IrInstruction *name = instruction->name->other; 18042 if (type_is_invalid(name->value.type)) 18043 return ira->codegen->builtin_types.entry_invalid; 18044 18045 Buf *define_name = ir_resolve_str(ira, name); 18046 if (!define_name) 18047 return ira->codegen->builtin_types.entry_invalid; 18048 18049 IrInstruction *value = instruction->value->other; 18050 if (type_is_invalid(value->value.type)) 18051 return ira->codegen->builtin_types.entry_invalid; 18052 18053 Buf *define_value = ir_resolve_str(ira, value); 18054 if (!define_value) 18055 return ira->codegen->builtin_types.entry_invalid; 18056 18057 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 18058 // We check for this error in pass1 18059 assert(c_import_buf); 18060 18061 buf_appendf(c_import_buf, "#define %s %s\n", buf_ptr(define_name), buf_ptr(define_value)); 18062 18063 ir_build_const_from(ira, &instruction->base); 18064 return ira->codegen->builtin_types.entry_void; 18065 } 18066 18067 static ZigType *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstructionCUndef *instruction) { 18068 IrInstruction *name = instruction->name->other; 18069 if (type_is_invalid(name->value.type)) 18070 return ira->codegen->builtin_types.entry_invalid; 18071 18072 Buf *undef_name = ir_resolve_str(ira, name); 18073 if (!undef_name) 18074 return ira->codegen->builtin_types.entry_invalid; 18075 18076 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 18077 // We check for this error in pass1 18078 assert(c_import_buf); 18079 18080 buf_appendf(c_import_buf, "#undef %s\n", buf_ptr(undef_name)); 18081 18082 ir_build_const_from(ira, &instruction->base); 18083 return ira->codegen->builtin_types.entry_void; 18084 } 18085 18086 static ZigType *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionEmbedFile *instruction) { 18087 IrInstruction *name = instruction->name->other; 18088 if (type_is_invalid(name->value.type)) 18089 return ira->codegen->builtin_types.entry_invalid; 18090 18091 Buf *rel_file_path = ir_resolve_str(ira, name); 18092 if (!rel_file_path) 18093 return ira->codegen->builtin_types.entry_invalid; 18094 18095 ImportTableEntry *import = get_scope_import(instruction->base.scope); 18096 // figure out absolute path to resource 18097 Buf source_dir_path = BUF_INIT; 18098 os_path_dirname(import->path, &source_dir_path); 18099 18100 Buf *resolve_paths[] = { 18101 &source_dir_path, 18102 rel_file_path, 18103 }; 18104 Buf file_path = os_path_resolve(resolve_paths, 2); 18105 18106 // load from file system into const expr 18107 Buf *file_contents = buf_alloc(); 18108 int err; 18109 if ((err = os_fetch_file_path(&file_path, file_contents, false))) { 18110 if (err == ErrorFileNotFound) { 18111 ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(&file_path))); 18112 return ira->codegen->builtin_types.entry_invalid; 18113 } else { 18114 ir_add_error(ira, instruction->name, buf_sprintf("unable to open '%s': %s", buf_ptr(&file_path), err_str(err))); 18115 return ira->codegen->builtin_types.entry_invalid; 18116 } 18117 } 18118 18119 // TODO add dependency on the file we embedded so that we know if it changes 18120 // we'll have to invalidate the cache 18121 18122 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 18123 init_const_str_lit(ira->codegen, out_val, file_contents); 18124 18125 return get_array_type(ira->codegen, ira->codegen->builtin_types.entry_u8, buf_len(file_contents)); 18126 } 18127 18128 static ZigType *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructionCmpxchg *instruction) { 18129 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->other); 18130 if (type_is_invalid(operand_type)) 18131 return ira->codegen->builtin_types.entry_invalid; 18132 18133 IrInstruction *ptr = instruction->ptr->other; 18134 if (type_is_invalid(ptr->value.type)) 18135 return ira->codegen->builtin_types.entry_invalid; 18136 18137 // TODO let this be volatile 18138 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 18139 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr, ptr_type); 18140 if (type_is_invalid(casted_ptr->value.type)) 18141 return ira->codegen->builtin_types.entry_invalid; 18142 18143 IrInstruction *cmp_value = instruction->cmp_value->other; 18144 if (type_is_invalid(cmp_value->value.type)) 18145 return ira->codegen->builtin_types.entry_invalid; 18146 18147 IrInstruction *new_value = instruction->new_value->other; 18148 if (type_is_invalid(new_value->value.type)) 18149 return ira->codegen->builtin_types.entry_invalid; 18150 18151 IrInstruction *success_order_value = instruction->success_order_value->other; 18152 if (type_is_invalid(success_order_value->value.type)) 18153 return ira->codegen->builtin_types.entry_invalid; 18154 18155 AtomicOrder success_order; 18156 if (!ir_resolve_atomic_order(ira, success_order_value, &success_order)) 18157 return ira->codegen->builtin_types.entry_invalid; 18158 18159 IrInstruction *failure_order_value = instruction->failure_order_value->other; 18160 if (type_is_invalid(failure_order_value->value.type)) 18161 return ira->codegen->builtin_types.entry_invalid; 18162 18163 AtomicOrder failure_order; 18164 if (!ir_resolve_atomic_order(ira, failure_order_value, &failure_order)) 18165 return ira->codegen->builtin_types.entry_invalid; 18166 18167 IrInstruction *casted_cmp_value = ir_implicit_cast(ira, cmp_value, operand_type); 18168 if (type_is_invalid(casted_cmp_value->value.type)) 18169 return ira->codegen->builtin_types.entry_invalid; 18170 18171 IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, operand_type); 18172 if (type_is_invalid(casted_new_value->value.type)) 18173 return ira->codegen->builtin_types.entry_invalid; 18174 18175 if (success_order < AtomicOrderMonotonic) { 18176 ir_add_error(ira, success_order_value, 18177 buf_sprintf("success atomic ordering must be Monotonic or stricter")); 18178 return ira->codegen->builtin_types.entry_invalid; 18179 } 18180 if (failure_order < AtomicOrderMonotonic) { 18181 ir_add_error(ira, failure_order_value, 18182 buf_sprintf("failure atomic ordering must be Monotonic or stricter")); 18183 return ira->codegen->builtin_types.entry_invalid; 18184 } 18185 if (failure_order > success_order) { 18186 ir_add_error(ira, failure_order_value, 18187 buf_sprintf("failure atomic ordering must be no stricter than success")); 18188 return ira->codegen->builtin_types.entry_invalid; 18189 } 18190 if (failure_order == AtomicOrderRelease || failure_order == AtomicOrderAcqRel) { 18191 ir_add_error(ira, failure_order_value, 18192 buf_sprintf("failure atomic ordering must not be Release or AcqRel")); 18193 return ira->codegen->builtin_types.entry_invalid; 18194 } 18195 18196 if (instr_is_comptime(casted_ptr) && instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) { 18197 zig_panic("TODO compile-time execution of cmpxchg"); 18198 } 18199 18200 IrInstruction *result = ir_build_cmpxchg(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 18201 nullptr, casted_ptr, casted_cmp_value, casted_new_value, nullptr, nullptr, instruction->is_weak, 18202 operand_type, success_order, failure_order); 18203 result->value.type = get_optional_type(ira->codegen, operand_type); 18204 ir_link_new_instruction(result, &instruction->base); 18205 ir_add_alloca(ira, result, result->value.type); 18206 return result->value.type; 18207 } 18208 18209 static ZigType *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { 18210 IrInstruction *order_value = instruction->order_value->other; 18211 if (type_is_invalid(order_value->value.type)) 18212 return ira->codegen->builtin_types.entry_invalid; 18213 18214 AtomicOrder order; 18215 if (!ir_resolve_atomic_order(ira, order_value, &order)) 18216 return ira->codegen->builtin_types.entry_invalid; 18217 18218 ir_build_fence_from(&ira->new_irb, &instruction->base, order_value, order); 18219 return ira->codegen->builtin_types.entry_void; 18220 } 18221 18222 static ZigType *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstructionTruncate *instruction) { 18223 IrInstruction *dest_type_value = instruction->dest_type->other; 18224 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 18225 if (type_is_invalid(dest_type)) 18226 return ira->codegen->builtin_types.entry_invalid; 18227 18228 if (dest_type->id != ZigTypeIdInt && 18229 dest_type->id != ZigTypeIdComptimeInt) 18230 { 18231 ir_add_error(ira, dest_type_value, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 18232 return ira->codegen->builtin_types.entry_invalid; 18233 } 18234 18235 IrInstruction *target = instruction->target->other; 18236 ZigType *src_type = target->value.type; 18237 if (type_is_invalid(src_type)) 18238 return ira->codegen->builtin_types.entry_invalid; 18239 18240 if (src_type->id != ZigTypeIdInt && 18241 src_type->id != ZigTypeIdComptimeInt) 18242 { 18243 ir_add_error(ira, target, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name))); 18244 return ira->codegen->builtin_types.entry_invalid; 18245 } 18246 18247 if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { 18248 const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; 18249 ir_add_error(ira, target, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); 18250 return ira->codegen->builtin_types.entry_invalid; 18251 } else if (src_type->data.integral.bit_count < dest_type->data.integral.bit_count) { 18252 ir_add_error(ira, target, buf_sprintf("type '%s' has fewer bits than destination type '%s'", 18253 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 18254 return ira->codegen->builtin_types.entry_invalid; 18255 } 18256 18257 if (target->value.special == ConstValSpecialStatic) { 18258 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 18259 bigint_truncate(&out_val->data.x_bigint, &target->value.data.x_bigint, dest_type->data.integral.bit_count, 18260 dest_type->data.integral.is_signed); 18261 return dest_type; 18262 } 18263 18264 IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope, 18265 instruction->base.source_node, dest_type_value, target); 18266 ir_link_new_instruction(new_instruction, &instruction->base); 18267 return dest_type; 18268 } 18269 18270 static ZigType *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstructionIntCast *instruction) { 18271 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->other); 18272 if (type_is_invalid(dest_type)) 18273 return ira->codegen->builtin_types.entry_invalid; 18274 18275 if (dest_type->id != ZigTypeIdInt) { 18276 ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 18277 return ira->codegen->builtin_types.entry_invalid; 18278 } 18279 18280 IrInstruction *target = instruction->target->other; 18281 if (type_is_invalid(target->value.type)) 18282 return ira->codegen->builtin_types.entry_invalid; 18283 18284 if (target->value.type->id == ZigTypeIdComptimeInt) { 18285 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { 18286 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, 18287 CastOpNumLitToConcrete, false); 18288 if (type_is_invalid(result->value.type)) 18289 return ira->codegen->builtin_types.entry_invalid; 18290 ir_link_new_instruction(result, &instruction->base); 18291 return dest_type; 18292 } else { 18293 return ira->codegen->builtin_types.entry_invalid; 18294 } 18295 } 18296 18297 if (target->value.type->id != ZigTypeIdInt) { 18298 ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", 18299 buf_ptr(&target->value.type->name))); 18300 return ira->codegen->builtin_types.entry_invalid; 18301 } 18302 18303 IrInstruction *result = ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); 18304 if (type_is_invalid(result->value.type)) 18305 return ira->codegen->builtin_types.entry_invalid; 18306 18307 ir_link_new_instruction(result, &instruction->base); 18308 return dest_type; 18309 } 18310 18311 static ZigType *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstructionFloatCast *instruction) { 18312 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->other); 18313 if (type_is_invalid(dest_type)) 18314 return ira->codegen->builtin_types.entry_invalid; 18315 18316 if (dest_type->id != ZigTypeIdFloat) { 18317 ir_add_error(ira, instruction->dest_type, 18318 buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); 18319 return ira->codegen->builtin_types.entry_invalid; 18320 } 18321 18322 IrInstruction *target = instruction->target->other; 18323 if (type_is_invalid(target->value.type)) 18324 return ira->codegen->builtin_types.entry_invalid; 18325 18326 if (target->value.type->id == ZigTypeIdComptimeInt || 18327 target->value.type->id == ZigTypeIdComptimeFloat) 18328 { 18329 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { 18330 CastOp op; 18331 if (target->value.type->id == ZigTypeIdComptimeInt) { 18332 op = CastOpIntToFloat; 18333 } else { 18334 op = CastOpNumLitToConcrete; 18335 } 18336 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false); 18337 if (type_is_invalid(result->value.type)) 18338 return ira->codegen->builtin_types.entry_invalid; 18339 ir_link_new_instruction(result, &instruction->base); 18340 return dest_type; 18341 } else { 18342 return ira->codegen->builtin_types.entry_invalid; 18343 } 18344 } 18345 18346 if (target->value.type->id != ZigTypeIdFloat) { 18347 ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", 18348 buf_ptr(&target->value.type->name))); 18349 return ira->codegen->builtin_types.entry_invalid; 18350 } 18351 18352 IrInstruction *result = ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); 18353 if (type_is_invalid(result->value.type)) 18354 return ira->codegen->builtin_types.entry_invalid; 18355 ir_link_new_instruction(result, &instruction->base); 18356 return dest_type; 18357 } 18358 18359 static ZigType *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstructionErrSetCast *instruction) { 18360 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->other); 18361 if (type_is_invalid(dest_type)) 18362 return ira->codegen->builtin_types.entry_invalid; 18363 18364 if (dest_type->id != ZigTypeIdErrorSet) { 18365 ir_add_error(ira, instruction->dest_type, 18366 buf_sprintf("expected error set type, found '%s'", buf_ptr(&dest_type->name))); 18367 return ira->codegen->builtin_types.entry_invalid; 18368 } 18369 18370 IrInstruction *target = instruction->target->other; 18371 if (type_is_invalid(target->value.type)) 18372 return ira->codegen->builtin_types.entry_invalid; 18373 18374 if (target->value.type->id != ZigTypeIdErrorSet) { 18375 ir_add_error(ira, instruction->target, 18376 buf_sprintf("expected error set type, found '%s'", buf_ptr(&target->value.type->name))); 18377 return ira->codegen->builtin_types.entry_invalid; 18378 } 18379 18380 IrInstruction *result = ir_analyze_err_set_cast(ira, &instruction->base, target, dest_type); 18381 if (type_is_invalid(result->value.type)) 18382 return ira->codegen->builtin_types.entry_invalid; 18383 ir_link_new_instruction(result, &instruction->base); 18384 return dest_type; 18385 } 18386 18387 static ZigType *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstructionFromBytes *instruction) { 18388 ZigType *dest_child_type = ir_resolve_type(ira, instruction->dest_child_type->other); 18389 if (type_is_invalid(dest_child_type)) 18390 return ira->codegen->builtin_types.entry_invalid; 18391 18392 IrInstruction *target = instruction->target->other; 18393 if (type_is_invalid(target->value.type)) 18394 return ira->codegen->builtin_types.entry_invalid; 18395 18396 bool src_ptr_const; 18397 bool src_ptr_volatile; 18398 uint32_t src_ptr_align; 18399 if (target->value.type->id == ZigTypeIdPointer) { 18400 src_ptr_const = target->value.type->data.pointer.is_const; 18401 src_ptr_volatile = target->value.type->data.pointer.is_volatile; 18402 src_ptr_align = target->value.type->data.pointer.alignment; 18403 } else if (is_slice(target->value.type)) { 18404 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry; 18405 src_ptr_const = src_ptr_type->data.pointer.is_const; 18406 src_ptr_volatile = src_ptr_type->data.pointer.is_volatile; 18407 src_ptr_align = src_ptr_type->data.pointer.alignment; 18408 } else { 18409 src_ptr_const = true; 18410 src_ptr_volatile = false; 18411 src_ptr_align = get_abi_alignment(ira->codegen, target->value.type); 18412 } 18413 18414 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_child_type, 18415 src_ptr_const, src_ptr_volatile, PtrLenUnknown, 18416 src_ptr_align, 0, 0); 18417 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); 18418 18419 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 18420 src_ptr_const, src_ptr_volatile, PtrLenUnknown, 18421 src_ptr_align, 0, 0); 18422 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 18423 18424 IrInstruction *casted_value = ir_implicit_cast(ira, target, u8_slice); 18425 if (type_is_invalid(casted_value->value.type)) 18426 return ira->codegen->builtin_types.entry_invalid; 18427 18428 bool have_known_len = false; 18429 uint64_t known_len; 18430 18431 if (instr_is_comptime(casted_value)) { 18432 ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad); 18433 if (!val) 18434 return ira->codegen->builtin_types.entry_invalid; 18435 18436 ConstExprValue *len_val = &val->data.x_struct.fields[slice_len_index]; 18437 if (value_is_comptime(len_val)) { 18438 known_len = bigint_as_unsigned(&len_val->data.x_bigint); 18439 have_known_len = true; 18440 } 18441 } 18442 18443 if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) { 18444 known_len = casted_value->value.data.rh_slice.len; 18445 have_known_len = true; 18446 } 18447 18448 if (have_known_len) { 18449 uint64_t child_type_size = type_size(ira->codegen, dest_child_type); 18450 uint64_t remainder = known_len % child_type_size; 18451 if (remainder != 0) { 18452 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 18453 buf_sprintf("unable to convert [%" ZIG_PRI_u64 "]u8 to %s: size mismatch", 18454 known_len, buf_ptr(&dest_slice_type->name))); 18455 add_error_note(ira->codegen, msg, instruction->dest_child_type->source_node, 18456 buf_sprintf("%s has size %" ZIG_PRI_u64 "; remaining bytes: %" ZIG_PRI_u64, 18457 buf_ptr(&dest_child_type->name), child_type_size, remainder)); 18458 return ira->codegen->builtin_types.entry_invalid; 18459 } 18460 } 18461 18462 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, casted_value, dest_slice_type, CastOpResizeSlice, true); 18463 ir_link_new_instruction(result, &instruction->base); 18464 return dest_slice_type; 18465 } 18466 18467 static ZigType *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { 18468 IrInstruction *target = instruction->target->other; 18469 if (type_is_invalid(target->value.type)) 18470 return ira->codegen->builtin_types.entry_invalid; 18471 18472 if (!is_slice(target->value.type)) { 18473 ir_add_error(ira, instruction->target, 18474 buf_sprintf("expected slice, found '%s'", buf_ptr(&target->value.type->name))); 18475 return ira->codegen->builtin_types.entry_invalid; 18476 } 18477 18478 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry; 18479 18480 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 18481 src_ptr_type->data.pointer.is_const, src_ptr_type->data.pointer.is_volatile, PtrLenUnknown, 18482 src_ptr_type->data.pointer.alignment, 0, 0); 18483 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); 18484 18485 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_slice_type, CastOpResizeSlice, true); 18486 ir_link_new_instruction(result, &instruction->base); 18487 return dest_slice_type; 18488 } 18489 18490 static ZigType *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) { 18491 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->other); 18492 if (type_is_invalid(dest_type)) 18493 return ira->codegen->builtin_types.entry_invalid; 18494 18495 IrInstruction *target = instruction->target->other; 18496 if (type_is_invalid(target->value.type)) 18497 return ira->codegen->builtin_types.entry_invalid; 18498 18499 if (target->value.type->id != ZigTypeIdInt && target->value.type->id != ZigTypeIdComptimeInt) { 18500 ir_add_error(ira, instruction->target, buf_sprintf("expected int type, found '%s'", 18501 buf_ptr(&target->value.type->name))); 18502 return ira->codegen->builtin_types.entry_invalid; 18503 } 18504 18505 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false); 18506 ir_link_new_instruction(result, &instruction->base); 18507 return dest_type; 18508 } 18509 18510 static ZigType *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { 18511 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->other); 18512 if (type_is_invalid(dest_type)) 18513 return ira->codegen->builtin_types.entry_invalid; 18514 18515 IrInstruction *target = instruction->target->other; 18516 if (type_is_invalid(target->value.type)) 18517 return ira->codegen->builtin_types.entry_invalid; 18518 18519 if (target->value.type->id == ZigTypeIdComptimeInt) { 18520 IrInstruction *casted_value = ir_implicit_cast(ira, target, dest_type); 18521 if (type_is_invalid(casted_value->value.type)) 18522 return ira->codegen->builtin_types.entry_invalid; 18523 ir_link_new_instruction(casted_value, &instruction->base); 18524 return casted_value->value.type; 18525 } 18526 18527 if (target->value.type->id != ZigTypeIdFloat && target->value.type->id != ZigTypeIdComptimeFloat) { 18528 ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", 18529 buf_ptr(&target->value.type->name))); 18530 return ira->codegen->builtin_types.entry_invalid; 18531 } 18532 18533 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false); 18534 ir_link_new_instruction(result, &instruction->base); 18535 return dest_type; 18536 } 18537 18538 static ZigType *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { 18539 IrInstruction *target = instruction->target->other; 18540 if (type_is_invalid(target->value.type)) 18541 return ira->codegen->builtin_types.entry_invalid; 18542 18543 IrInstruction *casted_target; 18544 if (target->value.type->id == ZigTypeIdErrorSet) { 18545 casted_target = target; 18546 } else { 18547 casted_target = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_global_error_set); 18548 if (type_is_invalid(casted_target->value.type)) 18549 return ira->codegen->builtin_types.entry_invalid; 18550 } 18551 18552 IrInstruction *result = ir_analyze_err_to_int(ira, &instruction->base, casted_target, ira->codegen->err_tag_type); 18553 ir_link_new_instruction(result, &instruction->base); 18554 return result->value.type; 18555 } 18556 18557 static ZigType *ir_analyze_instruction_int_to_err(IrAnalyze *ira, IrInstructionIntToErr *instruction) { 18558 IrInstruction *target = instruction->target->other; 18559 if (type_is_invalid(target->value.type)) 18560 return ira->codegen->builtin_types.entry_invalid; 18561 18562 IrInstruction *casted_target = ir_implicit_cast(ira, target, ira->codegen->err_tag_type); 18563 if (type_is_invalid(casted_target->value.type)) 18564 return ira->codegen->builtin_types.entry_invalid; 18565 18566 IrInstruction *result = ir_analyze_int_to_err(ira, &instruction->base, casted_target, ira->codegen->builtin_types.entry_global_error_set); 18567 ir_link_new_instruction(result, &instruction->base); 18568 return result->value.type; 18569 } 18570 18571 static ZigType *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstructionBoolToInt *instruction) { 18572 IrInstruction *target = instruction->target->other; 18573 if (type_is_invalid(target->value.type)) 18574 return ira->codegen->builtin_types.entry_invalid; 18575 18576 if (target->value.type->id != ZigTypeIdBool) { 18577 ir_add_error(ira, instruction->target, buf_sprintf("expected bool, found '%s'", 18578 buf_ptr(&target->value.type->name))); 18579 return ira->codegen->builtin_types.entry_invalid; 18580 } 18581 18582 if (instr_is_comptime(target)) { 18583 bool is_true; 18584 if (!ir_resolve_bool(ira, target, &is_true)) 18585 return ira->codegen->builtin_types.entry_invalid; 18586 18587 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 18588 bigint_init_unsigned(&out_val->data.x_bigint, is_true ? 1 : 0); 18589 return ira->codegen->builtin_types.entry_num_lit_int; 18590 } 18591 18592 ZigType *u1_type = get_int_type(ira->codegen, false, 1); 18593 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false); 18594 ir_link_new_instruction(result, &instruction->base); 18595 return u1_type; 18596 } 18597 18598 static ZigType *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { 18599 IrInstruction *is_signed_value = instruction->is_signed->other; 18600 bool is_signed; 18601 if (!ir_resolve_bool(ira, is_signed_value, &is_signed)) 18602 return ira->codegen->builtin_types.entry_invalid; 18603 18604 IrInstruction *bit_count_value = instruction->bit_count->other; 18605 uint64_t bit_count; 18606 if (!ir_resolve_unsigned(ira, bit_count_value, ira->codegen->builtin_types.entry_u32, &bit_count)) 18607 return ira->codegen->builtin_types.entry_invalid; 18608 18609 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 18610 out_val->data.x_type = get_int_type(ira->codegen, is_signed, (uint32_t)bit_count); 18611 return ira->codegen->builtin_types.entry_type; 18612 } 18613 18614 static ZigType *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { 18615 IrInstruction *value = instruction->value->other; 18616 if (type_is_invalid(value->value.type)) 18617 return ira->codegen->builtin_types.entry_invalid; 18618 18619 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 18620 18621 IrInstruction *casted_value = ir_implicit_cast(ira, value, bool_type); 18622 if (type_is_invalid(casted_value->value.type)) 18623 return ira->codegen->builtin_types.entry_invalid; 18624 18625 if (instr_is_comptime(casted_value)) { 18626 ConstExprValue *value = ir_resolve_const(ira, casted_value, UndefBad); 18627 if (value == nullptr) 18628 return ira->codegen->builtin_types.entry_invalid; 18629 18630 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 18631 out_val->data.x_bool = !value->data.x_bool; 18632 return bool_type; 18633 } 18634 18635 ir_build_bool_not_from(&ira->new_irb, &instruction->base, casted_value); 18636 return bool_type; 18637 } 18638 18639 static ZigType *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemset *instruction) { 18640 IrInstruction *dest_ptr = instruction->dest_ptr->other; 18641 if (type_is_invalid(dest_ptr->value.type)) 18642 return ira->codegen->builtin_types.entry_invalid; 18643 18644 IrInstruction *byte_value = instruction->byte->other; 18645 if (type_is_invalid(byte_value->value.type)) 18646 return ira->codegen->builtin_types.entry_invalid; 18647 18648 IrInstruction *count_value = instruction->count->other; 18649 if (type_is_invalid(count_value->value.type)) 18650 return ira->codegen->builtin_types.entry_invalid; 18651 18652 ZigType *dest_uncasted_type = dest_ptr->value.type; 18653 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 18654 dest_uncasted_type->data.pointer.is_volatile; 18655 18656 ZigType *usize = ira->codegen->builtin_types.entry_usize; 18657 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 18658 uint32_t dest_align = (dest_uncasted_type->id == ZigTypeIdPointer) ? 18659 dest_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8); 18660 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 18661 PtrLenUnknown, dest_align, 0, 0); 18662 18663 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr); 18664 if (type_is_invalid(casted_dest_ptr->value.type)) 18665 return ira->codegen->builtin_types.entry_invalid; 18666 18667 IrInstruction *casted_byte = ir_implicit_cast(ira, byte_value, u8); 18668 if (type_is_invalid(casted_byte->value.type)) 18669 return ira->codegen->builtin_types.entry_invalid; 18670 18671 IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); 18672 if (type_is_invalid(casted_count->value.type)) 18673 return ira->codegen->builtin_types.entry_invalid; 18674 18675 if (casted_dest_ptr->value.special == ConstValSpecialStatic && 18676 casted_byte->value.special == ConstValSpecialStatic && 18677 casted_count->value.special == ConstValSpecialStatic && 18678 casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) 18679 { 18680 ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; 18681 18682 ConstExprValue *dest_elements; 18683 size_t start; 18684 size_t bound_end; 18685 switch (dest_ptr_val->data.x_ptr.special) { 18686 case ConstPtrSpecialInvalid: 18687 case ConstPtrSpecialDiscard: 18688 zig_unreachable(); 18689 case ConstPtrSpecialRef: 18690 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 18691 start = 0; 18692 bound_end = 1; 18693 break; 18694 case ConstPtrSpecialBaseArray: 18695 { 18696 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 18697 expand_undef_array(ira->codegen, array_val); 18698 dest_elements = array_val->data.x_array.s_none.elements; 18699 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 18700 bound_end = array_val->type->data.array.len; 18701 break; 18702 } 18703 case ConstPtrSpecialBaseStruct: 18704 zig_panic("TODO memset on const inner struct"); 18705 case ConstPtrSpecialHardCodedAddr: 18706 zig_unreachable(); 18707 case ConstPtrSpecialFunction: 18708 zig_panic("TODO memset on ptr cast from function"); 18709 } 18710 18711 size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); 18712 size_t end = start + count; 18713 if (end > bound_end) { 18714 ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); 18715 return ira->codegen->builtin_types.entry_invalid; 18716 } 18717 18718 ConstExprValue *byte_val = &casted_byte->value; 18719 for (size_t i = start; i < end; i += 1) { 18720 dest_elements[i] = *byte_val; 18721 } 18722 18723 ir_build_const_from(ira, &instruction->base); 18724 return ira->codegen->builtin_types.entry_void; 18725 } 18726 18727 ir_build_memset_from(&ira->new_irb, &instruction->base, casted_dest_ptr, casted_byte, casted_count); 18728 return ira->codegen->builtin_types.entry_void; 18729 } 18730 18731 static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcpy *instruction) { 18732 IrInstruction *dest_ptr = instruction->dest_ptr->other; 18733 if (type_is_invalid(dest_ptr->value.type)) 18734 return ira->codegen->builtin_types.entry_invalid; 18735 18736 IrInstruction *src_ptr = instruction->src_ptr->other; 18737 if (type_is_invalid(src_ptr->value.type)) 18738 return ira->codegen->builtin_types.entry_invalid; 18739 18740 IrInstruction *count_value = instruction->count->other; 18741 if (type_is_invalid(count_value->value.type)) 18742 return ira->codegen->builtin_types.entry_invalid; 18743 18744 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 18745 ZigType *dest_uncasted_type = dest_ptr->value.type; 18746 ZigType *src_uncasted_type = src_ptr->value.type; 18747 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 18748 dest_uncasted_type->data.pointer.is_volatile; 18749 bool src_is_volatile = (src_uncasted_type->id == ZigTypeIdPointer) && 18750 src_uncasted_type->data.pointer.is_volatile; 18751 uint32_t dest_align = (dest_uncasted_type->id == ZigTypeIdPointer) ? 18752 dest_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8); 18753 uint32_t src_align = (src_uncasted_type->id == ZigTypeIdPointer) ? 18754 src_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8); 18755 18756 ZigType *usize = ira->codegen->builtin_types.entry_usize; 18757 ZigType *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 18758 PtrLenUnknown, dest_align, 0, 0); 18759 ZigType *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, 18760 PtrLenUnknown, src_align, 0, 0); 18761 18762 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut); 18763 if (type_is_invalid(casted_dest_ptr->value.type)) 18764 return ira->codegen->builtin_types.entry_invalid; 18765 18766 IrInstruction *casted_src_ptr = ir_implicit_cast(ira, src_ptr, u8_ptr_const); 18767 if (type_is_invalid(casted_src_ptr->value.type)) 18768 return ira->codegen->builtin_types.entry_invalid; 18769 18770 IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); 18771 if (type_is_invalid(casted_count->value.type)) 18772 return ira->codegen->builtin_types.entry_invalid; 18773 18774 if (casted_dest_ptr->value.special == ConstValSpecialStatic && 18775 casted_src_ptr->value.special == ConstValSpecialStatic && 18776 casted_count->value.special == ConstValSpecialStatic && 18777 casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) 18778 { 18779 size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); 18780 18781 ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; 18782 ConstExprValue *dest_elements; 18783 size_t dest_start; 18784 size_t dest_end; 18785 switch (dest_ptr_val->data.x_ptr.special) { 18786 case ConstPtrSpecialInvalid: 18787 case ConstPtrSpecialDiscard: 18788 zig_unreachable(); 18789 case ConstPtrSpecialRef: 18790 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 18791 dest_start = 0; 18792 dest_end = 1; 18793 break; 18794 case ConstPtrSpecialBaseArray: 18795 { 18796 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 18797 expand_undef_array(ira->codegen, array_val); 18798 dest_elements = array_val->data.x_array.s_none.elements; 18799 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 18800 dest_end = array_val->type->data.array.len; 18801 break; 18802 } 18803 case ConstPtrSpecialBaseStruct: 18804 zig_panic("TODO memcpy on const inner struct"); 18805 case ConstPtrSpecialHardCodedAddr: 18806 zig_unreachable(); 18807 case ConstPtrSpecialFunction: 18808 zig_panic("TODO memcpy on ptr cast from function"); 18809 } 18810 18811 if (dest_start + count > dest_end) { 18812 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); 18813 return ira->codegen->builtin_types.entry_invalid; 18814 } 18815 18816 ConstExprValue *src_ptr_val = &casted_src_ptr->value; 18817 ConstExprValue *src_elements; 18818 size_t src_start; 18819 size_t src_end; 18820 18821 switch (src_ptr_val->data.x_ptr.special) { 18822 case ConstPtrSpecialInvalid: 18823 case ConstPtrSpecialDiscard: 18824 zig_unreachable(); 18825 case ConstPtrSpecialRef: 18826 src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; 18827 src_start = 0; 18828 src_end = 1; 18829 break; 18830 case ConstPtrSpecialBaseArray: 18831 { 18832 ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; 18833 expand_undef_array(ira->codegen, array_val); 18834 src_elements = array_val->data.x_array.s_none.elements; 18835 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; 18836 src_end = array_val->type->data.array.len; 18837 break; 18838 } 18839 case ConstPtrSpecialBaseStruct: 18840 zig_panic("TODO memcpy on const inner struct"); 18841 case ConstPtrSpecialHardCodedAddr: 18842 zig_unreachable(); 18843 case ConstPtrSpecialFunction: 18844 zig_panic("TODO memcpy on ptr cast from function"); 18845 } 18846 18847 if (src_start + count > src_end) { 18848 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); 18849 return ira->codegen->builtin_types.entry_invalid; 18850 } 18851 18852 // TODO check for noalias violations - this should be generalized to work for any function 18853 18854 for (size_t i = 0; i < count; i += 1) { 18855 dest_elements[dest_start + i] = src_elements[src_start + i]; 18856 } 18857 18858 ir_build_const_from(ira, &instruction->base); 18859 return ira->codegen->builtin_types.entry_void; 18860 } 18861 18862 ir_build_memcpy_from(&ira->new_irb, &instruction->base, casted_dest_ptr, casted_src_ptr, casted_count); 18863 return ira->codegen->builtin_types.entry_void; 18864 } 18865 18866 static ZigType *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) { 18867 IrInstruction *ptr_ptr = instruction->ptr->other; 18868 if (type_is_invalid(ptr_ptr->value.type)) 18869 return ira->codegen->builtin_types.entry_invalid; 18870 18871 ZigType *ptr_type = ptr_ptr->value.type; 18872 assert(ptr_type->id == ZigTypeIdPointer); 18873 ZigType *array_type = ptr_type->data.pointer.child_type; 18874 18875 IrInstruction *start = instruction->start->other; 18876 if (type_is_invalid(start->value.type)) 18877 return ira->codegen->builtin_types.entry_invalid; 18878 18879 ZigType *usize = ira->codegen->builtin_types.entry_usize; 18880 IrInstruction *casted_start = ir_implicit_cast(ira, start, usize); 18881 if (type_is_invalid(casted_start->value.type)) 18882 return ira->codegen->builtin_types.entry_invalid; 18883 18884 IrInstruction *end; 18885 if (instruction->end) { 18886 end = instruction->end->other; 18887 if (type_is_invalid(end->value.type)) 18888 return ira->codegen->builtin_types.entry_invalid; 18889 end = ir_implicit_cast(ira, end, usize); 18890 if (type_is_invalid(end->value.type)) 18891 return ira->codegen->builtin_types.entry_invalid; 18892 } else { 18893 end = nullptr; 18894 } 18895 18896 ZigType *return_type; 18897 18898 if (array_type->id == ZigTypeIdArray) { 18899 uint32_t byte_alignment = ptr_type->data.pointer.alignment; 18900 if (array_type->data.array.len == 0 && byte_alignment == 0) { 18901 byte_alignment = get_abi_alignment(ira->codegen, array_type->data.array.child_type); 18902 } 18903 bool is_comptime_const = ptr_ptr->value.special == ConstValSpecialStatic && 18904 ptr_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst; 18905 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type, 18906 ptr_type->data.pointer.is_const || is_comptime_const, 18907 ptr_type->data.pointer.is_volatile, 18908 PtrLenUnknown, 18909 byte_alignment, 0, 0); 18910 return_type = get_slice_type(ira->codegen, slice_ptr_type); 18911 } else if (array_type->id == ZigTypeIdPointer) { 18912 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 18913 ZigType *main_type = array_type->data.pointer.child_type; 18914 if (main_type->id == ZigTypeIdArray) { 18915 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, 18916 main_type->data.pointer.child_type, 18917 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile, 18918 PtrLenUnknown, 18919 array_type->data.pointer.alignment, 0, 0); 18920 return_type = get_slice_type(ira->codegen, slice_ptr_type); 18921 } else { 18922 ir_add_error(ira, &instruction->base, buf_sprintf("slice of single-item pointer")); 18923 return ira->codegen->builtin_types.entry_invalid; 18924 } 18925 } else { 18926 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.pointer.child_type, 18927 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile, 18928 PtrLenUnknown, 18929 array_type->data.pointer.alignment, 0, 0); 18930 return_type = get_slice_type(ira->codegen, slice_ptr_type); 18931 if (!end) { 18932 ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value")); 18933 return ira->codegen->builtin_types.entry_invalid; 18934 } 18935 } 18936 } else if (is_slice(array_type)) { 18937 ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index].type_entry; 18938 return_type = get_slice_type(ira->codegen, ptr_type); 18939 } else { 18940 ir_add_error(ira, &instruction->base, 18941 buf_sprintf("slice of non-array type '%s'", buf_ptr(&array_type->name))); 18942 return ira->codegen->builtin_types.entry_invalid; 18943 } 18944 18945 if (instr_is_comptime(ptr_ptr) && 18946 value_is_comptime(&casted_start->value) && 18947 (!end || value_is_comptime(&end->value))) 18948 { 18949 ConstExprValue *array_val; 18950 ConstExprValue *parent_ptr; 18951 size_t abs_offset; 18952 size_t rel_end; 18953 bool ptr_is_undef = false; 18954 if (array_type->id == ZigTypeIdArray || 18955 (array_type->id == ZigTypeIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) 18956 { 18957 if (array_type->id == ZigTypeIdPointer) { 18958 ZigType *child_array_type = array_type->data.pointer.child_type; 18959 assert(child_array_type->id == ZigTypeIdArray); 18960 parent_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); 18961 if (parent_ptr == nullptr) 18962 return ira->codegen->builtin_types.entry_invalid; 18963 18964 array_val = ir_const_ptr_pointee(ira, parent_ptr, instruction->base.source_node); 18965 if (array_val == nullptr) 18966 return ira->codegen->builtin_types.entry_invalid; 18967 18968 rel_end = child_array_type->data.array.len; 18969 abs_offset = 0; 18970 } else { 18971 array_val = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); 18972 if (array_val == nullptr) 18973 return ira->codegen->builtin_types.entry_invalid; 18974 rel_end = array_type->data.array.len; 18975 parent_ptr = nullptr; 18976 abs_offset = 0; 18977 } 18978 } else if (array_type->id == ZigTypeIdPointer) { 18979 assert(array_type->data.pointer.ptr_len == PtrLenUnknown); 18980 parent_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); 18981 if (parent_ptr == nullptr) 18982 return ira->codegen->builtin_types.entry_invalid; 18983 18984 if (parent_ptr->special == ConstValSpecialUndef) { 18985 array_val = nullptr; 18986 abs_offset = 0; 18987 rel_end = SIZE_MAX; 18988 ptr_is_undef = true; 18989 } else switch (parent_ptr->data.x_ptr.special) { 18990 case ConstPtrSpecialInvalid: 18991 case ConstPtrSpecialDiscard: 18992 zig_unreachable(); 18993 case ConstPtrSpecialRef: 18994 array_val = nullptr; 18995 abs_offset = SIZE_MAX; 18996 rel_end = 1; 18997 break; 18998 case ConstPtrSpecialBaseArray: 18999 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 19000 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 19001 rel_end = array_val->type->data.array.len - abs_offset; 19002 break; 19003 case ConstPtrSpecialBaseStruct: 19004 zig_panic("TODO slice const inner struct"); 19005 case ConstPtrSpecialHardCodedAddr: 19006 array_val = nullptr; 19007 abs_offset = 0; 19008 rel_end = SIZE_MAX; 19009 break; 19010 case ConstPtrSpecialFunction: 19011 zig_panic("TODO slice of ptr cast from function"); 19012 } 19013 } else if (is_slice(array_type)) { 19014 ConstExprValue *slice_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); 19015 if (slice_ptr == nullptr) 19016 return ira->codegen->builtin_types.entry_invalid; 19017 19018 parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index]; 19019 ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index]; 19020 19021 switch (parent_ptr->data.x_ptr.special) { 19022 case ConstPtrSpecialInvalid: 19023 case ConstPtrSpecialDiscard: 19024 zig_unreachable(); 19025 case ConstPtrSpecialRef: 19026 array_val = nullptr; 19027 abs_offset = SIZE_MAX; 19028 rel_end = 1; 19029 break; 19030 case ConstPtrSpecialBaseArray: 19031 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 19032 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 19033 rel_end = bigint_as_unsigned(&len_val->data.x_bigint); 19034 break; 19035 case ConstPtrSpecialBaseStruct: 19036 zig_panic("TODO slice const inner struct"); 19037 case ConstPtrSpecialHardCodedAddr: 19038 array_val = nullptr; 19039 abs_offset = 0; 19040 rel_end = bigint_as_unsigned(&len_val->data.x_bigint); 19041 break; 19042 case ConstPtrSpecialFunction: 19043 zig_panic("TODO slice of slice cast from function"); 19044 } 19045 } else { 19046 zig_unreachable(); 19047 } 19048 19049 uint64_t start_scalar = bigint_as_unsigned(&casted_start->value.data.x_bigint); 19050 if (!ptr_is_undef && start_scalar > rel_end) { 19051 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); 19052 return ira->codegen->builtin_types.entry_invalid; 19053 } 19054 19055 uint64_t end_scalar; 19056 if (end) { 19057 end_scalar = bigint_as_unsigned(&end->value.data.x_bigint); 19058 } else { 19059 end_scalar = rel_end; 19060 } 19061 if (!ptr_is_undef) { 19062 if (end_scalar > rel_end) { 19063 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); 19064 return ira->codegen->builtin_types.entry_invalid; 19065 } 19066 if (start_scalar > end_scalar) { 19067 ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); 19068 return ira->codegen->builtin_types.entry_invalid; 19069 } 19070 } 19071 if (ptr_is_undef && start_scalar != end_scalar) { 19072 ir_add_error(ira, &instruction->base, buf_sprintf("non-zero length slice of undefined pointer")); 19073 return ira->codegen->builtin_types.entry_invalid; 19074 } 19075 19076 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19077 out_val->data.x_struct.fields = create_const_vals(2); 19078 19079 ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; 19080 19081 if (array_val) { 19082 size_t index = abs_offset + start_scalar; 19083 bool is_const = slice_is_const(return_type); 19084 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const, PtrLenUnknown); 19085 if (array_type->id == ZigTypeIdArray) { 19086 ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut; 19087 } else if (is_slice(array_type)) { 19088 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 19089 } else if (array_type->id == ZigTypeIdPointer) { 19090 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 19091 } 19092 } else if (ptr_is_undef) { 19093 ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type, 19094 slice_is_const(return_type)); 19095 ptr_val->special = ConstValSpecialUndef; 19096 } else switch (parent_ptr->data.x_ptr.special) { 19097 case ConstPtrSpecialInvalid: 19098 case ConstPtrSpecialDiscard: 19099 zig_unreachable(); 19100 case ConstPtrSpecialRef: 19101 init_const_ptr_ref(ira->codegen, ptr_val, 19102 parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); 19103 break; 19104 case ConstPtrSpecialBaseArray: 19105 zig_unreachable(); 19106 case ConstPtrSpecialBaseStruct: 19107 zig_panic("TODO"); 19108 case ConstPtrSpecialHardCodedAddr: 19109 init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, 19110 parent_ptr->type->data.pointer.child_type, 19111 parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, 19112 slice_is_const(return_type)); 19113 break; 19114 case ConstPtrSpecialFunction: 19115 zig_panic("TODO"); 19116 } 19117 19118 ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; 19119 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); 19120 19121 return return_type; 19122 } 19123 19124 IrInstruction *new_instruction = ir_build_slice_from(&ira->new_irb, &instruction->base, ptr_ptr, 19125 casted_start, end, instruction->safety_check_on); 19126 ir_add_alloca(ira, new_instruction, return_type); 19127 19128 return return_type; 19129 } 19130 19131 static ZigType *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { 19132 Error err; 19133 IrInstruction *container = instruction->container->other; 19134 if (type_is_invalid(container->value.type)) 19135 return ira->codegen->builtin_types.entry_invalid; 19136 ZigType *container_type = ir_resolve_type(ira, container); 19137 19138 if ((err = ensure_complete_type(ira->codegen, container_type))) 19139 return ira->codegen->builtin_types.entry_invalid; 19140 19141 uint64_t result; 19142 if (type_is_invalid(container_type)) { 19143 return ira->codegen->builtin_types.entry_invalid; 19144 } else if (container_type->id == ZigTypeIdEnum) { 19145 result = container_type->data.enumeration.src_field_count; 19146 } else if (container_type->id == ZigTypeIdStruct) { 19147 result = container_type->data.structure.src_field_count; 19148 } else if (container_type->id == ZigTypeIdUnion) { 19149 result = container_type->data.unionation.src_field_count; 19150 } else if (container_type->id == ZigTypeIdErrorSet) { 19151 if (!resolve_inferred_error_set(ira->codegen, container_type, instruction->base.source_node)) { 19152 return ira->codegen->builtin_types.entry_invalid; 19153 } 19154 if (type_is_global_error_set(container_type)) { 19155 ir_add_error(ira, &instruction->base, buf_sprintf("global error set member count not available at comptime")); 19156 return ira->codegen->builtin_types.entry_invalid; 19157 } 19158 result = container_type->data.error_set.err_count; 19159 } else { 19160 ir_add_error(ira, &instruction->base, buf_sprintf("no value count available for type '%s'", buf_ptr(&container_type->name))); 19161 return ira->codegen->builtin_types.entry_invalid; 19162 } 19163 19164 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19165 bigint_init_unsigned(&out_val->data.x_bigint, result); 19166 return ira->codegen->builtin_types.entry_num_lit_int; 19167 } 19168 19169 static ZigType *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstructionMemberType *instruction) { 19170 Error err; 19171 IrInstruction *container_type_value = instruction->container_type->other; 19172 ZigType *container_type = ir_resolve_type(ira, container_type_value); 19173 if (type_is_invalid(container_type)) 19174 return ira->codegen->builtin_types.entry_invalid; 19175 19176 if ((err = ensure_complete_type(ira->codegen, container_type))) 19177 return ira->codegen->builtin_types.entry_invalid; 19178 19179 19180 uint64_t member_index; 19181 IrInstruction *index_value = instruction->member_index->other; 19182 if (!ir_resolve_usize(ira, index_value, &member_index)) 19183 return ira->codegen->builtin_types.entry_invalid; 19184 19185 if (container_type->id == ZigTypeIdStruct) { 19186 if (member_index >= container_type->data.structure.src_field_count) { 19187 ir_add_error(ira, index_value, 19188 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 19189 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); 19190 return ira->codegen->builtin_types.entry_invalid; 19191 } 19192 TypeStructField *field = &container_type->data.structure.fields[member_index]; 19193 19194 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19195 out_val->data.x_type = field->type_entry; 19196 return ira->codegen->builtin_types.entry_type; 19197 } else if (container_type->id == ZigTypeIdUnion) { 19198 if (member_index >= container_type->data.unionation.src_field_count) { 19199 ir_add_error(ira, index_value, 19200 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 19201 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); 19202 return ira->codegen->builtin_types.entry_invalid; 19203 } 19204 TypeUnionField *field = &container_type->data.unionation.fields[member_index]; 19205 19206 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19207 out_val->data.x_type = field->type_entry; 19208 return ira->codegen->builtin_types.entry_type; 19209 } else { 19210 ir_add_error(ira, container_type_value, 19211 buf_sprintf("type '%s' does not support @memberType", buf_ptr(&container_type->name))); 19212 return ira->codegen->builtin_types.entry_invalid; 19213 } 19214 } 19215 19216 static ZigType *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstructionMemberName *instruction) { 19217 Error err; 19218 IrInstruction *container_type_value = instruction->container_type->other; 19219 ZigType *container_type = ir_resolve_type(ira, container_type_value); 19220 if (type_is_invalid(container_type)) 19221 return ira->codegen->builtin_types.entry_invalid; 19222 19223 if ((err = ensure_complete_type(ira->codegen, container_type))) 19224 return ira->codegen->builtin_types.entry_invalid; 19225 19226 uint64_t member_index; 19227 IrInstruction *index_value = instruction->member_index->other; 19228 if (!ir_resolve_usize(ira, index_value, &member_index)) 19229 return ira->codegen->builtin_types.entry_invalid; 19230 19231 if (container_type->id == ZigTypeIdStruct) { 19232 if (member_index >= container_type->data.structure.src_field_count) { 19233 ir_add_error(ira, index_value, 19234 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 19235 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); 19236 return ira->codegen->builtin_types.entry_invalid; 19237 } 19238 TypeStructField *field = &container_type->data.structure.fields[member_index]; 19239 19240 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19241 init_const_str_lit(ira->codegen, out_val, field->name); 19242 return out_val->type; 19243 } else if (container_type->id == ZigTypeIdEnum) { 19244 if (member_index >= container_type->data.enumeration.src_field_count) { 19245 ir_add_error(ira, index_value, 19246 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 19247 member_index, buf_ptr(&container_type->name), container_type->data.enumeration.src_field_count)); 19248 return ira->codegen->builtin_types.entry_invalid; 19249 } 19250 TypeEnumField *field = &container_type->data.enumeration.fields[member_index]; 19251 19252 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19253 init_const_str_lit(ira->codegen, out_val, field->name); 19254 return out_val->type; 19255 } else if (container_type->id == ZigTypeIdUnion) { 19256 if (member_index >= container_type->data.unionation.src_field_count) { 19257 ir_add_error(ira, index_value, 19258 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 19259 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); 19260 return ira->codegen->builtin_types.entry_invalid; 19261 } 19262 TypeUnionField *field = &container_type->data.unionation.fields[member_index]; 19263 19264 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19265 init_const_str_lit(ira->codegen, out_val, field->name); 19266 return out_val->type; 19267 } else { 19268 ir_add_error(ira, container_type_value, 19269 buf_sprintf("type '%s' does not support @memberName", buf_ptr(&container_type->name))); 19270 return ira->codegen->builtin_types.entry_invalid; 19271 } 19272 } 19273 19274 static ZigType *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) { 19275 ir_build_breakpoint_from(&ira->new_irb, &instruction->base); 19276 return ira->codegen->builtin_types.entry_void; 19277 } 19278 19279 static ZigType *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstructionReturnAddress *instruction) { 19280 ir_build_return_address_from(&ira->new_irb, &instruction->base); 19281 19282 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 19283 ZigType *u8_ptr_const = get_pointer_to_type(ira->codegen, u8, true); 19284 return u8_ptr_const; 19285 } 19286 19287 static ZigType *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstructionFrameAddress *instruction) { 19288 ir_build_frame_address_from(&ira->new_irb, &instruction->base); 19289 19290 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 19291 ZigType *u8_ptr_const = get_pointer_to_type(ira->codegen, u8, true); 19292 return u8_ptr_const; 19293 } 19294 19295 static ZigType *ir_analyze_instruction_handle(IrAnalyze *ira, IrInstructionHandle *instruction) { 19296 ir_build_handle_from(&ira->new_irb, &instruction->base); 19297 19298 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 19299 assert(fn_entry != nullptr); 19300 return get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type); 19301 } 19302 19303 static ZigType *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { 19304 Error err; 19305 IrInstruction *type_value = instruction->type_value->other; 19306 if (type_is_invalid(type_value->value.type)) 19307 return ira->codegen->builtin_types.entry_invalid; 19308 ZigType *type_entry = ir_resolve_type(ira, type_value); 19309 19310 if ((err = type_ensure_zero_bits_known(ira->codegen, type_entry))) 19311 return ira->codegen->builtin_types.entry_invalid; 19312 19313 switch (type_entry->id) { 19314 case ZigTypeIdInvalid: 19315 zig_unreachable(); 19316 case ZigTypeIdMetaType: 19317 case ZigTypeIdUnreachable: 19318 case ZigTypeIdComptimeFloat: 19319 case ZigTypeIdComptimeInt: 19320 case ZigTypeIdUndefined: 19321 case ZigTypeIdNull: 19322 case ZigTypeIdNamespace: 19323 case ZigTypeIdBlock: 19324 case ZigTypeIdBoundFn: 19325 case ZigTypeIdArgTuple: 19326 case ZigTypeIdVoid: 19327 case ZigTypeIdOpaque: 19328 ir_add_error(ira, instruction->type_value, 19329 buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); 19330 return ira->codegen->builtin_types.entry_invalid; 19331 case ZigTypeIdBool: 19332 case ZigTypeIdInt: 19333 case ZigTypeIdFloat: 19334 case ZigTypeIdPointer: 19335 case ZigTypeIdPromise: 19336 case ZigTypeIdArray: 19337 case ZigTypeIdStruct: 19338 case ZigTypeIdOptional: 19339 case ZigTypeIdErrorUnion: 19340 case ZigTypeIdErrorSet: 19341 case ZigTypeIdEnum: 19342 case ZigTypeIdUnion: 19343 case ZigTypeIdFn: 19344 { 19345 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); 19346 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19347 bigint_init_unsigned(&out_val->data.x_bigint, align_in_bytes); 19348 return ira->codegen->builtin_types.entry_num_lit_int; 19349 } 19350 } 19351 zig_unreachable(); 19352 } 19353 19354 static ZigType *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { 19355 IrInstruction *type_value = instruction->type_value->other; 19356 if (type_is_invalid(type_value->value.type)) 19357 return ira->codegen->builtin_types.entry_invalid; 19358 19359 ZigType *dest_type = ir_resolve_type(ira, type_value); 19360 if (type_is_invalid(dest_type)) 19361 return ira->codegen->builtin_types.entry_invalid; 19362 19363 if (dest_type->id != ZigTypeIdInt) { 19364 ir_add_error(ira, type_value, 19365 buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 19366 return ira->codegen->builtin_types.entry_invalid; 19367 } 19368 19369 IrInstruction *op1 = instruction->op1->other; 19370 if (type_is_invalid(op1->value.type)) 19371 return ira->codegen->builtin_types.entry_invalid; 19372 19373 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 19374 if (type_is_invalid(casted_op1->value.type)) 19375 return ira->codegen->builtin_types.entry_invalid; 19376 19377 IrInstruction *op2 = instruction->op2->other; 19378 if (type_is_invalid(op2->value.type)) 19379 return ira->codegen->builtin_types.entry_invalid; 19380 19381 IrInstruction *casted_op2; 19382 if (instruction->op == IrOverflowOpShl) { 19383 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 19384 dest_type->data.integral.bit_count - 1); 19385 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 19386 } else { 19387 casted_op2 = ir_implicit_cast(ira, op2, dest_type); 19388 } 19389 if (type_is_invalid(casted_op2->value.type)) 19390 return ira->codegen->builtin_types.entry_invalid; 19391 19392 IrInstruction *result_ptr = instruction->result_ptr->other; 19393 if (type_is_invalid(result_ptr->value.type)) 19394 return ira->codegen->builtin_types.entry_invalid; 19395 19396 ZigType *expected_ptr_type; 19397 if (result_ptr->value.type->id == ZigTypeIdPointer) { 19398 expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type, 19399 false, result_ptr->value.type->data.pointer.is_volatile, 19400 PtrLenSingle, 19401 result_ptr->value.type->data.pointer.alignment, 0, 0); 19402 } else { 19403 expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false); 19404 } 19405 19406 IrInstruction *casted_result_ptr = ir_implicit_cast(ira, result_ptr, expected_ptr_type); 19407 if (type_is_invalid(casted_result_ptr->value.type)) 19408 return ira->codegen->builtin_types.entry_invalid; 19409 19410 if (casted_op1->value.special == ConstValSpecialStatic && 19411 casted_op2->value.special == ConstValSpecialStatic && 19412 casted_result_ptr->value.special == ConstValSpecialStatic) 19413 { 19414 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19415 BigInt *op1_bigint = &casted_op1->value.data.x_bigint; 19416 BigInt *op2_bigint = &casted_op2->value.data.x_bigint; 19417 ConstExprValue *pointee_val = ir_const_ptr_pointee(ira, &casted_result_ptr->value, casted_result_ptr->source_node); 19418 if (pointee_val == nullptr) 19419 return ira->codegen->builtin_types.entry_invalid; 19420 BigInt *dest_bigint = &pointee_val->data.x_bigint; 19421 switch (instruction->op) { 19422 case IrOverflowOpAdd: 19423 bigint_add(dest_bigint, op1_bigint, op2_bigint); 19424 break; 19425 case IrOverflowOpSub: 19426 bigint_sub(dest_bigint, op1_bigint, op2_bigint); 19427 break; 19428 case IrOverflowOpMul: 19429 bigint_mul(dest_bigint, op1_bigint, op2_bigint); 19430 break; 19431 case IrOverflowOpShl: 19432 bigint_shl(dest_bigint, op1_bigint, op2_bigint); 19433 break; 19434 } 19435 if (!bigint_fits_in_bits(dest_bigint, dest_type->data.integral.bit_count, 19436 dest_type->data.integral.is_signed)) 19437 { 19438 out_val->data.x_bool = true; 19439 BigInt tmp_bigint; 19440 bigint_init_bigint(&tmp_bigint, dest_bigint); 19441 bigint_truncate(dest_bigint, &tmp_bigint, dest_type->data.integral.bit_count, 19442 dest_type->data.integral.is_signed); 19443 } 19444 pointee_val->special = ConstValSpecialStatic; 19445 return ira->codegen->builtin_types.entry_bool; 19446 } 19447 19448 ir_build_overflow_op_from(&ira->new_irb, &instruction->base, instruction->op, type_value, 19449 casted_op1, casted_op2, casted_result_ptr, dest_type); 19450 return ira->codegen->builtin_types.entry_bool; 19451 } 19452 19453 static ZigType *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErr *instruction) { 19454 IrInstruction *value = instruction->value->other; 19455 if (type_is_invalid(value->value.type)) 19456 return ira->codegen->builtin_types.entry_invalid; 19457 19458 ZigType *type_entry = value->value.type; 19459 if (type_is_invalid(type_entry)) { 19460 return ira->codegen->builtin_types.entry_invalid; 19461 } else if (type_entry->id == ZigTypeIdErrorUnion) { 19462 if (instr_is_comptime(value)) { 19463 ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); 19464 if (!err_union_val) 19465 return ira->codegen->builtin_types.entry_invalid; 19466 19467 if (err_union_val->special != ConstValSpecialRuntime) { 19468 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19469 out_val->data.x_bool = (err_union_val->data.x_err_union.err != nullptr); 19470 return ira->codegen->builtin_types.entry_bool; 19471 } 19472 } 19473 19474 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 19475 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { 19476 return ira->codegen->builtin_types.entry_invalid; 19477 } 19478 if (!type_is_global_error_set(err_set_type) && 19479 err_set_type->data.error_set.err_count == 0) 19480 { 19481 assert(err_set_type->data.error_set.infer_fn == nullptr); 19482 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19483 out_val->data.x_bool = false; 19484 return ira->codegen->builtin_types.entry_bool; 19485 } 19486 19487 ir_build_test_err_from(&ira->new_irb, &instruction->base, value); 19488 return ira->codegen->builtin_types.entry_bool; 19489 } else if (type_entry->id == ZigTypeIdErrorSet) { 19490 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19491 out_val->data.x_bool = true; 19492 return ira->codegen->builtin_types.entry_bool; 19493 } else { 19494 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19495 out_val->data.x_bool = false; 19496 return ira->codegen->builtin_types.entry_bool; 19497 } 19498 } 19499 19500 static ZigType *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, 19501 IrInstructionUnwrapErrCode *instruction) 19502 { 19503 IrInstruction *value = instruction->value->other; 19504 if (type_is_invalid(value->value.type)) 19505 return ira->codegen->builtin_types.entry_invalid; 19506 ZigType *ptr_type = value->value.type; 19507 19508 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 19509 assert(ptr_type->id == ZigTypeIdPointer); 19510 19511 ZigType *type_entry = ptr_type->data.pointer.child_type; 19512 if (type_is_invalid(type_entry)) { 19513 return ira->codegen->builtin_types.entry_invalid; 19514 } else if (type_entry->id == ZigTypeIdErrorUnion) { 19515 if (instr_is_comptime(value)) { 19516 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); 19517 if (!ptr_val) 19518 return ira->codegen->builtin_types.entry_invalid; 19519 ConstExprValue *err_union_val = ir_const_ptr_pointee(ira, ptr_val, instruction->base.source_node); 19520 if (err_union_val == nullptr) 19521 return ira->codegen->builtin_types.entry_invalid; 19522 if (err_union_val->special != ConstValSpecialRuntime) { 19523 ErrorTableEntry *err = err_union_val->data.x_err_union.err; 19524 assert(err); 19525 19526 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19527 out_val->data.x_err_set = err; 19528 return type_entry->data.error_union.err_set_type; 19529 } 19530 } 19531 19532 ir_build_unwrap_err_code_from(&ira->new_irb, &instruction->base, value); 19533 return type_entry->data.error_union.err_set_type; 19534 } else { 19535 ir_add_error(ira, value, 19536 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 19537 return ira->codegen->builtin_types.entry_invalid; 19538 } 19539 } 19540 19541 static ZigType *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, 19542 IrInstructionUnwrapErrPayload *instruction) 19543 { 19544 assert(instruction->value->other); 19545 IrInstruction *value = instruction->value->other; 19546 if (type_is_invalid(value->value.type)) 19547 return ira->codegen->builtin_types.entry_invalid; 19548 ZigType *ptr_type = value->value.type; 19549 19550 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 19551 assert(ptr_type->id == ZigTypeIdPointer); 19552 19553 ZigType *type_entry = ptr_type->data.pointer.child_type; 19554 if (type_is_invalid(type_entry)) { 19555 return ira->codegen->builtin_types.entry_invalid; 19556 } else if (type_entry->id == ZigTypeIdErrorUnion) { 19557 ZigType *payload_type = type_entry->data.error_union.payload_type; 19558 if (type_is_invalid(payload_type)) { 19559 return ira->codegen->builtin_types.entry_invalid; 19560 } 19561 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, 19562 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 19563 PtrLenSingle, 19564 get_abi_alignment(ira->codegen, payload_type), 0, 0); 19565 if (instr_is_comptime(value)) { 19566 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); 19567 if (!ptr_val) 19568 return ira->codegen->builtin_types.entry_invalid; 19569 ConstExprValue *err_union_val = ir_const_ptr_pointee(ira, ptr_val, instruction->base.source_node); 19570 if (err_union_val == nullptr) 19571 return ira->codegen->builtin_types.entry_invalid; 19572 if (err_union_val->special != ConstValSpecialRuntime) { 19573 ErrorTableEntry *err = err_union_val->data.x_err_union.err; 19574 if (err != nullptr) { 19575 ir_add_error(ira, &instruction->base, 19576 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); 19577 return ira->codegen->builtin_types.entry_invalid; 19578 } 19579 19580 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19581 out_val->data.x_ptr.special = ConstPtrSpecialRef; 19582 out_val->data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; 19583 return result_type; 19584 } 19585 } 19586 19587 ir_build_unwrap_err_payload_from(&ira->new_irb, &instruction->base, value, instruction->safety_check_on); 19588 return result_type; 19589 } else { 19590 ir_add_error(ira, value, 19591 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 19592 return ira->codegen->builtin_types.entry_invalid; 19593 } 19594 19595 } 19596 19597 static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { 19598 AstNode *proto_node = instruction->base.source_node; 19599 assert(proto_node->type == NodeTypeFnProto); 19600 19601 if (proto_node->data.fn_proto.auto_err_set) { 19602 ir_add_error(ira, &instruction->base, 19603 buf_sprintf("inferring error set of return type valid only for function definitions")); 19604 return ira->codegen->builtin_types.entry_invalid; 19605 } 19606 19607 FnTypeId fn_type_id = {0}; 19608 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); 19609 19610 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { 19611 AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); 19612 assert(param_node->type == NodeTypeParamDecl); 19613 19614 bool param_is_var_args = param_node->data.param_decl.is_var_args; 19615 if (param_is_var_args) { 19616 if (fn_type_id.cc == CallingConventionC) { 19617 fn_type_id.param_count = fn_type_id.next_param_index; 19618 continue; 19619 } else if (fn_type_id.cc == CallingConventionUnspecified) { 19620 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19621 out_val->data.x_type = get_generic_fn_type(ira->codegen, &fn_type_id); 19622 return ira->codegen->builtin_types.entry_type; 19623 } else { 19624 zig_unreachable(); 19625 } 19626 } 19627 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; 19628 param_info->is_noalias = param_node->data.param_decl.is_noalias; 19629 19630 if (instruction->param_types[fn_type_id.next_param_index] == nullptr) { 19631 param_info->type = nullptr; 19632 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19633 out_val->data.x_type = get_generic_fn_type(ira->codegen, &fn_type_id); 19634 return ira->codegen->builtin_types.entry_type; 19635 } else { 19636 IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->other; 19637 if (type_is_invalid(param_type_value->value.type)) 19638 return ira->codegen->builtin_types.entry_invalid; 19639 param_info->type = ir_resolve_type(ira, param_type_value); 19640 if (type_is_invalid(param_info->type)) 19641 return ira->codegen->builtin_types.entry_invalid; 19642 } 19643 19644 } 19645 19646 if (instruction->align_value != nullptr) { 19647 if (!ir_resolve_align(ira, instruction->align_value->other, &fn_type_id.alignment)) 19648 return ira->codegen->builtin_types.entry_invalid; 19649 } 19650 19651 IrInstruction *return_type_value = instruction->return_type->other; 19652 fn_type_id.return_type = ir_resolve_type(ira, return_type_value); 19653 if (type_is_invalid(fn_type_id.return_type)) 19654 return ira->codegen->builtin_types.entry_invalid; 19655 if (fn_type_id.return_type->id == ZigTypeIdOpaque) { 19656 ir_add_error(ira, instruction->return_type, 19657 buf_sprintf("return type cannot be opaque")); 19658 return ira->codegen->builtin_types.entry_invalid; 19659 } 19660 19661 if (fn_type_id.cc == CallingConventionAsync) { 19662 if (instruction->async_allocator_type_value == nullptr) { 19663 ir_add_error(ira, &instruction->base, 19664 buf_sprintf("async fn proto missing allocator type")); 19665 return ira->codegen->builtin_types.entry_invalid; 19666 } 19667 IrInstruction *async_allocator_type_value = instruction->async_allocator_type_value->other; 19668 fn_type_id.async_allocator_type = ir_resolve_type(ira, async_allocator_type_value); 19669 if (type_is_invalid(fn_type_id.async_allocator_type)) 19670 return ira->codegen->builtin_types.entry_invalid; 19671 } 19672 19673 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19674 out_val->data.x_type = get_fn_type(ira->codegen, &fn_type_id); 19675 return ira->codegen->builtin_types.entry_type; 19676 } 19677 19678 static ZigType *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { 19679 IrInstruction *value = instruction->value->other; 19680 if (type_is_invalid(value->value.type)) 19681 return ira->codegen->builtin_types.entry_invalid; 19682 19683 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 19684 out_val->data.x_bool = instr_is_comptime(value); 19685 return ira->codegen->builtin_types.entry_bool; 19686 } 19687 19688 static ZigType *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, 19689 IrInstructionCheckSwitchProngs *instruction) 19690 { 19691 IrInstruction *target_value = instruction->target_value->other; 19692 ZigType *switch_type = target_value->value.type; 19693 if (type_is_invalid(switch_type)) 19694 return ira->codegen->builtin_types.entry_invalid; 19695 19696 if (switch_type->id == ZigTypeIdEnum) { 19697 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> field_prev_uses = {}; 19698 field_prev_uses.init(switch_type->data.enumeration.src_field_count); 19699 19700 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 19701 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 19702 19703 IrInstruction *start_value = range->start->other; 19704 if (type_is_invalid(start_value->value.type)) 19705 return ira->codegen->builtin_types.entry_invalid; 19706 19707 IrInstruction *end_value = range->end->other; 19708 if (type_is_invalid(end_value->value.type)) 19709 return ira->codegen->builtin_types.entry_invalid; 19710 19711 if (start_value->value.type->id != ZigTypeIdEnum) { 19712 ir_add_error(ira, range->start, buf_sprintf("not an enum type")); 19713 return ira->codegen->builtin_types.entry_invalid; 19714 } 19715 19716 BigInt start_index; 19717 bigint_init_bigint(&start_index, &start_value->value.data.x_enum_tag); 19718 19719 assert(end_value->value.type->id == ZigTypeIdEnum); 19720 BigInt end_index; 19721 bigint_init_bigint(&end_index, &end_value->value.data.x_enum_tag); 19722 19723 BigInt field_index; 19724 bigint_init_bigint(&field_index, &start_index); 19725 for (;;) { 19726 Cmp cmp = bigint_cmp(&field_index, &end_index); 19727 if (cmp == CmpGT) { 19728 break; 19729 } 19730 auto entry = field_prev_uses.put_unique(field_index, start_value->source_node); 19731 if (entry) { 19732 AstNode *prev_node = entry->value; 19733 TypeEnumField *enum_field = find_enum_field_by_tag(switch_type, &field_index); 19734 assert(enum_field != nullptr); 19735 ErrorMsg *msg = ir_add_error(ira, start_value, 19736 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), 19737 buf_ptr(enum_field->name))); 19738 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 19739 } 19740 bigint_incr(&field_index); 19741 } 19742 } 19743 if (!instruction->have_else_prong) { 19744 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { 19745 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; 19746 19747 auto entry = field_prev_uses.maybe_get(enum_field->value); 19748 if (!entry) { 19749 ir_add_error(ira, &instruction->base, 19750 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), 19751 buf_ptr(enum_field->name))); 19752 } 19753 } 19754 } 19755 } else if (switch_type->id == ZigTypeIdErrorSet) { 19756 if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->source_node)) { 19757 return ira->codegen->builtin_types.entry_invalid; 19758 } 19759 19760 AstNode **field_prev_uses = allocate<AstNode *>(ira->codegen->errors_by_index.length); 19761 19762 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 19763 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 19764 19765 IrInstruction *start_value = range->start->other; 19766 if (type_is_invalid(start_value->value.type)) 19767 return ira->codegen->builtin_types.entry_invalid; 19768 19769 IrInstruction *end_value = range->end->other; 19770 if (type_is_invalid(end_value->value.type)) 19771 return ira->codegen->builtin_types.entry_invalid; 19772 19773 assert(start_value->value.type->id == ZigTypeIdErrorSet); 19774 uint32_t start_index = start_value->value.data.x_err_set->value; 19775 19776 assert(end_value->value.type->id == ZigTypeIdErrorSet); 19777 uint32_t end_index = end_value->value.data.x_err_set->value; 19778 19779 if (start_index != end_index) { 19780 ir_add_error(ira, end_value, buf_sprintf("ranges not allowed when switching on errors")); 19781 return ira->codegen->builtin_types.entry_invalid; 19782 } 19783 19784 AstNode *prev_node = field_prev_uses[start_index]; 19785 if (prev_node != nullptr) { 19786 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name; 19787 ErrorMsg *msg = ir_add_error(ira, start_value, 19788 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name))); 19789 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 19790 } 19791 field_prev_uses[start_index] = start_value->source_node; 19792 } 19793 if (!instruction->have_else_prong) { 19794 if (type_is_global_error_set(switch_type)) { 19795 ir_add_error(ira, &instruction->base, 19796 buf_sprintf("else prong required when switching on type 'error'")); 19797 return ira->codegen->builtin_types.entry_invalid; 19798 } else { 19799 for (uint32_t i = 0; i < switch_type->data.error_set.err_count; i += 1) { 19800 ErrorTableEntry *err_entry = switch_type->data.error_set.errors[i]; 19801 19802 AstNode *prev_node = field_prev_uses[err_entry->value]; 19803 if (prev_node == nullptr) { 19804 ir_add_error(ira, &instruction->base, 19805 buf_sprintf("error.%s not handled in switch", buf_ptr(&err_entry->name))); 19806 } 19807 } 19808 } 19809 } 19810 19811 free(field_prev_uses); 19812 } else if (switch_type->id == ZigTypeIdInt) { 19813 RangeSet rs = {0}; 19814 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 19815 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 19816 19817 IrInstruction *start_value = range->start->other; 19818 if (type_is_invalid(start_value->value.type)) 19819 return ira->codegen->builtin_types.entry_invalid; 19820 IrInstruction *casted_start_value = ir_implicit_cast(ira, start_value, switch_type); 19821 if (type_is_invalid(casted_start_value->value.type)) 19822 return ira->codegen->builtin_types.entry_invalid; 19823 19824 IrInstruction *end_value = range->end->other; 19825 if (type_is_invalid(end_value->value.type)) 19826 return ira->codegen->builtin_types.entry_invalid; 19827 IrInstruction *casted_end_value = ir_implicit_cast(ira, end_value, switch_type); 19828 if (type_is_invalid(casted_end_value->value.type)) 19829 return ira->codegen->builtin_types.entry_invalid; 19830 19831 ConstExprValue *start_val = ir_resolve_const(ira, casted_start_value, UndefBad); 19832 if (!start_val) 19833 return ira->codegen->builtin_types.entry_invalid; 19834 19835 ConstExprValue *end_val = ir_resolve_const(ira, casted_end_value, UndefBad); 19836 if (!end_val) 19837 return ira->codegen->builtin_types.entry_invalid; 19838 19839 assert(start_val->type->id == ZigTypeIdInt || start_val->type->id == ZigTypeIdComptimeInt); 19840 assert(end_val->type->id == ZigTypeIdInt || end_val->type->id == ZigTypeIdComptimeInt); 19841 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint, 19842 start_value->source_node); 19843 if (prev_node != nullptr) { 19844 ErrorMsg *msg = ir_add_error(ira, start_value, buf_sprintf("duplicate switch value")); 19845 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("previous value is here")); 19846 return ira->codegen->builtin_types.entry_invalid; 19847 } 19848 } 19849 if (!instruction->have_else_prong) { 19850 BigInt min_val; 19851 eval_min_max_value_int(ira->codegen, switch_type, &min_val, false); 19852 BigInt max_val; 19853 eval_min_max_value_int(ira->codegen, switch_type, &max_val, true); 19854 if (!rangeset_spans(&rs, &min_val, &max_val)) { 19855 ir_add_error(ira, &instruction->base, buf_sprintf("switch must handle all possibilities")); 19856 return ira->codegen->builtin_types.entry_invalid; 19857 } 19858 } 19859 } else if (!instruction->have_else_prong) { 19860 ir_add_error(ira, &instruction->base, 19861 buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); 19862 return ira->codegen->builtin_types.entry_invalid; 19863 } 19864 ir_build_const_from(ira, &instruction->base); 19865 return ira->codegen->builtin_types.entry_void; 19866 } 19867 19868 static ZigType *ir_analyze_instruction_check_statement_is_void(IrAnalyze *ira, 19869 IrInstructionCheckStatementIsVoid *instruction) 19870 { 19871 IrInstruction *statement_value = instruction->statement_value->other; 19872 ZigType *statement_type = statement_value->value.type; 19873 if (type_is_invalid(statement_type)) 19874 return ira->codegen->builtin_types.entry_invalid; 19875 19876 if (statement_type->id != ZigTypeIdVoid) { 19877 ir_add_error(ira, &instruction->base, buf_sprintf("expression value is ignored")); 19878 } 19879 19880 ir_build_const_from(ira, &instruction->base); 19881 return ira->codegen->builtin_types.entry_void; 19882 } 19883 19884 static ZigType *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructionPanic *instruction) { 19885 IrInstruction *msg = instruction->msg->other; 19886 if (type_is_invalid(msg->value.type)) 19887 return ir_unreach_error(ira); 19888 19889 if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) { 19890 ir_add_error(ira, &instruction->base, buf_sprintf("encountered @panic at compile-time")); 19891 return ir_unreach_error(ira); 19892 } 19893 19894 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 19895 true, false, PtrLenUnknown, get_abi_alignment(ira->codegen, ira->codegen->builtin_types.entry_u8), 0, 0); 19896 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 19897 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type); 19898 if (type_is_invalid(casted_msg->value.type)) 19899 return ir_unreach_error(ira); 19900 19901 IrInstruction *new_instruction = ir_build_panic(&ira->new_irb, instruction->base.scope, 19902 instruction->base.source_node, casted_msg); 19903 ir_link_new_instruction(new_instruction, &instruction->base); 19904 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); 19905 } 19906 19907 static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint32_t align_bytes, bool safety_check_on) { 19908 ZigType *target_type = target->value.type; 19909 assert(!type_is_invalid(target_type)); 19910 19911 ZigType *result_type; 19912 uint32_t old_align_bytes; 19913 19914 if (target_type->id == ZigTypeIdPointer) { 19915 result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes); 19916 old_align_bytes = target_type->data.pointer.alignment; 19917 } else if (target_type->id == ZigTypeIdFn) { 19918 FnTypeId fn_type_id = target_type->data.fn.fn_type_id; 19919 old_align_bytes = fn_type_id.alignment; 19920 fn_type_id.alignment = align_bytes; 19921 result_type = get_fn_type(ira->codegen, &fn_type_id); 19922 } else if (target_type->id == ZigTypeIdOptional && 19923 target_type->data.maybe.child_type->id == ZigTypeIdPointer) 19924 { 19925 ZigType *ptr_type = target_type->data.maybe.child_type; 19926 old_align_bytes = ptr_type->data.pointer.alignment; 19927 ZigType *better_ptr_type = adjust_ptr_align(ira->codegen, ptr_type, align_bytes); 19928 19929 result_type = get_optional_type(ira->codegen, better_ptr_type); 19930 } else if (target_type->id == ZigTypeIdOptional && 19931 target_type->data.maybe.child_type->id == ZigTypeIdFn) 19932 { 19933 FnTypeId fn_type_id = target_type->data.maybe.child_type->data.fn.fn_type_id; 19934 old_align_bytes = fn_type_id.alignment; 19935 fn_type_id.alignment = align_bytes; 19936 ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id); 19937 result_type = get_optional_type(ira->codegen, fn_type); 19938 } else if (is_slice(target_type)) { 19939 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry; 19940 old_align_bytes = slice_ptr_type->data.pointer.alignment; 19941 ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes); 19942 result_type = get_slice_type(ira->codegen, result_ptr_type); 19943 } else { 19944 ir_add_error(ira, target, 19945 buf_sprintf("expected pointer or slice, found '%s'", buf_ptr(&target_type->name))); 19946 return ira->codegen->invalid_instruction; 19947 } 19948 19949 if (instr_is_comptime(target)) { 19950 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 19951 if (!val) 19952 return ira->codegen->invalid_instruction; 19953 19954 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 19955 val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0) 19956 { 19957 ir_add_error(ira, target, 19958 buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes", 19959 val->data.x_ptr.data.hard_coded_addr.addr, align_bytes)); 19960 return ira->codegen->invalid_instruction; 19961 } 19962 19963 IrInstruction *result = ir_create_const(&ira->new_irb, target->scope, target->source_node, result_type); 19964 copy_const_val(&result->value, val, false); 19965 result->value.type = result_type; 19966 return result; 19967 } 19968 19969 IrInstruction *result; 19970 if (safety_check_on && align_bytes > old_align_bytes && align_bytes != 1) { 19971 result = ir_build_align_cast(&ira->new_irb, target->scope, target->source_node, nullptr, target); 19972 } else { 19973 result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, result_type, target, CastOpNoop); 19974 } 19975 result->value.type = result_type; 19976 return result; 19977 } 19978 19979 static ZigType *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtrCast *instruction) { 19980 Error err; 19981 19982 IrInstruction *dest_type_value = instruction->dest_type->other; 19983 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 19984 if (type_is_invalid(dest_type)) 19985 return ira->codegen->builtin_types.entry_invalid; 19986 19987 IrInstruction *ptr = instruction->ptr->other; 19988 ZigType *src_type = ptr->value.type; 19989 if (type_is_invalid(src_type)) 19990 return ira->codegen->builtin_types.entry_invalid; 19991 19992 if (get_codegen_ptr_type(src_type) == nullptr) { 19993 ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); 19994 return ira->codegen->builtin_types.entry_invalid; 19995 } 19996 19997 if (get_codegen_ptr_type(dest_type) == nullptr) { 19998 ir_add_error(ira, dest_type_value, 19999 buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 20000 return ira->codegen->builtin_types.entry_invalid; 20001 } 20002 20003 if (get_ptr_const(src_type) && !get_ptr_const(dest_type)) { 20004 ir_add_error(ira, &instruction->base, buf_sprintf("cast discards const qualifier")); 20005 return ira->codegen->builtin_types.entry_invalid; 20006 } 20007 20008 if (instr_is_comptime(ptr)) { 20009 ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk); 20010 if (!val) 20011 return ira->codegen->builtin_types.entry_invalid; 20012 20013 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 20014 copy_const_val(out_val, val, false); 20015 out_val->type = dest_type; 20016 return dest_type; 20017 } 20018 20019 uint32_t src_align_bytes = get_ptr_align(src_type); 20020 uint32_t dest_align_bytes = get_ptr_align(dest_type); 20021 20022 if (dest_align_bytes > src_align_bytes) { 20023 ErrorMsg *msg = ir_add_error(ira, &instruction->base, buf_sprintf("cast increases pointer alignment")); 20024 add_error_note(ira->codegen, msg, ptr->source_node, 20025 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); 20026 add_error_note(ira->codegen, msg, dest_type_value->source_node, 20027 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_type->name), dest_align_bytes)); 20028 return ira->codegen->builtin_types.entry_invalid; 20029 } 20030 20031 IrInstruction *casted_ptr = ir_build_ptr_cast(&ira->new_irb, instruction->base.scope, 20032 instruction->base.source_node, nullptr, ptr); 20033 casted_ptr->value.type = dest_type; 20034 20035 // Keep the bigger alignment, it can only help- 20036 // unless the target is zero bits. 20037 if ((err = type_ensure_zero_bits_known(ira->codegen, dest_type))) 20038 return ira->codegen->builtin_types.entry_invalid; 20039 20040 IrInstruction *result; 20041 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { 20042 result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); 20043 if (type_is_invalid(result->value.type)) 20044 return ira->codegen->builtin_types.entry_invalid; 20045 } else { 20046 result = casted_ptr; 20047 } 20048 ir_link_new_instruction(result, &instruction->base); 20049 return result->value.type; 20050 } 20051 20052 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) { 20053 assert(val->special == ConstValSpecialStatic); 20054 switch (val->type->id) { 20055 case ZigTypeIdInvalid: 20056 case ZigTypeIdMetaType: 20057 case ZigTypeIdOpaque: 20058 case ZigTypeIdBoundFn: 20059 case ZigTypeIdArgTuple: 20060 case ZigTypeIdNamespace: 20061 case ZigTypeIdBlock: 20062 case ZigTypeIdUnreachable: 20063 case ZigTypeIdComptimeFloat: 20064 case ZigTypeIdComptimeInt: 20065 case ZigTypeIdUndefined: 20066 case ZigTypeIdNull: 20067 case ZigTypeIdPromise: 20068 zig_unreachable(); 20069 case ZigTypeIdVoid: 20070 return; 20071 case ZigTypeIdBool: 20072 buf[0] = val->data.x_bool ? 1 : 0; 20073 return; 20074 case ZigTypeIdInt: 20075 bigint_write_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 20076 codegen->is_big_endian); 20077 return; 20078 case ZigTypeIdFloat: 20079 float_write_ieee597(val, buf, codegen->is_big_endian); 20080 return; 20081 case ZigTypeIdPointer: 20082 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 20083 BigInt bn; 20084 bigint_init_unsigned(&bn, val->data.x_ptr.data.hard_coded_addr.addr); 20085 bigint_write_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, codegen->is_big_endian); 20086 return; 20087 } else { 20088 zig_unreachable(); 20089 } 20090 case ZigTypeIdArray: 20091 { 20092 size_t buf_i = 0; 20093 expand_undef_array(codegen, val); 20094 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) { 20095 ConstExprValue *elem = &val->data.x_array.s_none.elements[elem_i]; 20096 buf_write_value_bytes(codegen, &buf[buf_i], elem); 20097 buf_i += type_size(codegen, elem->type); 20098 } 20099 } 20100 return; 20101 case ZigTypeIdStruct: 20102 zig_panic("TODO buf_write_value_bytes struct type"); 20103 case ZigTypeIdOptional: 20104 zig_panic("TODO buf_write_value_bytes maybe type"); 20105 case ZigTypeIdErrorUnion: 20106 zig_panic("TODO buf_write_value_bytes error union"); 20107 case ZigTypeIdErrorSet: 20108 zig_panic("TODO buf_write_value_bytes pure error type"); 20109 case ZigTypeIdEnum: 20110 zig_panic("TODO buf_write_value_bytes enum type"); 20111 case ZigTypeIdFn: 20112 zig_panic("TODO buf_write_value_bytes fn type"); 20113 case ZigTypeIdUnion: 20114 zig_panic("TODO buf_write_value_bytes union type"); 20115 } 20116 zig_unreachable(); 20117 } 20118 20119 static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) { 20120 assert(val->special == ConstValSpecialStatic); 20121 switch (val->type->id) { 20122 case ZigTypeIdInvalid: 20123 case ZigTypeIdMetaType: 20124 case ZigTypeIdOpaque: 20125 case ZigTypeIdBoundFn: 20126 case ZigTypeIdArgTuple: 20127 case ZigTypeIdNamespace: 20128 case ZigTypeIdBlock: 20129 case ZigTypeIdUnreachable: 20130 case ZigTypeIdComptimeFloat: 20131 case ZigTypeIdComptimeInt: 20132 case ZigTypeIdUndefined: 20133 case ZigTypeIdNull: 20134 case ZigTypeIdPromise: 20135 zig_unreachable(); 20136 case ZigTypeIdVoid: 20137 return; 20138 case ZigTypeIdBool: 20139 val->data.x_bool = (buf[0] != 0); 20140 return; 20141 case ZigTypeIdInt: 20142 bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 20143 codegen->is_big_endian, val->type->data.integral.is_signed); 20144 return; 20145 case ZigTypeIdFloat: 20146 float_read_ieee597(val, buf, codegen->is_big_endian); 20147 return; 20148 case ZigTypeIdPointer: 20149 { 20150 val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 20151 BigInt bn; 20152 bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, 20153 codegen->is_big_endian, false); 20154 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn); 20155 return; 20156 } 20157 case ZigTypeIdArray: 20158 zig_panic("TODO buf_read_value_bytes array type"); 20159 case ZigTypeIdStruct: 20160 zig_panic("TODO buf_read_value_bytes struct type"); 20161 case ZigTypeIdOptional: 20162 zig_panic("TODO buf_read_value_bytes maybe type"); 20163 case ZigTypeIdErrorUnion: 20164 zig_panic("TODO buf_read_value_bytes error union"); 20165 case ZigTypeIdErrorSet: 20166 zig_panic("TODO buf_read_value_bytes pure error type"); 20167 case ZigTypeIdEnum: 20168 zig_panic("TODO buf_read_value_bytes enum type"); 20169 case ZigTypeIdFn: 20170 zig_panic("TODO buf_read_value_bytes fn type"); 20171 case ZigTypeIdUnion: 20172 zig_panic("TODO buf_read_value_bytes union type"); 20173 } 20174 zig_unreachable(); 20175 } 20176 20177 static ZigType *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) { 20178 Error err; 20179 IrInstruction *dest_type_value = instruction->dest_type->other; 20180 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 20181 if (type_is_invalid(dest_type)) 20182 return ira->codegen->builtin_types.entry_invalid; 20183 20184 IrInstruction *value = instruction->value->other; 20185 ZigType *src_type = value->value.type; 20186 if (type_is_invalid(src_type)) 20187 return ira->codegen->builtin_types.entry_invalid; 20188 20189 if ((err = ensure_complete_type(ira->codegen, dest_type))) 20190 return ira->codegen->builtin_types.entry_invalid; 20191 20192 if ((err = ensure_complete_type(ira->codegen, src_type))) 20193 return ira->codegen->builtin_types.entry_invalid; 20194 20195 if (get_codegen_ptr_type(src_type) != nullptr) { 20196 ir_add_error(ira, value, 20197 buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name))); 20198 return ira->codegen->builtin_types.entry_invalid; 20199 } 20200 20201 switch (src_type->id) { 20202 case ZigTypeIdInvalid: 20203 case ZigTypeIdMetaType: 20204 case ZigTypeIdOpaque: 20205 case ZigTypeIdBoundFn: 20206 case ZigTypeIdArgTuple: 20207 case ZigTypeIdNamespace: 20208 case ZigTypeIdBlock: 20209 case ZigTypeIdUnreachable: 20210 case ZigTypeIdComptimeFloat: 20211 case ZigTypeIdComptimeInt: 20212 case ZigTypeIdUndefined: 20213 case ZigTypeIdNull: 20214 ir_add_error(ira, dest_type_value, 20215 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name))); 20216 return ira->codegen->builtin_types.entry_invalid; 20217 default: 20218 break; 20219 } 20220 20221 if (get_codegen_ptr_type(dest_type) != nullptr) { 20222 ir_add_error(ira, dest_type_value, 20223 buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); 20224 return ira->codegen->builtin_types.entry_invalid; 20225 } 20226 20227 switch (dest_type->id) { 20228 case ZigTypeIdInvalid: 20229 case ZigTypeIdMetaType: 20230 case ZigTypeIdOpaque: 20231 case ZigTypeIdBoundFn: 20232 case ZigTypeIdArgTuple: 20233 case ZigTypeIdNamespace: 20234 case ZigTypeIdBlock: 20235 case ZigTypeIdUnreachable: 20236 case ZigTypeIdComptimeFloat: 20237 case ZigTypeIdComptimeInt: 20238 case ZigTypeIdUndefined: 20239 case ZigTypeIdNull: 20240 ir_add_error(ira, dest_type_value, 20241 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); 20242 return ira->codegen->builtin_types.entry_invalid; 20243 default: 20244 break; 20245 } 20246 20247 uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); 20248 uint64_t src_size_bytes = type_size(ira->codegen, src_type); 20249 if (dest_size_bytes != src_size_bytes) { 20250 ir_add_error(ira, &instruction->base, 20251 buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64, 20252 buf_ptr(&dest_type->name), dest_size_bytes, 20253 buf_ptr(&src_type->name), src_size_bytes)); 20254 return ira->codegen->builtin_types.entry_invalid; 20255 } 20256 20257 if (instr_is_comptime(value)) { 20258 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 20259 if (!val) 20260 return ira->codegen->builtin_types.entry_invalid; 20261 20262 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 20263 out_val->type = dest_type; 20264 uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes); 20265 buf_write_value_bytes(ira->codegen, buf, val); 20266 buf_read_value_bytes(ira->codegen, buf, out_val); 20267 return dest_type; 20268 } 20269 20270 IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope, 20271 instruction->base.source_node, nullptr, value); 20272 ir_link_new_instruction(result, &instruction->base); 20273 result->value.type = dest_type; 20274 return dest_type; 20275 } 20276 20277 static ZigType *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) { 20278 Error err; 20279 IrInstruction *dest_type_value = instruction->dest_type->other; 20280 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 20281 if (type_is_invalid(dest_type)) 20282 return ira->codegen->builtin_types.entry_invalid; 20283 20284 if (get_codegen_ptr_type(dest_type) == nullptr) { 20285 ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 20286 return ira->codegen->builtin_types.entry_invalid; 20287 } 20288 20289 if ((err = type_ensure_zero_bits_known(ira->codegen, dest_type))) 20290 return ira->codegen->builtin_types.entry_invalid; 20291 if (!type_has_bits(dest_type)) { 20292 ir_add_error(ira, dest_type_value, 20293 buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name))); 20294 return ira->codegen->builtin_types.entry_invalid; 20295 } 20296 20297 IrInstruction *target = instruction->target->other; 20298 if (type_is_invalid(target->value.type)) 20299 return ira->codegen->builtin_types.entry_invalid; 20300 20301 IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); 20302 if (type_is_invalid(casted_int->value.type)) 20303 return ira->codegen->builtin_types.entry_invalid; 20304 20305 if (instr_is_comptime(casted_int)) { 20306 ConstExprValue *val = ir_resolve_const(ira, casted_int, UndefBad); 20307 if (!val) 20308 return ira->codegen->builtin_types.entry_invalid; 20309 20310 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 20311 out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 20312 out_val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&val->data.x_bigint); 20313 return dest_type; 20314 } 20315 20316 IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, instruction->base.scope, 20317 instruction->base.source_node, nullptr, casted_int); 20318 ir_link_new_instruction(result, &instruction->base); 20319 return dest_type; 20320 } 20321 20322 static ZigType *ir_analyze_instruction_decl_ref(IrAnalyze *ira, 20323 IrInstructionDeclRef *instruction) 20324 { 20325 Tld *tld = instruction->tld; 20326 LVal lval = instruction->lval; 20327 20328 resolve_top_level_decl(ira->codegen, tld, lval == LValPtr, instruction->base.source_node); 20329 if (tld->resolution == TldResolutionInvalid) 20330 return ira->codegen->builtin_types.entry_invalid; 20331 20332 switch (tld->id) { 20333 case TldIdContainer: 20334 case TldIdCompTime: 20335 zig_unreachable(); 20336 case TldIdVar: 20337 { 20338 TldVar *tld_var = (TldVar *)tld; 20339 ZigVar *var = tld_var->var; 20340 20341 IrInstruction *var_ptr = ir_get_var_ptr(ira, &instruction->base, var); 20342 if (type_is_invalid(var_ptr->value.type)) 20343 return ira->codegen->builtin_types.entry_invalid; 20344 20345 if (tld_var->extern_lib_name != nullptr) { 20346 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, instruction->base.source_node); 20347 } 20348 20349 if (lval == LValPtr) { 20350 ir_link_new_instruction(var_ptr, &instruction->base); 20351 return var_ptr->value.type; 20352 } else { 20353 IrInstruction *loaded_instr = ir_get_deref(ira, &instruction->base, var_ptr); 20354 ir_link_new_instruction(loaded_instr, &instruction->base); 20355 return loaded_instr->value.type; 20356 } 20357 } 20358 case TldIdFn: 20359 { 20360 TldFn *tld_fn = (TldFn *)tld; 20361 ZigFn *fn_entry = tld_fn->fn_entry; 20362 assert(fn_entry->type_entry); 20363 20364 if (tld_fn->extern_lib_name != nullptr) { 20365 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, instruction->base.source_node); 20366 } 20367 20368 IrInstruction *ref_instruction = ir_create_const_fn(&ira->new_irb, instruction->base.scope, 20369 instruction->base.source_node, fn_entry); 20370 if (lval == LValPtr) { 20371 IrInstruction *ptr_instr = ir_get_ref(ira, &instruction->base, ref_instruction, true, false); 20372 ir_link_new_instruction(ptr_instr, &instruction->base); 20373 return ptr_instr->value.type; 20374 } else { 20375 ir_link_new_instruction(ref_instruction, &instruction->base); 20376 return ref_instruction->value.type; 20377 } 20378 } 20379 } 20380 zig_unreachable(); 20381 } 20382 20383 static ZigType *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { 20384 IrInstruction *target = instruction->target->other; 20385 if (type_is_invalid(target->value.type)) 20386 return ira->codegen->builtin_types.entry_invalid; 20387 20388 ZigType *usize = ira->codegen->builtin_types.entry_usize; 20389 20390 if (get_codegen_ptr_type(target->value.type) == nullptr) { 20391 ir_add_error(ira, target, 20392 buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value.type->name))); 20393 return ira->codegen->builtin_types.entry_invalid; 20394 } 20395 20396 if (!type_has_bits(target->value.type)) { 20397 ir_add_error(ira, target, 20398 buf_sprintf("pointer to size 0 type has no address")); 20399 return ira->codegen->builtin_types.entry_invalid; 20400 } 20401 20402 if (instr_is_comptime(target)) { 20403 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 20404 if (!val) 20405 return ira->codegen->builtin_types.entry_invalid; 20406 if (val->type->id == ZigTypeIdPointer && val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 20407 IrInstruction *result = ir_create_const(&ira->new_irb, instruction->base.scope, 20408 instruction->base.source_node, usize); 20409 bigint_init_unsigned(&result->value.data.x_bigint, val->data.x_ptr.data.hard_coded_addr.addr); 20410 ir_link_new_instruction(result, &instruction->base); 20411 return usize; 20412 } 20413 } 20414 20415 IrInstruction *result = ir_build_ptr_to_int(&ira->new_irb, instruction->base.scope, 20416 instruction->base.source_node, target); 20417 result->value.type = usize; 20418 ir_link_new_instruction(result, &instruction->base); 20419 return usize; 20420 } 20421 20422 static ZigType *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) { 20423 Error err; 20424 ZigType *child_type = ir_resolve_type(ira, instruction->child_type->other); 20425 if (type_is_invalid(child_type)) 20426 return ira->codegen->builtin_types.entry_invalid; 20427 20428 if (child_type->id == ZigTypeIdUnreachable) { 20429 ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed")); 20430 return ira->codegen->builtin_types.entry_invalid; 20431 } else if (child_type->id == ZigTypeIdOpaque && instruction->ptr_len == PtrLenUnknown) { 20432 ir_add_error(ira, &instruction->base, buf_sprintf("unknown-length pointer to opaque")); 20433 return ira->codegen->builtin_types.entry_invalid; 20434 } 20435 20436 uint32_t align_bytes; 20437 if (instruction->align_value != nullptr) { 20438 if (!ir_resolve_align(ira, instruction->align_value->other, &align_bytes)) 20439 return ira->codegen->builtin_types.entry_invalid; 20440 } else { 20441 if ((err = type_ensure_zero_bits_known(ira->codegen, child_type))) 20442 return ira->codegen->builtin_types.entry_invalid; 20443 align_bytes = get_abi_alignment(ira->codegen, child_type); 20444 } 20445 20446 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 20447 out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type, 20448 instruction->is_const, instruction->is_volatile, 20449 instruction->ptr_len, align_bytes, 20450 instruction->bit_offset_start, instruction->bit_offset_end - instruction->bit_offset_start); 20451 20452 return ira->codegen->builtin_types.entry_type; 20453 } 20454 20455 static ZigType *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstructionAlignCast *instruction) { 20456 uint32_t align_bytes; 20457 IrInstruction *align_bytes_inst = instruction->align_bytes->other; 20458 if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes)) 20459 return ira->codegen->builtin_types.entry_invalid; 20460 20461 IrInstruction *target = instruction->target->other; 20462 if (type_is_invalid(target->value.type)) 20463 return ira->codegen->builtin_types.entry_invalid; 20464 20465 IrInstruction *result = ir_align_cast(ira, target, align_bytes, true); 20466 if (type_is_invalid(result->value.type)) 20467 return ira->codegen->builtin_types.entry_invalid; 20468 20469 ir_link_new_instruction(result, &instruction->base); 20470 return result->value.type; 20471 } 20472 20473 static ZigType *ir_analyze_instruction_opaque_type(IrAnalyze *ira, IrInstructionOpaqueType *instruction) { 20474 Buf *name = get_anon_type_name(ira->codegen, ira->new_irb.exec, "opaque", instruction->base.source_node); 20475 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 20476 out_val->data.x_type = get_opaque_type(ira->codegen, instruction->base.scope, instruction->base.source_node, 20477 buf_ptr(name)); 20478 return ira->codegen->builtin_types.entry_type; 20479 } 20480 20481 static ZigType *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstructionSetAlignStack *instruction) { 20482 uint32_t align_bytes; 20483 IrInstruction *align_bytes_inst = instruction->align_bytes->other; 20484 if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes)) 20485 return ira->codegen->builtin_types.entry_invalid; 20486 20487 if (align_bytes > 256) { 20488 ir_add_error(ira, &instruction->base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes)); 20489 return ira->codegen->builtin_types.entry_invalid; 20490 } 20491 20492 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 20493 if (fn_entry == nullptr) { 20494 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack outside function")); 20495 return ira->codegen->builtin_types.entry_invalid; 20496 } 20497 if (fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionNaked) { 20498 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in naked function")); 20499 return ira->codegen->builtin_types.entry_invalid; 20500 } 20501 20502 if (fn_entry->fn_inline == FnInlineAlways) { 20503 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in inline function")); 20504 return ira->codegen->builtin_types.entry_invalid; 20505 } 20506 20507 if (fn_entry->set_alignstack_node != nullptr) { 20508 ErrorMsg *msg = ir_add_error_node(ira, instruction->base.source_node, 20509 buf_sprintf("alignstack set twice")); 20510 add_error_note(ira->codegen, msg, fn_entry->set_alignstack_node, buf_sprintf("first set here")); 20511 return ira->codegen->builtin_types.entry_invalid; 20512 } 20513 20514 fn_entry->set_alignstack_node = instruction->base.source_node; 20515 fn_entry->alignstack_value = align_bytes; 20516 20517 ir_build_const_from(ira, &instruction->base); 20518 return ira->codegen->builtin_types.entry_void; 20519 } 20520 20521 static ZigType *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstructionArgType *instruction) { 20522 IrInstruction *fn_type_inst = instruction->fn_type->other; 20523 ZigType *fn_type = ir_resolve_type(ira, fn_type_inst); 20524 if (type_is_invalid(fn_type)) 20525 return ira->codegen->builtin_types.entry_invalid; 20526 20527 IrInstruction *arg_index_inst = instruction->arg_index->other; 20528 uint64_t arg_index; 20529 if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) 20530 return ira->codegen->builtin_types.entry_invalid; 20531 20532 if (fn_type->id != ZigTypeIdFn) { 20533 ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); 20534 return ira->codegen->builtin_types.entry_invalid; 20535 } 20536 20537 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 20538 if (arg_index >= fn_type_id->param_count) { 20539 ir_add_error(ira, arg_index_inst, 20540 buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", 20541 arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); 20542 return ira->codegen->builtin_types.entry_invalid; 20543 } 20544 20545 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 20546 out_val->data.x_type = fn_type_id->param_info[arg_index].type; 20547 if (out_val->data.x_type == nullptr) { 20548 // Args are only unresolved if our function is generic. 20549 assert(fn_type->data.fn.is_generic); 20550 20551 ir_add_error(ira, arg_index_inst, 20552 buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", 20553 arg_index, buf_ptr(&fn_type->name))); 20554 return ira->codegen->builtin_types.entry_invalid; 20555 } 20556 20557 return ira->codegen->builtin_types.entry_type; 20558 } 20559 20560 static ZigType *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstructionTagType *instruction) { 20561 Error err; 20562 IrInstruction *target_inst = instruction->target->other; 20563 ZigType *enum_type = ir_resolve_type(ira, target_inst); 20564 if (type_is_invalid(enum_type)) 20565 return ira->codegen->builtin_types.entry_invalid; 20566 20567 if (enum_type->id == ZigTypeIdEnum) { 20568 if ((err = ensure_complete_type(ira->codegen, enum_type))) 20569 return ira->codegen->builtin_types.entry_invalid; 20570 20571 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 20572 out_val->data.x_type = enum_type->data.enumeration.tag_int_type; 20573 return ira->codegen->builtin_types.entry_type; 20574 } else if (enum_type->id == ZigTypeIdUnion) { 20575 if ((err = ensure_complete_type(ira->codegen, enum_type))) 20576 return ira->codegen->builtin_types.entry_invalid; 20577 20578 AstNode *decl_node = enum_type->data.unionation.decl_node; 20579 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) { 20580 assert(enum_type->data.unionation.tag_type != nullptr); 20581 20582 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 20583 out_val->data.x_type = enum_type->data.unionation.tag_type; 20584 return ira->codegen->builtin_types.entry_type; 20585 } else { 20586 ErrorMsg *msg = ir_add_error(ira, target_inst, buf_sprintf("union '%s' has no tag", 20587 buf_ptr(&enum_type->name))); 20588 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here")); 20589 return ira->codegen->builtin_types.entry_invalid; 20590 } 20591 } else { 20592 ir_add_error(ira, target_inst, buf_sprintf("expected enum or union, found '%s'", 20593 buf_ptr(&enum_type->name))); 20594 return ira->codegen->builtin_types.entry_invalid; 20595 } 20596 } 20597 20598 static ZigType *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) { 20599 IrInstruction *target_inst = instruction->target->other; 20600 if (type_is_invalid(target_inst->value.type)) 20601 return ira->codegen->builtin_types.entry_invalid; 20602 IrInstruction *casted_target = ir_implicit_cast(ira, target_inst, ira->codegen->builtin_types.entry_promise); 20603 if (type_is_invalid(casted_target->value.type)) 20604 return ira->codegen->builtin_types.entry_invalid; 20605 20606 IrInstruction *result = ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_target); 20607 result->value.type = ira->codegen->builtin_types.entry_void; 20608 result->value.special = ConstValSpecialStatic; 20609 ir_link_new_instruction(result, &instruction->base); 20610 return result->value.type; 20611 } 20612 20613 static ZigType *ir_analyze_instruction_coro_id(IrAnalyze *ira, IrInstructionCoroId *instruction) { 20614 IrInstruction *promise_ptr = instruction->promise_ptr->other; 20615 if (type_is_invalid(promise_ptr->value.type)) 20616 return ira->codegen->builtin_types.entry_invalid; 20617 20618 IrInstruction *result = ir_build_coro_id(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 20619 promise_ptr); 20620 ir_link_new_instruction(result, &instruction->base); 20621 result->value.type = ira->codegen->builtin_types.entry_usize; 20622 return result->value.type; 20623 } 20624 20625 static ZigType *ir_analyze_instruction_coro_alloc(IrAnalyze *ira, IrInstructionCoroAlloc *instruction) { 20626 IrInstruction *coro_id = instruction->coro_id->other; 20627 if (type_is_invalid(coro_id->value.type)) 20628 return ira->codegen->builtin_types.entry_invalid; 20629 20630 IrInstruction *result = ir_build_coro_alloc(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 20631 coro_id); 20632 ir_link_new_instruction(result, &instruction->base); 20633 result->value.type = ira->codegen->builtin_types.entry_bool; 20634 return result->value.type; 20635 } 20636 20637 static ZigType *ir_analyze_instruction_coro_size(IrAnalyze *ira, IrInstructionCoroSize *instruction) { 20638 IrInstruction *result = ir_build_coro_size(&ira->new_irb, instruction->base.scope, instruction->base.source_node); 20639 ir_link_new_instruction(result, &instruction->base); 20640 result->value.type = ira->codegen->builtin_types.entry_usize; 20641 return result->value.type; 20642 } 20643 20644 static ZigType *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstructionCoroBegin *instruction) { 20645 IrInstruction *coro_id = instruction->coro_id->other; 20646 if (type_is_invalid(coro_id->value.type)) 20647 return ira->codegen->builtin_types.entry_invalid; 20648 20649 IrInstruction *coro_mem_ptr = instruction->coro_mem_ptr->other; 20650 if (type_is_invalid(coro_mem_ptr->value.type)) 20651 return ira->codegen->builtin_types.entry_invalid; 20652 20653 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 20654 assert(fn_entry != nullptr); 20655 IrInstruction *result = ir_build_coro_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 20656 coro_id, coro_mem_ptr); 20657 ir_link_new_instruction(result, &instruction->base); 20658 result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type); 20659 return result->value.type; 20660 } 20661 20662 static ZigType *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) { 20663 IrInstruction *result = ir_get_implicit_allocator(ira, &instruction->base, instruction->id); 20664 ir_link_new_instruction(result, &instruction->base); 20665 return result->value.type; 20666 } 20667 20668 static ZigType *ir_analyze_instruction_coro_alloc_fail(IrAnalyze *ira, IrInstructionCoroAllocFail *instruction) { 20669 IrInstruction *err_val = instruction->err_val->other; 20670 if (type_is_invalid(err_val->value.type)) 20671 return ir_unreach_error(ira); 20672 20673 IrInstruction *result = ir_build_coro_alloc_fail(&ira->new_irb, instruction->base.scope, instruction->base.source_node, err_val); 20674 ir_link_new_instruction(result, &instruction->base); 20675 result->value.type = ira->codegen->builtin_types.entry_unreachable; 20676 return ir_finish_anal(ira, result->value.type); 20677 } 20678 20679 static ZigType *ir_analyze_instruction_coro_suspend(IrAnalyze *ira, IrInstructionCoroSuspend *instruction) { 20680 IrInstruction *save_point = nullptr; 20681 if (instruction->save_point != nullptr) { 20682 save_point = instruction->save_point->other; 20683 if (type_is_invalid(save_point->value.type)) 20684 return ira->codegen->builtin_types.entry_invalid; 20685 } 20686 20687 IrInstruction *is_final = instruction->is_final->other; 20688 if (type_is_invalid(is_final->value.type)) 20689 return ira->codegen->builtin_types.entry_invalid; 20690 20691 IrInstruction *result = ir_build_coro_suspend(&ira->new_irb, instruction->base.scope, 20692 instruction->base.source_node, save_point, is_final); 20693 ir_link_new_instruction(result, &instruction->base); 20694 result->value.type = ira->codegen->builtin_types.entry_u8; 20695 return result->value.type; 20696 } 20697 20698 static ZigType *ir_analyze_instruction_coro_end(IrAnalyze *ira, IrInstructionCoroEnd *instruction) { 20699 IrInstruction *result = ir_build_coro_end(&ira->new_irb, instruction->base.scope, 20700 instruction->base.source_node); 20701 ir_link_new_instruction(result, &instruction->base); 20702 result->value.type = ira->codegen->builtin_types.entry_void; 20703 return result->value.type; 20704 } 20705 20706 static ZigType *ir_analyze_instruction_coro_free(IrAnalyze *ira, IrInstructionCoroFree *instruction) { 20707 IrInstruction *coro_id = instruction->coro_id->other; 20708 if (type_is_invalid(coro_id->value.type)) 20709 return ira->codegen->builtin_types.entry_invalid; 20710 20711 IrInstruction *coro_handle = instruction->coro_handle->other; 20712 if (type_is_invalid(coro_handle->value.type)) 20713 return ira->codegen->builtin_types.entry_invalid; 20714 20715 IrInstruction *result = ir_build_coro_free(&ira->new_irb, instruction->base.scope, 20716 instruction->base.source_node, coro_id, coro_handle); 20717 ir_link_new_instruction(result, &instruction->base); 20718 ZigType *ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false); 20719 result->value.type = get_optional_type(ira->codegen, ptr_type); 20720 return result->value.type; 20721 } 20722 20723 static ZigType *ir_analyze_instruction_coro_resume(IrAnalyze *ira, IrInstructionCoroResume *instruction) { 20724 IrInstruction *awaiter_handle = instruction->awaiter_handle->other; 20725 if (type_is_invalid(awaiter_handle->value.type)) 20726 return ira->codegen->builtin_types.entry_invalid; 20727 20728 IrInstruction *casted_target = ir_implicit_cast(ira, awaiter_handle, ira->codegen->builtin_types.entry_promise); 20729 if (type_is_invalid(casted_target->value.type)) 20730 return ira->codegen->builtin_types.entry_invalid; 20731 20732 IrInstruction *result = ir_build_coro_resume(&ira->new_irb, instruction->base.scope, 20733 instruction->base.source_node, casted_target); 20734 ir_link_new_instruction(result, &instruction->base); 20735 result->value.type = ira->codegen->builtin_types.entry_void; 20736 return result->value.type; 20737 } 20738 20739 static ZigType *ir_analyze_instruction_coro_save(IrAnalyze *ira, IrInstructionCoroSave *instruction) { 20740 IrInstruction *coro_handle = instruction->coro_handle->other; 20741 if (type_is_invalid(coro_handle->value.type)) 20742 return ira->codegen->builtin_types.entry_invalid; 20743 20744 IrInstruction *result = ir_build_coro_save(&ira->new_irb, instruction->base.scope, 20745 instruction->base.source_node, coro_handle); 20746 ir_link_new_instruction(result, &instruction->base); 20747 result->value.type = ira->codegen->builtin_types.entry_usize; 20748 return result->value.type; 20749 } 20750 20751 static ZigType *ir_analyze_instruction_coro_promise(IrAnalyze *ira, IrInstructionCoroPromise *instruction) { 20752 IrInstruction *coro_handle = instruction->coro_handle->other; 20753 if (type_is_invalid(coro_handle->value.type)) 20754 return ira->codegen->builtin_types.entry_invalid; 20755 20756 if (coro_handle->value.type->id != ZigTypeIdPromise || 20757 coro_handle->value.type->data.promise.result_type == nullptr) 20758 { 20759 ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'", 20760 buf_ptr(&coro_handle->value.type->name))); 20761 return ira->codegen->builtin_types.entry_invalid; 20762 } 20763 20764 ZigType *coro_frame_type = get_promise_frame_type(ira->codegen, 20765 coro_handle->value.type->data.promise.result_type); 20766 20767 IrInstruction *result = ir_build_coro_promise(&ira->new_irb, instruction->base.scope, 20768 instruction->base.source_node, coro_handle); 20769 ir_link_new_instruction(result, &instruction->base); 20770 result->value.type = get_pointer_to_type(ira->codegen, coro_frame_type, false); 20771 return result->value.type; 20772 } 20773 20774 static ZigType *ir_analyze_instruction_coro_alloc_helper(IrAnalyze *ira, IrInstructionCoroAllocHelper *instruction) { 20775 IrInstruction *alloc_fn = instruction->alloc_fn->other; 20776 if (type_is_invalid(alloc_fn->value.type)) 20777 return ira->codegen->builtin_types.entry_invalid; 20778 20779 IrInstruction *coro_size = instruction->coro_size->other; 20780 if (type_is_invalid(coro_size->value.type)) 20781 return ira->codegen->builtin_types.entry_invalid; 20782 20783 IrInstruction *result = ir_build_coro_alloc_helper(&ira->new_irb, instruction->base.scope, 20784 instruction->base.source_node, alloc_fn, coro_size); 20785 ir_link_new_instruction(result, &instruction->base); 20786 ZigType *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false); 20787 result->value.type = get_optional_type(ira->codegen, u8_ptr_type); 20788 return result->value.type; 20789 } 20790 20791 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op) { 20792 ZigType *operand_type = ir_resolve_type(ira, op); 20793 if (type_is_invalid(operand_type)) 20794 return ira->codegen->builtin_types.entry_invalid; 20795 20796 if (operand_type->id == ZigTypeIdInt) { 20797 if (operand_type->data.integral.bit_count < 8) { 20798 ir_add_error(ira, op, 20799 buf_sprintf("expected integer type 8 bits or larger, found %" PRIu32 "-bit integer type", 20800 operand_type->data.integral.bit_count)); 20801 return ira->codegen->builtin_types.entry_invalid; 20802 } 20803 if (operand_type->data.integral.bit_count > ira->codegen->pointer_size_bytes * 8) { 20804 ir_add_error(ira, op, 20805 buf_sprintf("expected integer type pointer size or smaller, found %" PRIu32 "-bit integer type", 20806 operand_type->data.integral.bit_count)); 20807 return ira->codegen->builtin_types.entry_invalid; 20808 } 20809 if (!is_power_of_2(operand_type->data.integral.bit_count)) { 20810 ir_add_error(ira, op, 20811 buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count)); 20812 return ira->codegen->builtin_types.entry_invalid; 20813 } 20814 } else if (get_codegen_ptr_type(operand_type) == nullptr) { 20815 ir_add_error(ira, op, 20816 buf_sprintf("expected integer or pointer type, found '%s'", buf_ptr(&operand_type->name))); 20817 return ira->codegen->builtin_types.entry_invalid; 20818 } 20819 20820 return operand_type; 20821 } 20822 20823 static ZigType *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstructionAtomicRmw *instruction) { 20824 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->other); 20825 if (type_is_invalid(operand_type)) 20826 return ira->codegen->builtin_types.entry_invalid; 20827 20828 IrInstruction *ptr_inst = instruction->ptr->other; 20829 if (type_is_invalid(ptr_inst->value.type)) 20830 return ira->codegen->builtin_types.entry_invalid; 20831 20832 // TODO let this be volatile 20833 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 20834 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 20835 if (type_is_invalid(casted_ptr->value.type)) 20836 return ira->codegen->builtin_types.entry_invalid; 20837 20838 AtomicRmwOp op; 20839 if (instruction->op == nullptr) { 20840 op = instruction->resolved_op; 20841 } else { 20842 if (!ir_resolve_atomic_rmw_op(ira, instruction->op->other, &op)) { 20843 return ira->codegen->builtin_types.entry_invalid; 20844 } 20845 } 20846 20847 IrInstruction *operand = instruction->operand->other; 20848 if (type_is_invalid(operand->value.type)) 20849 return ira->codegen->builtin_types.entry_invalid; 20850 20851 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, operand_type); 20852 if (type_is_invalid(casted_operand->value.type)) 20853 return ira->codegen->builtin_types.entry_invalid; 20854 20855 AtomicOrder ordering; 20856 if (instruction->ordering == nullptr) { 20857 ordering = instruction->resolved_ordering; 20858 } else { 20859 if (!ir_resolve_atomic_order(ira, instruction->ordering->other, &ordering)) 20860 return ira->codegen->builtin_types.entry_invalid; 20861 if (ordering == AtomicOrderUnordered) { 20862 ir_add_error(ira, instruction->ordering, 20863 buf_sprintf("@atomicRmw atomic ordering must not be Unordered")); 20864 return ira->codegen->builtin_types.entry_invalid; 20865 } 20866 } 20867 20868 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) 20869 { 20870 zig_panic("TODO compile-time execution of atomicRmw"); 20871 } 20872 20873 IrInstruction *result = ir_build_atomic_rmw(&ira->new_irb, instruction->base.scope, 20874 instruction->base.source_node, nullptr, casted_ptr, nullptr, casted_operand, nullptr, 20875 op, ordering); 20876 ir_link_new_instruction(result, &instruction->base); 20877 result->value.type = operand_type; 20878 return result->value.type; 20879 } 20880 20881 static ZigType *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstructionAtomicLoad *instruction) { 20882 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->other); 20883 if (type_is_invalid(operand_type)) 20884 return ira->codegen->builtin_types.entry_invalid; 20885 20886 IrInstruction *ptr_inst = instruction->ptr->other; 20887 if (type_is_invalid(ptr_inst->value.type)) 20888 return ira->codegen->builtin_types.entry_invalid; 20889 20890 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true); 20891 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 20892 if (type_is_invalid(casted_ptr->value.type)) 20893 return ira->codegen->builtin_types.entry_invalid; 20894 20895 AtomicOrder ordering; 20896 if (instruction->ordering == nullptr) { 20897 ordering = instruction->resolved_ordering; 20898 } else { 20899 if (!ir_resolve_atomic_order(ira, instruction->ordering->other, &ordering)) 20900 return ira->codegen->builtin_types.entry_invalid; 20901 } 20902 20903 if (ordering == AtomicOrderRelease || ordering == AtomicOrderAcqRel) { 20904 assert(instruction->ordering != nullptr); 20905 ir_add_error(ira, instruction->ordering, 20906 buf_sprintf("@atomicLoad atomic ordering must not be Release or AcqRel")); 20907 return ira->codegen->builtin_types.entry_invalid; 20908 } 20909 20910 if (instr_is_comptime(casted_ptr)) { 20911 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr); 20912 ir_link_new_instruction(result, &instruction->base); 20913 assert(result->value.type != nullptr); 20914 return result->value.type; 20915 } 20916 20917 IrInstruction *result = ir_build_atomic_load(&ira->new_irb, instruction->base.scope, 20918 instruction->base.source_node, nullptr, casted_ptr, nullptr, ordering); 20919 ir_link_new_instruction(result, &instruction->base); 20920 result->value.type = operand_type; 20921 return result->value.type; 20922 } 20923 20924 static ZigType *ir_analyze_instruction_promise_result_type(IrAnalyze *ira, IrInstructionPromiseResultType *instruction) { 20925 ZigType *promise_type = ir_resolve_type(ira, instruction->promise_type->other); 20926 if (type_is_invalid(promise_type)) 20927 return ira->codegen->builtin_types.entry_invalid; 20928 20929 if (promise_type->id != ZigTypeIdPromise || promise_type->data.promise.result_type == nullptr) { 20930 ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'", 20931 buf_ptr(&promise_type->name))); 20932 return ira->codegen->builtin_types.entry_invalid; 20933 } 20934 20935 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 20936 out_val->data.x_type = promise_type->data.promise.result_type; 20937 return ira->codegen->builtin_types.entry_type; 20938 } 20939 20940 static ZigType *ir_analyze_instruction_await_bookkeeping(IrAnalyze *ira, IrInstructionAwaitBookkeeping *instruction) { 20941 ZigType *promise_result_type = ir_resolve_type(ira, instruction->promise_result_type->other); 20942 if (type_is_invalid(promise_result_type)) 20943 return ira->codegen->builtin_types.entry_invalid; 20944 20945 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 20946 assert(fn_entry != nullptr); 20947 20948 if (type_can_fail(promise_result_type)) { 20949 fn_entry->calls_or_awaits_errorable_fn = true; 20950 } 20951 20952 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 20953 out_val->type = ira->codegen->builtin_types.entry_void; 20954 return out_val->type; 20955 } 20956 20957 static ZigType *ir_analyze_instruction_merge_err_ret_traces(IrAnalyze *ira, 20958 IrInstructionMergeErrRetTraces *instruction) 20959 { 20960 IrInstruction *coro_promise_ptr = instruction->coro_promise_ptr->other; 20961 if (type_is_invalid(coro_promise_ptr->value.type)) 20962 return ira->codegen->builtin_types.entry_invalid; 20963 20964 assert(coro_promise_ptr->value.type->id == ZigTypeIdPointer); 20965 ZigType *promise_frame_type = coro_promise_ptr->value.type->data.pointer.child_type; 20966 assert(promise_frame_type->id == ZigTypeIdStruct); 20967 ZigType *promise_result_type = promise_frame_type->data.structure.fields[1].type_entry; 20968 20969 if (!type_can_fail(promise_result_type)) { 20970 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 20971 out_val->type = ira->codegen->builtin_types.entry_void; 20972 return out_val->type; 20973 } 20974 20975 IrInstruction *src_err_ret_trace_ptr = instruction->src_err_ret_trace_ptr->other; 20976 if (type_is_invalid(src_err_ret_trace_ptr->value.type)) 20977 return ira->codegen->builtin_types.entry_invalid; 20978 20979 IrInstruction *dest_err_ret_trace_ptr = instruction->dest_err_ret_trace_ptr->other; 20980 if (type_is_invalid(dest_err_ret_trace_ptr->value.type)) 20981 return ira->codegen->builtin_types.entry_invalid; 20982 20983 IrInstruction *result = ir_build_merge_err_ret_traces(&ira->new_irb, instruction->base.scope, 20984 instruction->base.source_node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); 20985 ir_link_new_instruction(result, &instruction->base); 20986 result->value.type = ira->codegen->builtin_types.entry_void; 20987 return result->value.type; 20988 } 20989 20990 static ZigType *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) { 20991 IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope, 20992 instruction->base.source_node); 20993 ir_link_new_instruction(result, &instruction->base); 20994 result->value.type = ira->codegen->builtin_types.entry_void; 20995 return result->value.type; 20996 } 20997 20998 static ZigType *ir_analyze_instruction_mark_err_ret_trace_ptr(IrAnalyze *ira, IrInstructionMarkErrRetTracePtr *instruction) { 20999 IrInstruction *err_ret_trace_ptr = instruction->err_ret_trace_ptr->other; 21000 if (type_is_invalid(err_ret_trace_ptr->value.type)) 21001 return ira->codegen->builtin_types.entry_invalid; 21002 21003 IrInstruction *result = ir_build_mark_err_ret_trace_ptr(&ira->new_irb, instruction->base.scope, 21004 instruction->base.source_node, err_ret_trace_ptr); 21005 ir_link_new_instruction(result, &instruction->base); 21006 result->value.type = ira->codegen->builtin_types.entry_void; 21007 return result->value.type; 21008 } 21009 21010 static ZigType *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionSqrt *instruction) { 21011 ZigType *float_type = ir_resolve_type(ira, instruction->type->other); 21012 if (type_is_invalid(float_type)) 21013 return ira->codegen->builtin_types.entry_invalid; 21014 21015 IrInstruction *op = instruction->op->other; 21016 if (type_is_invalid(op->value.type)) 21017 return ira->codegen->builtin_types.entry_invalid; 21018 21019 bool ok_type = float_type->id == ZigTypeIdComptimeFloat || float_type->id == ZigTypeIdFloat; 21020 if (!ok_type) { 21021 ir_add_error(ira, instruction->type, buf_sprintf("@sqrt does not support type '%s'", buf_ptr(&float_type->name))); 21022 return ira->codegen->builtin_types.entry_invalid; 21023 } 21024 21025 IrInstruction *casted_op = ir_implicit_cast(ira, op, float_type); 21026 if (type_is_invalid(casted_op->value.type)) 21027 return ira->codegen->builtin_types.entry_invalid; 21028 21029 if (instr_is_comptime(casted_op)) { 21030 ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad); 21031 if (!val) 21032 return ira->codegen->builtin_types.entry_invalid; 21033 21034 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); 21035 21036 if (float_type->id == ZigTypeIdComptimeFloat) { 21037 bigfloat_sqrt(&out_val->data.x_bigfloat, &val->data.x_bigfloat); 21038 } else if (float_type->id == ZigTypeIdFloat) { 21039 switch (float_type->data.floating.bit_count) { 21040 case 16: 21041 out_val->data.x_f16 = f16_sqrt(val->data.x_f16); 21042 break; 21043 case 32: 21044 out_val->data.x_f32 = sqrtf(val->data.x_f32); 21045 break; 21046 case 64: 21047 out_val->data.x_f64 = sqrt(val->data.x_f64); 21048 break; 21049 case 128: 21050 f128M_sqrt(&val->data.x_f128, &out_val->data.x_f128); 21051 break; 21052 default: 21053 zig_unreachable(); 21054 } 21055 } else { 21056 zig_unreachable(); 21057 } 21058 21059 return float_type; 21060 } 21061 21062 assert(float_type->id == ZigTypeIdFloat); 21063 if (float_type->data.floating.bit_count != 16 && 21064 float_type->data.floating.bit_count != 32 && 21065 float_type->data.floating.bit_count != 64) { 21066 ir_add_error(ira, instruction->type, buf_sprintf("compiler TODO: add implementation of sqrt for '%s'", buf_ptr(&float_type->name))); 21067 return ira->codegen->builtin_types.entry_invalid; 21068 } 21069 21070 IrInstruction *result = ir_build_sqrt(&ira->new_irb, instruction->base.scope, 21071 instruction->base.source_node, nullptr, casted_op); 21072 ir_link_new_instruction(result, &instruction->base); 21073 result->value.type = float_type; 21074 return result->value.type; 21075 } 21076 21077 static ZigType *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstructionEnumToInt *instruction) { 21078 Error err; 21079 IrInstruction *target = instruction->target->other; 21080 if (type_is_invalid(target->value.type)) 21081 return ira->codegen->builtin_types.entry_invalid; 21082 21083 if (target->value.type->id != ZigTypeIdEnum) { 21084 ir_add_error(ira, instruction->target, 21085 buf_sprintf("expected enum, found type '%s'", buf_ptr(&target->value.type->name))); 21086 return ira->codegen->builtin_types.entry_invalid; 21087 } 21088 21089 if ((err = type_ensure_zero_bits_known(ira->codegen, target->value.type))) 21090 return ira->codegen->builtin_types.entry_invalid; 21091 21092 ZigType *tag_type = target->value.type->data.enumeration.tag_int_type; 21093 21094 IrInstruction *result = ir_analyze_enum_to_int(ira, &instruction->base, target, tag_type); 21095 ir_link_new_instruction(result, &instruction->base); 21096 return result->value.type; 21097 } 21098 21099 static ZigType *ir_analyze_instruction_int_to_enum(IrAnalyze *ira, IrInstructionIntToEnum *instruction) { 21100 Error err; 21101 IrInstruction *dest_type_value = instruction->dest_type->other; 21102 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 21103 if (type_is_invalid(dest_type)) 21104 return ira->codegen->builtin_types.entry_invalid; 21105 21106 if (dest_type->id != ZigTypeIdEnum) { 21107 ir_add_error(ira, instruction->dest_type, 21108 buf_sprintf("expected enum, found type '%s'", buf_ptr(&dest_type->name))); 21109 return ira->codegen->builtin_types.entry_invalid; 21110 } 21111 21112 if ((err = type_ensure_zero_bits_known(ira->codegen, dest_type))) 21113 return ira->codegen->builtin_types.entry_invalid; 21114 21115 ZigType *tag_type = dest_type->data.enumeration.tag_int_type; 21116 21117 IrInstruction *target = instruction->target->other; 21118 if (type_is_invalid(target->value.type)) 21119 return ira->codegen->builtin_types.entry_invalid; 21120 21121 IrInstruction *casted_target = ir_implicit_cast(ira, target, tag_type); 21122 if (type_is_invalid(casted_target->value.type)) 21123 return ira->codegen->builtin_types.entry_invalid; 21124 21125 IrInstruction *result = ir_analyze_int_to_enum(ira, &instruction->base, casted_target, dest_type); 21126 ir_link_new_instruction(result, &instruction->base); 21127 return result->value.type; 21128 } 21129 21130 static ZigType *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, IrInstructionCheckRuntimeScope *instruction) { 21131 IrInstruction *block_comptime_inst = instruction->scope_is_comptime->other; 21132 bool scope_is_comptime; 21133 if (!ir_resolve_bool(ira, block_comptime_inst, &scope_is_comptime)) 21134 return ira->codegen->builtin_types.entry_invalid; 21135 21136 IrInstruction *is_comptime_inst = instruction->is_comptime->other; 21137 bool is_comptime; 21138 if (!ir_resolve_bool(ira, is_comptime_inst, &is_comptime)) 21139 return ira->codegen->builtin_types.entry_invalid; 21140 21141 if (!scope_is_comptime && is_comptime) { 21142 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 21143 buf_sprintf("comptime control flow inside runtime block")); 21144 add_error_note(ira->codegen, msg, block_comptime_inst->source_node, 21145 buf_sprintf("runtime block created here")); 21146 return ira->codegen->builtin_types.entry_invalid; 21147 } 21148 21149 ir_build_const_from(ira, &instruction->base); 21150 return ira->codegen->builtin_types.entry_void; 21151 } 21152 21153 static ZigType *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { 21154 switch (instruction->id) { 21155 case IrInstructionIdInvalid: 21156 case IrInstructionIdWidenOrShorten: 21157 case IrInstructionIdStructInit: 21158 case IrInstructionIdUnionInit: 21159 case IrInstructionIdStructFieldPtr: 21160 case IrInstructionIdUnionFieldPtr: 21161 case IrInstructionIdOptionalWrap: 21162 case IrInstructionIdErrWrapCode: 21163 case IrInstructionIdErrWrapPayload: 21164 case IrInstructionIdCast: 21165 zig_unreachable(); 21166 21167 case IrInstructionIdReturn: 21168 return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction); 21169 case IrInstructionIdConst: 21170 return ir_analyze_instruction_const(ira, (IrInstructionConst *)instruction); 21171 case IrInstructionIdUnOp: 21172 return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction); 21173 case IrInstructionIdBinOp: 21174 return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction); 21175 case IrInstructionIdDeclVar: 21176 return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVar *)instruction); 21177 case IrInstructionIdLoadPtr: 21178 return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction); 21179 case IrInstructionIdStorePtr: 21180 return ir_analyze_instruction_store_ptr(ira, (IrInstructionStorePtr *)instruction); 21181 case IrInstructionIdElemPtr: 21182 return ir_analyze_instruction_elem_ptr(ira, (IrInstructionElemPtr *)instruction); 21183 case IrInstructionIdVarPtr: 21184 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); 21185 case IrInstructionIdFieldPtr: 21186 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); 21187 case IrInstructionIdCall: 21188 return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); 21189 case IrInstructionIdBr: 21190 return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); 21191 case IrInstructionIdCondBr: 21192 return ir_analyze_instruction_cond_br(ira, (IrInstructionCondBr *)instruction); 21193 case IrInstructionIdUnreachable: 21194 return ir_analyze_instruction_unreachable(ira, (IrInstructionUnreachable *)instruction); 21195 case IrInstructionIdPhi: 21196 return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); 21197 case IrInstructionIdTypeOf: 21198 return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); 21199 case IrInstructionIdToPtrType: 21200 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); 21201 case IrInstructionIdPtrTypeChild: 21202 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); 21203 case IrInstructionIdSetCold: 21204 return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); 21205 case IrInstructionIdSetRuntimeSafety: 21206 return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction); 21207 case IrInstructionIdSetFloatMode: 21208 return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction); 21209 case IrInstructionIdSliceType: 21210 return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction); 21211 case IrInstructionIdAsm: 21212 return ir_analyze_instruction_asm(ira, (IrInstructionAsm *)instruction); 21213 case IrInstructionIdArrayType: 21214 return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction); 21215 case IrInstructionIdPromiseType: 21216 return ir_analyze_instruction_promise_type(ira, (IrInstructionPromiseType *)instruction); 21217 case IrInstructionIdSizeOf: 21218 return ir_analyze_instruction_size_of(ira, (IrInstructionSizeOf *)instruction); 21219 case IrInstructionIdTestNonNull: 21220 return ir_analyze_instruction_test_non_null(ira, (IrInstructionTestNonNull *)instruction); 21221 case IrInstructionIdUnwrapOptional: 21222 return ir_analyze_instruction_unwrap_maybe(ira, (IrInstructionUnwrapOptional *)instruction); 21223 case IrInstructionIdClz: 21224 return ir_analyze_instruction_clz(ira, (IrInstructionClz *)instruction); 21225 case IrInstructionIdCtz: 21226 return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction); 21227 case IrInstructionIdPopCount: 21228 return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction); 21229 case IrInstructionIdSwitchBr: 21230 return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction); 21231 case IrInstructionIdSwitchTarget: 21232 return ir_analyze_instruction_switch_target(ira, (IrInstructionSwitchTarget *)instruction); 21233 case IrInstructionIdSwitchVar: 21234 return ir_analyze_instruction_switch_var(ira, (IrInstructionSwitchVar *)instruction); 21235 case IrInstructionIdUnionTag: 21236 return ir_analyze_instruction_union_tag(ira, (IrInstructionUnionTag *)instruction); 21237 case IrInstructionIdImport: 21238 return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction); 21239 case IrInstructionIdArrayLen: 21240 return ir_analyze_instruction_array_len(ira, (IrInstructionArrayLen *)instruction); 21241 case IrInstructionIdRef: 21242 return ir_analyze_instruction_ref(ira, (IrInstructionRef *)instruction); 21243 case IrInstructionIdContainerInitList: 21244 return ir_analyze_instruction_container_init_list(ira, (IrInstructionContainerInitList *)instruction); 21245 case IrInstructionIdContainerInitFields: 21246 return ir_analyze_instruction_container_init_fields(ira, (IrInstructionContainerInitFields *)instruction); 21247 case IrInstructionIdMinValue: 21248 return ir_analyze_instruction_min_value(ira, (IrInstructionMinValue *)instruction); 21249 case IrInstructionIdMaxValue: 21250 return ir_analyze_instruction_max_value(ira, (IrInstructionMaxValue *)instruction); 21251 case IrInstructionIdCompileErr: 21252 return ir_analyze_instruction_compile_err(ira, (IrInstructionCompileErr *)instruction); 21253 case IrInstructionIdCompileLog: 21254 return ir_analyze_instruction_compile_log(ira, (IrInstructionCompileLog *)instruction); 21255 case IrInstructionIdErrName: 21256 return ir_analyze_instruction_err_name(ira, (IrInstructionErrName *)instruction); 21257 case IrInstructionIdTypeName: 21258 return ir_analyze_instruction_type_name(ira, (IrInstructionTypeName *)instruction); 21259 case IrInstructionIdCImport: 21260 return ir_analyze_instruction_c_import(ira, (IrInstructionCImport *)instruction); 21261 case IrInstructionIdCInclude: 21262 return ir_analyze_instruction_c_include(ira, (IrInstructionCInclude *)instruction); 21263 case IrInstructionIdCDefine: 21264 return ir_analyze_instruction_c_define(ira, (IrInstructionCDefine *)instruction); 21265 case IrInstructionIdCUndef: 21266 return ir_analyze_instruction_c_undef(ira, (IrInstructionCUndef *)instruction); 21267 case IrInstructionIdEmbedFile: 21268 return ir_analyze_instruction_embed_file(ira, (IrInstructionEmbedFile *)instruction); 21269 case IrInstructionIdCmpxchg: 21270 return ir_analyze_instruction_cmpxchg(ira, (IrInstructionCmpxchg *)instruction); 21271 case IrInstructionIdFence: 21272 return ir_analyze_instruction_fence(ira, (IrInstructionFence *)instruction); 21273 case IrInstructionIdTruncate: 21274 return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction); 21275 case IrInstructionIdIntCast: 21276 return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction); 21277 case IrInstructionIdFloatCast: 21278 return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction); 21279 case IrInstructionIdErrSetCast: 21280 return ir_analyze_instruction_err_set_cast(ira, (IrInstructionErrSetCast *)instruction); 21281 case IrInstructionIdFromBytes: 21282 return ir_analyze_instruction_from_bytes(ira, (IrInstructionFromBytes *)instruction); 21283 case IrInstructionIdToBytes: 21284 return ir_analyze_instruction_to_bytes(ira, (IrInstructionToBytes *)instruction); 21285 case IrInstructionIdIntToFloat: 21286 return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); 21287 case IrInstructionIdFloatToInt: 21288 return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction); 21289 case IrInstructionIdBoolToInt: 21290 return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction); 21291 case IrInstructionIdIntType: 21292 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); 21293 case IrInstructionIdBoolNot: 21294 return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); 21295 case IrInstructionIdMemset: 21296 return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); 21297 case IrInstructionIdMemcpy: 21298 return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); 21299 case IrInstructionIdSlice: 21300 return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction); 21301 case IrInstructionIdMemberCount: 21302 return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); 21303 case IrInstructionIdMemberType: 21304 return ir_analyze_instruction_member_type(ira, (IrInstructionMemberType *)instruction); 21305 case IrInstructionIdMemberName: 21306 return ir_analyze_instruction_member_name(ira, (IrInstructionMemberName *)instruction); 21307 case IrInstructionIdBreakpoint: 21308 return ir_analyze_instruction_breakpoint(ira, (IrInstructionBreakpoint *)instruction); 21309 case IrInstructionIdReturnAddress: 21310 return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction); 21311 case IrInstructionIdFrameAddress: 21312 return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction); 21313 case IrInstructionIdHandle: 21314 return ir_analyze_instruction_handle(ira, (IrInstructionHandle *)instruction); 21315 case IrInstructionIdAlignOf: 21316 return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); 21317 case IrInstructionIdOverflowOp: 21318 return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); 21319 case IrInstructionIdTestErr: 21320 return ir_analyze_instruction_test_err(ira, (IrInstructionTestErr *)instruction); 21321 case IrInstructionIdUnwrapErrCode: 21322 return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); 21323 case IrInstructionIdUnwrapErrPayload: 21324 return ir_analyze_instruction_unwrap_err_payload(ira, (IrInstructionUnwrapErrPayload *)instruction); 21325 case IrInstructionIdFnProto: 21326 return ir_analyze_instruction_fn_proto(ira, (IrInstructionFnProto *)instruction); 21327 case IrInstructionIdTestComptime: 21328 return ir_analyze_instruction_test_comptime(ira, (IrInstructionTestComptime *)instruction); 21329 case IrInstructionIdCheckSwitchProngs: 21330 return ir_analyze_instruction_check_switch_prongs(ira, (IrInstructionCheckSwitchProngs *)instruction); 21331 case IrInstructionIdCheckStatementIsVoid: 21332 return ir_analyze_instruction_check_statement_is_void(ira, (IrInstructionCheckStatementIsVoid *)instruction); 21333 case IrInstructionIdDeclRef: 21334 return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction); 21335 case IrInstructionIdPanic: 21336 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); 21337 case IrInstructionIdPtrCast: 21338 return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCast *)instruction); 21339 case IrInstructionIdBitCast: 21340 return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction); 21341 case IrInstructionIdIntToPtr: 21342 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); 21343 case IrInstructionIdPtrToInt: 21344 return ir_analyze_instruction_ptr_to_int(ira, (IrInstructionPtrToInt *)instruction); 21345 case IrInstructionIdTagName: 21346 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionTagName *)instruction); 21347 case IrInstructionIdFieldParentPtr: 21348 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); 21349 case IrInstructionIdOffsetOf: 21350 return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction); 21351 case IrInstructionIdTypeInfo: 21352 return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); 21353 case IrInstructionIdTypeId: 21354 return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); 21355 case IrInstructionIdSetEvalBranchQuota: 21356 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstructionSetEvalBranchQuota *)instruction); 21357 case IrInstructionIdPtrType: 21358 return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); 21359 case IrInstructionIdAlignCast: 21360 return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); 21361 case IrInstructionIdOpaqueType: 21362 return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); 21363 case IrInstructionIdSetAlignStack: 21364 return ir_analyze_instruction_set_align_stack(ira, (IrInstructionSetAlignStack *)instruction); 21365 case IrInstructionIdArgType: 21366 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction); 21367 case IrInstructionIdTagType: 21368 return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction); 21369 case IrInstructionIdExport: 21370 return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction); 21371 case IrInstructionIdErrorReturnTrace: 21372 return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction); 21373 case IrInstructionIdErrorUnion: 21374 return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction); 21375 case IrInstructionIdCancel: 21376 return ir_analyze_instruction_cancel(ira, (IrInstructionCancel *)instruction); 21377 case IrInstructionIdCoroId: 21378 return ir_analyze_instruction_coro_id(ira, (IrInstructionCoroId *)instruction); 21379 case IrInstructionIdCoroAlloc: 21380 return ir_analyze_instruction_coro_alloc(ira, (IrInstructionCoroAlloc *)instruction); 21381 case IrInstructionIdCoroSize: 21382 return ir_analyze_instruction_coro_size(ira, (IrInstructionCoroSize *)instruction); 21383 case IrInstructionIdCoroBegin: 21384 return ir_analyze_instruction_coro_begin(ira, (IrInstructionCoroBegin *)instruction); 21385 case IrInstructionIdGetImplicitAllocator: 21386 return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction); 21387 case IrInstructionIdCoroAllocFail: 21388 return ir_analyze_instruction_coro_alloc_fail(ira, (IrInstructionCoroAllocFail *)instruction); 21389 case IrInstructionIdCoroSuspend: 21390 return ir_analyze_instruction_coro_suspend(ira, (IrInstructionCoroSuspend *)instruction); 21391 case IrInstructionIdCoroEnd: 21392 return ir_analyze_instruction_coro_end(ira, (IrInstructionCoroEnd *)instruction); 21393 case IrInstructionIdCoroFree: 21394 return ir_analyze_instruction_coro_free(ira, (IrInstructionCoroFree *)instruction); 21395 case IrInstructionIdCoroResume: 21396 return ir_analyze_instruction_coro_resume(ira, (IrInstructionCoroResume *)instruction); 21397 case IrInstructionIdCoroSave: 21398 return ir_analyze_instruction_coro_save(ira, (IrInstructionCoroSave *)instruction); 21399 case IrInstructionIdCoroPromise: 21400 return ir_analyze_instruction_coro_promise(ira, (IrInstructionCoroPromise *)instruction); 21401 case IrInstructionIdCoroAllocHelper: 21402 return ir_analyze_instruction_coro_alloc_helper(ira, (IrInstructionCoroAllocHelper *)instruction); 21403 case IrInstructionIdAtomicRmw: 21404 return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction); 21405 case IrInstructionIdAtomicLoad: 21406 return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction); 21407 case IrInstructionIdPromiseResultType: 21408 return ir_analyze_instruction_promise_result_type(ira, (IrInstructionPromiseResultType *)instruction); 21409 case IrInstructionIdAwaitBookkeeping: 21410 return ir_analyze_instruction_await_bookkeeping(ira, (IrInstructionAwaitBookkeeping *)instruction); 21411 case IrInstructionIdSaveErrRetAddr: 21412 return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction); 21413 case IrInstructionIdAddImplicitReturnType: 21414 return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction); 21415 case IrInstructionIdMergeErrRetTraces: 21416 return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction); 21417 case IrInstructionIdMarkErrRetTracePtr: 21418 return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); 21419 case IrInstructionIdSqrt: 21420 return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction); 21421 case IrInstructionIdIntToErr: 21422 return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); 21423 case IrInstructionIdErrToInt: 21424 return ir_analyze_instruction_err_to_int(ira, (IrInstructionErrToInt *)instruction); 21425 case IrInstructionIdIntToEnum: 21426 return ir_analyze_instruction_int_to_enum(ira, (IrInstructionIntToEnum *)instruction); 21427 case IrInstructionIdEnumToInt: 21428 return ir_analyze_instruction_enum_to_int(ira, (IrInstructionEnumToInt *)instruction); 21429 case IrInstructionIdCheckRuntimeScope: 21430 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction); 21431 } 21432 zig_unreachable(); 21433 } 21434 21435 static ZigType *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction) { 21436 ZigType *instruction_type = ir_analyze_instruction_nocast(ira, instruction); 21437 instruction->value.type = instruction_type; 21438 21439 if (instruction->other) { 21440 instruction->other->value.type = instruction_type; 21441 } else { 21442 assert(instruction_type->id == ZigTypeIdInvalid || 21443 instruction_type->id == ZigTypeIdUnreachable); 21444 instruction->other = instruction; 21445 } 21446 21447 return instruction_type; 21448 } 21449 21450 // This function attempts to evaluate IR code while doing type checking and other analysis. 21451 // It emits a new IrExecutable which is partially evaluated IR code. 21452 ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, 21453 ZigType *expected_type, AstNode *expected_type_source_node) 21454 { 21455 assert(!old_exec->invalid); 21456 assert(expected_type == nullptr || !type_is_invalid(expected_type)); 21457 21458 IrAnalyze *ira = allocate<IrAnalyze>(1); 21459 old_exec->analysis = ira; 21460 ira->codegen = codegen; 21461 21462 ZigFn *fn_entry = exec_fn_entry(old_exec); 21463 bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; 21464 ira->explicit_return_type = is_async ? get_promise_type(codegen, expected_type) : expected_type; 21465 21466 ira->old_irb.codegen = codegen; 21467 ira->old_irb.exec = old_exec; 21468 21469 ira->new_irb.codegen = codegen; 21470 ira->new_irb.exec = new_exec; 21471 21472 ConstExprValue *vals = create_const_vals(ira->old_irb.exec->mem_slot_count); 21473 ira->exec_context.mem_slot_list.resize(ira->old_irb.exec->mem_slot_count); 21474 for (size_t i = 0; i < ira->exec_context.mem_slot_list.length; i += 1) { 21475 ira->exec_context.mem_slot_list.items[i] = &vals[i]; 21476 } 21477 21478 IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); 21479 IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); 21480 ir_ref_bb(new_entry_bb); 21481 ira->new_irb.current_basic_block = new_entry_bb; 21482 ira->old_bb_index = 0; 21483 21484 ir_start_bb(ira, old_entry_bb, nullptr); 21485 21486 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 21487 IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 21488 21489 if (old_instruction->ref_count == 0 && !ir_has_side_effects(old_instruction)) { 21490 ira->instruction_index += 1; 21491 continue; 21492 } 21493 21494 ZigType *return_type = ir_analyze_instruction(ira, old_instruction); 21495 if (type_is_invalid(return_type) && ir_should_inline(new_exec, old_instruction->scope)) { 21496 return ira->codegen->builtin_types.entry_invalid; 21497 } 21498 21499 // unreachable instructions do their own control flow. 21500 if (return_type->id == ZigTypeIdUnreachable) 21501 continue; 21502 21503 ira->instruction_index += 1; 21504 } 21505 21506 if (new_exec->invalid) { 21507 return ira->codegen->builtin_types.entry_invalid; 21508 } else if (ira->src_implicit_return_type_list.length == 0) { 21509 return codegen->builtin_types.entry_unreachable; 21510 } else { 21511 return ir_resolve_peer_types(ira, expected_type_source_node, expected_type, ira->src_implicit_return_type_list.items, 21512 ira->src_implicit_return_type_list.length); 21513 } 21514 } 21515 21516 bool ir_has_side_effects(IrInstruction *instruction) { 21517 switch (instruction->id) { 21518 case IrInstructionIdInvalid: 21519 zig_unreachable(); 21520 case IrInstructionIdBr: 21521 case IrInstructionIdCondBr: 21522 case IrInstructionIdSwitchBr: 21523 case IrInstructionIdDeclVar: 21524 case IrInstructionIdStorePtr: 21525 case IrInstructionIdCall: 21526 case IrInstructionIdReturn: 21527 case IrInstructionIdUnreachable: 21528 case IrInstructionIdSetCold: 21529 case IrInstructionIdSetRuntimeSafety: 21530 case IrInstructionIdSetFloatMode: 21531 case IrInstructionIdImport: 21532 case IrInstructionIdCompileErr: 21533 case IrInstructionIdCompileLog: 21534 case IrInstructionIdCImport: 21535 case IrInstructionIdCInclude: 21536 case IrInstructionIdCDefine: 21537 case IrInstructionIdCUndef: 21538 case IrInstructionIdCmpxchg: 21539 case IrInstructionIdFence: 21540 case IrInstructionIdMemset: 21541 case IrInstructionIdMemcpy: 21542 case IrInstructionIdBreakpoint: 21543 case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free 21544 case IrInstructionIdCheckSwitchProngs: 21545 case IrInstructionIdCheckStatementIsVoid: 21546 case IrInstructionIdCheckRuntimeScope: 21547 case IrInstructionIdPanic: 21548 case IrInstructionIdSetEvalBranchQuota: 21549 case IrInstructionIdPtrType: 21550 case IrInstructionIdSetAlignStack: 21551 case IrInstructionIdExport: 21552 case IrInstructionIdCancel: 21553 case IrInstructionIdCoroId: 21554 case IrInstructionIdCoroBegin: 21555 case IrInstructionIdCoroAllocFail: 21556 case IrInstructionIdCoroEnd: 21557 case IrInstructionIdCoroResume: 21558 case IrInstructionIdCoroSave: 21559 case IrInstructionIdCoroAllocHelper: 21560 case IrInstructionIdAwaitBookkeeping: 21561 case IrInstructionIdSaveErrRetAddr: 21562 case IrInstructionIdAddImplicitReturnType: 21563 case IrInstructionIdMergeErrRetTraces: 21564 case IrInstructionIdMarkErrRetTracePtr: 21565 case IrInstructionIdAtomicRmw: 21566 return true; 21567 21568 case IrInstructionIdPhi: 21569 case IrInstructionIdUnOp: 21570 case IrInstructionIdBinOp: 21571 case IrInstructionIdLoadPtr: 21572 case IrInstructionIdConst: 21573 case IrInstructionIdCast: 21574 case IrInstructionIdContainerInitList: 21575 case IrInstructionIdContainerInitFields: 21576 case IrInstructionIdStructInit: 21577 case IrInstructionIdUnionInit: 21578 case IrInstructionIdFieldPtr: 21579 case IrInstructionIdElemPtr: 21580 case IrInstructionIdVarPtr: 21581 case IrInstructionIdTypeOf: 21582 case IrInstructionIdToPtrType: 21583 case IrInstructionIdPtrTypeChild: 21584 case IrInstructionIdArrayLen: 21585 case IrInstructionIdStructFieldPtr: 21586 case IrInstructionIdUnionFieldPtr: 21587 case IrInstructionIdArrayType: 21588 case IrInstructionIdPromiseType: 21589 case IrInstructionIdSliceType: 21590 case IrInstructionIdSizeOf: 21591 case IrInstructionIdTestNonNull: 21592 case IrInstructionIdUnwrapOptional: 21593 case IrInstructionIdClz: 21594 case IrInstructionIdCtz: 21595 case IrInstructionIdPopCount: 21596 case IrInstructionIdSwitchVar: 21597 case IrInstructionIdSwitchTarget: 21598 case IrInstructionIdUnionTag: 21599 case IrInstructionIdRef: 21600 case IrInstructionIdMinValue: 21601 case IrInstructionIdMaxValue: 21602 case IrInstructionIdEmbedFile: 21603 case IrInstructionIdTruncate: 21604 case IrInstructionIdIntType: 21605 case IrInstructionIdBoolNot: 21606 case IrInstructionIdSlice: 21607 case IrInstructionIdMemberCount: 21608 case IrInstructionIdMemberType: 21609 case IrInstructionIdMemberName: 21610 case IrInstructionIdAlignOf: 21611 case IrInstructionIdReturnAddress: 21612 case IrInstructionIdFrameAddress: 21613 case IrInstructionIdHandle: 21614 case IrInstructionIdTestErr: 21615 case IrInstructionIdUnwrapErrCode: 21616 case IrInstructionIdOptionalWrap: 21617 case IrInstructionIdErrWrapCode: 21618 case IrInstructionIdErrWrapPayload: 21619 case IrInstructionIdFnProto: 21620 case IrInstructionIdTestComptime: 21621 case IrInstructionIdPtrCast: 21622 case IrInstructionIdBitCast: 21623 case IrInstructionIdWidenOrShorten: 21624 case IrInstructionIdPtrToInt: 21625 case IrInstructionIdIntToPtr: 21626 case IrInstructionIdIntToEnum: 21627 case IrInstructionIdIntToErr: 21628 case IrInstructionIdErrToInt: 21629 case IrInstructionIdDeclRef: 21630 case IrInstructionIdErrName: 21631 case IrInstructionIdTypeName: 21632 case IrInstructionIdTagName: 21633 case IrInstructionIdFieldParentPtr: 21634 case IrInstructionIdOffsetOf: 21635 case IrInstructionIdTypeInfo: 21636 case IrInstructionIdTypeId: 21637 case IrInstructionIdAlignCast: 21638 case IrInstructionIdOpaqueType: 21639 case IrInstructionIdArgType: 21640 case IrInstructionIdTagType: 21641 case IrInstructionIdErrorReturnTrace: 21642 case IrInstructionIdErrorUnion: 21643 case IrInstructionIdGetImplicitAllocator: 21644 case IrInstructionIdCoroAlloc: 21645 case IrInstructionIdCoroSize: 21646 case IrInstructionIdCoroSuspend: 21647 case IrInstructionIdCoroFree: 21648 case IrInstructionIdCoroPromise: 21649 case IrInstructionIdPromiseResultType: 21650 case IrInstructionIdSqrt: 21651 case IrInstructionIdAtomicLoad: 21652 case IrInstructionIdIntCast: 21653 case IrInstructionIdFloatCast: 21654 case IrInstructionIdErrSetCast: 21655 case IrInstructionIdIntToFloat: 21656 case IrInstructionIdFloatToInt: 21657 case IrInstructionIdBoolToInt: 21658 case IrInstructionIdFromBytes: 21659 case IrInstructionIdToBytes: 21660 case IrInstructionIdEnumToInt: 21661 return false; 21662 21663 case IrInstructionIdAsm: 21664 { 21665 IrInstructionAsm *asm_instruction = (IrInstructionAsm *)instruction; 21666 return asm_instruction->has_side_effects; 21667 } 21668 case IrInstructionIdUnwrapErrPayload: 21669 { 21670 IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = 21671 (IrInstructionUnwrapErrPayload *)instruction; 21672 return unwrap_err_payload_instruction->safety_check_on; 21673 } 21674 } 21675 zig_unreachable(); 21676 }