blob e89d3023 (1078830B) - 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 #include <errno.h> 20 21 struct IrExecContext { 22 ZigList<ConstExprValue *> mem_slot_list; 23 }; 24 25 struct IrBuilder { 26 CodeGen *codegen; 27 IrExecutable *exec; 28 IrBasicBlock *current_basic_block; 29 }; 30 31 struct IrAnalyze { 32 CodeGen *codegen; 33 IrBuilder old_irb; 34 IrBuilder new_irb; 35 IrExecContext exec_context; 36 size_t old_bb_index; 37 size_t instruction_index; 38 ZigType *explicit_return_type; 39 AstNode *explicit_return_type_source_node; 40 ZigList<IrInstruction *> src_implicit_return_type_list; 41 IrBasicBlock *const_predecessor_bb; 42 }; 43 44 enum ConstCastResultId { 45 ConstCastResultIdOk, 46 ConstCastResultIdInvalid, 47 ConstCastResultIdErrSet, 48 ConstCastResultIdErrSetGlobal, 49 ConstCastResultIdPointerChild, 50 ConstCastResultIdSliceChild, 51 ConstCastResultIdOptionalChild, 52 ConstCastResultIdErrorUnionPayload, 53 ConstCastResultIdErrorUnionErrorSet, 54 ConstCastResultIdFnAlign, 55 ConstCastResultIdFnCC, 56 ConstCastResultIdFnVarArgs, 57 ConstCastResultIdFnIsGeneric, 58 ConstCastResultIdFnReturnType, 59 ConstCastResultIdFnArgCount, 60 ConstCastResultIdFnGenericArgCount, 61 ConstCastResultIdFnArg, 62 ConstCastResultIdFnArgNoAlias, 63 ConstCastResultIdType, 64 ConstCastResultIdUnresolvedInferredErrSet, 65 ConstCastResultIdAsyncAllocatorType, 66 ConstCastResultIdBadAllowsZero, 67 }; 68 69 struct ConstCastOnly; 70 struct ConstCastArg { 71 size_t arg_index; 72 ZigType *actual_param_type; 73 ZigType *expected_param_type; 74 ConstCastOnly *child; 75 }; 76 77 struct ConstCastArgNoAlias { 78 size_t arg_index; 79 }; 80 81 struct ConstCastOptionalMismatch; 82 struct ConstCastPointerMismatch; 83 struct ConstCastSliceMismatch; 84 struct ConstCastErrUnionErrSetMismatch; 85 struct ConstCastErrUnionPayloadMismatch; 86 struct ConstCastErrSetMismatch; 87 struct ConstCastTypeMismatch; 88 struct ConstCastBadAllowsZero; 89 90 struct ConstCastOnly { 91 ConstCastResultId id; 92 union { 93 ConstCastErrSetMismatch *error_set_mismatch; 94 ConstCastPointerMismatch *pointer_mismatch; 95 ConstCastSliceMismatch *slice_mismatch; 96 ConstCastOptionalMismatch *optional; 97 ConstCastErrUnionPayloadMismatch *error_union_payload; 98 ConstCastErrUnionErrSetMismatch *error_union_error_set; 99 ConstCastTypeMismatch *type_mismatch; 100 ConstCastOnly *return_type; 101 ConstCastOnly *async_allocator_type; 102 ConstCastOnly *null_wrap_ptr_child; 103 ConstCastArg fn_arg; 104 ConstCastArgNoAlias arg_no_alias; 105 ConstCastBadAllowsZero *bad_allows_zero; 106 } data; 107 }; 108 109 struct ConstCastTypeMismatch { 110 ZigType *wanted_type; 111 ZigType *actual_type; 112 }; 113 114 struct ConstCastOptionalMismatch { 115 ConstCastOnly child; 116 ZigType *wanted_child; 117 ZigType *actual_child; 118 }; 119 120 struct ConstCastPointerMismatch { 121 ConstCastOnly child; 122 ZigType *wanted_child; 123 ZigType *actual_child; 124 }; 125 126 struct ConstCastSliceMismatch { 127 ConstCastOnly child; 128 ZigType *wanted_child; 129 ZigType *actual_child; 130 }; 131 132 struct ConstCastErrUnionErrSetMismatch { 133 ConstCastOnly child; 134 ZigType *wanted_err_set; 135 ZigType *actual_err_set; 136 }; 137 138 struct ConstCastErrUnionPayloadMismatch { 139 ConstCastOnly child; 140 ZigType *wanted_payload; 141 ZigType *actual_payload; 142 }; 143 144 struct ConstCastErrSetMismatch { 145 ZigList<ErrorTableEntry *> missing_errors; 146 }; 147 148 struct ConstCastBadAllowsZero { 149 ZigType *wanted_type; 150 ZigType *actual_type; 151 }; 152 153 154 enum UndefAllowed { 155 UndefOk, 156 UndefBad, 157 }; 158 159 static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); 160 static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval); 161 static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); 162 static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type); 163 static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr); 164 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg); 165 static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 166 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type); 167 static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var); 168 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); 169 static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval); 170 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); 171 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); 172 static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val); 173 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); 174 static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 175 ConstExprValue *out_val, ConstExprValue *ptr_val); 176 static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, 177 ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on); 178 static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); 179 static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs); 180 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); 181 static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry); 182 static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 183 ZigType *ptr_type); 184 static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 185 ZigType *dest_type); 186 187 static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { 188 assert(get_src_ptr_type(const_val->type) != nullptr); 189 assert(const_val->special == ConstValSpecialStatic); 190 ConstExprValue *result; 191 192 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { 193 case OnePossibleValueInvalid: 194 zig_unreachable(); 195 case OnePossibleValueYes: 196 result = create_const_vals(1); 197 result->type = const_val->type->data.pointer.child_type; 198 result->special = ConstValSpecialStatic; 199 return result; 200 case OnePossibleValueNo: 201 break; 202 } 203 204 switch (const_val->data.x_ptr.special) { 205 case ConstPtrSpecialInvalid: 206 zig_unreachable(); 207 case ConstPtrSpecialRef: 208 result = const_val->data.x_ptr.data.ref.pointee; 209 break; 210 case ConstPtrSpecialBaseArray: { 211 ConstExprValue *array_val = const_val->data.x_ptr.data.base_array.array_val; 212 expand_undef_array(g, array_val); 213 result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index]; 214 break; 215 } 216 case ConstPtrSpecialBaseStruct: { 217 ConstExprValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val; 218 result = &struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; 219 break; 220 } 221 case ConstPtrSpecialBaseErrorUnionCode: 222 result = const_val->data.x_ptr.data.base_err_union_code.err_union_val->data.x_err_union.error_set; 223 break; 224 case ConstPtrSpecialBaseErrorUnionPayload: 225 result = const_val->data.x_ptr.data.base_err_union_payload.err_union_val->data.x_err_union.payload; 226 break; 227 case ConstPtrSpecialBaseOptionalPayload: 228 result = const_val->data.x_ptr.data.base_optional_payload.optional_val->data.x_optional; 229 break; 230 case ConstPtrSpecialNull: 231 result = const_val; 232 break; 233 case ConstPtrSpecialHardCodedAddr: 234 zig_unreachable(); 235 case ConstPtrSpecialDiscard: 236 zig_unreachable(); 237 case ConstPtrSpecialFunction: 238 zig_unreachable(); 239 } 240 assert(result != nullptr); 241 return result; 242 } 243 244 static bool is_opt_err_set(ZigType *ty) { 245 return ty->id == ZigTypeIdErrorSet || 246 (ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet); 247 } 248 249 // This function returns true when you can change the type of a ConstExprValue and the 250 // value remains meaningful. 251 static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { 252 if (a == b) 253 return true; 254 255 if (get_codegen_ptr_type(a) != nullptr && get_codegen_ptr_type(b) != nullptr) 256 return true; 257 258 if (is_opt_err_set(a) && is_opt_err_set(b)) 259 return true; 260 261 if (a->id != b->id) 262 return false; 263 264 switch (a->id) { 265 case ZigTypeIdInvalid: 266 case ZigTypeIdUnreachable: 267 zig_unreachable(); 268 case ZigTypeIdMetaType: 269 case ZigTypeIdVoid: 270 case ZigTypeIdBool: 271 case ZigTypeIdComptimeFloat: 272 case ZigTypeIdComptimeInt: 273 case ZigTypeIdEnumLiteral: 274 case ZigTypeIdPointer: 275 case ZigTypeIdUndefined: 276 case ZigTypeIdNull: 277 case ZigTypeIdBoundFn: 278 case ZigTypeIdErrorSet: 279 case ZigTypeIdOpaque: 280 return true; 281 case ZigTypeIdFloat: 282 return a->data.floating.bit_count == b->data.floating.bit_count; 283 case ZigTypeIdInt: 284 return a->data.integral.is_signed == b->data.integral.is_signed; 285 case ZigTypeIdArray: 286 case ZigTypeIdStruct: 287 case ZigTypeIdOptional: 288 case ZigTypeIdErrorUnion: 289 case ZigTypeIdEnum: 290 case ZigTypeIdUnion: 291 case ZigTypeIdFn: 292 case ZigTypeIdArgTuple: 293 case ZigTypeIdPromise: 294 case ZigTypeIdVector: 295 return false; 296 } 297 zig_unreachable(); 298 } 299 300 static bool ir_should_inline(IrExecutable *exec, Scope *scope) { 301 if (exec->is_inline) 302 return true; 303 304 while (scope != nullptr) { 305 if (scope->id == ScopeIdCompTime) 306 return true; 307 if (scope->id == ScopeIdFnDef) 308 break; 309 scope = scope->parent; 310 } 311 return false; 312 } 313 314 static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) { 315 assert(basic_block); 316 assert(instruction); 317 basic_block->instruction_list.append(instruction); 318 } 319 320 static size_t exec_next_debug_id(IrExecutable *exec) { 321 size_t result = exec->next_debug_id; 322 exec->next_debug_id += 1; 323 return result; 324 } 325 326 static size_t exec_next_mem_slot(IrExecutable *exec) { 327 size_t result = exec->mem_slot_count; 328 exec->mem_slot_count += 1; 329 return result; 330 } 331 332 static ZigFn *exec_fn_entry(IrExecutable *exec) { 333 return exec->fn_entry; 334 } 335 336 static Buf *exec_c_import_buf(IrExecutable *exec) { 337 return exec->c_import_buf; 338 } 339 340 static bool value_is_comptime(ConstExprValue *const_val) { 341 return const_val->special != ConstValSpecialRuntime; 342 } 343 344 static bool instr_is_comptime(IrInstruction *instruction) { 345 return value_is_comptime(&instruction->value); 346 } 347 348 static bool instr_is_unreachable(IrInstruction *instruction) { 349 return instruction->value.type && instruction->value.type->id == ZigTypeIdUnreachable; 350 } 351 352 static void ir_link_new_bb(IrBasicBlock *new_bb, IrBasicBlock *old_bb) { 353 new_bb->other = old_bb; 354 old_bb->other = new_bb; 355 } 356 357 static void ir_ref_bb(IrBasicBlock *bb) { 358 bb->ref_count += 1; 359 } 360 361 static void ir_ref_instruction(IrInstruction *instruction, IrBasicBlock *cur_bb) { 362 assert(instruction->id != IrInstructionIdInvalid); 363 instruction->ref_count += 1; 364 if (instruction->owner_bb != cur_bb && !instr_is_comptime(instruction)) 365 ir_ref_bb(instruction->owner_bb); 366 } 367 368 static void ir_ref_var(ZigVar *var) { 369 var->ref_count += 1; 370 } 371 372 ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { 373 ConstExprValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type, 374 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr, 375 node, nullptr, ira->new_irb.exec, nullptr); 376 377 if (type_is_invalid(result->type)) 378 return ira->codegen->builtin_types.entry_invalid; 379 380 assert(result->special != ConstValSpecialRuntime); 381 return result->data.x_type; 382 } 383 384 static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const char *name_hint) { 385 IrBasicBlock *result = allocate<IrBasicBlock>(1); 386 result->scope = scope; 387 result->name_hint = name_hint; 388 result->debug_id = exec_next_debug_id(irb->exec); 389 return result; 390 } 391 392 static IrBasicBlock *ir_build_bb_from(IrBuilder *irb, IrBasicBlock *other_bb) { 393 IrBasicBlock *new_bb = ir_create_basic_block(irb, other_bb->scope, other_bb->name_hint); 394 ir_link_new_bb(new_bb, other_bb); 395 return new_bb; 396 } 397 398 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVarSrc *) { 399 return IrInstructionIdDeclVarSrc; 400 } 401 402 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVarGen *) { 403 return IrInstructionIdDeclVarGen; 404 } 405 406 static constexpr IrInstructionId ir_instruction_id(IrInstructionCondBr *) { 407 return IrInstructionIdCondBr; 408 } 409 410 static constexpr IrInstructionId ir_instruction_id(IrInstructionBr *) { 411 return IrInstructionIdBr; 412 } 413 414 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchBr *) { 415 return IrInstructionIdSwitchBr; 416 } 417 418 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchVar *) { 419 return IrInstructionIdSwitchVar; 420 } 421 422 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchTarget *) { 423 return IrInstructionIdSwitchTarget; 424 } 425 426 static constexpr IrInstructionId ir_instruction_id(IrInstructionPhi *) { 427 return IrInstructionIdPhi; 428 } 429 430 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnOp *) { 431 return IrInstructionIdUnOp; 432 } 433 434 static constexpr IrInstructionId ir_instruction_id(IrInstructionBinOp *) { 435 return IrInstructionIdBinOp; 436 } 437 438 static constexpr IrInstructionId ir_instruction_id(IrInstructionExport *) { 439 return IrInstructionIdExport; 440 } 441 442 static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) { 443 return IrInstructionIdLoadPtr; 444 } 445 446 static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtrGen *) { 447 return IrInstructionIdLoadPtrGen; 448 } 449 450 static constexpr IrInstructionId ir_instruction_id(IrInstructionStorePtr *) { 451 return IrInstructionIdStorePtr; 452 } 453 454 static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldPtr *) { 455 return IrInstructionIdFieldPtr; 456 } 457 458 static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *) { 459 return IrInstructionIdStructFieldPtr; 460 } 461 462 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionFieldPtr *) { 463 return IrInstructionIdUnionFieldPtr; 464 } 465 466 static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) { 467 return IrInstructionIdElemPtr; 468 } 469 470 static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) { 471 return IrInstructionIdVarPtr; 472 } 473 474 static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) { 475 return IrInstructionIdCall; 476 } 477 478 static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) { 479 return IrInstructionIdConst; 480 } 481 482 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturn *) { 483 return IrInstructionIdReturn; 484 } 485 486 static constexpr IrInstructionId ir_instruction_id(IrInstructionCast *) { 487 return IrInstructionIdCast; 488 } 489 490 static constexpr IrInstructionId ir_instruction_id(IrInstructionResizeSlice *) { 491 return IrInstructionIdResizeSlice; 492 } 493 494 static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitList *) { 495 return IrInstructionIdContainerInitList; 496 } 497 498 static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitFields *) { 499 return IrInstructionIdContainerInitFields; 500 } 501 502 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnreachable *) { 503 return IrInstructionIdUnreachable; 504 } 505 506 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) { 507 return IrInstructionIdTypeOf; 508 } 509 510 static constexpr IrInstructionId ir_instruction_id(IrInstructionToPtrType *) { 511 return IrInstructionIdToPtrType; 512 } 513 514 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *) { 515 return IrInstructionIdPtrTypeChild; 516 } 517 518 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) { 519 return IrInstructionIdSetCold; 520 } 521 522 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetRuntimeSafety *) { 523 return IrInstructionIdSetRuntimeSafety; 524 } 525 526 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFloatMode *) { 527 return IrInstructionIdSetFloatMode; 528 } 529 530 static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) { 531 return IrInstructionIdArrayType; 532 } 533 534 static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseType *) { 535 return IrInstructionIdPromiseType; 536 } 537 538 static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { 539 return IrInstructionIdSliceType; 540 } 541 542 static constexpr IrInstructionId ir_instruction_id(IrInstructionGlobalAsm *) { 543 return IrInstructionIdGlobalAsm; 544 } 545 546 static constexpr IrInstructionId ir_instruction_id(IrInstructionAsm *) { 547 return IrInstructionIdAsm; 548 } 549 550 static constexpr IrInstructionId ir_instruction_id(IrInstructionSizeOf *) { 551 return IrInstructionIdSizeOf; 552 } 553 554 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestNonNull *) { 555 return IrInstructionIdTestNonNull; 556 } 557 558 static constexpr IrInstructionId ir_instruction_id(IrInstructionOptionalUnwrapPtr *) { 559 return IrInstructionIdOptionalUnwrapPtr; 560 } 561 562 static constexpr IrInstructionId ir_instruction_id(IrInstructionClz *) { 563 return IrInstructionIdClz; 564 } 565 566 static constexpr IrInstructionId ir_instruction_id(IrInstructionCtz *) { 567 return IrInstructionIdCtz; 568 } 569 570 static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) { 571 return IrInstructionIdPopCount; 572 } 573 574 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) { 575 return IrInstructionIdUnionTag; 576 } 577 578 static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) { 579 return IrInstructionIdImport; 580 } 581 582 static constexpr IrInstructionId ir_instruction_id(IrInstructionCImport *) { 583 return IrInstructionIdCImport; 584 } 585 586 static constexpr IrInstructionId ir_instruction_id(IrInstructionCInclude *) { 587 return IrInstructionIdCInclude; 588 } 589 590 static constexpr IrInstructionId ir_instruction_id(IrInstructionCDefine *) { 591 return IrInstructionIdCDefine; 592 } 593 594 static constexpr IrInstructionId ir_instruction_id(IrInstructionCUndef *) { 595 return IrInstructionIdCUndef; 596 } 597 598 static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) { 599 return IrInstructionIdRef; 600 } 601 602 static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) { 603 return IrInstructionIdStructInit; 604 } 605 606 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInit *) { 607 return IrInstructionIdUnionInit; 608 } 609 610 static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { 611 return IrInstructionIdCompileErr; 612 } 613 614 static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileLog *) { 615 return IrInstructionIdCompileLog; 616 } 617 618 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrName *) { 619 return IrInstructionIdErrName; 620 } 621 622 static constexpr IrInstructionId ir_instruction_id(IrInstructionEmbedFile *) { 623 return IrInstructionIdEmbedFile; 624 } 625 626 static constexpr IrInstructionId ir_instruction_id(IrInstructionCmpxchgSrc *) { 627 return IrInstructionIdCmpxchgSrc; 628 } 629 630 static constexpr IrInstructionId ir_instruction_id(IrInstructionCmpxchgGen *) { 631 return IrInstructionIdCmpxchgGen; 632 } 633 634 static constexpr IrInstructionId ir_instruction_id(IrInstructionFence *) { 635 return IrInstructionIdFence; 636 } 637 638 static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) { 639 return IrInstructionIdTruncate; 640 } 641 642 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntCast *) { 643 return IrInstructionIdIntCast; 644 } 645 646 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) { 647 return IrInstructionIdFloatCast; 648 } 649 650 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrSetCast *) { 651 return IrInstructionIdErrSetCast; 652 } 653 654 static constexpr IrInstructionId ir_instruction_id(IrInstructionToBytes *) { 655 return IrInstructionIdToBytes; 656 } 657 658 static constexpr IrInstructionId ir_instruction_id(IrInstructionFromBytes *) { 659 return IrInstructionIdFromBytes; 660 } 661 662 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) { 663 return IrInstructionIdIntToFloat; 664 } 665 666 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) { 667 return IrInstructionIdFloatToInt; 668 } 669 670 static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) { 671 return IrInstructionIdBoolToInt; 672 } 673 674 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { 675 return IrInstructionIdIntType; 676 } 677 678 static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorType *) { 679 return IrInstructionIdVectorType; 680 } 681 682 static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { 683 return IrInstructionIdBoolNot; 684 } 685 686 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemset *) { 687 return IrInstructionIdMemset; 688 } 689 690 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) { 691 return IrInstructionIdMemcpy; 692 } 693 694 static constexpr IrInstructionId ir_instruction_id(IrInstructionSlice *) { 695 return IrInstructionIdSlice; 696 } 697 698 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) { 699 return IrInstructionIdMemberCount; 700 } 701 702 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberType *) { 703 return IrInstructionIdMemberType; 704 } 705 706 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberName *) { 707 return IrInstructionIdMemberName; 708 } 709 710 static constexpr IrInstructionId ir_instruction_id(IrInstructionBreakpoint *) { 711 return IrInstructionIdBreakpoint; 712 } 713 714 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnAddress *) { 715 return IrInstructionIdReturnAddress; 716 } 717 718 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *) { 719 return IrInstructionIdFrameAddress; 720 } 721 722 static constexpr IrInstructionId ir_instruction_id(IrInstructionHandle *) { 723 return IrInstructionIdHandle; 724 } 725 726 static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignOf *) { 727 return IrInstructionIdAlignOf; 728 } 729 730 static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { 731 return IrInstructionIdOverflowOp; 732 } 733 734 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErr *) { 735 return IrInstructionIdTestErr; 736 } 737 738 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrCode *) { 739 return IrInstructionIdUnwrapErrCode; 740 } 741 742 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrPayload *) { 743 return IrInstructionIdUnwrapErrPayload; 744 } 745 746 static constexpr IrInstructionId ir_instruction_id(IrInstructionOptionalWrap *) { 747 return IrInstructionIdOptionalWrap; 748 } 749 750 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapPayload *) { 751 return IrInstructionIdErrWrapPayload; 752 } 753 754 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapCode *) { 755 return IrInstructionIdErrWrapCode; 756 } 757 758 static constexpr IrInstructionId ir_instruction_id(IrInstructionFnProto *) { 759 return IrInstructionIdFnProto; 760 } 761 762 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestComptime *) { 763 return IrInstructionIdTestComptime; 764 } 765 766 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastSrc *) { 767 return IrInstructionIdPtrCastSrc; 768 } 769 770 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) { 771 return IrInstructionIdPtrCastGen; 772 } 773 774 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) { 775 return IrInstructionIdBitCast; 776 } 777 778 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) { 779 return IrInstructionIdBitCastGen; 780 } 781 782 static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) { 783 return IrInstructionIdWidenOrShorten; 784 } 785 786 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrToInt *) { 787 return IrInstructionIdPtrToInt; 788 } 789 790 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToPtr *) { 791 return IrInstructionIdIntToPtr; 792 } 793 794 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToEnum *) { 795 return IrInstructionIdIntToEnum; 796 } 797 798 static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumToInt *) { 799 return IrInstructionIdEnumToInt; 800 } 801 802 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToErr *) { 803 return IrInstructionIdIntToErr; 804 } 805 806 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrToInt *) { 807 return IrInstructionIdErrToInt; 808 } 809 810 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckSwitchProngs *) { 811 return IrInstructionIdCheckSwitchProngs; 812 } 813 814 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckStatementIsVoid *) { 815 return IrInstructionIdCheckStatementIsVoid; 816 } 817 818 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeName *) { 819 return IrInstructionIdTypeName; 820 } 821 822 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) { 823 return IrInstructionIdDeclRef; 824 } 825 826 static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) { 827 return IrInstructionIdPanic; 828 } 829 830 static constexpr IrInstructionId ir_instruction_id(IrInstructionTagName *) { 831 return IrInstructionIdTagName; 832 } 833 834 static constexpr IrInstructionId ir_instruction_id(IrInstructionTagType *) { 835 return IrInstructionIdTagType; 836 } 837 838 static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) { 839 return IrInstructionIdFieldParentPtr; 840 } 841 842 static constexpr IrInstructionId ir_instruction_id(IrInstructionByteOffsetOf *) { 843 return IrInstructionIdByteOffsetOf; 844 } 845 846 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitOffsetOf *) { 847 return IrInstructionIdBitOffsetOf; 848 } 849 850 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { 851 return IrInstructionIdTypeInfo; 852 } 853 854 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { 855 return IrInstructionIdTypeId; 856 } 857 858 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetEvalBranchQuota *) { 859 return IrInstructionIdSetEvalBranchQuota; 860 } 861 862 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrType *) { 863 return IrInstructionIdPtrType; 864 } 865 866 static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { 867 return IrInstructionIdAlignCast; 868 } 869 870 static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { 871 return IrInstructionIdOpaqueType; 872 } 873 874 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetAlignStack *) { 875 return IrInstructionIdSetAlignStack; 876 } 877 878 static constexpr IrInstructionId ir_instruction_id(IrInstructionArgType *) { 879 return IrInstructionIdArgType; 880 } 881 882 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorReturnTrace *) { 883 return IrInstructionIdErrorReturnTrace; 884 } 885 886 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorUnion *) { 887 return IrInstructionIdErrorUnion; 888 } 889 890 static constexpr IrInstructionId ir_instruction_id(IrInstructionCancel *) { 891 return IrInstructionIdCancel; 892 } 893 894 static constexpr IrInstructionId ir_instruction_id(IrInstructionGetImplicitAllocator *) { 895 return IrInstructionIdGetImplicitAllocator; 896 } 897 898 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroId *) { 899 return IrInstructionIdCoroId; 900 } 901 902 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAlloc *) { 903 return IrInstructionIdCoroAlloc; 904 } 905 906 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSize *) { 907 return IrInstructionIdCoroSize; 908 } 909 910 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroBegin *) { 911 return IrInstructionIdCoroBegin; 912 } 913 914 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocFail *) { 915 return IrInstructionIdCoroAllocFail; 916 } 917 918 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSuspend *) { 919 return IrInstructionIdCoroSuspend; 920 } 921 922 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroEnd *) { 923 return IrInstructionIdCoroEnd; 924 } 925 926 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroFree *) { 927 return IrInstructionIdCoroFree; 928 } 929 930 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroResume *) { 931 return IrInstructionIdCoroResume; 932 } 933 934 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSave *) { 935 return IrInstructionIdCoroSave; 936 } 937 938 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroPromise *) { 939 return IrInstructionIdCoroPromise; 940 } 941 942 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocHelper *) { 943 return IrInstructionIdCoroAllocHelper; 944 } 945 946 static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicRmw *) { 947 return IrInstructionIdAtomicRmw; 948 } 949 950 static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) { 951 return IrInstructionIdAtomicLoad; 952 } 953 954 static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseResultType *) { 955 return IrInstructionIdPromiseResultType; 956 } 957 958 static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitBookkeeping *) { 959 return IrInstructionIdAwaitBookkeeping; 960 } 961 962 static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) { 963 return IrInstructionIdSaveErrRetAddr; 964 } 965 966 static constexpr IrInstructionId ir_instruction_id(IrInstructionAddImplicitReturnType *) { 967 return IrInstructionIdAddImplicitReturnType; 968 } 969 970 static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrRetTraces *) { 971 return IrInstructionIdMergeErrRetTraces; 972 } 973 974 static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTracePtr *) { 975 return IrInstructionIdMarkErrRetTracePtr; 976 } 977 978 static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) { 979 return IrInstructionIdSqrt; 980 } 981 982 static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) { 983 return IrInstructionIdBswap; 984 } 985 986 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) { 987 return IrInstructionIdBitReverse; 988 } 989 990 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { 991 return IrInstructionIdCheckRuntimeScope; 992 } 993 994 static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorToArray *) { 995 return IrInstructionIdVectorToArray; 996 } 997 998 static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayToVector *) { 999 return IrInstructionIdArrayToVector; 1000 } 1001 1002 static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertZero *) { 1003 return IrInstructionIdAssertZero; 1004 } 1005 1006 static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) { 1007 return IrInstructionIdAssertNonNull; 1008 } 1009 1010 template<typename T> 1011 static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1012 T *special_instruction = allocate<T>(1); 1013 special_instruction->base.id = ir_instruction_id(special_instruction); 1014 special_instruction->base.scope = scope; 1015 special_instruction->base.source_node = source_node; 1016 special_instruction->base.debug_id = exec_next_debug_id(irb->exec); 1017 special_instruction->base.owner_bb = irb->current_basic_block; 1018 special_instruction->base.value.global_refs = allocate<ConstGlobalRefs>(1); 1019 return special_instruction; 1020 } 1021 1022 template<typename T> 1023 static T *ir_build_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1024 T *special_instruction = ir_create_instruction<T>(irb, scope, source_node); 1025 ir_instruction_append(irb->current_basic_block, &special_instruction->base); 1026 return special_instruction; 1027 } 1028 1029 static IrInstruction *ir_build_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *dest_type, 1030 IrInstruction *value, CastOp cast_op) 1031 { 1032 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, scope, source_node); 1033 cast_instruction->dest_type = dest_type; 1034 cast_instruction->value = value; 1035 cast_instruction->cast_op = cast_op; 1036 1037 ir_ref_instruction(value, irb->current_basic_block); 1038 1039 return &cast_instruction->base; 1040 } 1041 1042 static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *condition, 1043 IrBasicBlock *then_block, IrBasicBlock *else_block, IrInstruction *is_comptime) 1044 { 1045 IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, scope, source_node); 1046 cond_br_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1047 cond_br_instruction->base.value.special = ConstValSpecialStatic; 1048 cond_br_instruction->condition = condition; 1049 cond_br_instruction->then_block = then_block; 1050 cond_br_instruction->else_block = else_block; 1051 cond_br_instruction->is_comptime = is_comptime; 1052 1053 ir_ref_instruction(condition, irb->current_basic_block); 1054 ir_ref_bb(then_block); 1055 ir_ref_bb(else_block); 1056 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); 1057 1058 return &cond_br_instruction->base; 1059 } 1060 1061 static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *return_value) { 1062 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); 1063 return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1064 return_instruction->base.value.special = ConstValSpecialStatic; 1065 return_instruction->value = return_value; 1066 1067 ir_ref_instruction(return_value, irb->current_basic_block); 1068 1069 return &return_instruction->base; 1070 } 1071 1072 static IrInstruction *ir_build_const_void(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1073 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1074 const_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1075 const_instruction->base.value.special = ConstValSpecialStatic; 1076 return &const_instruction->base; 1077 } 1078 1079 static IrInstruction *ir_build_const_undefined(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1080 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1081 const_instruction->base.value.special = ConstValSpecialUndef; 1082 const_instruction->base.value.type = irb->codegen->builtin_types.entry_undef; 1083 return &const_instruction->base; 1084 } 1085 1086 static IrInstruction *ir_build_const_uint(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { 1087 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1088 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_int; 1089 const_instruction->base.value.special = ConstValSpecialStatic; 1090 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); 1091 return &const_instruction->base; 1092 } 1093 1094 static IrInstruction *ir_build_const_bigint(IrBuilder *irb, Scope *scope, AstNode *source_node, BigInt *bigint) { 1095 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1096 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_int; 1097 const_instruction->base.value.special = ConstValSpecialStatic; 1098 bigint_init_bigint(&const_instruction->base.value.data.x_bigint, bigint); 1099 return &const_instruction->base; 1100 } 1101 1102 static IrInstruction *ir_build_const_bigfloat(IrBuilder *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) { 1103 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1104 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_float; 1105 const_instruction->base.value.special = ConstValSpecialStatic; 1106 bigfloat_init_bigfloat(&const_instruction->base.value.data.x_bigfloat, bigfloat); 1107 return &const_instruction->base; 1108 } 1109 1110 static IrInstruction *ir_build_const_null(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1111 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1112 const_instruction->base.value.type = irb->codegen->builtin_types.entry_null; 1113 const_instruction->base.value.special = ConstValSpecialStatic; 1114 return &const_instruction->base; 1115 } 1116 1117 static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { 1118 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1119 const_instruction->base.value.type = irb->codegen->builtin_types.entry_usize; 1120 const_instruction->base.value.special = ConstValSpecialStatic; 1121 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); 1122 return &const_instruction->base; 1123 } 1124 1125 static IrInstruction *ir_build_const_u8(IrBuilder *irb, Scope *scope, AstNode *source_node, uint8_t value) { 1126 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1127 const_instruction->base.value.type = irb->codegen->builtin_types.entry_u8; 1128 const_instruction->base.value.special = ConstValSpecialStatic; 1129 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); 1130 return &const_instruction->base; 1131 } 1132 1133 static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1134 ZigType *type_entry) 1135 { 1136 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1137 const_instruction->base.value.type = irb->codegen->builtin_types.entry_type; 1138 const_instruction->base.value.special = ConstValSpecialStatic; 1139 const_instruction->base.value.data.x_type = type_entry; 1140 return &const_instruction->base; 1141 } 1142 1143 static IrInstruction *ir_build_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1144 ZigType *type_entry) 1145 { 1146 IrInstruction *instruction = ir_create_const_type(irb, scope, source_node, type_entry); 1147 ir_instruction_append(irb->current_basic_block, instruction); 1148 return instruction; 1149 } 1150 1151 static IrInstruction *ir_create_const_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigFn *fn_entry) { 1152 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1153 const_instruction->base.value.type = fn_entry->type_entry; 1154 const_instruction->base.value.special = ConstValSpecialStatic; 1155 const_instruction->base.value.data.x_ptr.data.fn.fn_entry = fn_entry; 1156 const_instruction->base.value.data.x_ptr.mut = ConstPtrMutComptimeConst; 1157 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialFunction; 1158 return &const_instruction->base; 1159 } 1160 1161 static IrInstruction *ir_build_const_import(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *import) { 1162 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1163 const_instruction->base.value.type = irb->codegen->builtin_types.entry_type; 1164 const_instruction->base.value.special = ConstValSpecialStatic; 1165 const_instruction->base.value.data.x_type = import; 1166 return &const_instruction->base; 1167 } 1168 1169 static IrInstruction *ir_build_const_bool(IrBuilder *irb, Scope *scope, AstNode *source_node, bool value) { 1170 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1171 const_instruction->base.value.type = irb->codegen->builtin_types.entry_bool; 1172 const_instruction->base.value.special = ConstValSpecialStatic; 1173 const_instruction->base.value.data.x_bool = value; 1174 return &const_instruction->base; 1175 } 1176 1177 static IrInstruction *ir_build_const_enum_literal(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *name) { 1178 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1179 const_instruction->base.value.type = irb->codegen->builtin_types.entry_enum_literal; 1180 const_instruction->base.value.special = ConstValSpecialStatic; 1181 const_instruction->base.value.data.x_enum_literal = name; 1182 return &const_instruction->base; 1183 } 1184 1185 static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, 1186 ZigFn *fn_entry, IrInstruction *first_arg) 1187 { 1188 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1189 const_instruction->base.value.type = get_bound_fn_type(irb->codegen, fn_entry); 1190 const_instruction->base.value.special = ConstValSpecialStatic; 1191 const_instruction->base.value.data.x_bound_fn.fn = fn_entry; 1192 const_instruction->base.value.data.x_bound_fn.first_arg = first_arg; 1193 return &const_instruction->base; 1194 } 1195 1196 static IrInstruction *ir_create_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1197 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1198 init_const_str_lit(irb->codegen, &const_instruction->base.value, str); 1199 1200 return &const_instruction->base; 1201 } 1202 static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1203 IrInstruction *instruction = ir_create_const_str_lit(irb, scope, source_node, str); 1204 ir_instruction_append(irb->current_basic_block, instruction); 1205 return instruction; 1206 } 1207 1208 static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1209 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1210 init_const_c_str_lit(irb->codegen, &const_instruction->base.value, str); 1211 return &const_instruction->base; 1212 } 1213 1214 static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, 1215 IrInstruction *op1, IrInstruction *op2, bool safety_check_on) 1216 { 1217 IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irb, scope, source_node); 1218 bin_op_instruction->op_id = op_id; 1219 bin_op_instruction->op1 = op1; 1220 bin_op_instruction->op2 = op2; 1221 bin_op_instruction->safety_check_on = safety_check_on; 1222 1223 ir_ref_instruction(op1, irb->current_basic_block); 1224 ir_ref_instruction(op2, irb->current_basic_block); 1225 1226 return &bin_op_instruction->base; 1227 } 1228 1229 static IrInstruction *ir_build_var_ptr_x(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, 1230 ScopeFnDef *crossed_fndef_scope) 1231 { 1232 IrInstructionVarPtr *instruction = ir_build_instruction<IrInstructionVarPtr>(irb, scope, source_node); 1233 instruction->var = var; 1234 instruction->crossed_fndef_scope = crossed_fndef_scope; 1235 1236 ir_ref_var(var); 1237 1238 return &instruction->base; 1239 } 1240 1241 static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var) { 1242 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); 1243 } 1244 1245 static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr, 1246 IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len) 1247 { 1248 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); 1249 instruction->array_ptr = array_ptr; 1250 instruction->elem_index = elem_index; 1251 instruction->safety_check_on = safety_check_on; 1252 instruction->ptr_len = ptr_len; 1253 1254 ir_ref_instruction(array_ptr, irb->current_basic_block); 1255 ir_ref_instruction(elem_index, irb->current_basic_block); 1256 1257 return &instruction->base; 1258 } 1259 1260 static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node, 1261 IrInstruction *container_ptr, IrInstruction *field_name_expr) 1262 { 1263 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); 1264 instruction->container_ptr = container_ptr; 1265 instruction->field_name_buffer = nullptr; 1266 instruction->field_name_expr = field_name_expr; 1267 1268 ir_ref_instruction(container_ptr, irb->current_basic_block); 1269 ir_ref_instruction(field_name_expr, irb->current_basic_block); 1270 1271 return &instruction->base; 1272 } 1273 1274 static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1275 IrInstruction *container_ptr, Buf *field_name) 1276 { 1277 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); 1278 instruction->container_ptr = container_ptr; 1279 instruction->field_name_buffer = field_name; 1280 instruction->field_name_expr = nullptr; 1281 1282 ir_ref_instruction(container_ptr, irb->current_basic_block); 1283 1284 return &instruction->base; 1285 } 1286 1287 static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1288 IrInstruction *struct_ptr, TypeStructField *field) 1289 { 1290 IrInstructionStructFieldPtr *instruction = ir_build_instruction<IrInstructionStructFieldPtr>(irb, scope, source_node); 1291 instruction->struct_ptr = struct_ptr; 1292 instruction->field = field; 1293 1294 ir_ref_instruction(struct_ptr, irb->current_basic_block); 1295 1296 return &instruction->base; 1297 } 1298 1299 static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1300 IrInstruction *union_ptr, TypeUnionField *field) 1301 { 1302 IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node); 1303 instruction->union_ptr = union_ptr; 1304 instruction->field = field; 1305 1306 ir_ref_instruction(union_ptr, irb->current_basic_block); 1307 1308 return &instruction->base; 1309 } 1310 1311 static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node, 1312 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, 1313 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, 1314 IrInstruction *new_stack) 1315 { 1316 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node); 1317 call_instruction->fn_entry = fn_entry; 1318 call_instruction->fn_ref = fn_ref; 1319 call_instruction->is_comptime = is_comptime; 1320 call_instruction->fn_inline = fn_inline; 1321 call_instruction->args = args; 1322 call_instruction->arg_count = arg_count; 1323 call_instruction->is_async = is_async; 1324 call_instruction->async_allocator = async_allocator; 1325 call_instruction->new_stack = new_stack; 1326 1327 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); 1328 for (size_t i = 0; i < arg_count; i += 1) 1329 ir_ref_instruction(args[i], irb->current_basic_block); 1330 if (async_allocator != nullptr) ir_ref_instruction(async_allocator, irb->current_basic_block); 1331 if (new_stack != nullptr) ir_ref_instruction(new_stack, irb->current_basic_block); 1332 1333 return &call_instruction->base; 1334 } 1335 1336 static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, 1337 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values) 1338 { 1339 assert(incoming_count != 0); 1340 assert(incoming_count != SIZE_MAX); 1341 1342 IrInstructionPhi *phi_instruction = ir_build_instruction<IrInstructionPhi>(irb, scope, source_node); 1343 phi_instruction->incoming_count = incoming_count; 1344 phi_instruction->incoming_blocks = incoming_blocks; 1345 phi_instruction->incoming_values = incoming_values; 1346 1347 for (size_t i = 0; i < incoming_count; i += 1) { 1348 ir_ref_bb(incoming_blocks[i]); 1349 ir_ref_instruction(incoming_values[i], irb->current_basic_block); 1350 } 1351 1352 return &phi_instruction->base; 1353 } 1354 1355 static IrInstruction *ir_create_br(IrBuilder *irb, Scope *scope, AstNode *source_node, 1356 IrBasicBlock *dest_block, IrInstruction *is_comptime) 1357 { 1358 IrInstructionBr *br_instruction = ir_create_instruction<IrInstructionBr>(irb, scope, source_node); 1359 br_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1360 br_instruction->base.value.special = ConstValSpecialStatic; 1361 br_instruction->dest_block = dest_block; 1362 br_instruction->is_comptime = is_comptime; 1363 1364 ir_ref_bb(dest_block); 1365 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 1366 1367 return &br_instruction->base; 1368 } 1369 1370 static IrInstruction *ir_build_br(IrBuilder *irb, Scope *scope, AstNode *source_node, 1371 IrBasicBlock *dest_block, IrInstruction *is_comptime) 1372 { 1373 IrInstruction *instruction = ir_create_br(irb, scope, source_node, dest_block, is_comptime); 1374 ir_instruction_append(irb->current_basic_block, instruction); 1375 return instruction; 1376 } 1377 1378 static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1379 IrInstruction *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, 1380 IrInstruction *align_value, uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero) 1381 { 1382 IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node); 1383 ptr_type_of_instruction->align_value = align_value; 1384 ptr_type_of_instruction->child_type = child_type; 1385 ptr_type_of_instruction->is_const = is_const; 1386 ptr_type_of_instruction->is_volatile = is_volatile; 1387 ptr_type_of_instruction->ptr_len = ptr_len; 1388 ptr_type_of_instruction->bit_offset_start = bit_offset_start; 1389 ptr_type_of_instruction->host_int_bytes = host_int_bytes; 1390 ptr_type_of_instruction->is_allow_zero = is_allow_zero; 1391 1392 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 1393 ir_ref_instruction(child_type, irb->current_basic_block); 1394 1395 return &ptr_type_of_instruction->base; 1396 } 1397 1398 static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 1399 IrInstruction *value, LVal lval) 1400 { 1401 IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); 1402 instruction->op_id = op_id; 1403 instruction->value = value; 1404 instruction->lval = lval; 1405 1406 ir_ref_instruction(value, irb->current_basic_block); 1407 1408 return &instruction->base; 1409 } 1410 1411 static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 1412 IrInstruction *value) 1413 { 1414 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone); 1415 } 1416 1417 static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node, 1418 IrInstruction *container_type, size_t item_count, IrInstruction **items) 1419 { 1420 IrInstructionContainerInitList *container_init_list_instruction = 1421 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); 1422 container_init_list_instruction->container_type = container_type; 1423 container_init_list_instruction->item_count = item_count; 1424 container_init_list_instruction->items = items; 1425 1426 if (container_type != nullptr) ir_ref_instruction(container_type, irb->current_basic_block); 1427 for (size_t i = 0; i < item_count; i += 1) { 1428 ir_ref_instruction(items[i], irb->current_basic_block); 1429 } 1430 1431 return &container_init_list_instruction->base; 1432 } 1433 1434 static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node, 1435 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields) 1436 { 1437 IrInstructionContainerInitFields *container_init_fields_instruction = 1438 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); 1439 container_init_fields_instruction->container_type = container_type; 1440 container_init_fields_instruction->field_count = field_count; 1441 container_init_fields_instruction->fields = fields; 1442 1443 ir_ref_instruction(container_type, irb->current_basic_block); 1444 for (size_t i = 0; i < field_count; i += 1) { 1445 ir_ref_instruction(fields[i].value, irb->current_basic_block); 1446 } 1447 1448 return &container_init_fields_instruction->base; 1449 } 1450 1451 static IrInstruction *ir_build_struct_init(IrBuilder *irb, Scope *scope, AstNode *source_node, 1452 ZigType *struct_type, size_t field_count, IrInstructionStructInitField *fields) 1453 { 1454 IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, scope, source_node); 1455 struct_init_instruction->struct_type = struct_type; 1456 struct_init_instruction->field_count = field_count; 1457 struct_init_instruction->fields = fields; 1458 1459 for (size_t i = 0; i < field_count; i += 1) 1460 ir_ref_instruction(fields[i].value, irb->current_basic_block); 1461 1462 return &struct_init_instruction->base; 1463 } 1464 1465 static IrInstruction *ir_build_union_init(IrBuilder *irb, Scope *scope, AstNode *source_node, 1466 ZigType *union_type, TypeUnionField *field, IrInstruction *init_value) 1467 { 1468 IrInstructionUnionInit *union_init_instruction = ir_build_instruction<IrInstructionUnionInit>(irb, scope, source_node); 1469 union_init_instruction->union_type = union_type; 1470 union_init_instruction->field = field; 1471 union_init_instruction->init_value = init_value; 1472 1473 ir_ref_instruction(init_value, irb->current_basic_block); 1474 1475 return &union_init_instruction->base; 1476 } 1477 1478 static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1479 IrInstructionUnreachable *unreachable_instruction = 1480 ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); 1481 unreachable_instruction->base.value.special = ConstValSpecialStatic; 1482 unreachable_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1483 return &unreachable_instruction->base; 1484 } 1485 1486 static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1487 IrInstruction *ptr, IrInstruction *value) 1488 { 1489 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node); 1490 instruction->base.value.special = ConstValSpecialStatic; 1491 instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1492 instruction->ptr = ptr; 1493 instruction->value = value; 1494 1495 ir_ref_instruction(ptr, irb->current_basic_block); 1496 ir_ref_instruction(value, irb->current_basic_block); 1497 1498 return &instruction->base; 1499 } 1500 1501 static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 1502 ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value) 1503 { 1504 IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node); 1505 decl_var_instruction->base.value.special = ConstValSpecialStatic; 1506 decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1507 decl_var_instruction->var = var; 1508 decl_var_instruction->var_type = var_type; 1509 decl_var_instruction->align_value = align_value; 1510 decl_var_instruction->init_value = init_value; 1511 1512 if (var_type != nullptr) ir_ref_instruction(var_type, irb->current_basic_block); 1513 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 1514 ir_ref_instruction(init_value, irb->current_basic_block); 1515 1516 return &decl_var_instruction->base; 1517 } 1518 1519 static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction, 1520 ZigVar *var, IrInstruction *init_value) 1521 { 1522 IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb, 1523 source_instruction->scope, source_instruction->source_node); 1524 decl_var_instruction->base.value.special = ConstValSpecialStatic; 1525 decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void; 1526 decl_var_instruction->var = var; 1527 decl_var_instruction->init_value = init_value; 1528 1529 ir_ref_instruction(init_value, ira->new_irb.current_basic_block); 1530 1531 return &decl_var_instruction->base; 1532 } 1533 1534 static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction, 1535 IrInstruction *operand, ZigType *ty) 1536 { 1537 IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb, 1538 source_instruction->scope, source_instruction->source_node); 1539 instruction->base.value.type = ty; 1540 instruction->operand = operand; 1541 1542 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 1543 1544 return &instruction->base; 1545 } 1546 1547 static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node, 1548 IrInstruction *name, IrInstruction *target, IrInstruction *linkage) 1549 { 1550 IrInstructionExport *export_instruction = ir_build_instruction<IrInstructionExport>( 1551 irb, scope, source_node); 1552 export_instruction->base.value.special = ConstValSpecialStatic; 1553 export_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1554 export_instruction->name = name; 1555 export_instruction->target = target; 1556 export_instruction->linkage = linkage; 1557 1558 ir_ref_instruction(name, irb->current_basic_block); 1559 ir_ref_instruction(target, irb->current_basic_block); 1560 if (linkage) ir_ref_instruction(linkage, irb->current_basic_block); 1561 1562 return &export_instruction->base; 1563 } 1564 1565 static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { 1566 IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node); 1567 instruction->ptr = ptr; 1568 1569 ir_ref_instruction(ptr, irb->current_basic_block); 1570 1571 return &instruction->base; 1572 } 1573 1574 static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1575 IrInstructionTypeOf *instruction = ir_build_instruction<IrInstructionTypeOf>(irb, scope, source_node); 1576 instruction->value = value; 1577 1578 ir_ref_instruction(value, irb->current_basic_block); 1579 1580 return &instruction->base; 1581 } 1582 1583 static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { 1584 IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, scope, source_node); 1585 instruction->ptr = ptr; 1586 1587 ir_ref_instruction(ptr, irb->current_basic_block); 1588 1589 return &instruction->base; 1590 } 1591 1592 static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstNode *source_node, 1593 IrInstruction *value) 1594 { 1595 IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>( 1596 irb, scope, source_node); 1597 instruction->value = value; 1598 1599 ir_ref_instruction(value, irb->current_basic_block); 1600 1601 return &instruction->base; 1602 } 1603 1604 static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) { 1605 IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); 1606 instruction->is_cold = is_cold; 1607 1608 ir_ref_instruction(is_cold, irb->current_basic_block); 1609 1610 return &instruction->base; 1611 } 1612 1613 static IrInstruction *ir_build_set_runtime_safety(IrBuilder *irb, Scope *scope, AstNode *source_node, 1614 IrInstruction *safety_on) 1615 { 1616 IrInstructionSetRuntimeSafety *instruction = ir_build_instruction<IrInstructionSetRuntimeSafety>(irb, scope, source_node); 1617 instruction->safety_on = safety_on; 1618 1619 ir_ref_instruction(safety_on, irb->current_basic_block); 1620 1621 return &instruction->base; 1622 } 1623 1624 static IrInstruction *ir_build_set_float_mode(IrBuilder *irb, Scope *scope, AstNode *source_node, 1625 IrInstruction *mode_value) 1626 { 1627 IrInstructionSetFloatMode *instruction = ir_build_instruction<IrInstructionSetFloatMode>(irb, scope, source_node); 1628 instruction->mode_value = mode_value; 1629 1630 ir_ref_instruction(mode_value, irb->current_basic_block); 1631 1632 return &instruction->base; 1633 } 1634 1635 static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *size, 1636 IrInstruction *child_type) 1637 { 1638 IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, scope, source_node); 1639 instruction->size = size; 1640 instruction->child_type = child_type; 1641 1642 ir_ref_instruction(size, irb->current_basic_block); 1643 ir_ref_instruction(child_type, irb->current_basic_block); 1644 1645 return &instruction->base; 1646 } 1647 1648 static IrInstruction *ir_build_promise_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1649 IrInstruction *payload_type) 1650 { 1651 IrInstructionPromiseType *instruction = ir_build_instruction<IrInstructionPromiseType>(irb, scope, source_node); 1652 instruction->payload_type = payload_type; 1653 1654 if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); 1655 1656 return &instruction->base; 1657 } 1658 1659 static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1660 IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value, bool is_allow_zero) 1661 { 1662 IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, scope, source_node); 1663 instruction->is_const = is_const; 1664 instruction->is_volatile = is_volatile; 1665 instruction->child_type = child_type; 1666 instruction->align_value = align_value; 1667 instruction->is_allow_zero = is_allow_zero; 1668 1669 ir_ref_instruction(child_type, irb->current_basic_block); 1670 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 1671 1672 return &instruction->base; 1673 } 1674 1675 static IrInstruction *ir_build_global_asm(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *asm_code) { 1676 IrInstructionGlobalAsm *instruction = ir_build_instruction<IrInstructionGlobalAsm>(irb, scope, source_node); 1677 instruction->asm_code = asm_code; 1678 return &instruction->base; 1679 } 1680 1681 static IrInstruction *ir_build_asm(IrBuilder *irb, Scope *scope, AstNode *source_node, 1682 Buf *asm_template, AsmToken *token_list, size_t token_list_len, 1683 IrInstruction **input_list, IrInstruction **output_types, ZigVar **output_vars, size_t return_count, 1684 bool has_side_effects) 1685 { 1686 IrInstructionAsm *instruction = ir_build_instruction<IrInstructionAsm>(irb, scope, source_node); 1687 instruction->asm_template = asm_template; 1688 instruction->token_list = token_list; 1689 instruction->token_list_len = token_list_len; 1690 instruction->input_list = input_list; 1691 instruction->output_types = output_types; 1692 instruction->output_vars = output_vars; 1693 instruction->return_count = return_count; 1694 instruction->has_side_effects = has_side_effects; 1695 1696 assert(source_node->type == NodeTypeAsmExpr); 1697 for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) { 1698 IrInstruction *output_type = output_types[i]; 1699 if (output_type) ir_ref_instruction(output_type, irb->current_basic_block); 1700 } 1701 1702 for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) { 1703 IrInstruction *input_value = input_list[i]; 1704 ir_ref_instruction(input_value, irb->current_basic_block); 1705 } 1706 1707 return &instruction->base; 1708 } 1709 1710 static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { 1711 IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, scope, source_node); 1712 instruction->type_value = type_value; 1713 1714 ir_ref_instruction(type_value, irb->current_basic_block); 1715 1716 return &instruction->base; 1717 } 1718 1719 static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1720 IrInstructionTestNonNull *instruction = ir_build_instruction<IrInstructionTestNonNull>(irb, scope, source_node); 1721 instruction->value = value; 1722 1723 ir_ref_instruction(value, irb->current_basic_block); 1724 1725 return &instruction->base; 1726 } 1727 1728 static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1729 IrInstruction *base_ptr, bool safety_check_on) 1730 { 1731 IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node); 1732 instruction->base_ptr = base_ptr; 1733 instruction->safety_check_on = safety_check_on; 1734 1735 ir_ref_instruction(base_ptr, irb->current_basic_block); 1736 1737 return &instruction->base; 1738 } 1739 1740 static IrInstruction *ir_build_maybe_wrap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1741 IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>(irb, scope, source_node); 1742 instruction->value = value; 1743 1744 ir_ref_instruction(value, irb->current_basic_block); 1745 1746 return &instruction->base; 1747 } 1748 1749 static IrInstruction *ir_build_err_wrap_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1750 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(irb, scope, source_node); 1751 instruction->value = value; 1752 1753 ir_ref_instruction(value, irb->current_basic_block); 1754 1755 return &instruction->base; 1756 } 1757 1758 static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1759 IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node); 1760 instruction->value = value; 1761 1762 ir_ref_instruction(value, irb->current_basic_block); 1763 1764 return &instruction->base; 1765 } 1766 1767 static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1768 IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node); 1769 instruction->value = value; 1770 1771 ir_ref_instruction(value, irb->current_basic_block); 1772 1773 return &instruction->base; 1774 } 1775 1776 static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1777 IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node); 1778 instruction->value = value; 1779 1780 ir_ref_instruction(value, irb->current_basic_block); 1781 1782 return &instruction->base; 1783 } 1784 1785 static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1786 IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node); 1787 instruction->value = value; 1788 1789 ir_ref_instruction(value, irb->current_basic_block); 1790 1791 return &instruction->base; 1792 } 1793 1794 static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value, 1795 IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, 1796 IrInstruction *switch_prongs_void) 1797 { 1798 IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node); 1799 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1800 instruction->base.value.special = ConstValSpecialStatic; 1801 instruction->target_value = target_value; 1802 instruction->else_block = else_block; 1803 instruction->case_count = case_count; 1804 instruction->cases = cases; 1805 instruction->is_comptime = is_comptime; 1806 instruction->switch_prongs_void = switch_prongs_void; 1807 1808 ir_ref_instruction(target_value, irb->current_basic_block); 1809 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 1810 ir_ref_bb(else_block); 1811 if (switch_prongs_void) ir_ref_instruction(switch_prongs_void, irb->current_basic_block); 1812 1813 for (size_t i = 0; i < case_count; i += 1) { 1814 ir_ref_instruction(cases[i].value, irb->current_basic_block); 1815 ir_ref_bb(cases[i].block); 1816 } 1817 1818 return &instruction->base; 1819 } 1820 1821 static IrInstruction *ir_build_switch_target(IrBuilder *irb, Scope *scope, AstNode *source_node, 1822 IrInstruction *target_value_ptr) 1823 { 1824 IrInstructionSwitchTarget *instruction = ir_build_instruction<IrInstructionSwitchTarget>(irb, scope, source_node); 1825 instruction->target_value_ptr = target_value_ptr; 1826 1827 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 1828 1829 return &instruction->base; 1830 } 1831 1832 static IrInstruction *ir_build_switch_var(IrBuilder *irb, Scope *scope, AstNode *source_node, 1833 IrInstruction *target_value_ptr, IrInstruction *prong_value) 1834 { 1835 IrInstructionSwitchVar *instruction = ir_build_instruction<IrInstructionSwitchVar>(irb, scope, source_node); 1836 instruction->target_value_ptr = target_value_ptr; 1837 instruction->prong_value = prong_value; 1838 1839 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 1840 ir_ref_instruction(prong_value, irb->current_basic_block); 1841 1842 return &instruction->base; 1843 } 1844 1845 static IrInstruction *ir_build_union_tag(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1846 IrInstructionUnionTag *instruction = ir_build_instruction<IrInstructionUnionTag>(irb, scope, source_node); 1847 instruction->value = value; 1848 1849 ir_ref_instruction(value, irb->current_basic_block); 1850 1851 return &instruction->base; 1852 } 1853 1854 static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1855 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, scope, source_node); 1856 instruction->name = name; 1857 1858 ir_ref_instruction(name, irb->current_basic_block); 1859 1860 return &instruction->base; 1861 } 1862 1863 static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value, 1864 bool is_const, bool is_volatile) 1865 { 1866 IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, scope, source_node); 1867 instruction->value = value; 1868 instruction->is_const = is_const; 1869 instruction->is_volatile = is_volatile; 1870 1871 ir_ref_instruction(value, irb->current_basic_block); 1872 1873 return &instruction->base; 1874 } 1875 1876 static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { 1877 IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); 1878 instruction->msg = msg; 1879 1880 ir_ref_instruction(msg, irb->current_basic_block); 1881 1882 return &instruction->base; 1883 } 1884 1885 static IrInstruction *ir_build_compile_log(IrBuilder *irb, Scope *scope, AstNode *source_node, 1886 size_t msg_count, IrInstruction **msg_list) 1887 { 1888 IrInstructionCompileLog *instruction = ir_build_instruction<IrInstructionCompileLog>(irb, scope, source_node); 1889 instruction->msg_count = msg_count; 1890 instruction->msg_list = msg_list; 1891 1892 for (size_t i = 0; i < msg_count; i += 1) { 1893 ir_ref_instruction(msg_list[i], irb->current_basic_block); 1894 } 1895 1896 return &instruction->base; 1897 } 1898 1899 static IrInstruction *ir_build_err_name(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1900 IrInstructionErrName *instruction = ir_build_instruction<IrInstructionErrName>(irb, scope, source_node); 1901 instruction->value = value; 1902 1903 ir_ref_instruction(value, irb->current_basic_block); 1904 1905 return &instruction->base; 1906 } 1907 1908 static IrInstruction *ir_build_c_import(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1909 IrInstructionCImport *instruction = ir_build_instruction<IrInstructionCImport>(irb, scope, source_node); 1910 return &instruction->base; 1911 } 1912 1913 static IrInstruction *ir_build_c_include(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1914 IrInstructionCInclude *instruction = ir_build_instruction<IrInstructionCInclude>(irb, scope, source_node); 1915 instruction->name = name; 1916 1917 ir_ref_instruction(name, irb->current_basic_block); 1918 1919 return &instruction->base; 1920 } 1921 1922 static IrInstruction *ir_build_c_define(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name, IrInstruction *value) { 1923 IrInstructionCDefine *instruction = ir_build_instruction<IrInstructionCDefine>(irb, scope, source_node); 1924 instruction->name = name; 1925 instruction->value = value; 1926 1927 ir_ref_instruction(name, irb->current_basic_block); 1928 ir_ref_instruction(value, irb->current_basic_block); 1929 1930 return &instruction->base; 1931 } 1932 1933 static IrInstruction *ir_build_c_undef(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1934 IrInstructionCUndef *instruction = ir_build_instruction<IrInstructionCUndef>(irb, scope, source_node); 1935 instruction->name = name; 1936 1937 ir_ref_instruction(name, irb->current_basic_block); 1938 1939 return &instruction->base; 1940 } 1941 1942 static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1943 IrInstructionEmbedFile *instruction = ir_build_instruction<IrInstructionEmbedFile>(irb, scope, source_node); 1944 instruction->name = name; 1945 1946 ir_ref_instruction(name, irb->current_basic_block); 1947 1948 return &instruction->base; 1949 } 1950 1951 static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 1952 IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, 1953 IrInstruction *success_order_value, IrInstruction *failure_order_value, 1954 bool is_weak) 1955 { 1956 IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node); 1957 instruction->type_value = type_value; 1958 instruction->ptr = ptr; 1959 instruction->cmp_value = cmp_value; 1960 instruction->new_value = new_value; 1961 instruction->success_order_value = success_order_value; 1962 instruction->failure_order_value = failure_order_value; 1963 instruction->is_weak = is_weak; 1964 1965 ir_ref_instruction(type_value, irb->current_basic_block); 1966 ir_ref_instruction(ptr, irb->current_basic_block); 1967 ir_ref_instruction(cmp_value, irb->current_basic_block); 1968 ir_ref_instruction(new_value, irb->current_basic_block); 1969 ir_ref_instruction(success_order_value, irb->current_basic_block); 1970 ir_ref_instruction(failure_order_value, irb->current_basic_block); 1971 1972 return &instruction->base; 1973 } 1974 1975 static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, 1976 IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, 1977 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak) 1978 { 1979 IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb, 1980 source_instruction->scope, source_instruction->source_node); 1981 instruction->ptr = ptr; 1982 instruction->cmp_value = cmp_value; 1983 instruction->new_value = new_value; 1984 instruction->success_order = success_order; 1985 instruction->failure_order = failure_order; 1986 instruction->is_weak = is_weak; 1987 1988 ir_ref_instruction(ptr, ira->new_irb.current_basic_block); 1989 ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block); 1990 ir_ref_instruction(new_value, ira->new_irb.current_basic_block); 1991 1992 return &instruction->base; 1993 } 1994 1995 static IrInstruction *ir_build_fence(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *order_value, AtomicOrder order) { 1996 IrInstructionFence *instruction = ir_build_instruction<IrInstructionFence>(irb, scope, source_node); 1997 instruction->order_value = order_value; 1998 instruction->order = order; 1999 2000 ir_ref_instruction(order_value, irb->current_basic_block); 2001 2002 return &instruction->base; 2003 } 2004 2005 static IrInstruction *ir_build_truncate(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2006 IrInstructionTruncate *instruction = ir_build_instruction<IrInstructionTruncate>(irb, scope, source_node); 2007 instruction->dest_type = dest_type; 2008 instruction->target = target; 2009 2010 ir_ref_instruction(dest_type, irb->current_basic_block); 2011 ir_ref_instruction(target, irb->current_basic_block); 2012 2013 return &instruction->base; 2014 } 2015 2016 static IrInstruction *ir_build_int_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2017 IrInstructionIntCast *instruction = ir_build_instruction<IrInstructionIntCast>(irb, scope, source_node); 2018 instruction->dest_type = dest_type; 2019 instruction->target = target; 2020 2021 ir_ref_instruction(dest_type, irb->current_basic_block); 2022 ir_ref_instruction(target, irb->current_basic_block); 2023 2024 return &instruction->base; 2025 } 2026 2027 static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2028 IrInstructionFloatCast *instruction = ir_build_instruction<IrInstructionFloatCast>(irb, scope, source_node); 2029 instruction->dest_type = dest_type; 2030 instruction->target = target; 2031 2032 ir_ref_instruction(dest_type, irb->current_basic_block); 2033 ir_ref_instruction(target, irb->current_basic_block); 2034 2035 return &instruction->base; 2036 } 2037 2038 static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2039 IrInstructionErrSetCast *instruction = ir_build_instruction<IrInstructionErrSetCast>(irb, scope, source_node); 2040 instruction->dest_type = dest_type; 2041 instruction->target = target; 2042 2043 ir_ref_instruction(dest_type, irb->current_basic_block); 2044 ir_ref_instruction(target, irb->current_basic_block); 2045 2046 return &instruction->base; 2047 } 2048 2049 static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { 2050 IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); 2051 instruction->target = target; 2052 2053 ir_ref_instruction(target, irb->current_basic_block); 2054 2055 return &instruction->base; 2056 } 2057 2058 static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_child_type, IrInstruction *target) { 2059 IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); 2060 instruction->dest_child_type = dest_child_type; 2061 instruction->target = target; 2062 2063 ir_ref_instruction(dest_child_type, irb->current_basic_block); 2064 ir_ref_instruction(target, irb->current_basic_block); 2065 2066 return &instruction->base; 2067 } 2068 2069 static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2070 IrInstructionIntToFloat *instruction = ir_build_instruction<IrInstructionIntToFloat>(irb, scope, source_node); 2071 instruction->dest_type = dest_type; 2072 instruction->target = target; 2073 2074 ir_ref_instruction(dest_type, irb->current_basic_block); 2075 ir_ref_instruction(target, irb->current_basic_block); 2076 2077 return &instruction->base; 2078 } 2079 2080 static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2081 IrInstructionFloatToInt *instruction = ir_build_instruction<IrInstructionFloatToInt>(irb, scope, source_node); 2082 instruction->dest_type = dest_type; 2083 instruction->target = target; 2084 2085 ir_ref_instruction(dest_type, irb->current_basic_block); 2086 ir_ref_instruction(target, irb->current_basic_block); 2087 2088 return &instruction->base; 2089 } 2090 2091 static IrInstruction *ir_build_bool_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { 2092 IrInstructionBoolToInt *instruction = ir_build_instruction<IrInstructionBoolToInt>(irb, scope, source_node); 2093 instruction->target = target; 2094 2095 ir_ref_instruction(target, irb->current_basic_block); 2096 2097 return &instruction->base; 2098 } 2099 2100 static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) { 2101 IrInstructionIntType *instruction = ir_build_instruction<IrInstructionIntType>(irb, scope, source_node); 2102 instruction->is_signed = is_signed; 2103 instruction->bit_count = bit_count; 2104 2105 ir_ref_instruction(is_signed, irb->current_basic_block); 2106 ir_ref_instruction(bit_count, irb->current_basic_block); 2107 2108 return &instruction->base; 2109 } 2110 2111 static IrInstruction *ir_build_vector_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *len, 2112 IrInstruction *elem_type) 2113 { 2114 IrInstructionVectorType *instruction = ir_build_instruction<IrInstructionVectorType>(irb, scope, source_node); 2115 instruction->len = len; 2116 instruction->elem_type = elem_type; 2117 2118 ir_ref_instruction(len, irb->current_basic_block); 2119 ir_ref_instruction(elem_type, irb->current_basic_block); 2120 2121 return &instruction->base; 2122 } 2123 2124 static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2125 IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node); 2126 instruction->value = value; 2127 2128 ir_ref_instruction(value, irb->current_basic_block); 2129 2130 return &instruction->base; 2131 } 2132 2133 static IrInstruction *ir_build_memset(IrBuilder *irb, Scope *scope, AstNode *source_node, 2134 IrInstruction *dest_ptr, IrInstruction *byte, IrInstruction *count) 2135 { 2136 IrInstructionMemset *instruction = ir_build_instruction<IrInstructionMemset>(irb, scope, source_node); 2137 instruction->dest_ptr = dest_ptr; 2138 instruction->byte = byte; 2139 instruction->count = count; 2140 2141 ir_ref_instruction(dest_ptr, irb->current_basic_block); 2142 ir_ref_instruction(byte, irb->current_basic_block); 2143 ir_ref_instruction(count, irb->current_basic_block); 2144 2145 return &instruction->base; 2146 } 2147 2148 static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *source_node, 2149 IrInstruction *dest_ptr, IrInstruction *src_ptr, IrInstruction *count) 2150 { 2151 IrInstructionMemcpy *instruction = ir_build_instruction<IrInstructionMemcpy>(irb, scope, source_node); 2152 instruction->dest_ptr = dest_ptr; 2153 instruction->src_ptr = src_ptr; 2154 instruction->count = count; 2155 2156 ir_ref_instruction(dest_ptr, irb->current_basic_block); 2157 ir_ref_instruction(src_ptr, irb->current_basic_block); 2158 ir_ref_instruction(count, irb->current_basic_block); 2159 2160 return &instruction->base; 2161 } 2162 2163 static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *source_node, 2164 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on) 2165 { 2166 IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node); 2167 instruction->ptr = ptr; 2168 instruction->start = start; 2169 instruction->end = end; 2170 instruction->safety_check_on = safety_check_on; 2171 2172 ir_ref_instruction(ptr, irb->current_basic_block); 2173 ir_ref_instruction(start, irb->current_basic_block); 2174 if (end) ir_ref_instruction(end, irb->current_basic_block); 2175 2176 return &instruction->base; 2177 } 2178 2179 static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) { 2180 IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); 2181 instruction->container = container; 2182 2183 ir_ref_instruction(container, irb->current_basic_block); 2184 2185 return &instruction->base; 2186 } 2187 2188 static IrInstruction *ir_build_member_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2189 IrInstruction *container_type, IrInstruction *member_index) 2190 { 2191 IrInstructionMemberType *instruction = ir_build_instruction<IrInstructionMemberType>(irb, scope, source_node); 2192 instruction->container_type = container_type; 2193 instruction->member_index = member_index; 2194 2195 ir_ref_instruction(container_type, irb->current_basic_block); 2196 ir_ref_instruction(member_index, irb->current_basic_block); 2197 2198 return &instruction->base; 2199 } 2200 2201 static IrInstruction *ir_build_member_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2202 IrInstruction *container_type, IrInstruction *member_index) 2203 { 2204 IrInstructionMemberName *instruction = ir_build_instruction<IrInstructionMemberName>(irb, scope, source_node); 2205 instruction->container_type = container_type; 2206 instruction->member_index = member_index; 2207 2208 ir_ref_instruction(container_type, irb->current_basic_block); 2209 ir_ref_instruction(member_index, irb->current_basic_block); 2210 2211 return &instruction->base; 2212 } 2213 2214 static IrInstruction *ir_build_breakpoint(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2215 IrInstructionBreakpoint *instruction = ir_build_instruction<IrInstructionBreakpoint>(irb, scope, source_node); 2216 return &instruction->base; 2217 } 2218 2219 static IrInstruction *ir_build_return_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2220 IrInstructionReturnAddress *instruction = ir_build_instruction<IrInstructionReturnAddress>(irb, scope, source_node); 2221 return &instruction->base; 2222 } 2223 2224 static IrInstruction *ir_build_frame_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2225 IrInstructionFrameAddress *instruction = ir_build_instruction<IrInstructionFrameAddress>(irb, scope, source_node); 2226 return &instruction->base; 2227 } 2228 2229 static IrInstruction *ir_build_handle(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2230 IrInstructionHandle *instruction = ir_build_instruction<IrInstructionHandle>(irb, scope, source_node); 2231 return &instruction->base; 2232 } 2233 2234 static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode *source_node, 2235 IrOverflowOp op, IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, 2236 IrInstruction *result_ptr, ZigType *result_ptr_type) 2237 { 2238 IrInstructionOverflowOp *instruction = ir_build_instruction<IrInstructionOverflowOp>(irb, scope, source_node); 2239 instruction->op = op; 2240 instruction->type_value = type_value; 2241 instruction->op1 = op1; 2242 instruction->op2 = op2; 2243 instruction->result_ptr = result_ptr; 2244 instruction->result_ptr_type = result_ptr_type; 2245 2246 ir_ref_instruction(type_value, irb->current_basic_block); 2247 ir_ref_instruction(op1, irb->current_basic_block); 2248 ir_ref_instruction(op2, irb->current_basic_block); 2249 ir_ref_instruction(result_ptr, irb->current_basic_block); 2250 2251 return &instruction->base; 2252 } 2253 2254 static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { 2255 IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node); 2256 instruction->type_value = type_value; 2257 2258 ir_ref_instruction(type_value, irb->current_basic_block); 2259 2260 return &instruction->base; 2261 } 2262 2263 static IrInstruction *ir_build_test_err(IrBuilder *irb, Scope *scope, AstNode *source_node, 2264 IrInstruction *value) 2265 { 2266 IrInstructionTestErr *instruction = ir_build_instruction<IrInstructionTestErr>(irb, scope, source_node); 2267 instruction->value = value; 2268 2269 ir_ref_instruction(value, irb->current_basic_block); 2270 2271 return &instruction->base; 2272 } 2273 2274 static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, 2275 IrInstruction *err_union) 2276 { 2277 IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); 2278 instruction->err_union = err_union; 2279 2280 ir_ref_instruction(err_union, irb->current_basic_block); 2281 2282 return &instruction->base; 2283 } 2284 2285 static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, 2286 IrInstruction *value, bool safety_check_on) 2287 { 2288 IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); 2289 instruction->value = value; 2290 instruction->safety_check_on = safety_check_on; 2291 2292 ir_ref_instruction(value, irb->current_basic_block); 2293 2294 return &instruction->base; 2295 } 2296 2297 static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node, 2298 IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type, 2299 IrInstruction *async_allocator_type_value, bool is_var_args) 2300 { 2301 IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node); 2302 instruction->param_types = param_types; 2303 instruction->align_value = align_value; 2304 instruction->return_type = return_type; 2305 instruction->async_allocator_type_value = async_allocator_type_value; 2306 instruction->is_var_args = is_var_args; 2307 2308 assert(source_node->type == NodeTypeFnProto); 2309 size_t param_count = source_node->data.fn_proto.params.length; 2310 if (is_var_args) param_count -= 1; 2311 for (size_t i = 0; i < param_count; i += 1) { 2312 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); 2313 } 2314 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 2315 if (async_allocator_type_value != nullptr) ir_ref_instruction(async_allocator_type_value, irb->current_basic_block); 2316 ir_ref_instruction(return_type, irb->current_basic_block); 2317 2318 return &instruction->base; 2319 } 2320 2321 static IrInstruction *ir_build_test_comptime(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2322 IrInstructionTestComptime *instruction = ir_build_instruction<IrInstructionTestComptime>(irb, scope, source_node); 2323 instruction->value = value; 2324 2325 ir_ref_instruction(value, irb->current_basic_block); 2326 2327 return &instruction->base; 2328 } 2329 2330 static IrInstruction *ir_build_ptr_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2331 IrInstruction *dest_type, IrInstruction *ptr, bool safety_check_on) 2332 { 2333 IrInstructionPtrCastSrc *instruction = ir_build_instruction<IrInstructionPtrCastSrc>( 2334 irb, scope, source_node); 2335 instruction->dest_type = dest_type; 2336 instruction->ptr = ptr; 2337 instruction->safety_check_on = safety_check_on; 2338 2339 ir_ref_instruction(dest_type, irb->current_basic_block); 2340 ir_ref_instruction(ptr, irb->current_basic_block); 2341 2342 return &instruction->base; 2343 } 2344 2345 static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *source_instruction, 2346 ZigType *ptr_type, IrInstruction *ptr, bool safety_check_on) 2347 { 2348 IrInstructionPtrCastGen *instruction = ir_build_instruction<IrInstructionPtrCastGen>( 2349 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2350 instruction->base.value.type = ptr_type; 2351 instruction->ptr = ptr; 2352 instruction->safety_check_on = safety_check_on; 2353 2354 ir_ref_instruction(ptr, ira->new_irb.current_basic_block); 2355 2356 return &instruction->base; 2357 } 2358 2359 static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction, 2360 IrInstruction *ptr, ZigType *ty) 2361 { 2362 IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>( 2363 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2364 instruction->base.value.type = ty; 2365 instruction->ptr = ptr; 2366 2367 ir_ref_instruction(ptr, ira->new_irb.current_basic_block); 2368 2369 return &instruction->base; 2370 } 2371 2372 static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 2373 IrInstruction *dest_type, IrInstruction *value) 2374 { 2375 IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>( 2376 irb, scope, source_node); 2377 instruction->dest_type = dest_type; 2378 instruction->value = value; 2379 2380 ir_ref_instruction(dest_type, irb->current_basic_block); 2381 ir_ref_instruction(value, irb->current_basic_block); 2382 2383 return &instruction->base; 2384 } 2385 2386 static IrInstruction *ir_build_bit_cast_gen(IrAnalyze *ira, IrInstruction *source_instruction, 2387 IrInstruction *operand, ZigType *ty) 2388 { 2389 IrInstructionBitCastGen *instruction = ir_build_instruction<IrInstructionBitCastGen>( 2390 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2391 instruction->base.value.type = ty; 2392 instruction->operand = operand; 2393 2394 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 2395 2396 return &instruction->base; 2397 } 2398 2399 static IrInstruction *ir_build_widen_or_shorten(IrBuilder *irb, Scope *scope, AstNode *source_node, 2400 IrInstruction *target) 2401 { 2402 IrInstructionWidenOrShorten *instruction = ir_build_instruction<IrInstructionWidenOrShorten>( 2403 irb, scope, source_node); 2404 instruction->target = target; 2405 2406 ir_ref_instruction(target, irb->current_basic_block); 2407 2408 return &instruction->base; 2409 } 2410 2411 static IrInstruction *ir_build_int_to_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 2412 IrInstruction *dest_type, IrInstruction *target) 2413 { 2414 IrInstructionIntToPtr *instruction = ir_build_instruction<IrInstructionIntToPtr>( 2415 irb, scope, source_node); 2416 instruction->dest_type = dest_type; 2417 instruction->target = target; 2418 2419 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2420 ir_ref_instruction(target, irb->current_basic_block); 2421 2422 return &instruction->base; 2423 } 2424 2425 static IrInstruction *ir_build_ptr_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2426 IrInstruction *target) 2427 { 2428 IrInstructionPtrToInt *instruction = ir_build_instruction<IrInstructionPtrToInt>( 2429 irb, scope, source_node); 2430 instruction->target = target; 2431 2432 ir_ref_instruction(target, irb->current_basic_block); 2433 2434 return &instruction->base; 2435 } 2436 2437 static IrInstruction *ir_build_int_to_enum(IrBuilder *irb, Scope *scope, AstNode *source_node, 2438 IrInstruction *dest_type, IrInstruction *target) 2439 { 2440 IrInstructionIntToEnum *instruction = ir_build_instruction<IrInstructionIntToEnum>( 2441 irb, scope, source_node); 2442 instruction->dest_type = dest_type; 2443 instruction->target = target; 2444 2445 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2446 ir_ref_instruction(target, irb->current_basic_block); 2447 2448 return &instruction->base; 2449 } 2450 2451 2452 2453 static IrInstruction *ir_build_enum_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2454 IrInstruction *target) 2455 { 2456 IrInstructionEnumToInt *instruction = ir_build_instruction<IrInstructionEnumToInt>( 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_err(IrBuilder *irb, Scope *scope, AstNode *source_node, 2466 IrInstruction *target) 2467 { 2468 IrInstructionIntToErr *instruction = ir_build_instruction<IrInstructionIntToErr>( 2469 irb, scope, source_node); 2470 instruction->target = target; 2471 2472 ir_ref_instruction(target, irb->current_basic_block); 2473 2474 return &instruction->base; 2475 } 2476 2477 static IrInstruction *ir_build_err_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2478 IrInstruction *target) 2479 { 2480 IrInstructionErrToInt *instruction = ir_build_instruction<IrInstructionErrToInt>( 2481 irb, scope, source_node); 2482 instruction->target = target; 2483 2484 ir_ref_instruction(target, irb->current_basic_block); 2485 2486 return &instruction->base; 2487 } 2488 2489 static IrInstruction *ir_build_check_switch_prongs(IrBuilder *irb, Scope *scope, AstNode *source_node, 2490 IrInstruction *target_value, IrInstructionCheckSwitchProngsRange *ranges, size_t range_count, 2491 bool have_else_prong) 2492 { 2493 IrInstructionCheckSwitchProngs *instruction = ir_build_instruction<IrInstructionCheckSwitchProngs>( 2494 irb, scope, source_node); 2495 instruction->target_value = target_value; 2496 instruction->ranges = ranges; 2497 instruction->range_count = range_count; 2498 instruction->have_else_prong = have_else_prong; 2499 2500 ir_ref_instruction(target_value, irb->current_basic_block); 2501 for (size_t i = 0; i < range_count; i += 1) { 2502 ir_ref_instruction(ranges[i].start, irb->current_basic_block); 2503 ir_ref_instruction(ranges[i].end, irb->current_basic_block); 2504 } 2505 2506 return &instruction->base; 2507 } 2508 2509 static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *scope, AstNode *source_node, 2510 IrInstruction* statement_value) 2511 { 2512 IrInstructionCheckStatementIsVoid *instruction = ir_build_instruction<IrInstructionCheckStatementIsVoid>( 2513 irb, scope, source_node); 2514 instruction->statement_value = statement_value; 2515 2516 ir_ref_instruction(statement_value, irb->current_basic_block); 2517 2518 return &instruction->base; 2519 } 2520 2521 static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2522 IrInstruction *type_value) 2523 { 2524 IrInstructionTypeName *instruction = ir_build_instruction<IrInstructionTypeName>( 2525 irb, scope, source_node); 2526 instruction->type_value = type_value; 2527 2528 ir_ref_instruction(type_value, irb->current_basic_block); 2529 2530 return &instruction->base; 2531 } 2532 2533 static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, 2534 Tld *tld, LVal lval) 2535 { 2536 IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>( 2537 irb, scope, source_node); 2538 instruction->tld = tld; 2539 instruction->lval = lval; 2540 2541 return &instruction->base; 2542 } 2543 2544 static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { 2545 IrInstructionPanic *instruction = ir_build_instruction<IrInstructionPanic>(irb, scope, source_node); 2546 instruction->base.value.special = ConstValSpecialStatic; 2547 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 2548 instruction->msg = msg; 2549 2550 ir_ref_instruction(msg, irb->current_basic_block); 2551 2552 return &instruction->base; 2553 } 2554 2555 static IrInstruction *ir_build_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2556 IrInstruction *target) 2557 { 2558 IrInstructionTagName *instruction = ir_build_instruction<IrInstructionTagName>(irb, scope, source_node); 2559 instruction->target = target; 2560 2561 ir_ref_instruction(target, irb->current_basic_block); 2562 2563 return &instruction->base; 2564 } 2565 2566 static IrInstruction *ir_build_tag_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2567 IrInstruction *target) 2568 { 2569 IrInstructionTagType *instruction = ir_build_instruction<IrInstructionTagType>(irb, scope, source_node); 2570 instruction->target = target; 2571 2572 ir_ref_instruction(target, irb->current_basic_block); 2573 2574 return &instruction->base; 2575 } 2576 2577 static IrInstruction *ir_build_field_parent_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 2578 IrInstruction *type_value, IrInstruction *field_name, IrInstruction *field_ptr, TypeStructField *field) 2579 { 2580 IrInstructionFieldParentPtr *instruction = ir_build_instruction<IrInstructionFieldParentPtr>( 2581 irb, scope, source_node); 2582 instruction->type_value = type_value; 2583 instruction->field_name = field_name; 2584 instruction->field_ptr = field_ptr; 2585 instruction->field = field; 2586 2587 ir_ref_instruction(type_value, irb->current_basic_block); 2588 ir_ref_instruction(field_name, irb->current_basic_block); 2589 ir_ref_instruction(field_ptr, irb->current_basic_block); 2590 2591 return &instruction->base; 2592 } 2593 2594 static IrInstruction *ir_build_byte_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node, 2595 IrInstruction *type_value, IrInstruction *field_name) 2596 { 2597 IrInstructionByteOffsetOf *instruction = ir_build_instruction<IrInstructionByteOffsetOf>(irb, scope, source_node); 2598 instruction->type_value = type_value; 2599 instruction->field_name = field_name; 2600 2601 ir_ref_instruction(type_value, irb->current_basic_block); 2602 ir_ref_instruction(field_name, irb->current_basic_block); 2603 2604 return &instruction->base; 2605 } 2606 2607 static IrInstruction *ir_build_bit_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node, 2608 IrInstruction *type_value, IrInstruction *field_name) 2609 { 2610 IrInstructionBitOffsetOf *instruction = ir_build_instruction<IrInstructionBitOffsetOf>(irb, scope, source_node); 2611 instruction->type_value = type_value; 2612 instruction->field_name = field_name; 2613 2614 ir_ref_instruction(type_value, irb->current_basic_block); 2615 ir_ref_instruction(field_name, irb->current_basic_block); 2616 2617 return &instruction->base; 2618 } 2619 2620 static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *source_node, 2621 IrInstruction *type_value) { 2622 IrInstructionTypeInfo *instruction = ir_build_instruction<IrInstructionTypeInfo>(irb, scope, source_node); 2623 instruction->type_value = type_value; 2624 2625 ir_ref_instruction(type_value, irb->current_basic_block); 2626 2627 return &instruction->base; 2628 } 2629 2630 static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node, 2631 IrInstruction *type_value) 2632 { 2633 IrInstructionTypeId *instruction = ir_build_instruction<IrInstructionTypeId>(irb, scope, source_node); 2634 instruction->type_value = type_value; 2635 2636 ir_ref_instruction(type_value, irb->current_basic_block); 2637 2638 return &instruction->base; 2639 } 2640 2641 static IrInstruction *ir_build_set_eval_branch_quota(IrBuilder *irb, Scope *scope, AstNode *source_node, 2642 IrInstruction *new_quota) 2643 { 2644 IrInstructionSetEvalBranchQuota *instruction = ir_build_instruction<IrInstructionSetEvalBranchQuota>(irb, scope, source_node); 2645 instruction->new_quota = new_quota; 2646 2647 ir_ref_instruction(new_quota, irb->current_basic_block); 2648 2649 return &instruction->base; 2650 } 2651 2652 static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 2653 IrInstruction *align_bytes, IrInstruction *target) 2654 { 2655 IrInstructionAlignCast *instruction = ir_build_instruction<IrInstructionAlignCast>(irb, scope, source_node); 2656 instruction->align_bytes = align_bytes; 2657 instruction->target = target; 2658 2659 if (align_bytes) ir_ref_instruction(align_bytes, irb->current_basic_block); 2660 ir_ref_instruction(target, irb->current_basic_block); 2661 2662 return &instruction->base; 2663 } 2664 2665 static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2666 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); 2667 2668 return &instruction->base; 2669 } 2670 2671 static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, AstNode *source_node, 2672 IrInstruction *align_bytes) 2673 { 2674 IrInstructionSetAlignStack *instruction = ir_build_instruction<IrInstructionSetAlignStack>(irb, scope, source_node); 2675 instruction->align_bytes = align_bytes; 2676 2677 ir_ref_instruction(align_bytes, irb->current_basic_block); 2678 2679 return &instruction->base; 2680 } 2681 2682 static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2683 IrInstruction *fn_type, IrInstruction *arg_index) 2684 { 2685 IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node); 2686 instruction->fn_type = fn_type; 2687 instruction->arg_index = arg_index; 2688 2689 ir_ref_instruction(fn_type, irb->current_basic_block); 2690 ir_ref_instruction(arg_index, irb->current_basic_block); 2691 2692 return &instruction->base; 2693 } 2694 2695 static IrInstruction *ir_build_error_return_trace(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstructionErrorReturnTrace::Optional optional) { 2696 IrInstructionErrorReturnTrace *instruction = ir_build_instruction<IrInstructionErrorReturnTrace>(irb, scope, source_node); 2697 instruction->optional = optional; 2698 2699 return &instruction->base; 2700 } 2701 2702 static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode *source_node, 2703 IrInstruction *err_set, IrInstruction *payload) 2704 { 2705 IrInstructionErrorUnion *instruction = ir_build_instruction<IrInstructionErrorUnion>(irb, scope, source_node); 2706 instruction->err_set = err_set; 2707 instruction->payload = payload; 2708 2709 ir_ref_instruction(err_set, irb->current_basic_block); 2710 ir_ref_instruction(payload, irb->current_basic_block); 2711 2712 return &instruction->base; 2713 } 2714 2715 static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *source_node, 2716 IrInstruction *target) 2717 { 2718 IrInstructionCancel *instruction = ir_build_instruction<IrInstructionCancel>(irb, scope, source_node); 2719 instruction->target = target; 2720 2721 ir_ref_instruction(target, irb->current_basic_block); 2722 2723 return &instruction->base; 2724 } 2725 2726 static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *scope, AstNode *source_node, 2727 ImplicitAllocatorId id) 2728 { 2729 IrInstructionGetImplicitAllocator *instruction = ir_build_instruction<IrInstructionGetImplicitAllocator>(irb, scope, source_node); 2730 instruction->id = id; 2731 2732 return &instruction->base; 2733 } 2734 2735 static IrInstruction *ir_build_coro_id(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *promise_ptr) { 2736 IrInstructionCoroId *instruction = ir_build_instruction<IrInstructionCoroId>(irb, scope, source_node); 2737 instruction->promise_ptr = promise_ptr; 2738 2739 ir_ref_instruction(promise_ptr, irb->current_basic_block); 2740 2741 return &instruction->base; 2742 } 2743 2744 static IrInstruction *ir_build_coro_alloc(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id) { 2745 IrInstructionCoroAlloc *instruction = ir_build_instruction<IrInstructionCoroAlloc>(irb, scope, source_node); 2746 instruction->coro_id = coro_id; 2747 2748 ir_ref_instruction(coro_id, irb->current_basic_block); 2749 2750 return &instruction->base; 2751 } 2752 2753 static IrInstruction *ir_build_coro_size(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2754 IrInstructionCoroSize *instruction = ir_build_instruction<IrInstructionCoroSize>(irb, scope, source_node); 2755 2756 return &instruction->base; 2757 } 2758 2759 static IrInstruction *ir_build_coro_begin(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id, IrInstruction *coro_mem_ptr) { 2760 IrInstructionCoroBegin *instruction = ir_build_instruction<IrInstructionCoroBegin>(irb, scope, source_node); 2761 instruction->coro_id = coro_id; 2762 instruction->coro_mem_ptr = coro_mem_ptr; 2763 2764 ir_ref_instruction(coro_id, irb->current_basic_block); 2765 ir_ref_instruction(coro_mem_ptr, irb->current_basic_block); 2766 2767 return &instruction->base; 2768 } 2769 2770 static IrInstruction *ir_build_coro_alloc_fail(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_val) { 2771 IrInstructionCoroAllocFail *instruction = ir_build_instruction<IrInstructionCoroAllocFail>(irb, scope, source_node); 2772 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 2773 instruction->base.value.special = ConstValSpecialStatic; 2774 instruction->err_val = err_val; 2775 2776 ir_ref_instruction(err_val, irb->current_basic_block); 2777 2778 return &instruction->base; 2779 } 2780 2781 static IrInstruction *ir_build_coro_suspend(IrBuilder *irb, Scope *scope, AstNode *source_node, 2782 IrInstruction *save_point, IrInstruction *is_final) 2783 { 2784 IrInstructionCoroSuspend *instruction = ir_build_instruction<IrInstructionCoroSuspend>(irb, scope, source_node); 2785 instruction->save_point = save_point; 2786 instruction->is_final = is_final; 2787 2788 if (save_point != nullptr) ir_ref_instruction(save_point, irb->current_basic_block); 2789 ir_ref_instruction(is_final, irb->current_basic_block); 2790 2791 return &instruction->base; 2792 } 2793 2794 static IrInstruction *ir_build_coro_end(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2795 IrInstructionCoroEnd *instruction = ir_build_instruction<IrInstructionCoroEnd>(irb, scope, source_node); 2796 return &instruction->base; 2797 } 2798 2799 static IrInstruction *ir_build_coro_free(IrBuilder *irb, Scope *scope, AstNode *source_node, 2800 IrInstruction *coro_id, IrInstruction *coro_handle) 2801 { 2802 IrInstructionCoroFree *instruction = ir_build_instruction<IrInstructionCoroFree>(irb, scope, source_node); 2803 instruction->coro_id = coro_id; 2804 instruction->coro_handle = coro_handle; 2805 2806 ir_ref_instruction(coro_id, irb->current_basic_block); 2807 ir_ref_instruction(coro_handle, irb->current_basic_block); 2808 2809 return &instruction->base; 2810 } 2811 2812 static IrInstruction *ir_build_coro_resume(IrBuilder *irb, Scope *scope, AstNode *source_node, 2813 IrInstruction *awaiter_handle) 2814 { 2815 IrInstructionCoroResume *instruction = ir_build_instruction<IrInstructionCoroResume>(irb, scope, source_node); 2816 instruction->awaiter_handle = awaiter_handle; 2817 2818 ir_ref_instruction(awaiter_handle, irb->current_basic_block); 2819 2820 return &instruction->base; 2821 } 2822 2823 static IrInstruction *ir_build_coro_save(IrBuilder *irb, Scope *scope, AstNode *source_node, 2824 IrInstruction *coro_handle) 2825 { 2826 IrInstructionCoroSave *instruction = ir_build_instruction<IrInstructionCoroSave>(irb, scope, source_node); 2827 instruction->coro_handle = coro_handle; 2828 2829 ir_ref_instruction(coro_handle, irb->current_basic_block); 2830 2831 return &instruction->base; 2832 } 2833 2834 static IrInstruction *ir_build_coro_promise(IrBuilder *irb, Scope *scope, AstNode *source_node, 2835 IrInstruction *coro_handle) 2836 { 2837 IrInstructionCoroPromise *instruction = ir_build_instruction<IrInstructionCoroPromise>(irb, scope, source_node); 2838 instruction->coro_handle = coro_handle; 2839 2840 ir_ref_instruction(coro_handle, irb->current_basic_block); 2841 2842 return &instruction->base; 2843 } 2844 2845 static IrInstruction *ir_build_coro_alloc_helper(IrBuilder *irb, Scope *scope, AstNode *source_node, 2846 IrInstruction *realloc_fn, IrInstruction *coro_size) 2847 { 2848 IrInstructionCoroAllocHelper *instruction = ir_build_instruction<IrInstructionCoroAllocHelper>(irb, scope, source_node); 2849 instruction->realloc_fn = realloc_fn; 2850 instruction->coro_size = coro_size; 2851 2852 ir_ref_instruction(realloc_fn, irb->current_basic_block); 2853 ir_ref_instruction(coro_size, irb->current_basic_block); 2854 2855 return &instruction->base; 2856 } 2857 2858 static IrInstruction *ir_build_atomic_rmw(IrBuilder *irb, Scope *scope, AstNode *source_node, 2859 IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *op, IrInstruction *operand, 2860 IrInstruction *ordering, AtomicRmwOp resolved_op, AtomicOrder resolved_ordering) 2861 { 2862 IrInstructionAtomicRmw *instruction = ir_build_instruction<IrInstructionAtomicRmw>(irb, scope, source_node); 2863 instruction->operand_type = operand_type; 2864 instruction->ptr = ptr; 2865 instruction->op = op; 2866 instruction->operand = operand; 2867 instruction->ordering = ordering; 2868 instruction->resolved_op = resolved_op; 2869 instruction->resolved_ordering = resolved_ordering; 2870 2871 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); 2872 ir_ref_instruction(ptr, irb->current_basic_block); 2873 if (op != nullptr) ir_ref_instruction(op, irb->current_basic_block); 2874 ir_ref_instruction(operand, irb->current_basic_block); 2875 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); 2876 2877 return &instruction->base; 2878 } 2879 2880 static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode *source_node, 2881 IrInstruction *operand_type, IrInstruction *ptr, 2882 IrInstruction *ordering, AtomicOrder resolved_ordering) 2883 { 2884 IrInstructionAtomicLoad *instruction = ir_build_instruction<IrInstructionAtomicLoad>(irb, scope, source_node); 2885 instruction->operand_type = operand_type; 2886 instruction->ptr = ptr; 2887 instruction->ordering = ordering; 2888 instruction->resolved_ordering = resolved_ordering; 2889 2890 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); 2891 ir_ref_instruction(ptr, irb->current_basic_block); 2892 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); 2893 2894 return &instruction->base; 2895 } 2896 2897 static IrInstruction *ir_build_promise_result_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2898 IrInstruction *promise_type) 2899 { 2900 IrInstructionPromiseResultType *instruction = ir_build_instruction<IrInstructionPromiseResultType>(irb, scope, source_node); 2901 instruction->promise_type = promise_type; 2902 2903 ir_ref_instruction(promise_type, irb->current_basic_block); 2904 2905 return &instruction->base; 2906 } 2907 2908 static IrInstruction *ir_build_await_bookkeeping(IrBuilder *irb, Scope *scope, AstNode *source_node, 2909 IrInstruction *promise_result_type) 2910 { 2911 IrInstructionAwaitBookkeeping *instruction = ir_build_instruction<IrInstructionAwaitBookkeeping>(irb, scope, source_node); 2912 instruction->promise_result_type = promise_result_type; 2913 2914 ir_ref_instruction(promise_result_type, irb->current_basic_block); 2915 2916 return &instruction->base; 2917 } 2918 2919 static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2920 IrInstructionSaveErrRetAddr *instruction = ir_build_instruction<IrInstructionSaveErrRetAddr>(irb, scope, source_node); 2921 return &instruction->base; 2922 } 2923 2924 static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2925 IrInstruction *value) 2926 { 2927 IrInstructionAddImplicitReturnType *instruction = ir_build_instruction<IrInstructionAddImplicitReturnType>(irb, scope, source_node); 2928 instruction->value = value; 2929 2930 ir_ref_instruction(value, irb->current_basic_block); 2931 2932 return &instruction->base; 2933 } 2934 2935 static IrInstruction *ir_build_merge_err_ret_traces(IrBuilder *irb, Scope *scope, AstNode *source_node, 2936 IrInstruction *coro_promise_ptr, IrInstruction *src_err_ret_trace_ptr, IrInstruction *dest_err_ret_trace_ptr) 2937 { 2938 IrInstructionMergeErrRetTraces *instruction = ir_build_instruction<IrInstructionMergeErrRetTraces>(irb, scope, source_node); 2939 instruction->coro_promise_ptr = coro_promise_ptr; 2940 instruction->src_err_ret_trace_ptr = src_err_ret_trace_ptr; 2941 instruction->dest_err_ret_trace_ptr = dest_err_ret_trace_ptr; 2942 2943 ir_ref_instruction(coro_promise_ptr, irb->current_basic_block); 2944 ir_ref_instruction(src_err_ret_trace_ptr, irb->current_basic_block); 2945 ir_ref_instruction(dest_err_ret_trace_ptr, irb->current_basic_block); 2946 2947 return &instruction->base; 2948 } 2949 2950 static IrInstruction *ir_build_mark_err_ret_trace_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_ret_trace_ptr) { 2951 IrInstructionMarkErrRetTracePtr *instruction = ir_build_instruction<IrInstructionMarkErrRetTracePtr>(irb, scope, source_node); 2952 instruction->err_ret_trace_ptr = err_ret_trace_ptr; 2953 2954 ir_ref_instruction(err_ret_trace_ptr, irb->current_basic_block); 2955 2956 return &instruction->base; 2957 } 2958 2959 static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 2960 IrInstructionSqrt *instruction = ir_build_instruction<IrInstructionSqrt>(irb, scope, source_node); 2961 instruction->type = type; 2962 instruction->op = op; 2963 2964 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 2965 ir_ref_instruction(op, irb->current_basic_block); 2966 2967 return &instruction->base; 2968 } 2969 2970 static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 2971 IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node); 2972 instruction->type = type; 2973 instruction->op = op; 2974 2975 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 2976 ir_ref_instruction(op, irb->current_basic_block); 2977 2978 return &instruction->base; 2979 } 2980 2981 static IrInstruction *ir_build_bit_reverse(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 2982 IrInstructionBitReverse *instruction = ir_build_instruction<IrInstructionBitReverse>(irb, scope, source_node); 2983 instruction->type = type; 2984 instruction->op = op; 2985 2986 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 2987 ir_ref_instruction(op, irb->current_basic_block); 2988 2989 return &instruction->base; 2990 } 2991 2992 static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { 2993 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node); 2994 instruction->scope_is_comptime = scope_is_comptime; 2995 instruction->is_comptime = is_comptime; 2996 2997 ir_ref_instruction(scope_is_comptime, irb->current_basic_block); 2998 ir_ref_instruction(is_comptime, irb->current_basic_block); 2999 3000 return &instruction->base; 3001 } 3002 3003 static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction, 3004 IrInstruction *vector, ZigType *result_type) 3005 { 3006 IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb, 3007 source_instruction->scope, source_instruction->source_node); 3008 instruction->base.value.type = result_type; 3009 instruction->vector = vector; 3010 3011 ir_ref_instruction(vector, ira->new_irb.current_basic_block); 3012 3013 ir_add_alloca(ira, &instruction->base, result_type); 3014 3015 return &instruction->base; 3016 } 3017 3018 static IrInstruction *ir_build_array_to_vector(IrAnalyze *ira, IrInstruction *source_instruction, 3019 IrInstruction *array, ZigType *result_type) 3020 { 3021 IrInstructionArrayToVector *instruction = ir_build_instruction<IrInstructionArrayToVector>(&ira->new_irb, 3022 source_instruction->scope, source_instruction->source_node); 3023 instruction->base.value.type = result_type; 3024 instruction->array = array; 3025 3026 ir_ref_instruction(array, ira->new_irb.current_basic_block); 3027 3028 return &instruction->base; 3029 } 3030 3031 static IrInstruction *ir_build_assert_zero(IrAnalyze *ira, IrInstruction *source_instruction, 3032 IrInstruction *target) 3033 { 3034 IrInstructionAssertZero *instruction = ir_build_instruction<IrInstructionAssertZero>(&ira->new_irb, 3035 source_instruction->scope, source_instruction->source_node); 3036 instruction->base.value.type = ira->codegen->builtin_types.entry_void; 3037 instruction->target = target; 3038 3039 ir_ref_instruction(target, ira->new_irb.current_basic_block); 3040 3041 return &instruction->base; 3042 } 3043 3044 static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *source_instruction, 3045 IrInstruction *target) 3046 { 3047 IrInstructionAssertNonNull *instruction = ir_build_instruction<IrInstructionAssertNonNull>(&ira->new_irb, 3048 source_instruction->scope, source_instruction->source_node); 3049 instruction->base.value.type = ira->codegen->builtin_types.entry_void; 3050 instruction->target = target; 3051 3052 ir_ref_instruction(target, ira->new_irb.current_basic_block); 3053 3054 return &instruction->base; 3055 } 3056 3057 static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { 3058 results[ReturnKindUnconditional] = 0; 3059 results[ReturnKindError] = 0; 3060 3061 Scope *scope = inner_scope; 3062 3063 while (scope != outer_scope) { 3064 assert(scope); 3065 switch (scope->id) { 3066 case ScopeIdDefer: { 3067 AstNode *defer_node = scope->source_node; 3068 assert(defer_node->type == NodeTypeDefer); 3069 ReturnKind defer_kind = defer_node->data.defer.kind; 3070 results[defer_kind] += 1; 3071 scope = scope->parent; 3072 continue; 3073 } 3074 case ScopeIdDecls: 3075 case ScopeIdFnDef: 3076 return; 3077 case ScopeIdBlock: 3078 case ScopeIdVarDecl: 3079 case ScopeIdLoop: 3080 case ScopeIdSuspend: 3081 case ScopeIdCompTime: 3082 case ScopeIdRuntime: 3083 scope = scope->parent; 3084 continue; 3085 case ScopeIdDeferExpr: 3086 case ScopeIdCImport: 3087 case ScopeIdCoroPrelude: 3088 zig_unreachable(); 3089 } 3090 } 3091 } 3092 3093 static IrInstruction *ir_mark_gen(IrInstruction *instruction) { 3094 instruction->is_gen = true; 3095 return instruction; 3096 } 3097 3098 static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers) { 3099 Scope *scope = inner_scope; 3100 bool is_noreturn = false; 3101 while (scope != outer_scope) { 3102 if (!scope) 3103 return is_noreturn; 3104 3105 switch (scope->id) { 3106 case ScopeIdDefer: { 3107 AstNode *defer_node = scope->source_node; 3108 assert(defer_node->type == NodeTypeDefer); 3109 ReturnKind defer_kind = defer_node->data.defer.kind; 3110 if (defer_kind == ReturnKindUnconditional || 3111 (gen_error_defers && defer_kind == ReturnKindError)) 3112 { 3113 AstNode *defer_expr_node = defer_node->data.defer.expr; 3114 Scope *defer_expr_scope = defer_node->data.defer.expr_scope; 3115 IrInstruction *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); 3116 if (defer_expr_value != irb->codegen->invalid_instruction) { 3117 if (defer_expr_value->value.type != nullptr && 3118 defer_expr_value->value.type->id == ZigTypeIdUnreachable) 3119 { 3120 is_noreturn = true; 3121 } else { 3122 ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, 3123 defer_expr_value)); 3124 } 3125 } 3126 } 3127 scope = scope->parent; 3128 continue; 3129 } 3130 case ScopeIdDecls: 3131 case ScopeIdFnDef: 3132 return is_noreturn; 3133 case ScopeIdBlock: 3134 case ScopeIdVarDecl: 3135 case ScopeIdLoop: 3136 case ScopeIdSuspend: 3137 case ScopeIdCompTime: 3138 case ScopeIdRuntime: 3139 scope = scope->parent; 3140 continue; 3141 case ScopeIdDeferExpr: 3142 case ScopeIdCImport: 3143 case ScopeIdCoroPrelude: 3144 zig_unreachable(); 3145 } 3146 } 3147 return is_noreturn; 3148 } 3149 3150 static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { 3151 assert(basic_block); 3152 3153 irb->current_basic_block = basic_block; 3154 } 3155 3156 static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) { 3157 irb->exec->basic_block_list.append(basic_block); 3158 ir_set_cursor_at_end(irb, basic_block); 3159 } 3160 3161 static ScopeSuspend *get_scope_suspend(Scope *scope) { 3162 while (scope) { 3163 if (scope->id == ScopeIdSuspend) 3164 return (ScopeSuspend *)scope; 3165 if (scope->id == ScopeIdFnDef) 3166 return nullptr; 3167 3168 scope = scope->parent; 3169 } 3170 return nullptr; 3171 } 3172 3173 static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { 3174 while (scope) { 3175 if (scope->id == ScopeIdDeferExpr) 3176 return (ScopeDeferExpr *)scope; 3177 if (scope->id == ScopeIdFnDef) 3178 return nullptr; 3179 3180 scope = scope->parent; 3181 } 3182 return nullptr; 3183 } 3184 3185 static bool exec_is_async(IrExecutable *exec) { 3186 ZigFn *fn_entry = exec_fn_entry(exec); 3187 return fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; 3188 } 3189 3190 static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode *node, IrInstruction *return_value, 3191 bool is_generated_code) 3192 { 3193 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value)); 3194 3195 bool is_async = exec_is_async(irb->exec); 3196 if (!is_async) { 3197 IrInstruction *return_inst = ir_build_return(irb, scope, node, return_value); 3198 return_inst->is_gen = is_generated_code; 3199 return return_inst; 3200 } 3201 3202 IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "Suspended"); 3203 IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "NotSuspended"); 3204 IrBasicBlock *store_awaiter_block = ir_create_basic_block(irb, scope, "StoreAwaiter"); 3205 IrBasicBlock *check_canceled_block = ir_create_basic_block(irb, scope, "CheckCanceled"); 3206 3207 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 3208 IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 3209 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 3210 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 3211 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); 3212 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); 3213 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 3214 3215 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_field_ptr, return_value); 3216 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 3217 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 3218 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, ptr_mask, nullptr, 3219 AtomicRmwOp_or, AtomicOrderSeqCst); 3220 3221 IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 3222 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 3223 ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime); 3224 3225 ir_set_cursor_at_end_and_append_block(irb, suspended_block); 3226 ir_build_unreachable(irb, scope, node); 3227 3228 ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); 3229 IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 3230 // if we ever add null checking safety to the ptrtoint instruction, it needs to be disabled here 3231 IrInstruction *have_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); 3232 ir_build_cond_br(irb, scope, node, have_await_handle, store_awaiter_block, check_canceled_block, is_comptime); 3233 3234 ir_set_cursor_at_end_and_append_block(irb, store_awaiter_block); 3235 IrInstruction *await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, await_handle_addr); 3236 ir_build_store_ptr(irb, scope, node, irb->exec->await_handle_var_ptr, await_handle); 3237 ir_build_br(irb, scope, node, irb->exec->coro_normal_final, is_comptime); 3238 3239 ir_set_cursor_at_end_and_append_block(irb, check_canceled_block); 3240 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 3241 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 3242 return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime); 3243 } 3244 3245 static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 3246 assert(node->type == NodeTypeReturnExpr); 3247 3248 ZigFn *fn_entry = exec_fn_entry(irb->exec); 3249 if (!fn_entry) { 3250 add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition")); 3251 return irb->codegen->invalid_instruction; 3252 } 3253 3254 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); 3255 if (scope_defer_expr) { 3256 if (!scope_defer_expr->reported_err) { 3257 add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression")); 3258 scope_defer_expr->reported_err = true; 3259 } 3260 return irb->codegen->invalid_instruction; 3261 } 3262 3263 Scope *outer_scope = irb->exec->begin_scope; 3264 3265 AstNode *expr_node = node->data.return_expr.expr; 3266 switch (node->data.return_expr.kind) { 3267 case ReturnKindUnconditional: 3268 { 3269 IrInstruction *return_value; 3270 if (expr_node) { 3271 // Temporarily set this so that if we return a type it gets the name of the function 3272 ZigFn *prev_name_fn = irb->exec->name_fn; 3273 irb->exec->name_fn = exec_fn_entry(irb->exec); 3274 return_value = ir_gen_node(irb, expr_node, scope); 3275 irb->exec->name_fn = prev_name_fn; 3276 if (return_value == irb->codegen->invalid_instruction) 3277 return irb->codegen->invalid_instruction; 3278 } else { 3279 return_value = ir_build_const_void(irb, scope, node); 3280 } 3281 3282 size_t defer_counts[2]; 3283 ir_count_defers(irb, scope, outer_scope, defer_counts); 3284 bool have_err_defers = defer_counts[ReturnKindError] > 0; 3285 if (have_err_defers || irb->codegen->have_err_ret_tracing) { 3286 IrBasicBlock *err_block = ir_create_basic_block(irb, scope, "ErrRetErr"); 3287 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk"); 3288 if (!have_err_defers) { 3289 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3290 } 3291 3292 IrInstruction *is_err = ir_build_test_err(irb, scope, node, return_value); 3293 3294 bool should_inline = ir_should_inline(irb->exec, scope); 3295 IrInstruction *is_comptime; 3296 if (should_inline) { 3297 is_comptime = ir_build_const_bool(irb, scope, node, true); 3298 } else { 3299 is_comptime = ir_build_test_comptime(irb, scope, node, is_err); 3300 } 3301 3302 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); 3303 IrBasicBlock *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt"); 3304 3305 ir_set_cursor_at_end_and_append_block(irb, err_block); 3306 if (have_err_defers) { 3307 ir_gen_defers_for_block(irb, scope, outer_scope, true); 3308 } 3309 if (irb->codegen->have_err_ret_tracing && !should_inline) { 3310 ir_build_save_err_ret_addr(irb, scope, node); 3311 } 3312 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 3313 3314 ir_set_cursor_at_end_and_append_block(irb, ok_block); 3315 if (have_err_defers) { 3316 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3317 } 3318 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 3319 3320 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); 3321 return ir_gen_async_return(irb, scope, node, return_value, false); 3322 } else { 3323 // generate unconditional defers 3324 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3325 return ir_gen_async_return(irb, scope, node, return_value, false); 3326 } 3327 } 3328 case ReturnKindError: 3329 { 3330 assert(expr_node); 3331 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 3332 if (err_union_ptr == irb->codegen->invalid_instruction) 3333 return irb->codegen->invalid_instruction; 3334 IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr); 3335 IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_val); 3336 3337 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); 3338 IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); 3339 IrInstruction *is_comptime; 3340 bool should_inline = ir_should_inline(irb->exec, scope); 3341 if (should_inline) { 3342 is_comptime = ir_build_const_bool(irb, scope, node, true); 3343 } else { 3344 is_comptime = ir_build_test_comptime(irb, scope, node, is_err_val); 3345 } 3346 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime)); 3347 3348 ir_set_cursor_at_end_and_append_block(irb, return_block); 3349 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { 3350 IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); 3351 if (irb->codegen->have_err_ret_tracing && !should_inline) { 3352 ir_build_save_err_ret_addr(irb, scope, node); 3353 } 3354 ir_gen_async_return(irb, scope, node, err_val, false); 3355 } 3356 3357 ir_set_cursor_at_end_and_append_block(irb, continue_block); 3358 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false); 3359 if (lval == LValPtr) 3360 return unwrapped_ptr; 3361 else 3362 return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); 3363 } 3364 } 3365 zig_unreachable(); 3366 } 3367 3368 static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope, 3369 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime, 3370 bool skip_name_check) 3371 { 3372 ZigVar *variable_entry = allocate<ZigVar>(1); 3373 variable_entry->parent_scope = parent_scope; 3374 variable_entry->shadowable = is_shadowable; 3375 variable_entry->mem_slot_index = SIZE_MAX; 3376 variable_entry->is_comptime = is_comptime; 3377 variable_entry->src_arg_index = SIZE_MAX; 3378 variable_entry->const_value = create_const_vals(1); 3379 3380 if (is_comptime != nullptr) { 3381 is_comptime->ref_count += 1; 3382 } 3383 3384 if (name) { 3385 buf_init_from_buf(&variable_entry->name, name); 3386 3387 if (!skip_name_check) { 3388 ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr); 3389 if (existing_var && !existing_var->shadowable) { 3390 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) { 3391 ErrorMsg *msg = add_node_error(codegen, node, 3392 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); 3393 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); 3394 } 3395 variable_entry->var_type = codegen->builtin_types.entry_invalid; 3396 } else { 3397 ZigType *type; 3398 if (get_primitive_type(codegen, name, &type) != ErrorPrimitiveTypeNotFound) { 3399 add_node_error(codegen, node, 3400 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name))); 3401 variable_entry->var_type = codegen->builtin_types.entry_invalid; 3402 } else { 3403 Tld *tld = find_decl(codegen, parent_scope, name); 3404 if (tld != nullptr) { 3405 ErrorMsg *msg = add_node_error(codegen, node, 3406 buf_sprintf("redefinition of '%s'", buf_ptr(name))); 3407 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); 3408 variable_entry->var_type = codegen->builtin_types.entry_invalid; 3409 } 3410 } 3411 } 3412 } 3413 } else { 3414 assert(is_shadowable); 3415 // TODO make this name not actually be in scope. user should be able to make a variable called "_anon" 3416 // might already be solved, let's just make sure it has test coverage 3417 // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables 3418 buf_init_from_str(&variable_entry->name, "_anon"); 3419 } 3420 3421 variable_entry->src_is_const = src_is_const; 3422 variable_entry->gen_is_const = gen_is_const; 3423 variable_entry->decl_node = node; 3424 variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry); 3425 3426 return variable_entry; 3427 } 3428 3429 // Set name to nullptr to make the variable anonymous (not visible to programmer). 3430 // After you call this function var->child_scope has the variable in scope 3431 static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name, 3432 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime) 3433 { 3434 bool is_underscored = name ? buf_eql_str(name, "_") : false; 3435 ZigVar *var = create_local_var(irb->codegen, node, scope, 3436 (is_underscored ? nullptr : name), src_is_const, gen_is_const, 3437 (is_underscored ? true : is_shadowable), is_comptime, false); 3438 if (is_comptime != nullptr || gen_is_const) { 3439 var->mem_slot_index = exec_next_mem_slot(irb->exec); 3440 var->owner_exec = irb->exec; 3441 } 3442 assert(var->child_scope); 3443 return var; 3444 } 3445 3446 static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) { 3447 assert(block_node->type == NodeTypeBlock); 3448 3449 ZigList<IrInstruction *> incoming_values = {0}; 3450 ZigList<IrBasicBlock *> incoming_blocks = {0}; 3451 3452 ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope); 3453 3454 Scope *outer_block_scope = &scope_block->base; 3455 Scope *child_scope = outer_block_scope; 3456 3457 ZigFn *fn_entry = scope_fn_entry(parent_scope); 3458 if (fn_entry && fn_entry->child_scope == parent_scope) { 3459 fn_entry->def_scope = scope_block; 3460 } 3461 3462 if (block_node->data.block.statements.length == 0) { 3463 // {} 3464 return ir_build_const_void(irb, child_scope, block_node); 3465 } 3466 3467 if (block_node->data.block.name != nullptr) { 3468 scope_block->incoming_blocks = &incoming_blocks; 3469 scope_block->incoming_values = &incoming_values; 3470 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); 3471 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, 3472 ir_should_inline(irb->exec, parent_scope)); 3473 } 3474 3475 bool is_continuation_unreachable = false; 3476 IrInstruction *noreturn_return_value = nullptr; 3477 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { 3478 AstNode *statement_node = block_node->data.block.statements.at(i); 3479 3480 IrInstruction *statement_value = ir_gen_node(irb, statement_node, child_scope); 3481 is_continuation_unreachable = instr_is_unreachable(statement_value); 3482 if (is_continuation_unreachable) { 3483 // keep the last noreturn statement value around in case we need to return it 3484 noreturn_return_value = statement_value; 3485 } 3486 if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { 3487 // defer starts a new scope 3488 child_scope = statement_node->data.defer.child_scope; 3489 assert(child_scope); 3490 } else if (statement_value->id == IrInstructionIdDeclVarSrc) { 3491 // variable declarations start a new scope 3492 IrInstructionDeclVarSrc *decl_var_instruction = (IrInstructionDeclVarSrc *)statement_value; 3493 child_scope = decl_var_instruction->var->child_scope; 3494 } else if (statement_value != irb->codegen->invalid_instruction && !is_continuation_unreachable) { 3495 // this statement's value must be void 3496 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); 3497 } 3498 } 3499 3500 if (is_continuation_unreachable) { 3501 assert(noreturn_return_value != nullptr); 3502 if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) { 3503 return noreturn_return_value; 3504 } 3505 3506 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 3507 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 3508 } else { 3509 incoming_blocks.append(irb->current_basic_block); 3510 incoming_values.append(ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node))); 3511 } 3512 3513 if (block_node->data.block.name != nullptr) { 3514 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 3515 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); 3516 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 3517 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 3518 } else { 3519 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 3520 return ir_mark_gen(ir_mark_gen(ir_build_const_void(irb, child_scope, block_node))); 3521 } 3522 } 3523 3524 static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 3525 Scope *inner_scope = scope; 3526 if (op_id == IrBinOpArrayCat || op_id == IrBinOpArrayMult) { 3527 inner_scope = create_comptime_scope(irb->codegen, node, scope); 3528 } 3529 3530 IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, inner_scope); 3531 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, inner_scope); 3532 3533 if (op1 == irb->codegen->invalid_instruction || op2 == irb->codegen->invalid_instruction) 3534 return irb->codegen->invalid_instruction; 3535 3536 return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 3537 } 3538 3539 static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { 3540 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); 3541 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3542 3543 if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) 3544 return irb->codegen->invalid_instruction; 3545 3546 ir_build_store_ptr(irb, scope, node, lvalue, rvalue); 3547 return ir_build_const_void(irb, scope, node); 3548 } 3549 3550 static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 3551 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); 3552 if (lvalue == irb->codegen->invalid_instruction) 3553 return lvalue; 3554 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 3555 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3556 if (op2 == irb->codegen->invalid_instruction) 3557 return op2; 3558 IrInstruction *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 3559 ir_build_store_ptr(irb, scope, node, lvalue, result); 3560 return ir_build_const_void(irb, scope, node); 3561 } 3562 3563 static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node) { 3564 assert(node->type == NodeTypeBinOpExpr); 3565 3566 IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 3567 if (val1 == irb->codegen->invalid_instruction) 3568 return irb->codegen->invalid_instruction; 3569 IrBasicBlock *post_val1_block = irb->current_basic_block; 3570 3571 IrInstruction *is_comptime; 3572 if (ir_should_inline(irb->exec, scope)) { 3573 is_comptime = ir_build_const_bool(irb, scope, node, true); 3574 } else { 3575 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 3576 } 3577 3578 // block for when val1 == false 3579 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse"); 3580 // block for when val1 == true (don't even evaluate the second part) 3581 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue"); 3582 3583 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 3584 3585 ir_set_cursor_at_end_and_append_block(irb, false_block); 3586 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3587 if (val2 == irb->codegen->invalid_instruction) 3588 return irb->codegen->invalid_instruction; 3589 IrBasicBlock *post_val2_block = irb->current_basic_block; 3590 3591 ir_build_br(irb, scope, node, true_block, is_comptime); 3592 3593 ir_set_cursor_at_end_and_append_block(irb, true_block); 3594 3595 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 3596 incoming_values[0] = val1; 3597 incoming_values[1] = val2; 3598 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 3599 incoming_blocks[0] = post_val1_block; 3600 incoming_blocks[1] = post_val2_block; 3601 3602 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 3603 } 3604 3605 static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { 3606 assert(node->type == NodeTypeBinOpExpr); 3607 3608 IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 3609 if (val1 == irb->codegen->invalid_instruction) 3610 return irb->codegen->invalid_instruction; 3611 IrBasicBlock *post_val1_block = irb->current_basic_block; 3612 3613 IrInstruction *is_comptime; 3614 if (ir_should_inline(irb->exec, scope)) { 3615 is_comptime = ir_build_const_bool(irb, scope, node, true); 3616 } else { 3617 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 3618 } 3619 3620 // block for when val1 == true 3621 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue"); 3622 // block for when val1 == false (don't even evaluate the second part) 3623 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse"); 3624 3625 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 3626 3627 ir_set_cursor_at_end_and_append_block(irb, true_block); 3628 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3629 if (val2 == irb->codegen->invalid_instruction) 3630 return irb->codegen->invalid_instruction; 3631 IrBasicBlock *post_val2_block = irb->current_basic_block; 3632 3633 ir_build_br(irb, scope, node, false_block, is_comptime); 3634 3635 ir_set_cursor_at_end_and_append_block(irb, false_block); 3636 3637 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 3638 incoming_values[0] = val1; 3639 incoming_values[1] = val2; 3640 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 3641 incoming_blocks[0] = post_val1_block; 3642 incoming_blocks[1] = post_val2_block; 3643 3644 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 3645 } 3646 3647 static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 3648 assert(node->type == NodeTypeBinOpExpr); 3649 3650 AstNode *op1_node = node->data.bin_op_expr.op1; 3651 AstNode *op2_node = node->data.bin_op_expr.op2; 3652 3653 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); 3654 if (maybe_ptr == irb->codegen->invalid_instruction) 3655 return irb->codegen->invalid_instruction; 3656 3657 IrInstruction *maybe_val = ir_build_load_ptr(irb, parent_scope, node, maybe_ptr); 3658 IrInstruction *is_non_null = ir_build_test_nonnull(irb, parent_scope, node, maybe_val); 3659 3660 IrInstruction *is_comptime; 3661 if (ir_should_inline(irb->exec, parent_scope)) { 3662 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 3663 } else { 3664 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_non_null); 3665 } 3666 3667 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); 3668 IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); 3669 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); 3670 ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); 3671 3672 ir_set_cursor_at_end_and_append_block(irb, null_block); 3673 IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope); 3674 if (null_result == irb->codegen->invalid_instruction) 3675 return irb->codegen->invalid_instruction; 3676 IrBasicBlock *after_null_block = irb->current_basic_block; 3677 if (!instr_is_unreachable(null_result)) 3678 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 3679 3680 ir_set_cursor_at_end_and_append_block(irb, ok_block); 3681 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false); 3682 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 3683 IrBasicBlock *after_ok_block = irb->current_basic_block; 3684 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 3685 3686 ir_set_cursor_at_end_and_append_block(irb, end_block); 3687 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 3688 incoming_values[0] = null_result; 3689 incoming_values[1] = unwrapped_payload; 3690 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 3691 incoming_blocks[0] = after_null_block; 3692 incoming_blocks[1] = after_ok_block; 3693 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); 3694 } 3695 3696 static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 3697 assert(node->type == NodeTypeBinOpExpr); 3698 3699 AstNode *op1_node = node->data.bin_op_expr.op1; 3700 AstNode *op2_node = node->data.bin_op_expr.op2; 3701 3702 IrInstruction *err_set = ir_gen_node(irb, op1_node, parent_scope); 3703 if (err_set == irb->codegen->invalid_instruction) 3704 return irb->codegen->invalid_instruction; 3705 3706 IrInstruction *payload = ir_gen_node(irb, op2_node, parent_scope); 3707 if (payload == irb->codegen->invalid_instruction) 3708 return irb->codegen->invalid_instruction; 3709 3710 return ir_build_error_union(irb, parent_scope, node, err_set, payload); 3711 } 3712 3713 static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) { 3714 assert(node->type == NodeTypeBinOpExpr); 3715 3716 BinOpType bin_op_type = node->data.bin_op_expr.bin_op; 3717 switch (bin_op_type) { 3718 case BinOpTypeInvalid: 3719 zig_unreachable(); 3720 case BinOpTypeAssign: 3721 return ir_gen_assign(irb, scope, node); 3722 case BinOpTypeAssignTimes: 3723 return ir_gen_assign_op(irb, scope, node, IrBinOpMult); 3724 case BinOpTypeAssignTimesWrap: 3725 return ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap); 3726 case BinOpTypeAssignDiv: 3727 return ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified); 3728 case BinOpTypeAssignMod: 3729 return ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified); 3730 case BinOpTypeAssignPlus: 3731 return ir_gen_assign_op(irb, scope, node, IrBinOpAdd); 3732 case BinOpTypeAssignPlusWrap: 3733 return ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap); 3734 case BinOpTypeAssignMinus: 3735 return ir_gen_assign_op(irb, scope, node, IrBinOpSub); 3736 case BinOpTypeAssignMinusWrap: 3737 return ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap); 3738 case BinOpTypeAssignBitShiftLeft: 3739 return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy); 3740 case BinOpTypeAssignBitShiftRight: 3741 return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy); 3742 case BinOpTypeAssignBitAnd: 3743 return ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd); 3744 case BinOpTypeAssignBitXor: 3745 return ir_gen_assign_op(irb, scope, node, IrBinOpBinXor); 3746 case BinOpTypeAssignBitOr: 3747 return ir_gen_assign_op(irb, scope, node, IrBinOpBinOr); 3748 case BinOpTypeAssignMergeErrorSets: 3749 return ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets); 3750 case BinOpTypeBoolOr: 3751 return ir_gen_bool_or(irb, scope, node); 3752 case BinOpTypeBoolAnd: 3753 return ir_gen_bool_and(irb, scope, node); 3754 case BinOpTypeCmpEq: 3755 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq); 3756 case BinOpTypeCmpNotEq: 3757 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq); 3758 case BinOpTypeCmpLessThan: 3759 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan); 3760 case BinOpTypeCmpGreaterThan: 3761 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan); 3762 case BinOpTypeCmpLessOrEq: 3763 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq); 3764 case BinOpTypeCmpGreaterOrEq: 3765 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq); 3766 case BinOpTypeBinOr: 3767 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr); 3768 case BinOpTypeBinXor: 3769 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor); 3770 case BinOpTypeBinAnd: 3771 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd); 3772 case BinOpTypeBitShiftLeft: 3773 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy); 3774 case BinOpTypeBitShiftRight: 3775 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy); 3776 case BinOpTypeAdd: 3777 return ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd); 3778 case BinOpTypeAddWrap: 3779 return ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap); 3780 case BinOpTypeSub: 3781 return ir_gen_bin_op_id(irb, scope, node, IrBinOpSub); 3782 case BinOpTypeSubWrap: 3783 return ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap); 3784 case BinOpTypeMult: 3785 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMult); 3786 case BinOpTypeMultWrap: 3787 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap); 3788 case BinOpTypeDiv: 3789 return ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified); 3790 case BinOpTypeMod: 3791 return ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified); 3792 case BinOpTypeArrayCat: 3793 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat); 3794 case BinOpTypeArrayMult: 3795 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult); 3796 case BinOpTypeMergeErrorSets: 3797 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets); 3798 case BinOpTypeUnwrapOptional: 3799 return ir_gen_orelse(irb, scope, node); 3800 case BinOpTypeErrorUnion: 3801 return ir_gen_error_union(irb, scope, node); 3802 } 3803 zig_unreachable(); 3804 } 3805 3806 static IrInstruction *ir_gen_int_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 3807 assert(node->type == NodeTypeIntLiteral); 3808 3809 return ir_build_const_bigint(irb, scope, node, node->data.int_literal.bigint); 3810 } 3811 3812 static IrInstruction *ir_gen_float_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 3813 assert(node->type == NodeTypeFloatLiteral); 3814 3815 if (node->data.float_literal.overflow) { 3816 add_node_error(irb->codegen, node, buf_sprintf("float literal out of range of any type")); 3817 return irb->codegen->invalid_instruction; 3818 } 3819 3820 return ir_build_const_bigfloat(irb, scope, node, node->data.float_literal.bigfloat); 3821 } 3822 3823 static IrInstruction *ir_gen_char_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 3824 assert(node->type == NodeTypeCharLiteral); 3825 3826 return ir_build_const_uint(irb, scope, node, node->data.char_literal.value); 3827 } 3828 3829 static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 3830 assert(node->type == NodeTypeNullLiteral); 3831 3832 return ir_build_const_null(irb, scope, node); 3833 } 3834 3835 static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode *node, Buf *var_name) { 3836 ScopeDecls *scope_decls = nullptr; 3837 while (scope != nullptr) { 3838 if (scope->id == ScopeIdDecls) { 3839 scope_decls = reinterpret_cast<ScopeDecls *>(scope); 3840 } 3841 scope = scope->parent; 3842 } 3843 TldVar *tld_var = allocate<TldVar>(1); 3844 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); 3845 tld_var->base.resolution = TldResolutionInvalid; 3846 tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, 3847 &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid); 3848 scope_decls->decl_table.put(var_name, &tld_var->base); 3849 } 3850 3851 static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 3852 Error err; 3853 assert(node->type == NodeTypeSymbol); 3854 3855 Buf *variable_name = node->data.symbol_expr.symbol; 3856 3857 if (buf_eql_str(variable_name, "_") && lval == LValPtr) { 3858 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node); 3859 const_instruction->base.value.type = get_pointer_to_type(irb->codegen, 3860 irb->codegen->builtin_types.entry_void, false); 3861 const_instruction->base.value.special = ConstValSpecialStatic; 3862 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard; 3863 return &const_instruction->base; 3864 } 3865 3866 ZigType *primitive_type; 3867 if ((err = get_primitive_type(irb->codegen, variable_name, &primitive_type))) { 3868 if (err == ErrorOverflow) { 3869 add_node_error(irb->codegen, node, 3870 buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535", 3871 buf_ptr(variable_name))); 3872 return irb->codegen->invalid_instruction; 3873 } 3874 assert(err == ErrorPrimitiveTypeNotFound); 3875 } else { 3876 IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_type); 3877 if (lval == LValPtr) { 3878 return ir_build_ref(irb, scope, node, value, false, false); 3879 } else { 3880 return value; 3881 } 3882 } 3883 3884 ScopeFnDef *crossed_fndef_scope; 3885 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); 3886 if (var) { 3887 IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); 3888 if (lval == LValPtr) 3889 return var_ptr; 3890 else 3891 return ir_build_load_ptr(irb, scope, node, var_ptr); 3892 } 3893 3894 Tld *tld = find_decl(irb->codegen, scope, variable_name); 3895 if (tld) 3896 return ir_build_decl_ref(irb, scope, node, tld, lval); 3897 3898 if (get_container_scope(node->owner)->any_imports_failed) { 3899 // skip the error message since we had a failing import in this file 3900 // if an import breaks we don't need redundant undeclared identifier errors 3901 return irb->codegen->invalid_instruction; 3902 } 3903 3904 // put a variable of same name with invalid type in global scope 3905 // so that future references to this same name will find a variable with an invalid type 3906 populate_invalid_variable_in_scope(irb->codegen, scope, node, variable_name); 3907 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); 3908 return irb->codegen->invalid_instruction; 3909 } 3910 3911 static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 3912 assert(node->type == NodeTypeArrayAccessExpr); 3913 3914 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; 3915 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr); 3916 if (array_ref_instruction == irb->codegen->invalid_instruction) 3917 return array_ref_instruction; 3918 3919 AstNode *subscript_node = node->data.array_access_expr.subscript; 3920 IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, scope); 3921 if (subscript_instruction == irb->codegen->invalid_instruction) 3922 return subscript_instruction; 3923 3924 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, 3925 subscript_instruction, true, PtrLenSingle); 3926 if (lval == LValPtr) 3927 return ptr_instruction; 3928 3929 return ir_build_load_ptr(irb, scope, node, ptr_instruction); 3930 } 3931 3932 static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) { 3933 assert(node->type == NodeTypeFieldAccessExpr); 3934 3935 AstNode *container_ref_node = node->data.field_access_expr.struct_expr; 3936 Buf *field_name = node->data.field_access_expr.field_name; 3937 3938 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr); 3939 if (container_ref_instruction == irb->codegen->invalid_instruction) 3940 return container_ref_instruction; 3941 3942 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name); 3943 } 3944 3945 static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) { 3946 assert(node->type == NodeTypeFnCallExpr); 3947 3948 AstNode *type_node = node->data.fn_call_expr.params.at(0); 3949 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 3950 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 3951 AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3); 3952 3953 3954 IrInstruction *type_value = ir_gen_node(irb, type_node, scope); 3955 if (type_value == irb->codegen->invalid_instruction) 3956 return irb->codegen->invalid_instruction; 3957 3958 IrInstruction *op1 = ir_gen_node(irb, op1_node, scope); 3959 if (op1 == irb->codegen->invalid_instruction) 3960 return irb->codegen->invalid_instruction; 3961 3962 IrInstruction *op2 = ir_gen_node(irb, op2_node, scope); 3963 if (op2 == irb->codegen->invalid_instruction) 3964 return irb->codegen->invalid_instruction; 3965 3966 IrInstruction *result_ptr = ir_gen_node(irb, result_ptr_node, scope); 3967 if (result_ptr == irb->codegen->invalid_instruction) 3968 return irb->codegen->invalid_instruction; 3969 3970 return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr); 3971 } 3972 3973 static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *node) { 3974 for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) { 3975 if (it_scope->id == ScopeIdDecls) { 3976 ScopeDecls *decls_scope = (ScopeDecls *)it_scope; 3977 ZigType *container_type = decls_scope->container_type; 3978 if (container_type != nullptr) { 3979 return ir_build_const_type(irb, orig_scope, node, container_type); 3980 } else { 3981 return ir_build_const_import(irb, orig_scope, node, decls_scope->import); 3982 } 3983 } 3984 } 3985 zig_unreachable(); 3986 } 3987 3988 static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 3989 assert(node->type == NodeTypeFnCallExpr); 3990 3991 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; 3992 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 3993 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 3994 3995 if (!entry) { // new built in not found 3996 add_node_error(irb->codegen, node, 3997 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name))); 3998 return irb->codegen->invalid_instruction; 3999 } 4000 4001 BuiltinFnEntry *builtin_fn = entry->value; 4002 size_t actual_param_count = node->data.fn_call_expr.params.length; 4003 4004 if (builtin_fn->param_count != SIZE_MAX && builtin_fn->param_count != actual_param_count) { 4005 add_node_error(irb->codegen, node, 4006 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 4007 builtin_fn->param_count, actual_param_count)); 4008 return irb->codegen->invalid_instruction; 4009 } 4010 4011 bool is_async = exec_is_async(irb->exec); 4012 4013 switch (builtin_fn->id) { 4014 case BuiltinFnIdInvalid: 4015 zig_unreachable(); 4016 case BuiltinFnIdTypeof: 4017 { 4018 AstNode *arg_node = node->data.fn_call_expr.params.at(0); 4019 IrInstruction *arg = ir_gen_node(irb, arg_node, scope); 4020 if (arg == irb->codegen->invalid_instruction) 4021 return arg; 4022 4023 IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); 4024 return ir_lval_wrap(irb, scope, type_of, lval); 4025 } 4026 case BuiltinFnIdSetCold: 4027 { 4028 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4029 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4030 if (arg0_value == irb->codegen->invalid_instruction) 4031 return arg0_value; 4032 4033 IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); 4034 return ir_lval_wrap(irb, scope, set_cold, lval); 4035 } 4036 case BuiltinFnIdSetRuntimeSafety: 4037 { 4038 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4039 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4040 if (arg0_value == irb->codegen->invalid_instruction) 4041 return arg0_value; 4042 4043 IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); 4044 return ir_lval_wrap(irb, scope, set_safety, lval); 4045 } 4046 case BuiltinFnIdSetFloatMode: 4047 { 4048 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4049 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4050 if (arg0_value == irb->codegen->invalid_instruction) 4051 return arg0_value; 4052 4053 IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); 4054 return ir_lval_wrap(irb, scope, set_float_mode, lval); 4055 } 4056 case BuiltinFnIdSizeof: 4057 { 4058 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4059 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4060 if (arg0_value == irb->codegen->invalid_instruction) 4061 return arg0_value; 4062 4063 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); 4064 return ir_lval_wrap(irb, scope, size_of, lval); 4065 } 4066 case BuiltinFnIdCtz: 4067 { 4068 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4069 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4070 if (arg0_value == irb->codegen->invalid_instruction) 4071 return arg0_value; 4072 4073 IrInstruction *ctz = ir_build_ctz(irb, scope, node, arg0_value); 4074 return ir_lval_wrap(irb, scope, ctz, lval); 4075 } 4076 case BuiltinFnIdPopCount: 4077 { 4078 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4079 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4080 if (arg0_value == irb->codegen->invalid_instruction) 4081 return arg0_value; 4082 4083 IrInstruction *instr = ir_build_pop_count(irb, scope, node, arg0_value); 4084 return ir_lval_wrap(irb, scope, instr, lval); 4085 } 4086 case BuiltinFnIdClz: 4087 { 4088 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4089 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4090 if (arg0_value == irb->codegen->invalid_instruction) 4091 return arg0_value; 4092 4093 IrInstruction *clz = ir_build_clz(irb, scope, node, arg0_value); 4094 return ir_lval_wrap(irb, scope, clz, lval); 4095 } 4096 case BuiltinFnIdImport: 4097 { 4098 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4099 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4100 if (arg0_value == irb->codegen->invalid_instruction) 4101 return arg0_value; 4102 4103 IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); 4104 return ir_lval_wrap(irb, scope, import, lval); 4105 } 4106 case BuiltinFnIdCImport: 4107 { 4108 IrInstruction *c_import = ir_build_c_import(irb, scope, node); 4109 return ir_lval_wrap(irb, scope, c_import, lval); 4110 } 4111 case BuiltinFnIdCInclude: 4112 { 4113 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4114 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4115 if (arg0_value == irb->codegen->invalid_instruction) 4116 return arg0_value; 4117 4118 if (!exec_c_import_buf(irb->exec)) { 4119 add_node_error(irb->codegen, node, buf_sprintf("C include valid only inside C import block")); 4120 return irb->codegen->invalid_instruction; 4121 } 4122 4123 IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value); 4124 return ir_lval_wrap(irb, scope, c_include, lval); 4125 } 4126 case BuiltinFnIdCDefine: 4127 { 4128 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4129 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4130 if (arg0_value == irb->codegen->invalid_instruction) 4131 return arg0_value; 4132 4133 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4134 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4135 if (arg1_value == irb->codegen->invalid_instruction) 4136 return arg1_value; 4137 4138 if (!exec_c_import_buf(irb->exec)) { 4139 add_node_error(irb->codegen, node, buf_sprintf("C define valid only inside C import block")); 4140 return irb->codegen->invalid_instruction; 4141 } 4142 4143 IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); 4144 return ir_lval_wrap(irb, scope, c_define, lval); 4145 } 4146 case BuiltinFnIdCUndef: 4147 { 4148 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4149 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4150 if (arg0_value == irb->codegen->invalid_instruction) 4151 return arg0_value; 4152 4153 if (!exec_c_import_buf(irb->exec)) { 4154 add_node_error(irb->codegen, node, buf_sprintf("C undef valid only inside C import block")); 4155 return irb->codegen->invalid_instruction; 4156 } 4157 4158 IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); 4159 return ir_lval_wrap(irb, scope, c_undef, lval); 4160 } 4161 case BuiltinFnIdCompileErr: 4162 { 4163 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4164 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4165 if (arg0_value == irb->codegen->invalid_instruction) 4166 return arg0_value; 4167 4168 IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); 4169 return ir_lval_wrap(irb, scope, compile_err, lval); 4170 } 4171 case BuiltinFnIdCompileLog: 4172 { 4173 IrInstruction **args = allocate<IrInstruction*>(actual_param_count); 4174 4175 for (size_t i = 0; i < actual_param_count; i += 1) { 4176 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 4177 args[i] = ir_gen_node(irb, arg_node, scope); 4178 if (args[i] == irb->codegen->invalid_instruction) 4179 return irb->codegen->invalid_instruction; 4180 } 4181 4182 IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); 4183 return ir_lval_wrap(irb, scope, compile_log, lval); 4184 } 4185 case BuiltinFnIdErrName: 4186 { 4187 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4188 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4189 if (arg0_value == irb->codegen->invalid_instruction) 4190 return arg0_value; 4191 4192 IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value); 4193 return ir_lval_wrap(irb, scope, err_name, lval); 4194 } 4195 case BuiltinFnIdEmbedFile: 4196 { 4197 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4198 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4199 if (arg0_value == irb->codegen->invalid_instruction) 4200 return arg0_value; 4201 4202 IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); 4203 return ir_lval_wrap(irb, scope, embed_file, lval); 4204 } 4205 case BuiltinFnIdCmpxchgWeak: 4206 case BuiltinFnIdCmpxchgStrong: 4207 { 4208 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4209 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4210 if (arg0_value == irb->codegen->invalid_instruction) 4211 return arg0_value; 4212 4213 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4214 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4215 if (arg1_value == irb->codegen->invalid_instruction) 4216 return arg1_value; 4217 4218 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4219 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4220 if (arg2_value == irb->codegen->invalid_instruction) 4221 return arg2_value; 4222 4223 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 4224 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 4225 if (arg3_value == irb->codegen->invalid_instruction) 4226 return arg3_value; 4227 4228 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 4229 IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); 4230 if (arg4_value == irb->codegen->invalid_instruction) 4231 return arg4_value; 4232 4233 AstNode *arg5_node = node->data.fn_call_expr.params.at(5); 4234 IrInstruction *arg5_value = ir_gen_node(irb, arg5_node, scope); 4235 if (arg5_value == irb->codegen->invalid_instruction) 4236 return arg5_value; 4237 4238 IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, 4239 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak)); 4240 return ir_lval_wrap(irb, scope, cmpxchg, lval); 4241 } 4242 case BuiltinFnIdFence: 4243 { 4244 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4245 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4246 if (arg0_value == irb->codegen->invalid_instruction) 4247 return arg0_value; 4248 4249 IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); 4250 return ir_lval_wrap(irb, scope, fence, lval); 4251 } 4252 case BuiltinFnIdDivExact: 4253 { 4254 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4255 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4256 if (arg0_value == irb->codegen->invalid_instruction) 4257 return arg0_value; 4258 4259 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4260 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4261 if (arg1_value == irb->codegen->invalid_instruction) 4262 return arg1_value; 4263 4264 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); 4265 return ir_lval_wrap(irb, scope, bin_op, lval); 4266 } 4267 case BuiltinFnIdDivTrunc: 4268 { 4269 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4270 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4271 if (arg0_value == irb->codegen->invalid_instruction) 4272 return arg0_value; 4273 4274 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4275 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4276 if (arg1_value == irb->codegen->invalid_instruction) 4277 return arg1_value; 4278 4279 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); 4280 return ir_lval_wrap(irb, scope, bin_op, lval); 4281 } 4282 case BuiltinFnIdDivFloor: 4283 { 4284 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4285 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4286 if (arg0_value == irb->codegen->invalid_instruction) 4287 return arg0_value; 4288 4289 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4290 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4291 if (arg1_value == irb->codegen->invalid_instruction) 4292 return arg1_value; 4293 4294 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); 4295 return ir_lval_wrap(irb, scope, bin_op, lval); 4296 } 4297 case BuiltinFnIdRem: 4298 { 4299 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4300 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4301 if (arg0_value == irb->codegen->invalid_instruction) 4302 return arg0_value; 4303 4304 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4305 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4306 if (arg1_value == irb->codegen->invalid_instruction) 4307 return arg1_value; 4308 4309 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); 4310 return ir_lval_wrap(irb, scope, bin_op, lval); 4311 } 4312 case BuiltinFnIdMod: 4313 { 4314 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4315 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4316 if (arg0_value == irb->codegen->invalid_instruction) 4317 return arg0_value; 4318 4319 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4320 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4321 if (arg1_value == irb->codegen->invalid_instruction) 4322 return arg1_value; 4323 4324 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); 4325 return ir_lval_wrap(irb, scope, bin_op, lval); 4326 } 4327 case BuiltinFnIdSqrt: 4328 { 4329 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4330 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4331 if (arg0_value == irb->codegen->invalid_instruction) 4332 return arg0_value; 4333 4334 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4335 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4336 if (arg1_value == irb->codegen->invalid_instruction) 4337 return arg1_value; 4338 4339 IrInstruction *ir_sqrt = ir_build_sqrt(irb, scope, node, arg0_value, arg1_value); 4340 return ir_lval_wrap(irb, scope, ir_sqrt, lval); 4341 } 4342 case BuiltinFnIdTruncate: 4343 { 4344 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4345 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4346 if (arg0_value == irb->codegen->invalid_instruction) 4347 return arg0_value; 4348 4349 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4350 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4351 if (arg1_value == irb->codegen->invalid_instruction) 4352 return arg1_value; 4353 4354 IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); 4355 return ir_lval_wrap(irb, scope, truncate, lval); 4356 } 4357 case BuiltinFnIdIntCast: 4358 { 4359 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4360 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4361 if (arg0_value == irb->codegen->invalid_instruction) 4362 return arg0_value; 4363 4364 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4365 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4366 if (arg1_value == irb->codegen->invalid_instruction) 4367 return arg1_value; 4368 4369 IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); 4370 return ir_lval_wrap(irb, scope, result, lval); 4371 } 4372 case BuiltinFnIdFloatCast: 4373 { 4374 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4375 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4376 if (arg0_value == irb->codegen->invalid_instruction) 4377 return arg0_value; 4378 4379 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4380 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4381 if (arg1_value == irb->codegen->invalid_instruction) 4382 return arg1_value; 4383 4384 IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); 4385 return ir_lval_wrap(irb, scope, result, lval); 4386 } 4387 case BuiltinFnIdErrSetCast: 4388 { 4389 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4390 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4391 if (arg0_value == irb->codegen->invalid_instruction) 4392 return arg0_value; 4393 4394 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4395 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4396 if (arg1_value == irb->codegen->invalid_instruction) 4397 return arg1_value; 4398 4399 IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); 4400 return ir_lval_wrap(irb, scope, result, lval); 4401 } 4402 case BuiltinFnIdFromBytes: 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 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4410 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4411 if (arg1_value == irb->codegen->invalid_instruction) 4412 return arg1_value; 4413 4414 IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value); 4415 return ir_lval_wrap(irb, scope, result, lval); 4416 } 4417 case BuiltinFnIdToBytes: 4418 { 4419 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4420 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4421 if (arg0_value == irb->codegen->invalid_instruction) 4422 return arg0_value; 4423 4424 IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value); 4425 return ir_lval_wrap(irb, scope, result, lval); 4426 } 4427 case BuiltinFnIdIntToFloat: 4428 { 4429 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4430 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4431 if (arg0_value == irb->codegen->invalid_instruction) 4432 return arg0_value; 4433 4434 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4435 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4436 if (arg1_value == irb->codegen->invalid_instruction) 4437 return arg1_value; 4438 4439 IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); 4440 return ir_lval_wrap(irb, scope, result, lval); 4441 } 4442 case BuiltinFnIdFloatToInt: 4443 { 4444 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4445 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4446 if (arg0_value == irb->codegen->invalid_instruction) 4447 return arg0_value; 4448 4449 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4450 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4451 if (arg1_value == irb->codegen->invalid_instruction) 4452 return arg1_value; 4453 4454 IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); 4455 return ir_lval_wrap(irb, scope, result, lval); 4456 } 4457 case BuiltinFnIdErrToInt: 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 IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value); 4465 return ir_lval_wrap(irb, scope, result, lval); 4466 } 4467 case BuiltinFnIdIntToErr: 4468 { 4469 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4470 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4471 if (arg0_value == irb->codegen->invalid_instruction) 4472 return arg0_value; 4473 4474 IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value); 4475 return ir_lval_wrap(irb, scope, result, lval); 4476 } 4477 case BuiltinFnIdBoolToInt: 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 *result = ir_build_bool_to_int(irb, scope, node, arg0_value); 4485 return ir_lval_wrap(irb, scope, result, lval); 4486 } 4487 case BuiltinFnIdIntType: 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 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); 4500 return ir_lval_wrap(irb, scope, int_type, lval); 4501 } 4502 case BuiltinFnIdVectorType: 4503 { 4504 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4505 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4506 if (arg0_value == irb->codegen->invalid_instruction) 4507 return arg0_value; 4508 4509 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4510 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4511 if (arg1_value == irb->codegen->invalid_instruction) 4512 return arg1_value; 4513 4514 IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); 4515 return ir_lval_wrap(irb, scope, vector_type, lval); 4516 } 4517 case BuiltinFnIdMemcpy: 4518 { 4519 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4520 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4521 if (arg0_value == irb->codegen->invalid_instruction) 4522 return arg0_value; 4523 4524 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4525 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4526 if (arg1_value == irb->codegen->invalid_instruction) 4527 return arg1_value; 4528 4529 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4530 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4531 if (arg2_value == irb->codegen->invalid_instruction) 4532 return arg2_value; 4533 4534 IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value); 4535 return ir_lval_wrap(irb, scope, ir_memcpy, lval); 4536 } 4537 case BuiltinFnIdMemset: 4538 { 4539 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4540 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4541 if (arg0_value == irb->codegen->invalid_instruction) 4542 return arg0_value; 4543 4544 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4545 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4546 if (arg1_value == irb->codegen->invalid_instruction) 4547 return arg1_value; 4548 4549 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4550 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4551 if (arg2_value == irb->codegen->invalid_instruction) 4552 return arg2_value; 4553 4554 IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value); 4555 return ir_lval_wrap(irb, scope, ir_memset, lval); 4556 } 4557 case BuiltinFnIdMemberCount: 4558 { 4559 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4560 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4561 if (arg0_value == irb->codegen->invalid_instruction) 4562 return arg0_value; 4563 4564 IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value); 4565 return ir_lval_wrap(irb, scope, member_count, lval); 4566 } 4567 case BuiltinFnIdMemberType: 4568 { 4569 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4570 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4571 if (arg0_value == irb->codegen->invalid_instruction) 4572 return arg0_value; 4573 4574 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4575 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4576 if (arg1_value == irb->codegen->invalid_instruction) 4577 return arg1_value; 4578 4579 4580 IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value); 4581 return ir_lval_wrap(irb, scope, member_type, lval); 4582 } 4583 case BuiltinFnIdMemberName: 4584 { 4585 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4586 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4587 if (arg0_value == irb->codegen->invalid_instruction) 4588 return arg0_value; 4589 4590 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4591 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4592 if (arg1_value == irb->codegen->invalid_instruction) 4593 return arg1_value; 4594 4595 4596 IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value); 4597 return ir_lval_wrap(irb, scope, member_name, lval); 4598 } 4599 case BuiltinFnIdField: 4600 { 4601 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4602 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr); 4603 if (arg0_value == irb->codegen->invalid_instruction) 4604 return arg0_value; 4605 4606 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4607 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4608 if (arg1_value == irb->codegen->invalid_instruction) 4609 return arg1_value; 4610 4611 IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value); 4612 4613 if (lval == LValPtr) 4614 return ptr_instruction; 4615 4616 return ir_build_load_ptr(irb, scope, node, ptr_instruction); 4617 } 4618 case BuiltinFnIdTypeInfo: 4619 { 4620 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4621 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4622 if (arg0_value == irb->codegen->invalid_instruction) 4623 return arg0_value; 4624 4625 IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); 4626 return ir_lval_wrap(irb, scope, type_info, lval); 4627 } 4628 case BuiltinFnIdBreakpoint: 4629 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval); 4630 case BuiltinFnIdReturnAddress: 4631 return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval); 4632 case BuiltinFnIdFrameAddress: 4633 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval); 4634 case BuiltinFnIdHandle: 4635 if (!irb->exec->fn_entry) { 4636 add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition")); 4637 return irb->codegen->invalid_instruction; 4638 } 4639 if (!is_async) { 4640 add_node_error(irb->codegen, node, buf_sprintf("@handle() in non-async function")); 4641 return irb->codegen->invalid_instruction; 4642 } 4643 return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval); 4644 case BuiltinFnIdAlignOf: 4645 { 4646 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4647 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4648 if (arg0_value == irb->codegen->invalid_instruction) 4649 return arg0_value; 4650 4651 IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value); 4652 return ir_lval_wrap(irb, scope, align_of, lval); 4653 } 4654 case BuiltinFnIdAddWithOverflow: 4655 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval); 4656 case BuiltinFnIdSubWithOverflow: 4657 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval); 4658 case BuiltinFnIdMulWithOverflow: 4659 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval); 4660 case BuiltinFnIdShlWithOverflow: 4661 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval); 4662 case BuiltinFnIdTypeName: 4663 { 4664 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4665 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4666 if (arg0_value == irb->codegen->invalid_instruction) 4667 return arg0_value; 4668 4669 IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value); 4670 return ir_lval_wrap(irb, scope, type_name, lval); 4671 } 4672 case BuiltinFnIdPanic: 4673 { 4674 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4675 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4676 if (arg0_value == irb->codegen->invalid_instruction) 4677 return arg0_value; 4678 4679 IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); 4680 return ir_lval_wrap(irb, scope, panic, lval); 4681 } 4682 case BuiltinFnIdPtrCast: 4683 { 4684 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4685 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4686 if (arg0_value == irb->codegen->invalid_instruction) 4687 return arg0_value; 4688 4689 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4690 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4691 if (arg1_value == irb->codegen->invalid_instruction) 4692 return arg1_value; 4693 4694 IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); 4695 return ir_lval_wrap(irb, scope, ptr_cast, lval); 4696 } 4697 case BuiltinFnIdBitCast: 4698 { 4699 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4700 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4701 if (arg0_value == irb->codegen->invalid_instruction) 4702 return arg0_value; 4703 4704 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4705 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4706 if (arg1_value == irb->codegen->invalid_instruction) 4707 return arg1_value; 4708 4709 IrInstruction *bit_cast = ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value); 4710 return ir_lval_wrap(irb, scope, bit_cast, lval); 4711 } 4712 case BuiltinFnIdIntToPtr: 4713 { 4714 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4715 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4716 if (arg0_value == irb->codegen->invalid_instruction) 4717 return arg0_value; 4718 4719 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4720 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4721 if (arg1_value == irb->codegen->invalid_instruction) 4722 return arg1_value; 4723 4724 IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value); 4725 return ir_lval_wrap(irb, scope, int_to_ptr, lval); 4726 } 4727 case BuiltinFnIdPtrToInt: 4728 { 4729 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4730 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4731 if (arg0_value == irb->codegen->invalid_instruction) 4732 return arg0_value; 4733 4734 IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value); 4735 return ir_lval_wrap(irb, scope, ptr_to_int, lval); 4736 } 4737 case BuiltinFnIdTagName: 4738 { 4739 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4740 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4741 if (arg0_value == irb->codegen->invalid_instruction) 4742 return arg0_value; 4743 4744 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value); 4745 IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag); 4746 return ir_lval_wrap(irb, scope, tag_name, lval); 4747 } 4748 case BuiltinFnIdTagType: 4749 { 4750 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4751 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4752 if (arg0_value == irb->codegen->invalid_instruction) 4753 return arg0_value; 4754 4755 IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); 4756 return ir_lval_wrap(irb, scope, tag_type, lval); 4757 } 4758 case BuiltinFnIdFieldParentPtr: 4759 { 4760 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4761 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4762 if (arg0_value == irb->codegen->invalid_instruction) 4763 return arg0_value; 4764 4765 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4766 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4767 if (arg1_value == irb->codegen->invalid_instruction) 4768 return arg1_value; 4769 4770 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4771 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4772 if (arg2_value == irb->codegen->invalid_instruction) 4773 return arg2_value; 4774 4775 IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr); 4776 return ir_lval_wrap(irb, scope, field_parent_ptr, lval); 4777 } 4778 case BuiltinFnIdByteOffsetOf: 4779 { 4780 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4781 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4782 if (arg0_value == irb->codegen->invalid_instruction) 4783 return arg0_value; 4784 4785 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4786 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4787 if (arg1_value == irb->codegen->invalid_instruction) 4788 return arg1_value; 4789 4790 IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); 4791 return ir_lval_wrap(irb, scope, offset_of, lval); 4792 } 4793 case BuiltinFnIdBitOffsetOf: 4794 { 4795 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4796 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4797 if (arg0_value == irb->codegen->invalid_instruction) 4798 return arg0_value; 4799 4800 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4801 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4802 if (arg1_value == irb->codegen->invalid_instruction) 4803 return arg1_value; 4804 4805 IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); 4806 return ir_lval_wrap(irb, scope, offset_of, lval); 4807 } 4808 case BuiltinFnIdInlineCall: 4809 case BuiltinFnIdNoInlineCall: 4810 { 4811 if (node->data.fn_call_expr.params.length == 0) { 4812 add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0")); 4813 return irb->codegen->invalid_instruction; 4814 } 4815 4816 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(0); 4817 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 4818 if (fn_ref == irb->codegen->invalid_instruction) 4819 return fn_ref; 4820 4821 size_t arg_count = node->data.fn_call_expr.params.length - 1; 4822 4823 IrInstruction **args = allocate<IrInstruction*>(arg_count); 4824 for (size_t i = 0; i < arg_count; i += 1) { 4825 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 1); 4826 args[i] = ir_gen_node(irb, arg_node, scope); 4827 if (args[i] == irb->codegen->invalid_instruction) 4828 return args[i]; 4829 } 4830 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; 4831 4832 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr); 4833 return ir_lval_wrap(irb, scope, call, lval); 4834 } 4835 case BuiltinFnIdNewStackCall: 4836 { 4837 if (node->data.fn_call_expr.params.length == 0) { 4838 add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0")); 4839 return irb->codegen->invalid_instruction; 4840 } 4841 4842 AstNode *new_stack_node = node->data.fn_call_expr.params.at(0); 4843 IrInstruction *new_stack = ir_gen_node(irb, new_stack_node, scope); 4844 if (new_stack == irb->codegen->invalid_instruction) 4845 return new_stack; 4846 4847 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); 4848 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 4849 if (fn_ref == irb->codegen->invalid_instruction) 4850 return fn_ref; 4851 4852 size_t arg_count = node->data.fn_call_expr.params.length - 2; 4853 4854 IrInstruction **args = allocate<IrInstruction*>(arg_count); 4855 for (size_t i = 0; i < arg_count; i += 1) { 4856 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 2); 4857 args[i] = ir_gen_node(irb, arg_node, scope); 4858 if (args[i] == irb->codegen->invalid_instruction) 4859 return args[i]; 4860 } 4861 4862 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack); 4863 return ir_lval_wrap(irb, scope, call, lval); 4864 } 4865 case BuiltinFnIdTypeId: 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 IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value); 4873 return ir_lval_wrap(irb, scope, type_id, lval); 4874 } 4875 case BuiltinFnIdShlExact: 4876 { 4877 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4878 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4879 if (arg0_value == irb->codegen->invalid_instruction) 4880 return arg0_value; 4881 4882 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4883 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4884 if (arg1_value == irb->codegen->invalid_instruction) 4885 return arg1_value; 4886 4887 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); 4888 return ir_lval_wrap(irb, scope, bin_op, lval); 4889 } 4890 case BuiltinFnIdShrExact: 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 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); 4903 return ir_lval_wrap(irb, scope, bin_op, lval); 4904 } 4905 case BuiltinFnIdSetEvalBranchQuota: 4906 { 4907 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4908 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4909 if (arg0_value == irb->codegen->invalid_instruction) 4910 return arg0_value; 4911 4912 IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); 4913 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval); 4914 } 4915 case BuiltinFnIdAlignCast: 4916 { 4917 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4918 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4919 if (arg0_value == irb->codegen->invalid_instruction) 4920 return arg0_value; 4921 4922 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4923 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4924 if (arg1_value == irb->codegen->invalid_instruction) 4925 return arg1_value; 4926 4927 IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value); 4928 return ir_lval_wrap(irb, scope, align_cast, lval); 4929 } 4930 case BuiltinFnIdOpaqueType: 4931 { 4932 IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); 4933 return ir_lval_wrap(irb, scope, opaque_type, lval); 4934 } 4935 case BuiltinFnIdThis: 4936 { 4937 IrInstruction *this_inst = ir_gen_this(irb, scope, node); 4938 return ir_lval_wrap(irb, scope, this_inst, lval); 4939 } 4940 case BuiltinFnIdSetAlignStack: 4941 { 4942 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4943 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4944 if (arg0_value == irb->codegen->invalid_instruction) 4945 return arg0_value; 4946 4947 IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); 4948 return ir_lval_wrap(irb, scope, set_align_stack, lval); 4949 } 4950 case BuiltinFnIdArgType: 4951 { 4952 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4953 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4954 if (arg0_value == irb->codegen->invalid_instruction) 4955 return arg0_value; 4956 4957 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4958 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4959 if (arg1_value == irb->codegen->invalid_instruction) 4960 return arg1_value; 4961 4962 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); 4963 return ir_lval_wrap(irb, scope, arg_type, lval); 4964 } 4965 case BuiltinFnIdExport: 4966 { 4967 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4968 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4969 if (arg0_value == irb->codegen->invalid_instruction) 4970 return arg0_value; 4971 4972 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4973 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4974 if (arg1_value == irb->codegen->invalid_instruction) 4975 return arg1_value; 4976 4977 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4978 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4979 if (arg2_value == irb->codegen->invalid_instruction) 4980 return arg2_value; 4981 4982 IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); 4983 return ir_lval_wrap(irb, scope, ir_export, lval); 4984 } 4985 case BuiltinFnIdErrorReturnTrace: 4986 { 4987 IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null); 4988 return ir_lval_wrap(irb, scope, error_return_trace, lval); 4989 } 4990 case BuiltinFnIdAtomicRmw: 4991 { 4992 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4993 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4994 if (arg0_value == irb->codegen->invalid_instruction) 4995 return arg0_value; 4996 4997 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4998 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4999 if (arg1_value == irb->codegen->invalid_instruction) 5000 return arg1_value; 5001 5002 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5003 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5004 if (arg2_value == irb->codegen->invalid_instruction) 5005 return arg2_value; 5006 5007 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 5008 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 5009 if (arg3_value == irb->codegen->invalid_instruction) 5010 return arg3_value; 5011 5012 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 5013 IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); 5014 if (arg4_value == irb->codegen->invalid_instruction) 5015 return arg4_value; 5016 5017 return ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, 5018 arg4_value, 5019 // these 2 values don't mean anything since we passed non-null values for other args 5020 AtomicRmwOp_xchg, AtomicOrderMonotonic); 5021 } 5022 case BuiltinFnIdAtomicLoad: 5023 { 5024 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5025 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5026 if (arg0_value == irb->codegen->invalid_instruction) 5027 return arg0_value; 5028 5029 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5030 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5031 if (arg1_value == irb->codegen->invalid_instruction) 5032 return arg1_value; 5033 5034 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5035 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5036 if (arg2_value == irb->codegen->invalid_instruction) 5037 return arg2_value; 5038 5039 return ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, 5040 // this value does not mean anything since we passed non-null values for other arg 5041 AtomicOrderMonotonic); 5042 } 5043 case BuiltinFnIdIntToEnum: 5044 { 5045 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5046 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5047 if (arg0_value == irb->codegen->invalid_instruction) 5048 return arg0_value; 5049 5050 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5051 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5052 if (arg1_value == irb->codegen->invalid_instruction) 5053 return arg1_value; 5054 5055 IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value); 5056 return ir_lval_wrap(irb, scope, result, lval); 5057 } 5058 case BuiltinFnIdEnumToInt: 5059 { 5060 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5061 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5062 if (arg0_value == irb->codegen->invalid_instruction) 5063 return arg0_value; 5064 5065 IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); 5066 return ir_lval_wrap(irb, scope, result, lval); 5067 } 5068 case BuiltinFnIdBswap: 5069 { 5070 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5071 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5072 if (arg0_value == irb->codegen->invalid_instruction) 5073 return arg0_value; 5074 5075 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5076 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5077 if (arg1_value == irb->codegen->invalid_instruction) 5078 return arg1_value; 5079 5080 IrInstruction *result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value); 5081 return ir_lval_wrap(irb, scope, result, lval); 5082 } 5083 case BuiltinFnIdBitReverse: 5084 { 5085 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5086 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5087 if (arg0_value == irb->codegen->invalid_instruction) 5088 return arg0_value; 5089 5090 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5091 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5092 if (arg1_value == irb->codegen->invalid_instruction) 5093 return arg1_value; 5094 5095 IrInstruction *result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value); 5096 return ir_lval_wrap(irb, scope, result, lval); 5097 } 5098 } 5099 zig_unreachable(); 5100 } 5101 5102 static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 5103 assert(node->type == NodeTypeFnCallExpr); 5104 5105 if (node->data.fn_call_expr.is_builtin) 5106 return ir_gen_builtin_fn_call(irb, scope, node, lval); 5107 5108 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; 5109 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 5110 if (fn_ref == irb->codegen->invalid_instruction) 5111 return fn_ref; 5112 5113 size_t arg_count = node->data.fn_call_expr.params.length; 5114 IrInstruction **args = allocate<IrInstruction*>(arg_count); 5115 for (size_t i = 0; i < arg_count; i += 1) { 5116 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 5117 args[i] = ir_gen_node(irb, arg_node, scope); 5118 if (args[i] == irb->codegen->invalid_instruction) 5119 return args[i]; 5120 } 5121 5122 bool is_async = node->data.fn_call_expr.is_async; 5123 IrInstruction *async_allocator = nullptr; 5124 if (is_async) { 5125 if (node->data.fn_call_expr.async_allocator) { 5126 async_allocator = ir_gen_node(irb, node->data.fn_call_expr.async_allocator, scope); 5127 if (async_allocator == irb->codegen->invalid_instruction) 5128 return async_allocator; 5129 } 5130 } 5131 5132 IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, 5133 is_async, async_allocator, nullptr); 5134 return ir_lval_wrap(irb, scope, fn_call, lval); 5135 } 5136 5137 static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5138 assert(node->type == NodeTypeIfBoolExpr); 5139 5140 IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); 5141 if (condition == irb->codegen->invalid_instruction) 5142 return irb->codegen->invalid_instruction; 5143 5144 IrInstruction *is_comptime; 5145 if (ir_should_inline(irb->exec, scope)) { 5146 is_comptime = ir_build_const_bool(irb, scope, node, true); 5147 } else { 5148 is_comptime = ir_build_test_comptime(irb, scope, node, condition); 5149 } 5150 5151 AstNode *then_node = node->data.if_bool_expr.then_block; 5152 AstNode *else_node = node->data.if_bool_expr.else_node; 5153 5154 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "Then"); 5155 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); 5156 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); 5157 5158 ir_build_cond_br(irb, scope, condition->source_node, condition, then_block, else_block, is_comptime); 5159 5160 ir_set_cursor_at_end_and_append_block(irb, then_block); 5161 5162 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 5163 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope); 5164 if (then_expr_result == irb->codegen->invalid_instruction) 5165 return irb->codegen->invalid_instruction; 5166 IrBasicBlock *after_then_block = irb->current_basic_block; 5167 if (!instr_is_unreachable(then_expr_result)) 5168 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5169 5170 ir_set_cursor_at_end_and_append_block(irb, else_block); 5171 IrInstruction *else_expr_result; 5172 if (else_node) { 5173 else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); 5174 if (else_expr_result == irb->codegen->invalid_instruction) 5175 return irb->codegen->invalid_instruction; 5176 } else { 5177 else_expr_result = ir_build_const_void(irb, scope, node); 5178 } 5179 IrBasicBlock *after_else_block = irb->current_basic_block; 5180 if (!instr_is_unreachable(else_expr_result)) 5181 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5182 5183 ir_set_cursor_at_end_and_append_block(irb, endif_block); 5184 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 5185 incoming_values[0] = then_expr_result; 5186 incoming_values[1] = else_expr_result; 5187 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 5188 incoming_blocks[0] = after_then_block; 5189 incoming_blocks[1] = after_else_block; 5190 5191 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 5192 } 5193 5194 static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { 5195 assert(node->type == NodeTypePrefixOpExpr); 5196 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 5197 5198 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); 5199 if (value == irb->codegen->invalid_instruction) 5200 return value; 5201 5202 return ir_build_un_op(irb, scope, node, op_id, value); 5203 } 5204 5205 static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id) { 5206 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); 5207 } 5208 5209 static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval) { 5210 if (lval != LValPtr) 5211 return value; 5212 if (value == irb->codegen->invalid_instruction) 5213 return value; 5214 5215 // We needed a pointer to a value, but we got a value. So we create 5216 // an instruction which just makes a const pointer of it. 5217 return ir_build_ref(irb, scope, value->source_node, value, false, false); 5218 } 5219 5220 static PtrLen star_token_to_ptr_len(TokenId token_id) { 5221 switch (token_id) { 5222 case TokenIdStar: 5223 case TokenIdStarStar: 5224 return PtrLenSingle; 5225 case TokenIdBracketStarBracket: 5226 return PtrLenUnknown; 5227 case TokenIdBracketStarCBracket: 5228 return PtrLenC; 5229 default: 5230 zig_unreachable(); 5231 } 5232 } 5233 5234 static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) { 5235 assert(node->type == NodeTypePointerType); 5236 PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id); 5237 bool is_const = node->data.pointer_type.is_const; 5238 bool is_volatile = node->data.pointer_type.is_volatile; 5239 bool is_allow_zero = node->data.pointer_type.allow_zero_token != nullptr; 5240 AstNode *expr_node = node->data.pointer_type.op_expr; 5241 AstNode *align_expr = node->data.pointer_type.align_expr; 5242 5243 IrInstruction *align_value; 5244 if (align_expr != nullptr) { 5245 align_value = ir_gen_node(irb, align_expr, scope); 5246 if (align_value == irb->codegen->invalid_instruction) 5247 return align_value; 5248 } else { 5249 align_value = nullptr; 5250 } 5251 5252 IrInstruction *child_type = ir_gen_node(irb, expr_node, scope); 5253 if (child_type == irb->codegen->invalid_instruction) 5254 return child_type; 5255 5256 uint32_t bit_offset_start = 0; 5257 if (node->data.pointer_type.bit_offset_start != nullptr) { 5258 if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_start, 32, false)) { 5259 Buf *val_buf = buf_alloc(); 5260 bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10); 5261 exec_add_error_node(irb->codegen, irb->exec, node, 5262 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); 5263 return irb->codegen->invalid_instruction; 5264 } 5265 bit_offset_start = bigint_as_unsigned(node->data.pointer_type.bit_offset_start); 5266 } 5267 5268 uint32_t host_int_bytes = 0; 5269 if (node->data.pointer_type.host_int_bytes != nullptr) { 5270 if (!bigint_fits_in_bits(node->data.pointer_type.host_int_bytes, 32, false)) { 5271 Buf *val_buf = buf_alloc(); 5272 bigint_append_buf(val_buf, node->data.pointer_type.host_int_bytes, 10); 5273 exec_add_error_node(irb->codegen, irb->exec, node, 5274 buf_sprintf("value %s too large for u32 byte count", buf_ptr(val_buf))); 5275 return irb->codegen->invalid_instruction; 5276 } 5277 host_int_bytes = bigint_as_unsigned(node->data.pointer_type.host_int_bytes); 5278 } 5279 5280 if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) { 5281 exec_add_error_node(irb->codegen, irb->exec, node, 5282 buf_sprintf("bit offset starts after end of host integer")); 5283 return irb->codegen->invalid_instruction; 5284 } 5285 5286 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, 5287 ptr_len, align_value, bit_offset_start, host_int_bytes, is_allow_zero); 5288 } 5289 5290 static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node, 5291 LVal lval) 5292 { 5293 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 5294 if (err_union_ptr == irb->codegen->invalid_instruction) 5295 return irb->codegen->invalid_instruction; 5296 5297 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true); 5298 if (payload_ptr == irb->codegen->invalid_instruction) 5299 return irb->codegen->invalid_instruction; 5300 5301 if (lval == LValPtr) 5302 return payload_ptr; 5303 5304 return ir_build_load_ptr(irb, scope, source_node, payload_ptr); 5305 } 5306 5307 static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) { 5308 assert(node->type == NodeTypePrefixOpExpr); 5309 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 5310 5311 IrInstruction *value = ir_gen_node(irb, expr_node, scope); 5312 if (value == irb->codegen->invalid_instruction) 5313 return irb->codegen->invalid_instruction; 5314 5315 return ir_build_bool_not(irb, scope, node, value); 5316 } 5317 5318 static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 5319 assert(node->type == NodeTypePrefixOpExpr); 5320 5321 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; 5322 5323 switch (prefix_op) { 5324 case PrefixOpInvalid: 5325 zig_unreachable(); 5326 case PrefixOpBoolNot: 5327 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval); 5328 case PrefixOpBinNot: 5329 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval); 5330 case PrefixOpNegation: 5331 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval); 5332 case PrefixOpNegationWrap: 5333 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval); 5334 case PrefixOpOptional: 5335 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval); 5336 case PrefixOpAddrOf: { 5337 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 5338 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval); 5339 } 5340 } 5341 zig_unreachable(); 5342 } 5343 5344 static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5345 assert(node->type == NodeTypeContainerInitExpr); 5346 5347 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; 5348 ContainerInitKind kind = container_init_expr->kind; 5349 5350 IrInstruction *container_type = ir_gen_node(irb, container_init_expr->type, scope); 5351 if (container_type == irb->codegen->invalid_instruction) 5352 return container_type; 5353 5354 if (kind == ContainerInitKindStruct) { 5355 size_t field_count = container_init_expr->entries.length; 5356 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); 5357 for (size_t i = 0; i < field_count; i += 1) { 5358 AstNode *entry_node = container_init_expr->entries.at(i); 5359 assert(entry_node->type == NodeTypeStructValueField); 5360 5361 Buf *name = entry_node->data.struct_val_field.name; 5362 AstNode *expr_node = entry_node->data.struct_val_field.expr; 5363 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); 5364 if (expr_value == irb->codegen->invalid_instruction) 5365 return expr_value; 5366 5367 fields[i].name = name; 5368 fields[i].value = expr_value; 5369 fields[i].source_node = entry_node; 5370 } 5371 return ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields); 5372 } else if (kind == ContainerInitKindArray) { 5373 size_t item_count = container_init_expr->entries.length; 5374 IrInstruction **values = allocate<IrInstruction *>(item_count); 5375 for (size_t i = 0; i < item_count; i += 1) { 5376 AstNode *expr_node = container_init_expr->entries.at(i); 5377 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); 5378 if (expr_value == irb->codegen->invalid_instruction) 5379 return expr_value; 5380 5381 values[i] = expr_value; 5382 } 5383 return ir_build_container_init_list(irb, scope, node, container_type, item_count, values); 5384 } else { 5385 zig_unreachable(); 5386 } 5387 } 5388 5389 static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) { 5390 assert(node->type == NodeTypeVariableDeclaration); 5391 5392 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; 5393 5394 if (buf_eql_str(variable_declaration->symbol, "_")) { 5395 add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol")); 5396 return irb->codegen->invalid_instruction; 5397 } 5398 5399 IrInstruction *type_instruction; 5400 if (variable_declaration->type != nullptr) { 5401 type_instruction = ir_gen_node(irb, variable_declaration->type, scope); 5402 if (type_instruction == irb->codegen->invalid_instruction) 5403 return type_instruction; 5404 } else { 5405 type_instruction = nullptr; 5406 } 5407 5408 bool is_shadowable = false; 5409 bool is_const = variable_declaration->is_const; 5410 bool is_extern = variable_declaration->is_extern; 5411 5412 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, 5413 ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime); 5414 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, 5415 is_const, is_const, is_shadowable, is_comptime); 5416 // we detect IrInstructionIdDeclVarSrc in gen_block to make sure the next node 5417 // is inside var->child_scope 5418 5419 if (!is_extern && !variable_declaration->expr) { 5420 var->var_type = irb->codegen->builtin_types.entry_invalid; 5421 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); 5422 return irb->codegen->invalid_instruction; 5423 } 5424 5425 IrInstruction *align_value = nullptr; 5426 if (variable_declaration->align_expr != nullptr) { 5427 align_value = ir_gen_node(irb, variable_declaration->align_expr, scope); 5428 if (align_value == irb->codegen->invalid_instruction) 5429 return align_value; 5430 } 5431 5432 if (variable_declaration->section_expr != nullptr) { 5433 add_node_error(irb->codegen, variable_declaration->section_expr, 5434 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol))); 5435 } 5436 5437 // Parser should ensure that this never happens 5438 assert(variable_declaration->threadlocal_tok == nullptr); 5439 5440 // Temporarily set the name of the IrExecutable to the VariableDeclaration 5441 // so that the struct or enum from the init expression inherits the name. 5442 Buf *old_exec_name = irb->exec->name; 5443 irb->exec->name = variable_declaration->symbol; 5444 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope); 5445 irb->exec->name = old_exec_name; 5446 5447 if (init_value == irb->codegen->invalid_instruction) 5448 return init_value; 5449 5450 return ir_build_var_decl_src(irb, scope, node, var, type_instruction, align_value, init_value); 5451 } 5452 5453 static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5454 assert(node->type == NodeTypeWhileExpr); 5455 5456 AstNode *continue_expr_node = node->data.while_expr.continue_expr; 5457 AstNode *else_node = node->data.while_expr.else_node; 5458 5459 IrBasicBlock *cond_block = ir_create_basic_block(irb, scope, "WhileCond"); 5460 IrBasicBlock *body_block = ir_create_basic_block(irb, scope, "WhileBody"); 5461 IrBasicBlock *continue_block = continue_expr_node ? 5462 ir_create_basic_block(irb, scope, "WhileContinue") : cond_block; 5463 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "WhileEnd"); 5464 IrBasicBlock *else_block = else_node ? 5465 ir_create_basic_block(irb, scope, "WhileElse") : end_block; 5466 5467 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, 5468 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline); 5469 ir_build_br(irb, scope, node, cond_block, is_comptime); 5470 5471 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 5472 Buf *var_symbol = node->data.while_expr.var_symbol; 5473 Buf *err_symbol = node->data.while_expr.err_symbol; 5474 if (err_symbol != nullptr) { 5475 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5476 5477 Scope *payload_scope; 5478 AstNode *symbol_node = node; // TODO make more accurate 5479 ZigVar *payload_var; 5480 if (var_symbol) { 5481 // TODO make it an error to write to payload variable 5482 payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 5483 true, false, false, is_comptime); 5484 payload_scope = payload_var->child_scope; 5485 } else { 5486 payload_scope = subexpr_scope; 5487 } 5488 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); 5489 if (err_val_ptr == irb->codegen->invalid_instruction) 5490 return err_val_ptr; 5491 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr); 5492 IrInstruction *is_err = ir_build_test_err(irb, scope, node->data.while_expr.condition, err_val); 5493 IrBasicBlock *after_cond_block = irb->current_basic_block; 5494 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 5495 if (!instr_is_unreachable(is_err)) { 5496 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, 5497 else_block, body_block, is_comptime)); 5498 } 5499 5500 ir_set_cursor_at_end_and_append_block(irb, body_block); 5501 if (var_symbol) { 5502 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, 5503 err_val_ptr, false); 5504 IrInstruction *var_value = node->data.while_expr.var_is_ptr ? 5505 var_ptr_value : ir_build_load_ptr(irb, payload_scope, symbol_node, var_ptr_value); 5506 ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, nullptr, var_value); 5507 } 5508 5509 ZigList<IrInstruction *> incoming_values = {0}; 5510 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5511 5512 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope); 5513 loop_scope->break_block = end_block; 5514 loop_scope->continue_block = continue_block; 5515 loop_scope->is_comptime = is_comptime; 5516 loop_scope->incoming_blocks = &incoming_blocks; 5517 loop_scope->incoming_values = &incoming_values; 5518 5519 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 5520 if (body_result == irb->codegen->invalid_instruction) 5521 return body_result; 5522 5523 if (!instr_is_unreachable(body_result)) { 5524 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result)); 5525 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime)); 5526 } 5527 5528 if (continue_expr_node) { 5529 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5530 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope); 5531 if (expr_result == irb->codegen->invalid_instruction) 5532 return expr_result; 5533 if (!instr_is_unreachable(expr_result)) { 5534 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, continue_expr_node, expr_result)); 5535 ir_mark_gen(ir_build_br(irb, payload_scope, node, cond_block, is_comptime)); 5536 } 5537 } 5538 5539 ir_set_cursor_at_end_and_append_block(irb, else_block); 5540 assert(else_node != nullptr); 5541 5542 // TODO make it an error to write to error variable 5543 AstNode *err_symbol_node = else_node; // TODO make more accurate 5544 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, 5545 true, false, false, is_comptime); 5546 Scope *err_scope = err_var->child_scope; 5547 IrInstruction *err_var_value = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); 5548 ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, nullptr, err_var_value); 5549 5550 IrInstruction *else_result = ir_gen_node(irb, else_node, err_scope); 5551 if (else_result == irb->codegen->invalid_instruction) 5552 return else_result; 5553 if (!instr_is_unreachable(else_result)) 5554 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 5555 IrBasicBlock *after_else_block = irb->current_basic_block; 5556 ir_set_cursor_at_end_and_append_block(irb, end_block); 5557 if (else_result) { 5558 incoming_blocks.append(after_else_block); 5559 incoming_values.append(else_result); 5560 } else { 5561 incoming_blocks.append(after_cond_block); 5562 incoming_values.append(void_else_result); 5563 } 5564 5565 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5566 } else if (var_symbol != nullptr) { 5567 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5568 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 5569 // TODO make it an error to write to payload variable 5570 AstNode *symbol_node = node; // TODO make more accurate 5571 5572 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 5573 true, false, false, is_comptime); 5574 Scope *child_scope = payload_var->child_scope; 5575 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); 5576 if (maybe_val_ptr == irb->codegen->invalid_instruction) 5577 return maybe_val_ptr; 5578 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); 5579 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); 5580 IrBasicBlock *after_cond_block = irb->current_basic_block; 5581 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 5582 if (!instr_is_unreachable(is_non_null)) { 5583 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, 5584 body_block, else_block, is_comptime)); 5585 } 5586 5587 ir_set_cursor_at_end_and_append_block(irb, body_block); 5588 IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false); 5589 IrInstruction *var_value = node->data.while_expr.var_is_ptr ? 5590 var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value); 5591 ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, nullptr, var_value); 5592 5593 ZigList<IrInstruction *> incoming_values = {0}; 5594 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5595 5596 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 5597 loop_scope->break_block = end_block; 5598 loop_scope->continue_block = continue_block; 5599 loop_scope->is_comptime = is_comptime; 5600 loop_scope->incoming_blocks = &incoming_blocks; 5601 loop_scope->incoming_values = &incoming_values; 5602 5603 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 5604 if (body_result == irb->codegen->invalid_instruction) 5605 return body_result; 5606 5607 if (!instr_is_unreachable(body_result)) { 5608 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result)); 5609 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 5610 } 5611 5612 if (continue_expr_node) { 5613 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5614 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, child_scope); 5615 if (expr_result == irb->codegen->invalid_instruction) 5616 return expr_result; 5617 if (!instr_is_unreachable(expr_result)) { 5618 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, continue_expr_node, expr_result)); 5619 ir_mark_gen(ir_build_br(irb, child_scope, node, cond_block, is_comptime)); 5620 } 5621 } 5622 5623 IrInstruction *else_result = nullptr; 5624 if (else_node) { 5625 ir_set_cursor_at_end_and_append_block(irb, else_block); 5626 5627 else_result = ir_gen_node(irb, else_node, scope); 5628 if (else_result == irb->codegen->invalid_instruction) 5629 return else_result; 5630 if (!instr_is_unreachable(else_result)) 5631 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 5632 } 5633 IrBasicBlock *after_else_block = irb->current_basic_block; 5634 ir_set_cursor_at_end_and_append_block(irb, end_block); 5635 if (else_result) { 5636 incoming_blocks.append(after_else_block); 5637 incoming_values.append(else_result); 5638 } else { 5639 incoming_blocks.append(after_cond_block); 5640 incoming_values.append(void_else_result); 5641 } 5642 5643 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5644 } else { 5645 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5646 IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); 5647 if (cond_val == irb->codegen->invalid_instruction) 5648 return cond_val; 5649 IrBasicBlock *after_cond_block = irb->current_basic_block; 5650 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 5651 if (!instr_is_unreachable(cond_val)) { 5652 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, 5653 body_block, else_block, is_comptime)); 5654 } 5655 5656 ir_set_cursor_at_end_and_append_block(irb, body_block); 5657 5658 ZigList<IrInstruction *> incoming_values = {0}; 5659 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5660 5661 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 5662 5663 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope); 5664 loop_scope->break_block = end_block; 5665 loop_scope->continue_block = continue_block; 5666 loop_scope->is_comptime = is_comptime; 5667 loop_scope->incoming_blocks = &incoming_blocks; 5668 loop_scope->incoming_values = &incoming_values; 5669 5670 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 5671 if (body_result == irb->codegen->invalid_instruction) 5672 return body_result; 5673 5674 if (!instr_is_unreachable(body_result)) { 5675 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result)); 5676 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime)); 5677 } 5678 5679 if (continue_expr_node) { 5680 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5681 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, subexpr_scope); 5682 if (expr_result == irb->codegen->invalid_instruction) 5683 return expr_result; 5684 if (!instr_is_unreachable(expr_result)) { 5685 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, continue_expr_node, expr_result)); 5686 ir_mark_gen(ir_build_br(irb, scope, node, cond_block, is_comptime)); 5687 } 5688 } 5689 5690 IrInstruction *else_result = nullptr; 5691 if (else_node) { 5692 ir_set_cursor_at_end_and_append_block(irb, else_block); 5693 5694 else_result = ir_gen_node(irb, else_node, subexpr_scope); 5695 if (else_result == irb->codegen->invalid_instruction) 5696 return else_result; 5697 if (!instr_is_unreachable(else_result)) 5698 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 5699 } 5700 IrBasicBlock *after_else_block = irb->current_basic_block; 5701 ir_set_cursor_at_end_and_append_block(irb, end_block); 5702 if (else_result) { 5703 incoming_blocks.append(after_else_block); 5704 incoming_values.append(else_result); 5705 } else { 5706 incoming_blocks.append(after_cond_block); 5707 incoming_values.append(void_else_result); 5708 } 5709 5710 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5711 } 5712 } 5713 5714 static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 5715 assert(node->type == NodeTypeForExpr); 5716 5717 AstNode *array_node = node->data.for_expr.array_expr; 5718 AstNode *elem_node = node->data.for_expr.elem_node; 5719 AstNode *index_node = node->data.for_expr.index_node; 5720 AstNode *body_node = node->data.for_expr.body; 5721 AstNode *else_node = node->data.for_expr.else_node; 5722 5723 if (!elem_node) { 5724 add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter")); 5725 return irb->codegen->invalid_instruction; 5726 } 5727 assert(elem_node->type == NodeTypeSymbol); 5728 5729 IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr); 5730 if (array_val_ptr == irb->codegen->invalid_instruction) 5731 return array_val_ptr; 5732 5733 IrInstruction *pointer_type = ir_build_to_ptr_type(irb, parent_scope, array_node, array_val_ptr); 5734 IrInstruction *elem_var_type; 5735 if (node->data.for_expr.elem_is_ptr) { 5736 elem_var_type = pointer_type; 5737 } else { 5738 elem_var_type = ir_build_ptr_type_child(irb, parent_scope, elem_node, pointer_type); 5739 } 5740 5741 IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, 5742 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); 5743 5744 // TODO make it an error to write to element variable or i variable. 5745 Buf *elem_var_name = elem_node->data.symbol_expr.symbol; 5746 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); 5747 Scope *child_scope = elem_var->child_scope; 5748 5749 IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node); 5750 ir_build_var_decl_src(irb, child_scope, elem_node, elem_var, elem_var_type, nullptr, undefined_value); 5751 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var); 5752 5753 AstNode *index_var_source_node; 5754 ZigVar *index_var; 5755 if (index_node) { 5756 index_var_source_node = index_node; 5757 Buf *index_var_name = index_node->data.symbol_expr.symbol; 5758 index_var = ir_create_var(irb, index_node, child_scope, index_var_name, true, false, false, is_comptime); 5759 } else { 5760 index_var_source_node = node; 5761 index_var = ir_create_var(irb, node, child_scope, nullptr, true, false, true, is_comptime); 5762 } 5763 child_scope = index_var->child_scope; 5764 5765 IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize); 5766 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0); 5767 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1); 5768 ir_build_var_decl_src(irb, child_scope, index_var_source_node, index_var, usize, nullptr, zero); 5769 IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var); 5770 5771 5772 IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond"); 5773 IrBasicBlock *body_block = ir_create_basic_block(irb, child_scope, "ForBody"); 5774 IrBasicBlock *end_block = ir_create_basic_block(irb, child_scope, "ForEnd"); 5775 IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, child_scope, "ForElse") : end_block; 5776 IrBasicBlock *continue_block = ir_create_basic_block(irb, child_scope, "ForContinue"); 5777 5778 Buf *len_field_name = buf_create_from_str("len"); 5779 IrInstruction *len_ref = ir_build_field_ptr(irb, child_scope, node, array_val_ptr, len_field_name); 5780 IrInstruction *len_val = ir_build_load_ptr(irb, child_scope, node, len_ref); 5781 ir_build_br(irb, child_scope, node, cond_block, is_comptime); 5782 5783 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5784 IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr); 5785 IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); 5786 IrBasicBlock *after_cond_block = irb->current_basic_block; 5787 IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); 5788 ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime)); 5789 5790 ir_set_cursor_at_end_and_append_block(irb, body_block); 5791 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false, PtrLenSingle); 5792 IrInstruction *elem_val; 5793 if (node->data.for_expr.elem_is_ptr) { 5794 elem_val = elem_ptr; 5795 } else { 5796 elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr); 5797 } 5798 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val)); 5799 5800 ZigList<IrInstruction *> incoming_values = {0}; 5801 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5802 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 5803 loop_scope->break_block = end_block; 5804 loop_scope->continue_block = continue_block; 5805 loop_scope->is_comptime = is_comptime; 5806 loop_scope->incoming_blocks = &incoming_blocks; 5807 loop_scope->incoming_values = &incoming_values; 5808 5809 IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base); 5810 5811 if (!instr_is_unreachable(body_result)) { 5812 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result)); 5813 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 5814 } 5815 5816 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5817 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); 5818 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)); 5819 ir_build_br(irb, child_scope, node, cond_block, is_comptime); 5820 5821 IrInstruction *else_result = nullptr; 5822 if (else_node) { 5823 ir_set_cursor_at_end_and_append_block(irb, else_block); 5824 5825 else_result = ir_gen_node(irb, else_node, parent_scope); 5826 if (else_result == irb->codegen->invalid_instruction) 5827 return else_result; 5828 if (!instr_is_unreachable(else_result)) 5829 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 5830 } 5831 IrBasicBlock *after_else_block = irb->current_basic_block; 5832 ir_set_cursor_at_end_and_append_block(irb, end_block); 5833 5834 if (else_result) { 5835 incoming_blocks.append(after_else_block); 5836 incoming_values.append(else_result); 5837 } else { 5838 incoming_blocks.append(after_cond_block); 5839 incoming_values.append(void_else_value); 5840 } 5841 5842 return ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5843 } 5844 5845 static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 5846 assert(node->type == NodeTypeBoolLiteral); 5847 return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value); 5848 } 5849 5850 static IrInstruction *ir_gen_enum_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 5851 assert(node->type == NodeTypeEnumLiteral); 5852 Buf *name = &node->data.enum_literal.identifier->data.str_lit.str; 5853 return ir_build_const_enum_literal(irb, scope, node, name); 5854 } 5855 5856 static IrInstruction *ir_gen_string_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 5857 assert(node->type == NodeTypeStringLiteral); 5858 5859 if (node->data.string_literal.c) { 5860 return ir_build_const_c_str_lit(irb, scope, node, node->data.string_literal.buf); 5861 } else { 5862 return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf); 5863 } 5864 } 5865 5866 static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *node) { 5867 assert(node->type == NodeTypeArrayType); 5868 5869 AstNode *size_node = node->data.array_type.size; 5870 AstNode *child_type_node = node->data.array_type.child_type; 5871 bool is_const = node->data.array_type.is_const; 5872 bool is_volatile = node->data.array_type.is_volatile; 5873 bool is_allow_zero = node->data.array_type.allow_zero_token != nullptr; 5874 AstNode *align_expr = node->data.array_type.align_expr; 5875 5876 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 5877 if (size_node) { 5878 if (is_const) { 5879 add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); 5880 return irb->codegen->invalid_instruction; 5881 } 5882 if (is_volatile) { 5883 add_node_error(irb->codegen, node, buf_create_from_str("volatile qualifier invalid on array type")); 5884 return irb->codegen->invalid_instruction; 5885 } 5886 if (is_allow_zero) { 5887 add_node_error(irb->codegen, node, buf_create_from_str("allowzero qualifier invalid on array type")); 5888 return irb->codegen->invalid_instruction; 5889 } 5890 if (align_expr != nullptr) { 5891 add_node_error(irb->codegen, node, buf_create_from_str("align qualifier invalid on array type")); 5892 return irb->codegen->invalid_instruction; 5893 } 5894 5895 IrInstruction *size_value = ir_gen_node(irb, size_node, comptime_scope); 5896 if (size_value == irb->codegen->invalid_instruction) 5897 return size_value; 5898 5899 IrInstruction *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 5900 if (child_type == irb->codegen->invalid_instruction) 5901 return child_type; 5902 5903 return ir_build_array_type(irb, scope, node, size_value, child_type); 5904 } else { 5905 IrInstruction *align_value; 5906 if (align_expr != nullptr) { 5907 align_value = ir_gen_node(irb, align_expr, comptime_scope); 5908 if (align_value == irb->codegen->invalid_instruction) 5909 return align_value; 5910 } else { 5911 align_value = nullptr; 5912 } 5913 5914 IrInstruction *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 5915 if (child_type == irb->codegen->invalid_instruction) 5916 return child_type; 5917 5918 return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, align_value, is_allow_zero); 5919 } 5920 } 5921 5922 static IrInstruction *ir_gen_promise_type(IrBuilder *irb, Scope *scope, AstNode *node) { 5923 assert(node->type == NodeTypePromiseType); 5924 5925 AstNode *payload_type_node = node->data.promise_type.payload_type; 5926 IrInstruction *payload_type_value = nullptr; 5927 5928 if (payload_type_node != nullptr) { 5929 payload_type_value = ir_gen_node(irb, payload_type_node, scope); 5930 if (payload_type_value == irb->codegen->invalid_instruction) 5931 return payload_type_value; 5932 5933 } 5934 5935 return ir_build_promise_type(irb, scope, node, payload_type_value); 5936 } 5937 5938 static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 5939 assert(node->type == NodeTypeUndefinedLiteral); 5940 return ir_build_const_undefined(irb, scope, node); 5941 } 5942 5943 static Error parse_asm_template(IrBuilder *irb, AstNode *source_node, Buf *asm_template, 5944 ZigList<AsmToken> *tok_list) 5945 { 5946 // TODO Connect the errors in this function back up to the actual source location 5947 // rather than just the token. https://github.com/ziglang/zig/issues/2080 5948 enum State { 5949 StateStart, 5950 StatePercent, 5951 StateTemplate, 5952 StateVar, 5953 }; 5954 5955 assert(tok_list->length == 0); 5956 5957 AsmToken *cur_tok = nullptr; 5958 5959 enum State state = StateStart; 5960 5961 for (size_t i = 0; i < buf_len(asm_template); i += 1) { 5962 uint8_t c = *((uint8_t*)buf_ptr(asm_template) + i); 5963 switch (state) { 5964 case StateStart: 5965 if (c == '%') { 5966 tok_list->add_one(); 5967 cur_tok = &tok_list->last(); 5968 cur_tok->id = AsmTokenIdPercent; 5969 cur_tok->start = i; 5970 state = StatePercent; 5971 } else { 5972 tok_list->add_one(); 5973 cur_tok = &tok_list->last(); 5974 cur_tok->id = AsmTokenIdTemplate; 5975 cur_tok->start = i; 5976 state = StateTemplate; 5977 } 5978 break; 5979 case StatePercent: 5980 if (c == '%') { 5981 cur_tok->end = i; 5982 state = StateStart; 5983 } else if (c == '[') { 5984 cur_tok->id = AsmTokenIdVar; 5985 state = StateVar; 5986 } else if (c == '=') { 5987 cur_tok->id = AsmTokenIdUniqueId; 5988 cur_tok->end = i; 5989 state = StateStart; 5990 } else { 5991 add_node_error(irb->codegen, source_node, 5992 buf_create_from_str("expected a '%' or '['")); 5993 return ErrorSemanticAnalyzeFail; 5994 } 5995 break; 5996 case StateTemplate: 5997 if (c == '%') { 5998 cur_tok->end = i; 5999 i -= 1; 6000 cur_tok = nullptr; 6001 state = StateStart; 6002 } 6003 break; 6004 case StateVar: 6005 if (c == ']') { 6006 cur_tok->end = i; 6007 state = StateStart; 6008 } else if ((c >= 'a' && c <= 'z') || 6009 (c >= '0' && c <= '9') || 6010 (c == '_')) 6011 { 6012 // do nothing 6013 } else { 6014 add_node_error(irb->codegen, source_node, 6015 buf_sprintf("invalid substitution character: '%c'", c)); 6016 return ErrorSemanticAnalyzeFail; 6017 } 6018 break; 6019 } 6020 } 6021 6022 switch (state) { 6023 case StateStart: 6024 break; 6025 case StatePercent: 6026 case StateVar: 6027 add_node_error(irb->codegen, source_node, buf_sprintf("unexpected end of assembly template")); 6028 return ErrorSemanticAnalyzeFail; 6029 case StateTemplate: 6030 cur_tok->end = buf_len(asm_template); 6031 break; 6032 } 6033 return ErrorNone; 6034 } 6035 6036 static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 6037 Error err; 6038 assert(node->type == NodeTypeAsmExpr); 6039 AstNodeAsmExpr *asm_expr = &node->data.asm_expr; 6040 bool is_volatile = asm_expr->volatile_token != nullptr; 6041 bool in_fn_scope = (scope_fn_entry(scope) != nullptr); 6042 6043 Buf *template_buf = &asm_expr->asm_template->data.str_lit.str; 6044 6045 if (!in_fn_scope) { 6046 if (is_volatile) { 6047 add_token_error(irb->codegen, node->owner, asm_expr->volatile_token, 6048 buf_sprintf("volatile is meaningless on global assembly")); 6049 return irb->codegen->invalid_instruction; 6050 } 6051 6052 if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 || 6053 asm_expr->clobber_list.length != 0) 6054 { 6055 add_node_error(irb->codegen, node, 6056 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers")); 6057 return irb->codegen->invalid_instruction; 6058 } 6059 6060 return ir_build_global_asm(irb, scope, node, template_buf); 6061 } 6062 6063 ZigList<AsmToken> tok_list = {}; 6064 if ((err = parse_asm_template(irb, node, template_buf, &tok_list))) { 6065 return irb->codegen->invalid_instruction; 6066 } 6067 6068 IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length); 6069 IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length); 6070 ZigVar **output_vars = allocate<ZigVar *>(asm_expr->output_list.length); 6071 size_t return_count = 0; 6072 if (!is_volatile && asm_expr->output_list.length == 0) { 6073 add_node_error(irb->codegen, node, 6074 buf_sprintf("assembly expression with no output must be marked volatile")); 6075 return irb->codegen->invalid_instruction; 6076 } 6077 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 6078 AsmOutput *asm_output = asm_expr->output_list.at(i); 6079 if (asm_output->return_type) { 6080 return_count += 1; 6081 6082 IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, scope); 6083 if (return_type == irb->codegen->invalid_instruction) 6084 return irb->codegen->invalid_instruction; 6085 if (return_count > 1) { 6086 add_node_error(irb->codegen, node, 6087 buf_sprintf("inline assembly allows up to one output value")); 6088 return irb->codegen->invalid_instruction; 6089 } 6090 output_types[i] = return_type; 6091 } else { 6092 Buf *variable_name = asm_output->variable_name; 6093 // TODO there is some duplication here with ir_gen_symbol. I need to do a full audit of how 6094 // inline assembly works. https://github.com/ziglang/zig/issues/215 6095 ZigVar *var = find_variable(irb->codegen, scope, variable_name, nullptr); 6096 if (var) { 6097 output_vars[i] = var; 6098 } else { 6099 add_node_error(irb->codegen, node, 6100 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); 6101 return irb->codegen->invalid_instruction; 6102 } 6103 } 6104 6105 const char modifier = *buf_ptr(asm_output->constraint); 6106 if (modifier != '=') { 6107 add_node_error(irb->codegen, node, 6108 buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported." 6109 " Compiler TODO: see https://github.com/ziglang/zig/issues/215", 6110 buf_ptr(asm_output->asm_symbolic_name), modifier)); 6111 return irb->codegen->invalid_instruction; 6112 } 6113 } 6114 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 6115 AsmInput *asm_input = asm_expr->input_list.at(i); 6116 IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, scope); 6117 if (input_value == irb->codegen->invalid_instruction) 6118 return irb->codegen->invalid_instruction; 6119 6120 input_list[i] = input_value; 6121 } 6122 6123 return ir_build_asm(irb, scope, node, template_buf, tok_list.items, tok_list.length, 6124 input_list, output_types, output_vars, return_count, is_volatile); 6125 } 6126 6127 static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 6128 assert(node->type == NodeTypeIfOptional); 6129 6130 Buf *var_symbol = node->data.test_expr.var_symbol; 6131 AstNode *expr_node = node->data.test_expr.target_node; 6132 AstNode *then_node = node->data.test_expr.then_node; 6133 AstNode *else_node = node->data.test_expr.else_node; 6134 bool var_is_ptr = node->data.test_expr.var_is_ptr; 6135 6136 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 6137 if (maybe_val_ptr == irb->codegen->invalid_instruction) 6138 return maybe_val_ptr; 6139 6140 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); 6141 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_val); 6142 6143 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "OptionalThen"); 6144 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "OptionalElse"); 6145 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "OptionalEndIf"); 6146 6147 IrInstruction *is_comptime; 6148 if (ir_should_inline(irb->exec, scope)) { 6149 is_comptime = ir_build_const_bool(irb, scope, node, true); 6150 } else { 6151 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); 6152 } 6153 ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime); 6154 6155 ir_set_cursor_at_end_and_append_block(irb, then_block); 6156 6157 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6158 Scope *var_scope; 6159 if (var_symbol) { 6160 IrInstruction *var_type = nullptr; 6161 bool is_shadowable = false; 6162 bool is_const = true; 6163 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 6164 var_symbol, is_const, is_const, is_shadowable, is_comptime); 6165 6166 IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false); 6167 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); 6168 ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value); 6169 var_scope = var->child_scope; 6170 } else { 6171 var_scope = subexpr_scope; 6172 } 6173 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); 6174 if (then_expr_result == irb->codegen->invalid_instruction) 6175 return then_expr_result; 6176 IrBasicBlock *after_then_block = irb->current_basic_block; 6177 if (!instr_is_unreachable(then_expr_result)) 6178 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 6179 6180 ir_set_cursor_at_end_and_append_block(irb, else_block); 6181 IrInstruction *else_expr_result; 6182 if (else_node) { 6183 else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); 6184 if (else_expr_result == irb->codegen->invalid_instruction) 6185 return else_expr_result; 6186 } else { 6187 else_expr_result = ir_build_const_void(irb, scope, node); 6188 } 6189 IrBasicBlock *after_else_block = irb->current_basic_block; 6190 if (!instr_is_unreachable(else_expr_result)) 6191 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 6192 6193 ir_set_cursor_at_end_and_append_block(irb, endif_block); 6194 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 6195 incoming_values[0] = then_expr_result; 6196 incoming_values[1] = else_expr_result; 6197 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 6198 incoming_blocks[0] = after_then_block; 6199 incoming_blocks[1] = after_else_block; 6200 6201 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 6202 } 6203 6204 static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 6205 assert(node->type == NodeTypeIfErrorExpr); 6206 6207 AstNode *target_node = node->data.if_err_expr.target_node; 6208 AstNode *then_node = node->data.if_err_expr.then_node; 6209 AstNode *else_node = node->data.if_err_expr.else_node; 6210 bool var_is_ptr = node->data.if_err_expr.var_is_ptr; 6211 bool var_is_const = true; 6212 Buf *var_symbol = node->data.if_err_expr.var_symbol; 6213 Buf *err_symbol = node->data.if_err_expr.err_symbol; 6214 6215 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); 6216 if (err_val_ptr == irb->codegen->invalid_instruction) 6217 return err_val_ptr; 6218 6219 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 6220 IrInstruction *is_err = ir_build_test_err(irb, scope, node, err_val); 6221 6222 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); 6223 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); 6224 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "TryEnd"); 6225 6226 bool force_comptime = ir_should_inline(irb->exec, scope); 6227 IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); 6228 ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); 6229 6230 ir_set_cursor_at_end_and_append_block(irb, ok_block); 6231 6232 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6233 Scope *var_scope; 6234 if (var_symbol) { 6235 IrInstruction *var_type = nullptr; 6236 bool is_shadowable = false; 6237 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); 6238 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 6239 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); 6240 6241 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false); 6242 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); 6243 ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value); 6244 var_scope = var->child_scope; 6245 } else { 6246 var_scope = subexpr_scope; 6247 } 6248 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); 6249 if (then_expr_result == irb->codegen->invalid_instruction) 6250 return then_expr_result; 6251 IrBasicBlock *after_then_block = irb->current_basic_block; 6252 if (!instr_is_unreachable(then_expr_result)) 6253 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 6254 6255 ir_set_cursor_at_end_and_append_block(irb, else_block); 6256 6257 IrInstruction *else_expr_result; 6258 if (else_node) { 6259 Scope *err_var_scope; 6260 if (err_symbol) { 6261 IrInstruction *var_type = nullptr; 6262 bool is_shadowable = false; 6263 bool is_const = true; 6264 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 6265 err_symbol, is_const, is_const, is_shadowable, is_comptime); 6266 6267 IrInstruction *var_value = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr); 6268 ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value); 6269 err_var_scope = var->child_scope; 6270 } else { 6271 err_var_scope = subexpr_scope; 6272 } 6273 else_expr_result = ir_gen_node(irb, else_node, err_var_scope); 6274 if (else_expr_result == irb->codegen->invalid_instruction) 6275 return else_expr_result; 6276 } else { 6277 else_expr_result = ir_build_const_void(irb, scope, node); 6278 } 6279 IrBasicBlock *after_else_block = irb->current_basic_block; 6280 if (!instr_is_unreachable(else_expr_result)) 6281 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 6282 6283 ir_set_cursor_at_end_and_append_block(irb, endif_block); 6284 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 6285 incoming_values[0] = then_expr_result; 6286 incoming_values[1] = else_expr_result; 6287 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 6288 incoming_blocks[0] = after_then_block; 6289 incoming_blocks[1] = after_else_block; 6290 6291 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 6292 } 6293 6294 static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, 6295 IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, 6296 IrInstruction *target_value_ptr, IrInstruction *prong_value, 6297 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values) 6298 { 6299 assert(switch_node->type == NodeTypeSwitchExpr); 6300 assert(prong_node->type == NodeTypeSwitchProng); 6301 6302 AstNode *expr_node = prong_node->data.switch_prong.expr; 6303 AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol; 6304 Scope *child_scope; 6305 if (var_symbol_node) { 6306 assert(var_symbol_node->type == NodeTypeSymbol); 6307 Buf *var_name = var_symbol_node->data.symbol_expr.symbol; 6308 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr; 6309 6310 bool is_shadowable = false; 6311 bool is_const = true; 6312 ZigVar *var = ir_create_var(irb, var_symbol_node, scope, 6313 var_name, is_const, is_const, is_shadowable, var_is_comptime); 6314 child_scope = var->child_scope; 6315 IrInstruction *var_value; 6316 if (prong_value) { 6317 IrInstruction *var_ptr_value = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, prong_value); 6318 var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); 6319 } else { 6320 var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr); 6321 } 6322 IrInstruction *var_type = nullptr; // infer the type 6323 ir_build_var_decl_src(irb, scope, var_symbol_node, var, var_type, nullptr, var_value); 6324 } else { 6325 child_scope = scope; 6326 } 6327 6328 IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope); 6329 if (expr_result == irb->codegen->invalid_instruction) 6330 return false; 6331 if (!instr_is_unreachable(expr_result)) 6332 ir_mark_gen(ir_build_br(irb, scope, switch_node, end_block, is_comptime)); 6333 incoming_blocks->append(irb->current_basic_block); 6334 incoming_values->append(expr_result); 6335 return true; 6336 } 6337 6338 static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 6339 assert(node->type == NodeTypeSwitchExpr); 6340 6341 AstNode *target_node = node->data.switch_expr.expr; 6342 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); 6343 if (target_value_ptr == irb->codegen->invalid_instruction) 6344 return target_value_ptr; 6345 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); 6346 6347 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "SwitchElse"); 6348 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "SwitchEnd"); 6349 6350 size_t prong_count = node->data.switch_expr.prongs.length; 6351 ZigList<IrInstructionSwitchBrCase> cases = {0}; 6352 6353 IrInstruction *is_comptime; 6354 IrInstruction *var_is_comptime; 6355 if (ir_should_inline(irb->exec, scope)) { 6356 is_comptime = ir_build_const_bool(irb, scope, node, true); 6357 var_is_comptime = is_comptime; 6358 } else { 6359 is_comptime = ir_build_test_comptime(irb, scope, node, target_value); 6360 var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr); 6361 } 6362 6363 ZigList<IrInstruction *> incoming_values = {0}; 6364 ZigList<IrBasicBlock *> incoming_blocks = {0}; 6365 ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0}; 6366 6367 // First do the else and the ranges 6368 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6369 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 6370 AstNode *else_prong = nullptr; 6371 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 6372 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 6373 size_t prong_item_count = prong_node->data.switch_prong.items.length; 6374 if (prong_item_count == 0) { 6375 if (else_prong) { 6376 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 6377 buf_sprintf("multiple else prongs in switch expression")); 6378 add_error_note(irb->codegen, msg, else_prong, 6379 buf_sprintf("previous else prong is here")); 6380 return irb->codegen->invalid_instruction; 6381 } 6382 else_prong = prong_node; 6383 6384 IrBasicBlock *prev_block = irb->current_basic_block; 6385 ir_set_cursor_at_end_and_append_block(irb, else_block); 6386 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 6387 is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values)) 6388 { 6389 return irb->codegen->invalid_instruction; 6390 } 6391 ir_set_cursor_at_end(irb, prev_block); 6392 } else if (prong_node->data.switch_prong.any_items_are_range) { 6393 IrInstruction *ok_bit = nullptr; 6394 AstNode *last_item_node = nullptr; 6395 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 6396 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 6397 last_item_node = item_node; 6398 if (item_node->type == NodeTypeSwitchRange) { 6399 AstNode *start_node = item_node->data.switch_range.start; 6400 AstNode *end_node = item_node->data.switch_range.end; 6401 6402 IrInstruction *start_value = ir_gen_node(irb, start_node, comptime_scope); 6403 if (start_value == irb->codegen->invalid_instruction) 6404 return irb->codegen->invalid_instruction; 6405 6406 IrInstruction *end_value = ir_gen_node(irb, end_node, comptime_scope); 6407 if (end_value == irb->codegen->invalid_instruction) 6408 return irb->codegen->invalid_instruction; 6409 6410 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 6411 check_range->start = start_value; 6412 check_range->end = end_value; 6413 6414 IrInstruction *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq, 6415 target_value, start_value, false); 6416 IrInstruction *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq, 6417 target_value, end_value, false); 6418 IrInstruction *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd, 6419 lower_range_ok, upper_range_ok, false); 6420 if (ok_bit) { 6421 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false); 6422 } else { 6423 ok_bit = both_ok; 6424 } 6425 } else { 6426 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); 6427 if (item_value == irb->codegen->invalid_instruction) 6428 return irb->codegen->invalid_instruction; 6429 6430 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 6431 check_range->start = item_value; 6432 check_range->end = item_value; 6433 6434 IrInstruction *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq, 6435 item_value, target_value, false); 6436 if (ok_bit) { 6437 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false); 6438 } else { 6439 ok_bit = cmp_ok; 6440 } 6441 } 6442 } 6443 6444 IrBasicBlock *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes"); 6445 IrBasicBlock *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo"); 6446 6447 assert(ok_bit); 6448 assert(last_item_node); 6449 ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, 6450 range_block_no, is_comptime)); 6451 6452 ir_set_cursor_at_end_and_append_block(irb, range_block_yes); 6453 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 6454 is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values)) 6455 { 6456 return irb->codegen->invalid_instruction; 6457 } 6458 6459 ir_set_cursor_at_end_and_append_block(irb, range_block_no); 6460 } 6461 } 6462 6463 // next do the non-else non-ranges 6464 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 6465 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 6466 size_t prong_item_count = prong_node->data.switch_prong.items.length; 6467 if (prong_item_count == 0) 6468 continue; 6469 if (prong_node->data.switch_prong.any_items_are_range) 6470 continue; 6471 6472 IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); 6473 IrInstruction *last_item_value = nullptr; 6474 6475 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 6476 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 6477 assert(item_node->type != NodeTypeSwitchRange); 6478 6479 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); 6480 if (item_value == irb->codegen->invalid_instruction) 6481 return irb->codegen->invalid_instruction; 6482 6483 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 6484 check_range->start = item_value; 6485 check_range->end = item_value; 6486 6487 IrInstructionSwitchBrCase *this_case = cases.add_one(); 6488 this_case->value = item_value; 6489 this_case->block = prong_block; 6490 6491 last_item_value = item_value; 6492 } 6493 IrInstruction *only_item_value = (prong_item_count == 1) ? last_item_value : nullptr; 6494 6495 IrBasicBlock *prev_block = irb->current_basic_block; 6496 ir_set_cursor_at_end_and_append_block(irb, prong_block); 6497 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 6498 is_comptime, var_is_comptime, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values)) 6499 { 6500 return irb->codegen->invalid_instruction; 6501 } 6502 6503 ir_set_cursor_at_end(irb, prev_block); 6504 6505 } 6506 6507 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length, 6508 else_prong != nullptr); 6509 6510 if (cases.length == 0) { 6511 ir_build_br(irb, scope, node, else_block, is_comptime); 6512 } else { 6513 ir_build_switch_br(irb, scope, node, target_value, else_block, cases.length, cases.items, is_comptime, switch_prongs_void); 6514 } 6515 6516 if (!else_prong) { 6517 ir_set_cursor_at_end_and_append_block(irb, else_block); 6518 ir_build_unreachable(irb, scope, node); 6519 } 6520 6521 ir_set_cursor_at_end_and_append_block(irb, end_block); 6522 assert(incoming_blocks.length == incoming_values.length); 6523 if (incoming_blocks.length == 0) { 6524 return ir_build_const_void(irb, scope, node); 6525 } else { 6526 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 6527 } 6528 } 6529 6530 static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { 6531 assert(node->type == NodeTypeCompTime); 6532 6533 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); 6534 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval); 6535 } 6536 6537 static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { 6538 IrInstruction *is_comptime; 6539 if (ir_should_inline(irb->exec, break_scope)) { 6540 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 6541 } else { 6542 is_comptime = block_scope->is_comptime; 6543 } 6544 6545 IrInstruction *result_value; 6546 if (node->data.break_expr.expr) { 6547 result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); 6548 if (result_value == irb->codegen->invalid_instruction) 6549 return irb->codegen->invalid_instruction; 6550 } else { 6551 result_value = ir_build_const_void(irb, break_scope, node); 6552 } 6553 6554 IrBasicBlock *dest_block = block_scope->end_block; 6555 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 6556 6557 block_scope->incoming_blocks->append(irb->current_basic_block); 6558 block_scope->incoming_values->append(result_value); 6559 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 6560 } 6561 6562 static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *node) { 6563 assert(node->type == NodeTypeBreak); 6564 6565 // Search up the scope. We'll find one of these things first: 6566 // * function definition scope or global scope => error, break outside loop 6567 // * defer expression scope => error, cannot break out of defer expression 6568 // * loop scope => OK 6569 // * (if it's a labeled break) labeled block => OK 6570 6571 Scope *search_scope = break_scope; 6572 ScopeLoop *loop_scope; 6573 for (;;) { 6574 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 6575 if (node->data.break_expr.name != nullptr) { 6576 add_node_error(irb->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name))); 6577 return irb->codegen->invalid_instruction; 6578 } else { 6579 add_node_error(irb->codegen, node, buf_sprintf("break expression outside loop")); 6580 return irb->codegen->invalid_instruction; 6581 } 6582 } else if (search_scope->id == ScopeIdDeferExpr) { 6583 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of defer expression")); 6584 return irb->codegen->invalid_instruction; 6585 } else if (search_scope->id == ScopeIdLoop) { 6586 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 6587 if (node->data.break_expr.name == nullptr || 6588 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name))) 6589 { 6590 loop_scope = this_loop_scope; 6591 break; 6592 } 6593 } else if (search_scope->id == ScopeIdBlock) { 6594 ScopeBlock *this_block_scope = (ScopeBlock *)search_scope; 6595 if (node->data.break_expr.name != nullptr && 6596 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name))) 6597 { 6598 assert(this_block_scope->end_block != nullptr); 6599 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope); 6600 } 6601 } else if (search_scope->id == ScopeIdSuspend) { 6602 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of suspend block")); 6603 return irb->codegen->invalid_instruction; 6604 } 6605 search_scope = search_scope->parent; 6606 } 6607 6608 IrInstruction *is_comptime; 6609 if (ir_should_inline(irb->exec, break_scope)) { 6610 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 6611 } else { 6612 is_comptime = loop_scope->is_comptime; 6613 } 6614 6615 IrInstruction *result_value; 6616 if (node->data.break_expr.expr) { 6617 result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); 6618 if (result_value == irb->codegen->invalid_instruction) 6619 return irb->codegen->invalid_instruction; 6620 } else { 6621 result_value = ir_build_const_void(irb, break_scope, node); 6622 } 6623 6624 IrBasicBlock *dest_block = loop_scope->break_block; 6625 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 6626 6627 loop_scope->incoming_blocks->append(irb->current_basic_block); 6628 loop_scope->incoming_values->append(result_value); 6629 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 6630 } 6631 6632 static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, AstNode *node) { 6633 assert(node->type == NodeTypeContinue); 6634 6635 // Search up the scope. We'll find one of these things first: 6636 // * function definition scope or global scope => error, break outside loop 6637 // * defer expression scope => error, cannot break out of defer expression 6638 // * loop scope => OK 6639 6640 ZigList<ScopeRuntime *> runtime_scopes = {}; 6641 6642 Scope *search_scope = continue_scope; 6643 ScopeLoop *loop_scope; 6644 for (;;) { 6645 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 6646 if (node->data.continue_expr.name != nullptr) { 6647 add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name))); 6648 return irb->codegen->invalid_instruction; 6649 } else { 6650 add_node_error(irb->codegen, node, buf_sprintf("continue expression outside loop")); 6651 return irb->codegen->invalid_instruction; 6652 } 6653 } else if (search_scope->id == ScopeIdDeferExpr) { 6654 add_node_error(irb->codegen, node, buf_sprintf("cannot continue out of defer expression")); 6655 return irb->codegen->invalid_instruction; 6656 } else if (search_scope->id == ScopeIdLoop) { 6657 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 6658 if (node->data.continue_expr.name == nullptr || 6659 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name))) 6660 { 6661 loop_scope = this_loop_scope; 6662 break; 6663 } 6664 } else if (search_scope->id == ScopeIdRuntime) { 6665 ScopeRuntime *scope_runtime = (ScopeRuntime *)search_scope; 6666 runtime_scopes.append(scope_runtime); 6667 } 6668 search_scope = search_scope->parent; 6669 } 6670 6671 IrInstruction *is_comptime; 6672 if (ir_should_inline(irb->exec, continue_scope)) { 6673 is_comptime = ir_build_const_bool(irb, continue_scope, node, true); 6674 } else { 6675 is_comptime = loop_scope->is_comptime; 6676 } 6677 6678 for (size_t i = 0; i < runtime_scopes.length; i += 1) { 6679 ScopeRuntime *scope_runtime = runtime_scopes.at(i); 6680 ir_mark_gen(ir_build_check_runtime_scope(irb, continue_scope, node, scope_runtime->is_comptime, is_comptime)); 6681 } 6682 6683 IrBasicBlock *dest_block = loop_scope->continue_block; 6684 ir_gen_defers_for_block(irb, continue_scope, dest_block->scope, false); 6685 return ir_mark_gen(ir_build_br(irb, continue_scope, node, dest_block, is_comptime)); 6686 } 6687 6688 static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) { 6689 assert(node->type == NodeTypeErrorType); 6690 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set); 6691 } 6692 6693 static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6694 assert(node->type == NodeTypeDefer); 6695 6696 ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope); 6697 node->data.defer.child_scope = &defer_child_scope->base; 6698 6699 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope); 6700 node->data.defer.expr_scope = &defer_expr_scope->base; 6701 6702 return ir_build_const_void(irb, parent_scope, node); 6703 } 6704 6705 static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) { 6706 assert(node->type == NodeTypeSliceExpr); 6707 6708 AstNodeSliceExpr *slice_expr = &node->data.slice_expr; 6709 AstNode *array_node = slice_expr->array_ref_expr; 6710 AstNode *start_node = slice_expr->start; 6711 AstNode *end_node = slice_expr->end; 6712 6713 IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr); 6714 if (ptr_value == irb->codegen->invalid_instruction) 6715 return irb->codegen->invalid_instruction; 6716 6717 IrInstruction *start_value = ir_gen_node(irb, start_node, scope); 6718 if (start_value == irb->codegen->invalid_instruction) 6719 return irb->codegen->invalid_instruction; 6720 6721 IrInstruction *end_value; 6722 if (end_node) { 6723 end_value = ir_gen_node(irb, end_node, scope); 6724 if (end_value == irb->codegen->invalid_instruction) 6725 return irb->codegen->invalid_instruction; 6726 } else { 6727 end_value = nullptr; 6728 } 6729 6730 return ir_build_slice(irb, scope, node, ptr_value, start_value, end_value, true); 6731 } 6732 6733 static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6734 assert(node->type == NodeTypeUnwrapErrorExpr); 6735 6736 AstNode *op1_node = node->data.unwrap_err_expr.op1; 6737 AstNode *op2_node = node->data.unwrap_err_expr.op2; 6738 AstNode *var_node = node->data.unwrap_err_expr.symbol; 6739 6740 if (op2_node->type == NodeTypeUnreachable) { 6741 if (var_node != nullptr) { 6742 assert(var_node->type == NodeTypeSymbol); 6743 Buf *var_name = var_node->data.symbol_expr.symbol; 6744 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); 6745 return irb->codegen->invalid_instruction; 6746 } 6747 return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, LValNone); 6748 } 6749 6750 6751 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); 6752 if (err_union_ptr == irb->codegen->invalid_instruction) 6753 return irb->codegen->invalid_instruction; 6754 6755 IrInstruction *err_union_val = ir_build_load_ptr(irb, parent_scope, node, err_union_ptr); 6756 IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_union_val); 6757 6758 IrInstruction *is_comptime; 6759 if (ir_should_inline(irb->exec, parent_scope)) { 6760 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 6761 } else { 6762 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_err); 6763 } 6764 6765 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); 6766 IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); 6767 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); 6768 ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); 6769 6770 ir_set_cursor_at_end_and_append_block(irb, err_block); 6771 Scope *err_scope; 6772 if (var_node) { 6773 assert(var_node->type == NodeTypeSymbol); 6774 Buf *var_name = var_node->data.symbol_expr.symbol; 6775 bool is_const = true; 6776 bool is_shadowable = false; 6777 ZigVar *var = ir_create_var(irb, node, parent_scope, var_name, 6778 is_const, is_const, is_shadowable, is_comptime); 6779 err_scope = var->child_scope; 6780 IrInstruction *err_val = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); 6781 ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, nullptr, err_val); 6782 } else { 6783 err_scope = parent_scope; 6784 } 6785 IrInstruction *err_result = ir_gen_node(irb, op2_node, err_scope); 6786 if (err_result == irb->codegen->invalid_instruction) 6787 return irb->codegen->invalid_instruction; 6788 IrBasicBlock *after_err_block = irb->current_basic_block; 6789 if (!instr_is_unreachable(err_result)) 6790 ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime)); 6791 6792 ir_set_cursor_at_end_and_append_block(irb, ok_block); 6793 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false); 6794 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 6795 IrBasicBlock *after_ok_block = irb->current_basic_block; 6796 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 6797 6798 ir_set_cursor_at_end_and_append_block(irb, end_block); 6799 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 6800 incoming_values[0] = err_result; 6801 incoming_values[1] = unwrapped_payload; 6802 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 6803 incoming_blocks[0] = after_err_block; 6804 incoming_blocks[1] = after_ok_block; 6805 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); 6806 } 6807 6808 static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { 6809 if (inner_scope == nullptr || inner_scope == outer_scope) return false; 6810 bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent); 6811 if (inner_scope->id != ScopeIdVarDecl) 6812 return need_comma; 6813 6814 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; 6815 if (need_comma) 6816 buf_append_char(name, ','); 6817 // TODO: const ptr reinterpret here to make the var type agree with the value? 6818 render_const_value(codegen, name, var_scope->var->const_value); 6819 return true; 6820 } 6821 6822 static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, 6823 Scope *scope, AstNode *source_node, Buf *out_bare_name) 6824 { 6825 if (exec->name) { 6826 ZigType *import = get_scope_import(scope); 6827 Buf *namespace_name = buf_create_from_buf(&import->name); 6828 if (buf_len(namespace_name) != 0) buf_append_char(namespace_name, NAMESPACE_SEP_CHAR); 6829 buf_append_buf(namespace_name, exec->name); 6830 buf_init_from_buf(out_bare_name, exec->name); 6831 return namespace_name; 6832 } else if (exec->name_fn != nullptr) { 6833 Buf *name = buf_alloc(); 6834 buf_append_buf(name, &exec->name_fn->symbol_name); 6835 buf_appendf(name, "("); 6836 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope); 6837 buf_appendf(name, ")"); 6838 buf_init_from_buf(out_bare_name, name); 6839 return name; 6840 } else { 6841 ZigType *import = get_scope_import(scope); 6842 Buf *namespace_name = buf_create_from_buf(&import->name); 6843 if (buf_len(namespace_name) != 0) buf_append_char(namespace_name, NAMESPACE_SEP_CHAR); 6844 buf_appendf(namespace_name, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, kind_name, 6845 source_node->line + 1, source_node->column + 1); 6846 buf_init_from_buf(out_bare_name, namespace_name); 6847 return namespace_name; 6848 } 6849 } 6850 6851 static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6852 assert(node->type == NodeTypeContainerDecl); 6853 6854 ContainerKind kind = node->data.container_decl.kind; 6855 Buf *bare_name = buf_alloc(); 6856 Buf *name = get_anon_type_name(irb->codegen, irb->exec, container_string(kind), parent_scope, node, bare_name); 6857 6858 ContainerLayout layout = node->data.container_decl.layout; 6859 ZigType *container_type = get_partial_container_type(irb->codegen, parent_scope, 6860 kind, node, buf_ptr(name), bare_name, layout); 6861 ScopeDecls *child_scope = get_container_scope(container_type); 6862 6863 for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) { 6864 AstNode *child_node = node->data.container_decl.decls.at(i); 6865 scan_decls(irb->codegen, child_scope, child_node); 6866 } 6867 6868 TldContainer *tld_container = allocate<TldContainer>(1); 6869 init_tld(&tld_container->base, TldIdContainer, bare_name, VisibModPub, node, parent_scope); 6870 tld_container->type_entry = container_type; 6871 tld_container->decls_scope = child_scope; 6872 irb->codegen->resolve_queue.append(&tld_container->base); 6873 6874 // Add this to the list to mark as invalid if analyzing this exec fails. 6875 irb->exec->tld_list.append(&tld_container->base); 6876 6877 return ir_build_const_type(irb, parent_scope, node, container_type); 6878 } 6879 6880 // errors should be populated with set1's values 6881 static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigType *set1, ZigType *set2) { 6882 assert(set1->id == ZigTypeIdErrorSet); 6883 assert(set2->id == ZigTypeIdErrorSet); 6884 6885 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 6886 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 6887 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 6888 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 6889 buf_resize(&err_set_type->name, 0); 6890 buf_appendf(&err_set_type->name, "error{"); 6891 6892 for (uint32_t i = 0, count = set1->data.error_set.err_count; i < count; i += 1) { 6893 assert(errors[set1->data.error_set.errors[i]->value] == set1->data.error_set.errors[i]); 6894 } 6895 6896 uint32_t count = set1->data.error_set.err_count; 6897 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 6898 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 6899 if (errors[error_entry->value] == nullptr) { 6900 count += 1; 6901 } 6902 } 6903 6904 err_set_type->data.error_set.err_count = count; 6905 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(count); 6906 6907 for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { 6908 ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; 6909 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 6910 err_set_type->data.error_set.errors[i] = error_entry; 6911 } 6912 6913 uint32_t index = set1->data.error_set.err_count; 6914 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 6915 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 6916 if (errors[error_entry->value] == nullptr) { 6917 errors[error_entry->value] = error_entry; 6918 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 6919 err_set_type->data.error_set.errors[index] = error_entry; 6920 index += 1; 6921 } 6922 } 6923 assert(index == count); 6924 assert(count != 0); 6925 6926 buf_appendf(&err_set_type->name, "}"); 6927 6928 return err_set_type; 6929 6930 } 6931 6932 static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstNode *node, 6933 ErrorTableEntry *err_entry) 6934 { 6935 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 6936 buf_resize(&err_set_type->name, 0); 6937 buf_appendf(&err_set_type->name, "error{%s}", buf_ptr(&err_entry->name)); 6938 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 6939 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 6940 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 6941 err_set_type->data.error_set.err_count = 1; 6942 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1); 6943 6944 err_set_type->data.error_set.errors[0] = err_entry; 6945 6946 return err_set_type; 6947 } 6948 6949 static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6950 assert(node->type == NodeTypeErrorSetDecl); 6951 6952 uint32_t err_count = node->data.err_set_decl.decls.length; 6953 6954 Buf bare_name = BUF_INIT; 6955 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", parent_scope, node, &bare_name); 6956 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 6957 buf_init_from_buf(&err_set_type->name, type_name); 6958 err_set_type->data.error_set.err_count = err_count; 6959 err_set_type->size_in_bits = irb->codegen->builtin_types.entry_global_error_set->size_in_bits; 6960 err_set_type->abi_align = irb->codegen->builtin_types.entry_global_error_set->abi_align; 6961 err_set_type->abi_size = irb->codegen->builtin_types.entry_global_error_set->abi_size; 6962 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(err_count); 6963 6964 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(irb->codegen->errors_by_index.length + err_count); 6965 6966 for (uint32_t i = 0; i < err_count; i += 1) { 6967 AstNode *symbol_node = node->data.err_set_decl.decls.at(i); 6968 assert(symbol_node->type == NodeTypeSymbol); 6969 Buf *err_name = symbol_node->data.symbol_expr.symbol; 6970 ErrorTableEntry *err = allocate<ErrorTableEntry>(1); 6971 err->decl_node = symbol_node; 6972 buf_init_from_buf(&err->name, err_name); 6973 6974 auto existing_entry = irb->codegen->error_table.put_unique(err_name, err); 6975 if (existing_entry) { 6976 err->value = existing_entry->value->value; 6977 } else { 6978 size_t error_value_count = irb->codegen->errors_by_index.length; 6979 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)irb->codegen->err_tag_type->data.integral.bit_count)); 6980 err->value = error_value_count; 6981 irb->codegen->errors_by_index.append(err); 6982 } 6983 err_set_type->data.error_set.errors[i] = err; 6984 6985 ErrorTableEntry *prev_err = errors[err->value]; 6986 if (prev_err != nullptr) { 6987 ErrorMsg *msg = add_node_error(irb->codegen, err->decl_node, buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name))); 6988 add_error_note(irb->codegen, msg, prev_err->decl_node, buf_sprintf("other error here")); 6989 return irb->codegen->invalid_instruction; 6990 } 6991 errors[err->value] = err; 6992 } 6993 free(errors); 6994 return ir_build_const_type(irb, parent_scope, node, err_set_type); 6995 } 6996 6997 static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6998 assert(node->type == NodeTypeFnProto); 6999 7000 size_t param_count = node->data.fn_proto.params.length; 7001 IrInstruction **param_types = allocate<IrInstruction*>(param_count); 7002 7003 bool is_var_args = false; 7004 for (size_t i = 0; i < param_count; i += 1) { 7005 AstNode *param_node = node->data.fn_proto.params.at(i); 7006 if (param_node->data.param_decl.is_var_args) { 7007 is_var_args = true; 7008 break; 7009 } 7010 if (param_node->data.param_decl.var_token == nullptr) { 7011 AstNode *type_node = param_node->data.param_decl.type; 7012 IrInstruction *type_value = ir_gen_node(irb, type_node, parent_scope); 7013 if (type_value == irb->codegen->invalid_instruction) 7014 return irb->codegen->invalid_instruction; 7015 param_types[i] = type_value; 7016 } else { 7017 param_types[i] = nullptr; 7018 } 7019 } 7020 7021 IrInstruction *align_value = nullptr; 7022 if (node->data.fn_proto.align_expr != nullptr) { 7023 align_value = ir_gen_node(irb, node->data.fn_proto.align_expr, parent_scope); 7024 if (align_value == irb->codegen->invalid_instruction) 7025 return irb->codegen->invalid_instruction; 7026 } 7027 7028 IrInstruction *return_type; 7029 if (node->data.fn_proto.return_var_token == nullptr) { 7030 if (node->data.fn_proto.return_type == nullptr) { 7031 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void); 7032 } else { 7033 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope); 7034 if (return_type == irb->codegen->invalid_instruction) 7035 return irb->codegen->invalid_instruction; 7036 } 7037 } else { 7038 add_node_error(irb->codegen, node, 7039 buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); 7040 return irb->codegen->invalid_instruction; 7041 //return_type = nullptr; 7042 } 7043 7044 IrInstruction *async_allocator_type_value = nullptr; 7045 if (node->data.fn_proto.async_allocator_type != nullptr) { 7046 async_allocator_type_value = ir_gen_node(irb, node->data.fn_proto.async_allocator_type, parent_scope); 7047 if (async_allocator_type_value == irb->codegen->invalid_instruction) 7048 return irb->codegen->invalid_instruction; 7049 } 7050 7051 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, 7052 async_allocator_type_value, is_var_args); 7053 } 7054 7055 static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode *node, 7056 IrInstruction *target_inst, bool cancel_non_suspended, bool cancel_awaited) 7057 { 7058 IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "CancelDone"); 7059 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); 7060 IrBasicBlock *pre_return_block = ir_create_basic_block(irb, scope, "PreReturn"); 7061 IrBasicBlock *post_return_block = ir_create_basic_block(irb, scope, "PostReturn"); 7062 IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel"); 7063 7064 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 7065 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 7066 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); 7067 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 7068 IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node, 7069 get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void)); 7070 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 7071 IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 7072 IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100 7073 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 7074 7075 // TODO relies on Zig not re-ordering fields 7076 IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst, 7077 false); 7078 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); 7079 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 7080 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 7081 atomic_state_field_name); 7082 7083 // set the is_canceled bit 7084 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 7085 usize_type_val, atomic_state_ptr, nullptr, is_canceled_mask, nullptr, 7086 AtomicRmwOp_or, AtomicOrderSeqCst); 7087 7088 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 7089 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 7090 ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime); 7091 7092 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 7093 IrInstruction *awaiter_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 7094 IrInstruction *is_returned_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, awaiter_addr, ptr_mask, false); 7095 ir_build_cond_br(irb, scope, node, is_returned_bool, post_return_block, pre_return_block, is_comptime); 7096 7097 ir_set_cursor_at_end_and_append_block(irb, post_return_block); 7098 if (cancel_awaited) { 7099 ir_build_br(irb, scope, node, do_cancel_block, is_comptime); 7100 } else { 7101 IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false); 7102 IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false); 7103 ir_build_cond_br(irb, scope, node, is_awaited_bool, done_block, do_cancel_block, is_comptime); 7104 } 7105 7106 ir_set_cursor_at_end_and_append_block(irb, pre_return_block); 7107 if (cancel_awaited) { 7108 if (cancel_non_suspended) { 7109 ir_build_br(irb, scope, node, do_cancel_block, is_comptime); 7110 } else { 7111 IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 7112 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 7113 ir_build_cond_br(irb, scope, node, is_suspended_bool, do_cancel_block, done_block, is_comptime); 7114 } 7115 } else { 7116 ir_build_br(irb, scope, node, done_block, is_comptime); 7117 } 7118 7119 ir_set_cursor_at_end_and_append_block(irb, do_cancel_block); 7120 ir_build_cancel(irb, scope, node, target_inst); 7121 ir_build_br(irb, scope, node, done_block, is_comptime); 7122 7123 ir_set_cursor_at_end_and_append_block(irb, done_block); 7124 return ir_build_const_void(irb, scope, node); 7125 } 7126 7127 static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *scope, AstNode *node) { 7128 assert(node->type == NodeTypeCancel); 7129 7130 IrInstruction *target_inst = ir_gen_node(irb, node->data.cancel_expr.expr, scope); 7131 if (target_inst == irb->codegen->invalid_instruction) 7132 return irb->codegen->invalid_instruction; 7133 7134 return ir_gen_cancel_target(irb, scope, node, target_inst, false, true); 7135 } 7136 7137 static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode *node, 7138 IrInstruction *target_inst) 7139 { 7140 IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "ResumeDone"); 7141 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); 7142 IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "IsSuspended"); 7143 IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "IsNotSuspended"); 7144 7145 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 7146 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 7147 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 7148 IrInstruction *and_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, is_suspended_mask); 7149 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); 7150 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 7151 IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node, 7152 get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void)); 7153 7154 // TODO relies on Zig not re-ordering fields 7155 IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst, 7156 false); 7157 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); 7158 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 7159 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 7160 atomic_state_field_name); 7161 7162 // clear the is_suspended bit 7163 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 7164 usize_type_val, atomic_state_ptr, nullptr, and_mask, nullptr, 7165 AtomicRmwOp_and, AtomicOrderSeqCst); 7166 7167 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 7168 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 7169 ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime); 7170 7171 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 7172 IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 7173 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 7174 ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime); 7175 7176 ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); 7177 ir_build_unreachable(irb, scope, node); 7178 7179 ir_set_cursor_at_end_and_append_block(irb, suspended_block); 7180 ir_build_coro_resume(irb, scope, node, target_inst); 7181 ir_build_br(irb, scope, node, done_block, is_comptime); 7182 7183 ir_set_cursor_at_end_and_append_block(irb, done_block); 7184 return ir_build_const_void(irb, scope, node); 7185 } 7186 7187 static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) { 7188 assert(node->type == NodeTypeResume); 7189 7190 IrInstruction *target_inst = ir_gen_node(irb, node->data.resume_expr.expr, scope); 7191 if (target_inst == irb->codegen->invalid_instruction) 7192 return irb->codegen->invalid_instruction; 7193 7194 return ir_gen_resume_target(irb, scope, node, target_inst); 7195 } 7196 7197 static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 7198 assert(node->type == NodeTypeAwaitExpr); 7199 7200 IrInstruction *target_inst = ir_gen_node(irb, node->data.await_expr.expr, scope); 7201 if (target_inst == irb->codegen->invalid_instruction) 7202 return irb->codegen->invalid_instruction; 7203 7204 ZigFn *fn_entry = exec_fn_entry(irb->exec); 7205 if (!fn_entry) { 7206 add_node_error(irb->codegen, node, buf_sprintf("await outside function definition")); 7207 return irb->codegen->invalid_instruction; 7208 } 7209 if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) { 7210 add_node_error(irb->codegen, node, buf_sprintf("await in non-async function")); 7211 return irb->codegen->invalid_instruction; 7212 } 7213 7214 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); 7215 if (scope_defer_expr) { 7216 if (!scope_defer_expr->reported_err) { 7217 add_node_error(irb->codegen, node, buf_sprintf("cannot await inside defer expression")); 7218 scope_defer_expr->reported_err = true; 7219 } 7220 return irb->codegen->invalid_instruction; 7221 } 7222 7223 Scope *outer_scope = irb->exec->begin_scope; 7224 7225 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst); 7226 Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); 7227 IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); 7228 7229 if (irb->codegen->have_err_ret_tracing) { 7230 IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); 7231 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); 7232 IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); 7233 ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr); 7234 } 7235 7236 IrBasicBlock *already_awaited_block = ir_create_basic_block(irb, scope, "AlreadyAwaited"); 7237 IrBasicBlock *not_awaited_block = ir_create_basic_block(irb, scope, "NotAwaited"); 7238 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); 7239 IrBasicBlock *yes_suspend_block = ir_create_basic_block(irb, scope, "YesSuspend"); 7240 IrBasicBlock *no_suspend_block = ir_create_basic_block(irb, scope, "NoSuspend"); 7241 IrBasicBlock *merge_block = ir_create_basic_block(irb, scope, "MergeSuspend"); 7242 IrBasicBlock *cleanup_block = ir_create_basic_block(irb, scope, "SuspendCleanup"); 7243 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "SuspendResume"); 7244 IrBasicBlock *cancel_target_block = ir_create_basic_block(irb, scope, "CancelTarget"); 7245 IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel"); 7246 IrBasicBlock *do_defers_block = ir_create_basic_block(irb, scope, "DoDefers"); 7247 IrBasicBlock *destroy_block = ir_create_basic_block(irb, scope, "DestroyBlock"); 7248 IrBasicBlock *my_suspended_block = ir_create_basic_block(irb, scope, "AlreadySuspended"); 7249 IrBasicBlock *my_not_suspended_block = ir_create_basic_block(irb, scope, "NotAlreadySuspended"); 7250 IrBasicBlock *do_suspend_block = ir_create_basic_block(irb, scope, "DoSuspend"); 7251 7252 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 7253 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 7254 atomic_state_field_name); 7255 7256 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); 7257 IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false); 7258 IrInstruction *undefined_value = ir_build_const_undefined(irb, scope, node); 7259 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 7260 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 7261 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 7262 IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 7263 IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100 7264 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 7265 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 7266 7267 ZigVar *result_var = ir_create_var(irb, node, scope, nullptr, 7268 false, false, true, const_bool_false); 7269 IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst); 7270 IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type); 7271 ir_build_await_bookkeeping(irb, scope, node, promise_result_type); 7272 ir_build_var_decl_src(irb, scope, node, result_var, promise_result_type, nullptr, undefined_value); 7273 IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var); 7274 ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr); 7275 IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle); 7276 7277 IrInstruction *coro_handle_addr = ir_build_ptr_to_int(irb, scope, node, irb->exec->coro_handle); 7278 IrInstruction *mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, coro_handle_addr, await_mask, false); 7279 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 7280 usize_type_val, atomic_state_ptr, nullptr, mask_bits, nullptr, 7281 AtomicRmwOp_or, AtomicOrderSeqCst); 7282 7283 IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false); 7284 IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false); 7285 ir_build_cond_br(irb, scope, node, is_awaited_bool, already_awaited_block, not_awaited_block, const_bool_false); 7286 7287 ir_set_cursor_at_end_and_append_block(irb, already_awaited_block); 7288 ir_build_unreachable(irb, scope, node); 7289 7290 ir_set_cursor_at_end_and_append_block(irb, not_awaited_block); 7291 IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 7292 IrInstruction *is_non_null = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); 7293 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 7294 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 7295 ir_build_cond_br(irb, scope, node, is_canceled_bool, cancel_target_block, not_canceled_block, const_bool_false); 7296 7297 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 7298 ir_build_cond_br(irb, scope, node, is_non_null, no_suspend_block, yes_suspend_block, const_bool_false); 7299 7300 ir_set_cursor_at_end_and_append_block(irb, cancel_target_block); 7301 ir_build_cancel(irb, scope, node, target_inst); 7302 ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false)); 7303 7304 ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); 7305 if (irb->codegen->have_err_ret_tracing) { 7306 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); 7307 IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); 7308 IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); 7309 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); 7310 } 7311 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); 7312 IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); 7313 // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to, 7314 // because we're about to destroy the memory. So we store it into our result variable. 7315 IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr); 7316 ir_build_store_ptr(irb, scope, node, my_result_var_ptr, no_suspend_result); 7317 ir_build_cancel(irb, scope, node, target_inst); 7318 ir_build_br(irb, scope, node, merge_block, const_bool_false); 7319 7320 7321 ir_set_cursor_at_end_and_append_block(irb, yes_suspend_block); 7322 IrInstruction *my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 7323 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr, 7324 AtomicRmwOp_or, AtomicOrderSeqCst); 7325 IrInstruction *my_is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_suspended_mask, false); 7326 IrInstruction *my_is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_suspended_value, zero, false); 7327 ir_build_cond_br(irb, scope, node, my_is_suspended_bool, my_suspended_block, my_not_suspended_block, const_bool_false); 7328 7329 ir_set_cursor_at_end_and_append_block(irb, my_suspended_block); 7330 ir_build_unreachable(irb, scope, node); 7331 7332 ir_set_cursor_at_end_and_append_block(irb, my_not_suspended_block); 7333 IrInstruction *my_is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_canceled_mask, false); 7334 IrInstruction *my_is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_canceled_value, zero, false); 7335 ir_build_cond_br(irb, scope, node, my_is_canceled_bool, cleanup_block, do_suspend_block, const_bool_false); 7336 7337 ir_set_cursor_at_end_and_append_block(irb, do_suspend_block); 7338 IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, save_token, const_bool_false); 7339 7340 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); 7341 cases[0].value = ir_build_const_u8(irb, scope, node, 0); 7342 cases[0].block = resume_block; 7343 cases[1].value = ir_build_const_u8(irb, scope, node, 1); 7344 cases[1].block = destroy_block; 7345 ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 7346 2, cases, const_bool_false, nullptr); 7347 7348 ir_set_cursor_at_end_and_append_block(irb, destroy_block); 7349 ir_gen_cancel_target(irb, scope, node, target_inst, false, true); 7350 ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false)); 7351 7352 ir_set_cursor_at_end_and_append_block(irb, cleanup_block); 7353 IrInstruction *my_mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, ptr_mask, is_canceled_mask, false); 7354 IrInstruction *b_my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 7355 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, my_mask_bits, nullptr, 7356 AtomicRmwOp_or, AtomicOrderSeqCst); 7357 IrInstruction *my_await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, b_my_prev_atomic_value, ptr_mask, false); 7358 IrInstruction *dont_have_my_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, my_await_handle_addr, zero, false); 7359 IrInstruction *dont_destroy_ourselves = ir_build_bin_op(irb, scope, node, IrBinOpBoolAnd, dont_have_my_await_handle, is_canceled_bool, false); 7360 ir_build_cond_br(irb, scope, node, dont_have_my_await_handle, do_defers_block, do_cancel_block, const_bool_false); 7361 7362 ir_set_cursor_at_end_and_append_block(irb, do_cancel_block); 7363 IrInstruction *my_await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, my_await_handle_addr); 7364 ir_gen_cancel_target(irb, scope, node, my_await_handle, true, false); 7365 ir_mark_gen(ir_build_br(irb, scope, node, do_defers_block, const_bool_false)); 7366 7367 ir_set_cursor_at_end_and_append_block(irb, do_defers_block); 7368 ir_gen_defers_for_block(irb, scope, outer_scope, true); 7369 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)); 7370 7371 ir_set_cursor_at_end_and_append_block(irb, resume_block); 7372 ir_build_br(irb, scope, node, merge_block, const_bool_false); 7373 7374 ir_set_cursor_at_end_and_append_block(irb, merge_block); 7375 return ir_build_load_ptr(irb, scope, node, my_result_var_ptr); 7376 } 7377 7378 static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 7379 assert(node->type == NodeTypeSuspend); 7380 7381 ZigFn *fn_entry = exec_fn_entry(irb->exec); 7382 if (!fn_entry) { 7383 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition")); 7384 return irb->codegen->invalid_instruction; 7385 } 7386 if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) { 7387 add_node_error(irb->codegen, node, buf_sprintf("suspend in non-async function")); 7388 return irb->codegen->invalid_instruction; 7389 } 7390 7391 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(parent_scope); 7392 if (scope_defer_expr) { 7393 if (!scope_defer_expr->reported_err) { 7394 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside defer expression")); 7395 add_error_note(irb->codegen, msg, scope_defer_expr->base.source_node, buf_sprintf("defer here")); 7396 scope_defer_expr->reported_err = true; 7397 } 7398 return irb->codegen->invalid_instruction; 7399 } 7400 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope); 7401 if (existing_suspend_scope) { 7402 if (!existing_suspend_scope->reported_err) { 7403 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block")); 7404 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here")); 7405 existing_suspend_scope->reported_err = true; 7406 } 7407 return irb->codegen->invalid_instruction; 7408 } 7409 7410 Scope *outer_scope = irb->exec->begin_scope; 7411 7412 IrBasicBlock *cleanup_block = ir_create_basic_block(irb, parent_scope, "SuspendCleanup"); 7413 IrBasicBlock *resume_block = ir_create_basic_block(irb, parent_scope, "SuspendResume"); 7414 IrBasicBlock *suspended_block = ir_create_basic_block(irb, parent_scope, "AlreadySuspended"); 7415 IrBasicBlock *canceled_block = ir_create_basic_block(irb, parent_scope, "IsCanceled"); 7416 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, parent_scope, "NotCanceled"); 7417 IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, parent_scope, "NotAlreadySuspended"); 7418 IrBasicBlock *cancel_awaiter_block = ir_create_basic_block(irb, parent_scope, "CancelAwaiter"); 7419 7420 IrInstruction *promise_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_promise); 7421 IrInstruction *const_bool_true = ir_build_const_bool(irb, parent_scope, node, true); 7422 IrInstruction *const_bool_false = ir_build_const_bool(irb, parent_scope, node, false); 7423 IrInstruction *usize_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_usize); 7424 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, parent_scope, node, 0x1); // 0b001 7425 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, parent_scope, node, 0x2); // 0b010 7426 IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0); 7427 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, parent_scope, node, 0x7); // 0b111 7428 IrInstruction *ptr_mask = ir_build_un_op(irb, parent_scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 7429 7430 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, parent_scope, node, 7431 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr, 7432 AtomicRmwOp_or, AtomicOrderSeqCst); 7433 7434 IrInstruction *is_canceled_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 7435 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 7436 ir_build_cond_br(irb, parent_scope, node, is_canceled_bool, canceled_block, not_canceled_block, const_bool_false); 7437 7438 ir_set_cursor_at_end_and_append_block(irb, canceled_block); 7439 IrInstruction *await_handle_addr = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 7440 IrInstruction *have_await_handle = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); 7441 IrBasicBlock *post_canceled_block = irb->current_basic_block; 7442 ir_build_cond_br(irb, parent_scope, node, have_await_handle, cancel_awaiter_block, cleanup_block, const_bool_false); 7443 7444 ir_set_cursor_at_end_and_append_block(irb, cancel_awaiter_block); 7445 IrInstruction *await_handle = ir_build_int_to_ptr(irb, parent_scope, node, promise_type_val, await_handle_addr); 7446 ir_gen_cancel_target(irb, parent_scope, node, await_handle, true, false); 7447 IrBasicBlock *post_cancel_awaiter_block = irb->current_basic_block; 7448 ir_build_br(irb, parent_scope, node, cleanup_block, const_bool_false); 7449 7450 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 7451 IrInstruction *is_suspended_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 7452 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 7453 ir_build_cond_br(irb, parent_scope, node, is_suspended_bool, suspended_block, not_suspended_block, const_bool_false); 7454 7455 ir_set_cursor_at_end_and_append_block(irb, suspended_block); 7456 ir_build_unreachable(irb, parent_scope, node); 7457 7458 ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); 7459 IrInstruction *suspend_code; 7460 if (node->data.suspend.block == nullptr) { 7461 suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false); 7462 } else { 7463 Scope *child_scope; 7464 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); 7465 suspend_scope->resume_block = resume_block; 7466 child_scope = &suspend_scope->base; 7467 IrInstruction *save_token = ir_build_coro_save(irb, child_scope, node, irb->exec->coro_handle); 7468 ir_gen_node(irb, node->data.suspend.block, child_scope); 7469 suspend_code = ir_mark_gen(ir_build_coro_suspend(irb, parent_scope, node, save_token, const_bool_false)); 7470 } 7471 7472 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); 7473 cases[0].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 0)); 7474 cases[0].block = resume_block; 7475 cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1)); 7476 cases[1].block = canceled_block; 7477 ir_mark_gen(ir_build_switch_br(irb, parent_scope, node, suspend_code, irb->exec->coro_suspend_block, 7478 2, cases, const_bool_false, nullptr)); 7479 7480 ir_set_cursor_at_end_and_append_block(irb, cleanup_block); 7481 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 7482 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 7483 incoming_blocks[0] = post_canceled_block; 7484 incoming_values[0] = const_bool_true; 7485 incoming_blocks[1] = post_cancel_awaiter_block; 7486 incoming_values[1] = const_bool_false; 7487 IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); 7488 ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); 7489 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)); 7490 7491 ir_set_cursor_at_end_and_append_block(irb, resume_block); 7492 return ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); 7493 } 7494 7495 static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, 7496 LVal lval) 7497 { 7498 assert(scope); 7499 switch (node->type) { 7500 case NodeTypeStructValueField: 7501 case NodeTypeParamDecl: 7502 case NodeTypeUse: 7503 case NodeTypeSwitchProng: 7504 case NodeTypeSwitchRange: 7505 case NodeTypeStructField: 7506 case NodeTypeFnDef: 7507 case NodeTypeTestDecl: 7508 zig_unreachable(); 7509 case NodeTypeBlock: 7510 return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); 7511 case NodeTypeGroupedExpr: 7512 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval); 7513 case NodeTypeBinOpExpr: 7514 return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval); 7515 case NodeTypeIntLiteral: 7516 return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval); 7517 case NodeTypeFloatLiteral: 7518 return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval); 7519 case NodeTypeCharLiteral: 7520 return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval); 7521 case NodeTypeSymbol: 7522 return ir_gen_symbol(irb, scope, node, lval); 7523 case NodeTypeFnCallExpr: 7524 return ir_gen_fn_call(irb, scope, node, lval); 7525 case NodeTypeIfBoolExpr: 7526 return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval); 7527 case NodeTypePrefixOpExpr: 7528 return ir_gen_prefix_op_expr(irb, scope, node, lval); 7529 case NodeTypeContainerInitExpr: 7530 return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval); 7531 case NodeTypeVariableDeclaration: 7532 return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval); 7533 case NodeTypeWhileExpr: 7534 return ir_lval_wrap(irb, scope, ir_gen_while_expr(irb, scope, node), lval); 7535 case NodeTypeForExpr: 7536 return ir_lval_wrap(irb, scope, ir_gen_for_expr(irb, scope, node), lval); 7537 case NodeTypeArrayAccessExpr: 7538 return ir_gen_array_access(irb, scope, node, lval); 7539 case NodeTypeReturnExpr: 7540 return ir_gen_return(irb, scope, node, lval); 7541 case NodeTypeFieldAccessExpr: 7542 { 7543 IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); 7544 if (ptr_instruction == irb->codegen->invalid_instruction) 7545 return ptr_instruction; 7546 if (lval == LValPtr) 7547 return ptr_instruction; 7548 7549 return ir_build_load_ptr(irb, scope, node, ptr_instruction); 7550 } 7551 case NodeTypePtrDeref: { 7552 AstNode *expr_node = node->data.ptr_deref_expr.target; 7553 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); 7554 if (value == irb->codegen->invalid_instruction) 7555 return value; 7556 7557 // We essentially just converted any lvalue from &(x.*) to (&x).*; 7558 // this inhibits checking that x is a pointer later, so we directly 7559 // record whether the pointer check is needed 7560 return ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval); 7561 } 7562 case NodeTypeUnwrapOptional: { 7563 AstNode *expr_node = node->data.unwrap_optional.expr; 7564 7565 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 7566 if (maybe_ptr == irb->codegen->invalid_instruction) 7567 return irb->codegen->invalid_instruction; 7568 7569 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true); 7570 if (lval == LValPtr) 7571 return unwrapped_ptr; 7572 7573 return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); 7574 } 7575 case NodeTypeBoolLiteral: 7576 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval); 7577 case NodeTypeArrayType: 7578 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval); 7579 case NodeTypePointerType: 7580 return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval); 7581 case NodeTypePromiseType: 7582 return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval); 7583 case NodeTypeStringLiteral: 7584 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval); 7585 case NodeTypeUndefinedLiteral: 7586 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval); 7587 case NodeTypeAsmExpr: 7588 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval); 7589 case NodeTypeNullLiteral: 7590 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); 7591 case NodeTypeIfErrorExpr: 7592 return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval); 7593 case NodeTypeIfOptional: 7594 return ir_lval_wrap(irb, scope, ir_gen_if_optional_expr(irb, scope, node), lval); 7595 case NodeTypeSwitchExpr: 7596 return ir_lval_wrap(irb, scope, ir_gen_switch_expr(irb, scope, node), lval); 7597 case NodeTypeCompTime: 7598 return ir_gen_comptime(irb, scope, node, lval); 7599 case NodeTypeErrorType: 7600 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval); 7601 case NodeTypeBreak: 7602 return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval); 7603 case NodeTypeContinue: 7604 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval); 7605 case NodeTypeUnreachable: 7606 return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval); 7607 case NodeTypeDefer: 7608 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval); 7609 case NodeTypeSliceExpr: 7610 return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval); 7611 case NodeTypeUnwrapErrorExpr: 7612 return ir_lval_wrap(irb, scope, ir_gen_catch(irb, scope, node), lval); 7613 case NodeTypeContainerDecl: 7614 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval); 7615 case NodeTypeFnProto: 7616 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval); 7617 case NodeTypeErrorSetDecl: 7618 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval); 7619 case NodeTypeCancel: 7620 return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval); 7621 case NodeTypeResume: 7622 return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval); 7623 case NodeTypeAwaitExpr: 7624 return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval); 7625 case NodeTypeSuspend: 7626 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval); 7627 case NodeTypeEnumLiteral: 7628 return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval); 7629 } 7630 zig_unreachable(); 7631 } 7632 7633 static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) { 7634 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval); 7635 irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); 7636 return result; 7637 } 7638 7639 static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { 7640 return ir_gen_node_extra(irb, node, scope, LValNone); 7641 } 7642 7643 static void invalidate_exec(IrExecutable *exec) { 7644 if (exec->invalid) 7645 return; 7646 7647 exec->invalid = true; 7648 7649 for (size_t i = 0; i < exec->tld_list.length; i += 1) { 7650 exec->tld_list.items[i]->resolution = TldResolutionInvalid; 7651 } 7652 7653 if (exec->source_exec != nullptr) 7654 invalidate_exec(exec->source_exec); 7655 } 7656 7657 7658 bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) { 7659 assert(node->owner); 7660 7661 IrBuilder ir_builder = {0}; 7662 IrBuilder *irb = &ir_builder; 7663 7664 irb->codegen = codegen; 7665 irb->exec = ir_executable; 7666 7667 IrBasicBlock *entry_block = ir_create_basic_block(irb, scope, "Entry"); 7668 ir_set_cursor_at_end_and_append_block(irb, entry_block); 7669 // Entry block gets a reference because we enter it to begin. 7670 ir_ref_bb(irb->current_basic_block); 7671 7672 ZigFn *fn_entry = exec_fn_entry(irb->exec); 7673 7674 bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; 7675 IrInstruction *coro_id; 7676 IrInstruction *u8_ptr_type; 7677 IrInstruction *const_bool_false; 7678 IrInstruction *coro_promise_ptr; 7679 IrInstruction *err_ret_trace_ptr; 7680 ZigType *return_type; 7681 Buf *result_ptr_field_name; 7682 ZigVar *coro_size_var; 7683 if (is_async) { 7684 // create the coro promise 7685 Scope *coro_scope = create_coro_prelude_scope(irb->codegen, node, scope); 7686 const_bool_false = ir_build_const_bool(irb, coro_scope, node, false); 7687 ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); 7688 7689 return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; 7690 IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); 7691 ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type); 7692 IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type); 7693 // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa 7694 ir_build_var_decl_src(irb, coro_scope, node, promise_var, coro_frame_type_value, nullptr, undef); 7695 coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var); 7696 7697 ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); 7698 IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); 7699 IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node, 7700 get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); 7701 ir_build_var_decl_src(irb, coro_scope, node, await_handle_var, await_handle_type_val, nullptr, null_value); 7702 irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var); 7703 7704 u8_ptr_type = ir_build_const_type(irb, coro_scope, node, 7705 get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false)); 7706 IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type, 7707 coro_promise_ptr, false); 7708 coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr); 7709 coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); 7710 IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node); 7711 ir_build_var_decl_src(irb, coro_scope, node, coro_size_var, nullptr, nullptr, coro_size); 7712 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node, 7713 ImplicitAllocatorIdArg); 7714 irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false); 7715 ir_build_var_decl_src(irb, coro_scope, node, irb->exec->coro_allocator_var, nullptr, nullptr, implicit_allocator_ptr); 7716 Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); 7717 IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name); 7718 IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr); 7719 IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size); 7720 IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr); 7721 IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, coro_scope, "AllocError"); 7722 IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, coro_scope, "AllocOk"); 7723 ir_build_cond_br(irb, coro_scope, node, alloc_result_is_ok, alloc_ok_block, alloc_err_block, const_bool_false); 7724 7725 ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); 7726 // we can return undefined here, because the caller passes a pointer to the error struct field 7727 // in the error union result, and we populate it in case of allocation failure. 7728 ir_build_return(irb, coro_scope, node, undef); 7729 7730 ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); 7731 IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type, maybe_coro_mem_ptr, 7732 false); 7733 irb->exec->coro_handle = ir_build_coro_begin(irb, coro_scope, node, coro_id, coro_mem_ptr); 7734 7735 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 7736 irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 7737 atomic_state_field_name); 7738 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 7739 ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero); 7740 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); 7741 irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); 7742 result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); 7743 irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); 7744 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); 7745 if (irb->codegen->have_err_ret_tracing) { 7746 // initialize the error return trace 7747 Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME); 7748 IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name); 7749 7750 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); 7751 err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); 7752 ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr); 7753 7754 // coordinate with builtin.zig 7755 Buf *index_name = buf_create_from_str("index"); 7756 IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name); 7757 ir_build_store_ptr(irb, scope, node, index_ptr, zero); 7758 7759 Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); 7760 IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name); 7761 7762 IrInstruction *slice_value = ir_build_slice(irb, scope, node, return_addresses_ptr, zero, nullptr, false); 7763 ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value); 7764 } 7765 7766 7767 irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal"); 7768 irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal"); 7769 irb->exec->coro_suspend_block = ir_create_basic_block(irb, scope, "Suspend"); 7770 irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup"); 7771 } 7772 7773 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone); 7774 assert(result); 7775 if (irb->exec->invalid) 7776 return false; 7777 7778 if (!instr_is_unreachable(result)) { 7779 // no need for save_err_ret_addr because this cannot return error 7780 ir_gen_async_return(irb, scope, result->source_node, result, true); 7781 } 7782 7783 if (is_async) { 7784 IrBasicBlock *invalid_resume_block = ir_create_basic_block(irb, scope, "InvalidResume"); 7785 IrBasicBlock *check_free_block = ir_create_basic_block(irb, scope, "CheckFree"); 7786 7787 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_early_final); 7788 IrInstruction *const_bool_true = ir_build_const_bool(irb, scope, node, true); 7789 IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, nullptr, const_bool_true); 7790 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); 7791 cases[0].value = ir_build_const_u8(irb, scope, node, 0); 7792 cases[0].block = invalid_resume_block; 7793 cases[1].value = ir_build_const_u8(irb, scope, node, 1); 7794 cases[1].block = irb->exec->coro_final_cleanup_block; 7795 ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr); 7796 7797 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_suspend_block); 7798 ir_build_coro_end(irb, scope, node); 7799 ir_build_return(irb, scope, node, irb->exec->coro_handle); 7800 7801 ir_set_cursor_at_end_and_append_block(irb, invalid_resume_block); 7802 ir_build_unreachable(irb, scope, node); 7803 7804 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_normal_final); 7805 if (type_has_bits(return_type)) { 7806 IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node, 7807 get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8, 7808 false, false, PtrLenUnknown, 0, 0, 0, false)); 7809 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr); 7810 IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len, 7811 result_ptr, false); 7812 IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node, 7813 u8_ptr_type_unknown_len, irb->exec->coro_result_field_ptr, false); 7814 IrInstruction *return_type_inst = ir_build_const_type(irb, scope, node, 7815 fn_entry->type_entry->data.fn.fn_type_id.return_type); 7816 IrInstruction *size_of_ret_val = ir_build_size_of(irb, scope, node, return_type_inst); 7817 ir_build_memcpy(irb, scope, node, result_ptr_as_u8_ptr, return_value_ptr_as_u8_ptr, size_of_ret_val); 7818 } 7819 if (irb->codegen->have_err_ret_tracing) { 7820 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); 7821 IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); 7822 IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr); 7823 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr); 7824 } 7825 // Before we destroy the coroutine frame, we need to load the target promise into 7826 // a register or local variable which does not get spilled into the frame, 7827 // otherwise llvm tries to access memory inside the destroyed frame. 7828 IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, 7829 irb->exec->await_handle_var_ptr, false); 7830 IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); 7831 ir_build_br(irb, scope, node, check_free_block, const_bool_false); 7832 7833 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_final_cleanup_block); 7834 ir_build_br(irb, scope, node, check_free_block, const_bool_false); 7835 7836 ir_set_cursor_at_end_and_append_block(irb, check_free_block); 7837 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 7838 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 7839 incoming_blocks[0] = irb->exec->coro_final_cleanup_block; 7840 incoming_values[0] = const_bool_false; 7841 incoming_blocks[1] = irb->exec->coro_normal_final; 7842 incoming_values[1] = const_bool_true; 7843 IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 7844 7845 IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); 7846 IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); 7847 merge_incoming_blocks[0] = irb->exec->coro_final_cleanup_block; 7848 merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); 7849 merge_incoming_blocks[1] = irb->exec->coro_normal_final; 7850 merge_incoming_values[1] = await_handle_in_block; 7851 IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values); 7852 7853 Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME); 7854 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, 7855 ImplicitAllocatorIdLocalVar); 7856 IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name); 7857 IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr); 7858 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 7859 IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); 7860 IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node, 7861 get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8, 7862 false, false, PtrLenUnknown, 0, 0, 0, false)); 7863 IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len, 7864 coro_mem_ptr_maybe, false); 7865 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false); 7866 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var); 7867 IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr); 7868 IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false); 7869 size_t arg_count = 5; 7870 IrInstruction **args = allocate<IrInstruction *>(arg_count); 7871 args[0] = implicit_allocator_ptr; // self 7872 args[1] = mem_slice; // old_mem 7873 args[2] = ir_build_const_usize(irb, scope, node, 8); // old_align 7874 // TODO: intentional memory leak here. If this is set to 0 then there is an issue where a coroutine 7875 // calls the function and it frees its own stack frame, but then the return value is a slice, which 7876 // is implemented as an sret struct. writing to the return pointer causes invalid memory write. 7877 // We could work around it by having a global helper function which has a void return type 7878 // and calling that instead. But instead this hack will suffice until I rework coroutines to be 7879 // non-allocating. Basically coroutines are not supported right now until they are reworked. 7880 args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size 7881 args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align 7882 ir_build_call(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr); 7883 7884 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); 7885 ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false); 7886 7887 ir_set_cursor_at_end_and_append_block(irb, resume_block); 7888 ir_gen_resume_target(irb, scope, node, awaiter_handle); 7889 ir_build_br(irb, scope, node, irb->exec->coro_suspend_block, const_bool_false); 7890 } 7891 7892 return true; 7893 } 7894 7895 bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { 7896 assert(fn_entry); 7897 7898 IrExecutable *ir_executable = &fn_entry->ir_executable; 7899 AstNode *body_node = fn_entry->body_node; 7900 7901 assert(fn_entry->child_scope); 7902 7903 return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); 7904 } 7905 7906 static void add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) { 7907 if (!exec || !exec->source_node || limit < 0) return; 7908 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); 7909 7910 add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1); 7911 } 7912 7913 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) { 7914 invalidate_exec(exec); 7915 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); 7916 if (exec->parent_exec) { 7917 add_call_stack_errors(codegen, exec, err_msg, 10); 7918 } 7919 return err_msg; 7920 } 7921 7922 static ErrorMsg *ir_add_error_node(IrAnalyze *ira, AstNode *source_node, Buf *msg) { 7923 return exec_add_error_node(ira->codegen, ira->new_irb.exec, source_node, msg); 7924 } 7925 7926 static ErrorMsg *opt_ir_add_error_node(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, Buf *msg) { 7927 if (ira != nullptr) 7928 return exec_add_error_node(codegen, ira->new_irb.exec, source_node, msg); 7929 else 7930 return add_node_error(codegen, source_node, msg); 7931 } 7932 7933 static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction, Buf *msg) { 7934 return ir_add_error_node(ira, source_instruction->source_node, msg); 7935 } 7936 7937 static void ir_assert(bool ok, IrInstruction *source_instruction) { 7938 if (ok) return; 7939 src_assert(ok, source_instruction->source_node); 7940 } 7941 7942 // This function takes a comptime ptr and makes the child const value conform to the type 7943 // described by the pointer. 7944 static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 7945 ConstExprValue *ptr_val) 7946 { 7947 Error err; 7948 assert(ptr_val->type->id == ZigTypeIdPointer); 7949 ConstExprValue tmp = {}; 7950 tmp.special = ConstValSpecialStatic; 7951 tmp.type = ptr_val->type->data.pointer.child_type; 7952 if ((err = ir_read_const_ptr(ira, codegen, source_node, &tmp, ptr_val))) 7953 return err; 7954 ConstExprValue *child_val = const_ptr_pointee_unchecked(codegen, ptr_val); 7955 copy_const_val(child_val, &tmp, false); 7956 return ErrorNone; 7957 } 7958 7959 ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprValue *const_val, 7960 AstNode *source_node) 7961 { 7962 Error err; 7963 ConstExprValue *val = const_ptr_pointee_unchecked(codegen, const_val); 7964 assert(val != nullptr); 7965 assert(const_val->type->id == ZigTypeIdPointer); 7966 ZigType *expected_type = const_val->type->data.pointer.child_type; 7967 if (!types_have_same_zig_comptime_repr(val->type, expected_type)) { 7968 if ((err = eval_comptime_ptr_reinterpret(ira, codegen, source_node, const_val))) 7969 return nullptr; 7970 return const_ptr_pointee_unchecked(codegen, const_val); 7971 } 7972 return val; 7973 } 7974 7975 static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec) { 7976 IrBasicBlock *bb = exec->basic_block_list.at(0); 7977 for (size_t i = 0; i < bb->instruction_list.length; i += 1) { 7978 IrInstruction *instruction = bb->instruction_list.at(i); 7979 if (instruction->id == IrInstructionIdReturn) { 7980 IrInstructionReturn *ret_inst = (IrInstructionReturn *)instruction; 7981 IrInstruction *value = ret_inst->value; 7982 if (value->value.special == ConstValSpecialRuntime) { 7983 exec_add_error_node(codegen, exec, value->source_node, 7984 buf_sprintf("unable to evaluate constant expression")); 7985 return &codegen->invalid_instruction->value; 7986 } 7987 return &value->value; 7988 } else if (ir_has_side_effects(instruction)) { 7989 exec_add_error_node(codegen, exec, instruction->source_node, 7990 buf_sprintf("unable to evaluate constant expression")); 7991 return &codegen->invalid_instruction->value; 7992 } 7993 } 7994 zig_unreachable(); 7995 } 7996 7997 static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) { 7998 if (ir_should_inline(ira->new_irb.exec, source_instruction->scope)) { 7999 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression")); 8000 return false; 8001 } 8002 return true; 8003 } 8004 8005 static bool const_val_fits_in_num_lit(ConstExprValue *const_val, ZigType *num_lit_type) { 8006 return ((num_lit_type->id == ZigTypeIdComptimeFloat && 8007 (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat)) || 8008 (num_lit_type->id == ZigTypeIdComptimeInt && 8009 (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt))); 8010 } 8011 8012 static bool float_has_fraction(ConstExprValue *const_val) { 8013 if (const_val->type->id == ZigTypeIdComptimeFloat) { 8014 return bigfloat_has_fraction(&const_val->data.x_bigfloat); 8015 } else if (const_val->type->id == ZigTypeIdFloat) { 8016 switch (const_val->type->data.floating.bit_count) { 8017 case 16: 8018 { 8019 float16_t floored = f16_roundToInt(const_val->data.x_f16, softfloat_round_minMag, false); 8020 return !f16_eq(floored, const_val->data.x_f16); 8021 } 8022 case 32: 8023 return floorf(const_val->data.x_f32) != const_val->data.x_f32; 8024 case 64: 8025 return floor(const_val->data.x_f64) != const_val->data.x_f64; 8026 case 128: 8027 { 8028 float128_t floored; 8029 f128M_roundToInt(&const_val->data.x_f128, softfloat_round_minMag, false, &floored); 8030 return !f128M_eq(&floored, &const_val->data.x_f128); 8031 } 8032 default: 8033 zig_unreachable(); 8034 } 8035 } else { 8036 zig_unreachable(); 8037 } 8038 } 8039 8040 static void float_append_buf(Buf *buf, ConstExprValue *const_val) { 8041 if (const_val->type->id == ZigTypeIdComptimeFloat) { 8042 bigfloat_append_buf(buf, &const_val->data.x_bigfloat); 8043 } else if (const_val->type->id == ZigTypeIdFloat) { 8044 switch (const_val->type->data.floating.bit_count) { 8045 case 16: 8046 buf_appendf(buf, "%f", zig_f16_to_double(const_val->data.x_f16)); 8047 break; 8048 case 32: 8049 buf_appendf(buf, "%f", const_val->data.x_f32); 8050 break; 8051 case 64: 8052 buf_appendf(buf, "%f", const_val->data.x_f64); 8053 break; 8054 case 128: 8055 { 8056 // TODO actual implementation 8057 const size_t extra_len = 100; 8058 size_t old_len = buf_len(buf); 8059 buf_resize(buf, old_len + extra_len); 8060 8061 float64_t f64_value = f128M_to_f64(&const_val->data.x_f128); 8062 double double_value; 8063 memcpy(&double_value, &f64_value, sizeof(double)); 8064 8065 int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value); 8066 assert(len > 0); 8067 buf_resize(buf, old_len + len); 8068 break; 8069 } 8070 default: 8071 zig_unreachable(); 8072 } 8073 } else { 8074 zig_unreachable(); 8075 } 8076 } 8077 8078 static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) { 8079 if (const_val->type->id == ZigTypeIdComptimeFloat) { 8080 bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat); 8081 } else if (const_val->type->id == ZigTypeIdFloat) { 8082 switch (const_val->type->data.floating.bit_count) { 8083 case 16: 8084 { 8085 double x = zig_f16_to_double(const_val->data.x_f16); 8086 if (x >= 0) { 8087 bigint_init_unsigned(bigint, (uint64_t)x); 8088 } else { 8089 bigint_init_unsigned(bigint, (uint64_t)-x); 8090 bigint->is_negative = true; 8091 } 8092 break; 8093 } 8094 case 32: 8095 if (const_val->data.x_f32 >= 0) { 8096 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f32)); 8097 } else { 8098 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f32)); 8099 bigint->is_negative = true; 8100 } 8101 break; 8102 case 64: 8103 if (const_val->data.x_f64 >= 0) { 8104 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f64)); 8105 } else { 8106 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f64)); 8107 bigint->is_negative = true; 8108 } 8109 break; 8110 case 128: 8111 { 8112 BigFloat tmp_float; 8113 bigfloat_init_128(&tmp_float, const_val->data.x_f128); 8114 bigint_init_bigfloat(bigint, &tmp_float); 8115 } 8116 break; 8117 default: 8118 zig_unreachable(); 8119 } 8120 } else { 8121 zig_unreachable(); 8122 } 8123 } 8124 8125 static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) { 8126 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8127 bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat); 8128 } else if (dest_val->type->id == ZigTypeIdFloat) { 8129 switch (dest_val->type->data.floating.bit_count) { 8130 case 16: 8131 dest_val->data.x_f16 = bigfloat_to_f16(bigfloat); 8132 break; 8133 case 32: 8134 dest_val->data.x_f32 = bigfloat_to_f32(bigfloat); 8135 break; 8136 case 64: 8137 dest_val->data.x_f64 = bigfloat_to_f64(bigfloat); 8138 break; 8139 case 80: 8140 zig_panic("TODO"); 8141 case 128: 8142 dest_val->data.x_f128 = bigfloat_to_f128(bigfloat); 8143 break; 8144 default: 8145 zig_unreachable(); 8146 } 8147 } else { 8148 zig_unreachable(); 8149 } 8150 } 8151 8152 static void float_init_f16(ConstExprValue *dest_val, float16_t x) { 8153 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8154 bigfloat_init_16(&dest_val->data.x_bigfloat, x); 8155 } else if (dest_val->type->id == ZigTypeIdFloat) { 8156 switch (dest_val->type->data.floating.bit_count) { 8157 case 16: 8158 dest_val->data.x_f16 = x; 8159 break; 8160 case 32: 8161 dest_val->data.x_f32 = zig_f16_to_double(x); 8162 break; 8163 case 64: 8164 dest_val->data.x_f64 = zig_f16_to_double(x); 8165 break; 8166 case 128: 8167 f16_to_f128M(x, &dest_val->data.x_f128); 8168 break; 8169 default: 8170 zig_unreachable(); 8171 } 8172 } else { 8173 zig_unreachable(); 8174 } 8175 } 8176 8177 static void float_init_f32(ConstExprValue *dest_val, float x) { 8178 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8179 bigfloat_init_32(&dest_val->data.x_bigfloat, x); 8180 } else if (dest_val->type->id == ZigTypeIdFloat) { 8181 switch (dest_val->type->data.floating.bit_count) { 8182 case 16: 8183 dest_val->data.x_f16 = zig_double_to_f16(x); 8184 break; 8185 case 32: 8186 dest_val->data.x_f32 = x; 8187 break; 8188 case 64: 8189 dest_val->data.x_f64 = x; 8190 break; 8191 case 128: 8192 { 8193 float32_t x_f32; 8194 memcpy(&x_f32, &x, sizeof(float)); 8195 f32_to_f128M(x_f32, &dest_val->data.x_f128); 8196 break; 8197 } 8198 default: 8199 zig_unreachable(); 8200 } 8201 } else { 8202 zig_unreachable(); 8203 } 8204 } 8205 8206 static void float_init_f64(ConstExprValue *dest_val, double x) { 8207 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8208 bigfloat_init_64(&dest_val->data.x_bigfloat, x); 8209 } else if (dest_val->type->id == ZigTypeIdFloat) { 8210 switch (dest_val->type->data.floating.bit_count) { 8211 case 16: 8212 dest_val->data.x_f16 = zig_double_to_f16(x); 8213 break; 8214 case 32: 8215 dest_val->data.x_f32 = x; 8216 break; 8217 case 64: 8218 dest_val->data.x_f64 = x; 8219 break; 8220 case 128: 8221 { 8222 float64_t x_f64; 8223 memcpy(&x_f64, &x, sizeof(double)); 8224 f64_to_f128M(x_f64, &dest_val->data.x_f128); 8225 break; 8226 } 8227 default: 8228 zig_unreachable(); 8229 } 8230 } else { 8231 zig_unreachable(); 8232 } 8233 } 8234 8235 static void float_init_f128(ConstExprValue *dest_val, float128_t x) { 8236 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8237 bigfloat_init_128(&dest_val->data.x_bigfloat, x); 8238 } else if (dest_val->type->id == ZigTypeIdFloat) { 8239 switch (dest_val->type->data.floating.bit_count) { 8240 case 16: 8241 dest_val->data.x_f16 = f128M_to_f16(&x); 8242 break; 8243 case 32: 8244 { 8245 float32_t f32_val = f128M_to_f32(&x); 8246 memcpy(&dest_val->data.x_f32, &f32_val, sizeof(float)); 8247 break; 8248 } 8249 case 64: 8250 { 8251 float64_t f64_val = f128M_to_f64(&x); 8252 memcpy(&dest_val->data.x_f64, &f64_val, sizeof(double)); 8253 break; 8254 } 8255 case 128: 8256 { 8257 memcpy(&dest_val->data.x_f128, &x, sizeof(float128_t)); 8258 break; 8259 } 8260 default: 8261 zig_unreachable(); 8262 } 8263 } else { 8264 zig_unreachable(); 8265 } 8266 } 8267 8268 static void float_init_float(ConstExprValue *dest_val, ConstExprValue *src_val) { 8269 if (src_val->type->id == ZigTypeIdComptimeFloat) { 8270 float_init_bigfloat(dest_val, &src_val->data.x_bigfloat); 8271 } else if (src_val->type->id == ZigTypeIdFloat) { 8272 switch (src_val->type->data.floating.bit_count) { 8273 case 16: 8274 float_init_f16(dest_val, src_val->data.x_f16); 8275 break; 8276 case 32: 8277 float_init_f32(dest_val, src_val->data.x_f32); 8278 break; 8279 case 64: 8280 float_init_f64(dest_val, src_val->data.x_f64); 8281 break; 8282 case 128: 8283 float_init_f128(dest_val, src_val->data.x_f128); 8284 break; 8285 default: 8286 zig_unreachable(); 8287 } 8288 } else { 8289 zig_unreachable(); 8290 } 8291 } 8292 8293 static bool float_is_nan(ConstExprValue *op) { 8294 if (op->type->id == ZigTypeIdComptimeFloat) { 8295 return bigfloat_is_nan(&op->data.x_bigfloat); 8296 } else if (op->type->id == ZigTypeIdFloat) { 8297 switch (op->type->data.floating.bit_count) { 8298 case 16: 8299 return f16_isSignalingNaN(op->data.x_f16); 8300 case 32: 8301 return op->data.x_f32 != op->data.x_f32; 8302 case 64: 8303 return op->data.x_f64 != op->data.x_f64; 8304 case 128: 8305 return f128M_isSignalingNaN(&op->data.x_f128); 8306 default: 8307 zig_unreachable(); 8308 } 8309 } else { 8310 zig_unreachable(); 8311 } 8312 } 8313 8314 static Cmp float_cmp(ConstExprValue *op1, ConstExprValue *op2) { 8315 assert(op1->type == op2->type); 8316 if (op1->type->id == ZigTypeIdComptimeFloat) { 8317 return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat); 8318 } else if (op1->type->id == ZigTypeIdFloat) { 8319 switch (op1->type->data.floating.bit_count) { 8320 case 16: 8321 if (f16_lt(op1->data.x_f16, op2->data.x_f16)) { 8322 return CmpLT; 8323 } else if (f16_lt(op2->data.x_f16, op1->data.x_f16)) { 8324 return CmpGT; 8325 } else { 8326 return CmpEQ; 8327 } 8328 case 32: 8329 if (op1->data.x_f32 > op2->data.x_f32) { 8330 return CmpGT; 8331 } else if (op1->data.x_f32 < op2->data.x_f32) { 8332 return CmpLT; 8333 } else { 8334 return CmpEQ; 8335 } 8336 case 64: 8337 if (op1->data.x_f64 > op2->data.x_f64) { 8338 return CmpGT; 8339 } else if (op1->data.x_f64 < op2->data.x_f64) { 8340 return CmpLT; 8341 } else { 8342 return CmpEQ; 8343 } 8344 case 128: 8345 if (f128M_lt(&op1->data.x_f128, &op2->data.x_f128)) { 8346 return CmpLT; 8347 } else if (f128M_eq(&op1->data.x_f128, &op2->data.x_f128)) { 8348 return CmpEQ; 8349 } else { 8350 return CmpGT; 8351 } 8352 default: 8353 zig_unreachable(); 8354 } 8355 } else { 8356 zig_unreachable(); 8357 } 8358 } 8359 8360 static Cmp float_cmp_zero(ConstExprValue *op) { 8361 if (op->type->id == ZigTypeIdComptimeFloat) { 8362 return bigfloat_cmp_zero(&op->data.x_bigfloat); 8363 } else if (op->type->id == ZigTypeIdFloat) { 8364 switch (op->type->data.floating.bit_count) { 8365 case 16: 8366 { 8367 const float16_t zero = zig_double_to_f16(0); 8368 if (f16_lt(op->data.x_f16, zero)) { 8369 return CmpLT; 8370 } else if (f16_lt(zero, op->data.x_f16)) { 8371 return CmpGT; 8372 } else { 8373 return CmpEQ; 8374 } 8375 } 8376 case 32: 8377 if (op->data.x_f32 < 0.0) { 8378 return CmpLT; 8379 } else if (op->data.x_f32 > 0.0) { 8380 return CmpGT; 8381 } else { 8382 return CmpEQ; 8383 } 8384 case 64: 8385 if (op->data.x_f64 < 0.0) { 8386 return CmpLT; 8387 } else if (op->data.x_f64 > 0.0) { 8388 return CmpGT; 8389 } else { 8390 return CmpEQ; 8391 } 8392 case 128: 8393 float128_t zero_float; 8394 ui32_to_f128M(0, &zero_float); 8395 if (f128M_lt(&op->data.x_f128, &zero_float)) { 8396 return CmpLT; 8397 } else if (f128M_eq(&op->data.x_f128, &zero_float)) { 8398 return CmpEQ; 8399 } else { 8400 return CmpGT; 8401 } 8402 default: 8403 zig_unreachable(); 8404 } 8405 } else { 8406 zig_unreachable(); 8407 } 8408 } 8409 8410 static void float_add(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8411 assert(op1->type == op2->type); 8412 out_val->type = op1->type; 8413 if (op1->type->id == ZigTypeIdComptimeFloat) { 8414 bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8415 } else if (op1->type->id == ZigTypeIdFloat) { 8416 switch (op1->type->data.floating.bit_count) { 8417 case 16: 8418 out_val->data.x_f16 = f16_add(op1->data.x_f16, op2->data.x_f16); 8419 return; 8420 case 32: 8421 out_val->data.x_f32 = op1->data.x_f32 + op2->data.x_f32; 8422 return; 8423 case 64: 8424 out_val->data.x_f64 = op1->data.x_f64 + op2->data.x_f64; 8425 return; 8426 case 128: 8427 f128M_add(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8428 return; 8429 default: 8430 zig_unreachable(); 8431 } 8432 } else { 8433 zig_unreachable(); 8434 } 8435 } 8436 8437 static void float_sub(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8438 assert(op1->type == op2->type); 8439 out_val->type = op1->type; 8440 if (op1->type->id == ZigTypeIdComptimeFloat) { 8441 bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8442 } else if (op1->type->id == ZigTypeIdFloat) { 8443 switch (op1->type->data.floating.bit_count) { 8444 case 16: 8445 out_val->data.x_f16 = f16_sub(op1->data.x_f16, op2->data.x_f16); 8446 return; 8447 case 32: 8448 out_val->data.x_f32 = op1->data.x_f32 - op2->data.x_f32; 8449 return; 8450 case 64: 8451 out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64; 8452 return; 8453 case 128: 8454 f128M_sub(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8455 return; 8456 default: 8457 zig_unreachable(); 8458 } 8459 } else { 8460 zig_unreachable(); 8461 } 8462 } 8463 8464 static void float_mul(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8465 assert(op1->type == op2->type); 8466 out_val->type = op1->type; 8467 if (op1->type->id == ZigTypeIdComptimeFloat) { 8468 bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8469 } else if (op1->type->id == ZigTypeIdFloat) { 8470 switch (op1->type->data.floating.bit_count) { 8471 case 16: 8472 out_val->data.x_f16 = f16_mul(op1->data.x_f16, op2->data.x_f16); 8473 return; 8474 case 32: 8475 out_val->data.x_f32 = op1->data.x_f32 * op2->data.x_f32; 8476 return; 8477 case 64: 8478 out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64; 8479 return; 8480 case 128: 8481 f128M_mul(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8482 return; 8483 default: 8484 zig_unreachable(); 8485 } 8486 } else { 8487 zig_unreachable(); 8488 } 8489 } 8490 8491 static void float_div(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8492 assert(op1->type == op2->type); 8493 out_val->type = op1->type; 8494 if (op1->type->id == ZigTypeIdComptimeFloat) { 8495 bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8496 } else if (op1->type->id == ZigTypeIdFloat) { 8497 switch (op1->type->data.floating.bit_count) { 8498 case 16: 8499 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 8500 return; 8501 case 32: 8502 out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32; 8503 return; 8504 case 64: 8505 out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64; 8506 return; 8507 case 128: 8508 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8509 return; 8510 default: 8511 zig_unreachable(); 8512 } 8513 } else { 8514 zig_unreachable(); 8515 } 8516 } 8517 8518 static void float_div_trunc(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8519 assert(op1->type == op2->type); 8520 out_val->type = op1->type; 8521 if (op1->type->id == ZigTypeIdComptimeFloat) { 8522 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8523 } else if (op1->type->id == ZigTypeIdFloat) { 8524 switch (op1->type->data.floating.bit_count) { 8525 case 16: 8526 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 8527 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_minMag, false); 8528 return; 8529 case 32: 8530 out_val->data.x_f32 = truncf(op1->data.x_f32 / op2->data.x_f32); 8531 return; 8532 case 64: 8533 out_val->data.x_f64 = trunc(op1->data.x_f64 / op2->data.x_f64); 8534 return; 8535 case 128: 8536 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8537 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_minMag, false, &out_val->data.x_f128); 8538 return; 8539 default: 8540 zig_unreachable(); 8541 } 8542 } else { 8543 zig_unreachable(); 8544 } 8545 } 8546 8547 static void float_div_floor(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8548 assert(op1->type == op2->type); 8549 out_val->type = op1->type; 8550 if (op1->type->id == ZigTypeIdComptimeFloat) { 8551 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8552 } else if (op1->type->id == ZigTypeIdFloat) { 8553 switch (op1->type->data.floating.bit_count) { 8554 case 16: 8555 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 8556 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_min, false); 8557 return; 8558 case 32: 8559 out_val->data.x_f32 = floorf(op1->data.x_f32 / op2->data.x_f32); 8560 return; 8561 case 64: 8562 out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64); 8563 return; 8564 case 128: 8565 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8566 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_min, false, &out_val->data.x_f128); 8567 return; 8568 default: 8569 zig_unreachable(); 8570 } 8571 } else { 8572 zig_unreachable(); 8573 } 8574 } 8575 8576 static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8577 assert(op1->type == op2->type); 8578 out_val->type = op1->type; 8579 if (op1->type->id == ZigTypeIdComptimeFloat) { 8580 bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8581 } else if (op1->type->id == ZigTypeIdFloat) { 8582 switch (op1->type->data.floating.bit_count) { 8583 case 16: 8584 out_val->data.x_f16 = f16_rem(op1->data.x_f16, op2->data.x_f16); 8585 return; 8586 case 32: 8587 out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32); 8588 return; 8589 case 64: 8590 out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64); 8591 return; 8592 case 128: 8593 f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8594 return; 8595 default: 8596 zig_unreachable(); 8597 } 8598 } else { 8599 zig_unreachable(); 8600 } 8601 } 8602 8603 // c = a - b * trunc(a / b) 8604 static float16_t zig_f16_mod(float16_t a, float16_t b) { 8605 float16_t c; 8606 c = f16_div(a, b); 8607 c = f16_roundToInt(c, softfloat_round_min, true); 8608 c = f16_mul(b, c); 8609 c = f16_sub(a, c); 8610 return c; 8611 } 8612 8613 // c = a - b * trunc(a / b) 8614 static void zig_f128M_mod(const float128_t* a, const float128_t* b, float128_t* c) { 8615 f128M_div(a, b, c); 8616 f128M_roundToInt(c, softfloat_round_min, true, c); 8617 f128M_mul(b, c, c); 8618 f128M_sub(a, c, c); 8619 } 8620 8621 static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8622 assert(op1->type == op2->type); 8623 out_val->type = op1->type; 8624 if (op1->type->id == ZigTypeIdComptimeFloat) { 8625 bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8626 } else if (op1->type->id == ZigTypeIdFloat) { 8627 switch (op1->type->data.floating.bit_count) { 8628 case 16: 8629 out_val->data.x_f16 = zig_f16_mod(op1->data.x_f16, op2->data.x_f16); 8630 return; 8631 case 32: 8632 out_val->data.x_f32 = fmodf(fmodf(op1->data.x_f32, op2->data.x_f32) + op2->data.x_f32, op2->data.x_f32); 8633 return; 8634 case 64: 8635 out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64); 8636 return; 8637 case 128: 8638 zig_f128M_mod(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8639 return; 8640 default: 8641 zig_unreachable(); 8642 } 8643 } else { 8644 zig_unreachable(); 8645 } 8646 } 8647 8648 static void float_negate(ConstExprValue *out_val, ConstExprValue *op) { 8649 out_val->type = op->type; 8650 if (op->type->id == ZigTypeIdComptimeFloat) { 8651 bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat); 8652 } else if (op->type->id == ZigTypeIdFloat) { 8653 switch (op->type->data.floating.bit_count) { 8654 case 16: 8655 { 8656 const float16_t zero = zig_double_to_f16(0); 8657 out_val->data.x_f16 = f16_sub(zero, op->data.x_f16); 8658 return; 8659 } 8660 case 32: 8661 out_val->data.x_f32 = -op->data.x_f32; 8662 return; 8663 case 64: 8664 out_val->data.x_f64 = -op->data.x_f64; 8665 return; 8666 case 128: 8667 float128_t zero_f128; 8668 ui32_to_f128M(0, &zero_f128); 8669 f128M_sub(&zero_f128, &op->data.x_f128, &out_val->data.x_f128); 8670 return; 8671 default: 8672 zig_unreachable(); 8673 } 8674 } else { 8675 zig_unreachable(); 8676 } 8677 } 8678 8679 void float_write_ieee597(ConstExprValue *op, uint8_t *buf, bool is_big_endian) { 8680 if (op->type->id == ZigTypeIdFloat) { 8681 switch (op->type->data.floating.bit_count) { 8682 case 16: 8683 memcpy(buf, &op->data.x_f16, 2); // TODO wrong when compiler is big endian 8684 return; 8685 case 32: 8686 memcpy(buf, &op->data.x_f32, 4); // TODO wrong when compiler is big endian 8687 return; 8688 case 64: 8689 memcpy(buf, &op->data.x_f64, 8); // TODO wrong when compiler is big endian 8690 return; 8691 case 128: 8692 memcpy(buf, &op->data.x_f128, 16); // TODO wrong when compiler is big endian 8693 return; 8694 default: 8695 zig_unreachable(); 8696 } 8697 } else { 8698 zig_unreachable(); 8699 } 8700 } 8701 8702 void float_read_ieee597(ConstExprValue *val, uint8_t *buf, bool is_big_endian) { 8703 if (val->type->id == ZigTypeIdFloat) { 8704 switch (val->type->data.floating.bit_count) { 8705 case 16: 8706 memcpy(&val->data.x_f16, buf, 2); // TODO wrong when compiler is big endian 8707 return; 8708 case 32: 8709 memcpy(&val->data.x_f32, buf, 4); // TODO wrong when compiler is big endian 8710 return; 8711 case 64: 8712 memcpy(&val->data.x_f64, buf, 8); // TODO wrong when compiler is big endian 8713 return; 8714 case 128: 8715 memcpy(&val->data.x_f128, buf, 16); // TODO wrong when compiler is big endian 8716 return; 8717 default: 8718 zig_unreachable(); 8719 } 8720 } else { 8721 zig_unreachable(); 8722 } 8723 } 8724 8725 static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, ZigType *other_type, 8726 bool explicit_cast) 8727 { 8728 if (type_is_invalid(other_type)) { 8729 return false; 8730 } 8731 8732 ConstExprValue *const_val = ir_resolve_const(ira, instruction, UndefBad); 8733 assert(const_val != nullptr); 8734 8735 bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt); 8736 bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); 8737 assert(const_val_is_int || const_val_is_float); 8738 8739 if (other_type->id == ZigTypeIdFloat) { 8740 if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) { 8741 return true; 8742 } 8743 if (const_val->type->id == ZigTypeIdInt) { 8744 BigFloat tmp_bf; 8745 bigfloat_init_bigint(&tmp_bf, &const_val->data.x_bigint); 8746 BigFloat orig_bf; 8747 switch (other_type->data.floating.bit_count) { 8748 case 16: { 8749 float16_t tmp = bigfloat_to_f16(&tmp_bf); 8750 bigfloat_init_16(&orig_bf, tmp); 8751 break; 8752 } 8753 case 32: { 8754 float tmp = bigfloat_to_f32(&tmp_bf); 8755 bigfloat_init_32(&orig_bf, tmp); 8756 break; 8757 } 8758 case 64: { 8759 double tmp = bigfloat_to_f64(&tmp_bf); 8760 bigfloat_init_64(&orig_bf, tmp); 8761 break; 8762 } 8763 case 80: 8764 zig_panic("TODO"); 8765 case 128: { 8766 float128_t tmp = bigfloat_to_f128(&tmp_bf); 8767 bigfloat_init_128(&orig_bf, tmp); 8768 break; 8769 } 8770 default: 8771 zig_unreachable(); 8772 } 8773 BigInt orig_bi; 8774 bigint_init_bigfloat(&orig_bi, &orig_bf); 8775 if (bigint_cmp(&orig_bi, &const_val->data.x_bigint) == CmpEQ) { 8776 return true; 8777 } 8778 Buf *val_buf = buf_alloc(); 8779 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 8780 ir_add_error(ira, instruction, 8781 buf_sprintf("integer value %s has no representation in type '%s'", 8782 buf_ptr(val_buf), 8783 buf_ptr(&other_type->name))); 8784 return false; 8785 } 8786 if (other_type->data.floating.bit_count >= const_val->type->data.floating.bit_count) { 8787 return true; 8788 } 8789 switch (other_type->data.floating.bit_count) { 8790 case 16: 8791 switch (const_val->type->data.floating.bit_count) { 8792 case 32: { 8793 float16_t tmp = zig_double_to_f16(const_val->data.x_f32); 8794 float orig = zig_f16_to_double(tmp); 8795 if (const_val->data.x_f32 == orig) { 8796 return true; 8797 } 8798 break; 8799 } 8800 case 64: { 8801 float16_t tmp = zig_double_to_f16(const_val->data.x_f64); 8802 double orig = zig_f16_to_double(tmp); 8803 if (const_val->data.x_f64 == orig) { 8804 return true; 8805 } 8806 break; 8807 } 8808 case 80: 8809 zig_panic("TODO"); 8810 case 128: { 8811 float16_t tmp = f128M_to_f16(&const_val->data.x_f128); 8812 float128_t orig; 8813 f16_to_f128M(tmp, &orig); 8814 if (f128M_eq(&orig, &const_val->data.x_f128)) { 8815 return true; 8816 } 8817 break; 8818 } 8819 default: 8820 zig_unreachable(); 8821 } 8822 break; 8823 case 32: 8824 switch (const_val->type->data.floating.bit_count) { 8825 case 64: { 8826 float tmp = const_val->data.x_f64; 8827 double orig = tmp; 8828 if (const_val->data.x_f64 == orig) { 8829 return true; 8830 } 8831 break; 8832 } 8833 case 80: 8834 zig_panic("TODO"); 8835 case 128: { 8836 float32_t tmp = f128M_to_f32(&const_val->data.x_f128); 8837 float128_t orig; 8838 f32_to_f128M(tmp, &orig); 8839 if (f128M_eq(&orig, &const_val->data.x_f128)) { 8840 return true; 8841 } 8842 break; 8843 } 8844 default: 8845 zig_unreachable(); 8846 } 8847 break; 8848 case 64: 8849 switch (const_val->type->data.floating.bit_count) { 8850 case 80: 8851 zig_panic("TODO"); 8852 case 128: { 8853 float64_t tmp = f128M_to_f64(&const_val->data.x_f128); 8854 float128_t orig; 8855 f64_to_f128M(tmp, &orig); 8856 if (f128M_eq(&orig, &const_val->data.x_f128)) { 8857 return true; 8858 } 8859 break; 8860 } 8861 default: 8862 zig_unreachable(); 8863 } 8864 break; 8865 case 80: 8866 assert(const_val->type->data.floating.bit_count == 128); 8867 zig_panic("TODO"); 8868 case 128: 8869 return true; 8870 default: 8871 zig_unreachable(); 8872 } 8873 Buf *val_buf = buf_alloc(); 8874 float_append_buf(val_buf, const_val); 8875 ir_add_error(ira, instruction, 8876 buf_sprintf("cast of value %s to type '%s' loses information", 8877 buf_ptr(val_buf), 8878 buf_ptr(&other_type->name))); 8879 return false; 8880 } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { 8881 if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 8882 Buf *val_buf = buf_alloc(); 8883 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 8884 ir_add_error(ira, instruction, 8885 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 8886 buf_ptr(val_buf), 8887 buf_ptr(&other_type->name))); 8888 return false; 8889 } 8890 if (bigint_fits_in_bits(&const_val->data.x_bigint, other_type->data.integral.bit_count, 8891 other_type->data.integral.is_signed)) 8892 { 8893 return true; 8894 } 8895 } else if (const_val_fits_in_num_lit(const_val, other_type)) { 8896 return true; 8897 } else if (other_type->id == ZigTypeIdOptional) { 8898 ZigType *child_type = other_type->data.maybe.child_type; 8899 if (const_val_fits_in_num_lit(const_val, child_type)) { 8900 return true; 8901 } else if (child_type->id == ZigTypeIdInt && const_val_is_int) { 8902 if (!child_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 8903 Buf *val_buf = buf_alloc(); 8904 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 8905 ir_add_error(ira, instruction, 8906 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 8907 buf_ptr(val_buf), 8908 buf_ptr(&child_type->name))); 8909 return false; 8910 } 8911 if (bigint_fits_in_bits(&const_val->data.x_bigint, 8912 child_type->data.integral.bit_count, 8913 child_type->data.integral.is_signed)) 8914 { 8915 return true; 8916 } 8917 } else if (child_type->id == ZigTypeIdFloat && const_val_is_float) { 8918 return true; 8919 } 8920 } 8921 if (explicit_cast && (other_type->id == ZigTypeIdInt || other_type->id == ZigTypeIdComptimeInt) && 8922 const_val_is_float) 8923 { 8924 if (float_has_fraction(const_val)) { 8925 Buf *val_buf = buf_alloc(); 8926 float_append_buf(val_buf, const_val); 8927 8928 ir_add_error(ira, instruction, 8929 buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", 8930 buf_ptr(val_buf), 8931 buf_ptr(&other_type->name))); 8932 return false; 8933 } else { 8934 if (other_type->id == ZigTypeIdComptimeInt) { 8935 return true; 8936 } else { 8937 BigInt bigint; 8938 float_init_bigint(&bigint, const_val); 8939 if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count, 8940 other_type->data.integral.is_signed)) 8941 { 8942 return true; 8943 } 8944 } 8945 } 8946 } 8947 8948 const char *num_lit_str; 8949 Buf *val_buf = buf_alloc(); 8950 if (const_val_is_float) { 8951 num_lit_str = "float"; 8952 float_append_buf(val_buf, const_val); 8953 } else { 8954 num_lit_str = "integer"; 8955 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 8956 } 8957 8958 ir_add_error(ira, instruction, 8959 buf_sprintf("%s value %s cannot be implicitly casted to type '%s'", 8960 num_lit_str, 8961 buf_ptr(val_buf), 8962 buf_ptr(&other_type->name))); 8963 return false; 8964 } 8965 8966 static bool is_slice(ZigType *type) { 8967 return type->id == ZigTypeIdStruct && type->data.structure.is_slice; 8968 } 8969 8970 static bool slice_is_const(ZigType *type) { 8971 assert(is_slice(type)); 8972 return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; 8973 } 8974 8975 static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigType *set2, 8976 AstNode *source_node) 8977 { 8978 assert(set1->id == ZigTypeIdErrorSet); 8979 assert(set2->id == ZigTypeIdErrorSet); 8980 8981 if (!resolve_inferred_error_set(ira->codegen, set1, source_node)) { 8982 return ira->codegen->builtin_types.entry_invalid; 8983 } 8984 if (!resolve_inferred_error_set(ira->codegen, set2, source_node)) { 8985 return ira->codegen->builtin_types.entry_invalid; 8986 } 8987 if (type_is_global_error_set(set1)) { 8988 return set2; 8989 } 8990 if (type_is_global_error_set(set2)) { 8991 return set1; 8992 } 8993 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 8994 for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { 8995 ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; 8996 assert(errors[error_entry->value] == nullptr); 8997 errors[error_entry->value] = error_entry; 8998 } 8999 ZigList<ErrorTableEntry *> intersection_list = {}; 9000 9001 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9002 buf_resize(&err_set_type->name, 0); 9003 buf_appendf(&err_set_type->name, "error{"); 9004 9005 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 9006 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 9007 ErrorTableEntry *existing_entry = errors[error_entry->value]; 9008 if (existing_entry != nullptr) { 9009 intersection_list.append(existing_entry); 9010 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&existing_entry->name)); 9011 } 9012 } 9013 free(errors); 9014 9015 err_set_type->data.error_set.err_count = intersection_list.length; 9016 err_set_type->data.error_set.errors = intersection_list.items; 9017 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 9018 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 9019 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 9020 9021 buf_appendf(&err_set_type->name, "}"); 9022 9023 return err_set_type; 9024 } 9025 9026 static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted_type, 9027 ZigType *actual_type, AstNode *source_node, bool wanted_is_mutable) 9028 { 9029 CodeGen *g = ira->codegen; 9030 ConstCastOnly result = {}; 9031 result.id = ConstCastResultIdOk; 9032 9033 Error err; 9034 9035 if (wanted_type == actual_type) 9036 return result; 9037 9038 // If pointers have the same representation in memory, they can be "const-casted". 9039 // `const` attribute can be gained 9040 // `volatile` attribute can be gained 9041 // `allowzero` attribute can be gained (whether from explicit attribute, C pointer, or optional pointer) 9042 // but only if !wanted_is_mutable 9043 // alignment can be decreased 9044 // bit offset attributes must match exactly 9045 // PtrLenSingle/PtrLenUnknown must match exactly, but PtrLenC matches either one 9046 ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type); 9047 ZigType *actual_ptr_type = get_src_ptr_type(actual_type); 9048 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 9049 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 9050 bool wanted_is_c_ptr = wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC; 9051 bool actual_is_c_ptr = actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenC; 9052 bool wanted_opt_or_ptr = wanted_ptr_type != nullptr && 9053 (wanted_type->id == ZigTypeIdPointer || wanted_type->id == ZigTypeIdOptional); 9054 bool actual_opt_or_ptr = actual_ptr_type != nullptr && 9055 (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional); 9056 if (wanted_opt_or_ptr && actual_opt_or_ptr) { 9057 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 9058 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 9059 if (child.id == ConstCastResultIdInvalid) 9060 return child; 9061 if (child.id != ConstCastResultIdOk) { 9062 result.id = ConstCastResultIdPointerChild; 9063 result.data.pointer_mismatch = allocate_nonzero<ConstCastPointerMismatch>(1); 9064 result.data.pointer_mismatch->child = child; 9065 result.data.pointer_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 9066 result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 9067 return result; 9068 } 9069 bool ok_allows_zero = (wanted_allows_zero && 9070 (actual_allows_zero || !wanted_is_mutable)) || 9071 (!wanted_allows_zero && !actual_allows_zero); 9072 if (!ok_allows_zero) { 9073 result.id = ConstCastResultIdBadAllowsZero; 9074 result.data.bad_allows_zero = allocate_nonzero<ConstCastBadAllowsZero>(1); 9075 result.data.bad_allows_zero->wanted_type = wanted_type; 9076 result.data.bad_allows_zero->actual_type = actual_type; 9077 return result; 9078 } 9079 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 9080 result.id = ConstCastResultIdInvalid; 9081 return result; 9082 } 9083 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 9084 result.id = ConstCastResultIdInvalid; 9085 return result; 9086 } 9087 bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; 9088 if ((ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr) && 9089 type_has_bits(wanted_type) == type_has_bits(actual_type) && 9090 (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 9091 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && 9092 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 9093 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 9094 get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type)) 9095 { 9096 return result; 9097 } 9098 } 9099 9100 // slice const 9101 if (is_slice(wanted_type) && is_slice(actual_type)) { 9102 ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry; 9103 ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 9104 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 9105 result.id = ConstCastResultIdInvalid; 9106 return result; 9107 } 9108 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 9109 result.id = ConstCastResultIdInvalid; 9110 return result; 9111 } 9112 if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 9113 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && 9114 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 9115 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 9116 get_ptr_align(g, actual_ptr_type) >= get_ptr_align(g, wanted_ptr_type)) 9117 { 9118 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 9119 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 9120 if (child.id == ConstCastResultIdInvalid) 9121 return child; 9122 if (child.id != ConstCastResultIdOk) { 9123 result.id = ConstCastResultIdSliceChild; 9124 result.data.slice_mismatch = allocate_nonzero<ConstCastSliceMismatch>(1); 9125 result.data.slice_mismatch->child = child; 9126 result.data.slice_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 9127 result.data.slice_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 9128 } 9129 return result; 9130 } 9131 } 9132 9133 // maybe 9134 if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdOptional) { 9135 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, 9136 actual_type->data.maybe.child_type, source_node, wanted_is_mutable); 9137 if (child.id == ConstCastResultIdInvalid) 9138 return child; 9139 if (child.id != ConstCastResultIdOk) { 9140 result.id = ConstCastResultIdOptionalChild; 9141 result.data.optional = allocate_nonzero<ConstCastOptionalMismatch>(1); 9142 result.data.optional->child = child; 9143 result.data.optional->wanted_child = wanted_type->data.maybe.child_type; 9144 result.data.optional->actual_child = actual_type->data.maybe.child_type; 9145 } 9146 return result; 9147 } 9148 9149 // error union 9150 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id == ZigTypeIdErrorUnion) { 9151 ConstCastOnly payload_child = types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, 9152 actual_type->data.error_union.payload_type, source_node, wanted_is_mutable); 9153 if (payload_child.id == ConstCastResultIdInvalid) 9154 return payload_child; 9155 if (payload_child.id != ConstCastResultIdOk) { 9156 result.id = ConstCastResultIdErrorUnionPayload; 9157 result.data.error_union_payload = allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1); 9158 result.data.error_union_payload->child = payload_child; 9159 result.data.error_union_payload->wanted_payload = wanted_type->data.error_union.payload_type; 9160 result.data.error_union_payload->actual_payload = actual_type->data.error_union.payload_type; 9161 return result; 9162 } 9163 ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type, 9164 actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable); 9165 if (error_set_child.id == ConstCastResultIdInvalid) 9166 return error_set_child; 9167 if (error_set_child.id != ConstCastResultIdOk) { 9168 result.id = ConstCastResultIdErrorUnionErrorSet; 9169 result.data.error_union_error_set = allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1); 9170 result.data.error_union_error_set->child = error_set_child; 9171 result.data.error_union_error_set->wanted_err_set = wanted_type->data.error_union.err_set_type; 9172 result.data.error_union_error_set->actual_err_set = actual_type->data.error_union.err_set_type; 9173 return result; 9174 } 9175 return result; 9176 } 9177 9178 // error set 9179 if (wanted_type->id == ZigTypeIdErrorSet && actual_type->id == ZigTypeIdErrorSet) { 9180 ZigType *contained_set = actual_type; 9181 ZigType *container_set = wanted_type; 9182 9183 // if the container set is inferred, then this will always work. 9184 if (container_set->data.error_set.infer_fn != nullptr) { 9185 return result; 9186 } 9187 // if the container set is the global one, it will always work. 9188 if (type_is_global_error_set(container_set)) { 9189 return result; 9190 } 9191 9192 if (!resolve_inferred_error_set(ira->codegen, contained_set, source_node)) { 9193 result.id = ConstCastResultIdUnresolvedInferredErrSet; 9194 return result; 9195 } 9196 9197 if (type_is_global_error_set(contained_set)) { 9198 result.id = ConstCastResultIdErrSetGlobal; 9199 return result; 9200 } 9201 9202 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(g->errors_by_index.length); 9203 for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) { 9204 ErrorTableEntry *error_entry = container_set->data.error_set.errors[i]; 9205 assert(errors[error_entry->value] == nullptr); 9206 errors[error_entry->value] = error_entry; 9207 } 9208 for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) { 9209 ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i]; 9210 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9211 if (error_entry == nullptr) { 9212 if (result.id == ConstCastResultIdOk) { 9213 result.id = ConstCastResultIdErrSet; 9214 result.data.error_set_mismatch = allocate<ConstCastErrSetMismatch>(1); 9215 } 9216 result.data.error_set_mismatch->missing_errors.append(contained_error_entry); 9217 } 9218 } 9219 free(errors); 9220 return result; 9221 } 9222 9223 if (wanted_type == ira->codegen->builtin_types.entry_promise && 9224 actual_type->id == ZigTypeIdPromise) 9225 { 9226 return result; 9227 } 9228 9229 // fn 9230 if (wanted_type->id == ZigTypeIdFn && 9231 actual_type->id == ZigTypeIdFn) 9232 { 9233 if (wanted_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) { 9234 result.id = ConstCastResultIdFnAlign; 9235 return result; 9236 } 9237 if (wanted_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) { 9238 result.id = ConstCastResultIdFnCC; 9239 return result; 9240 } 9241 if (wanted_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) { 9242 result.id = ConstCastResultIdFnVarArgs; 9243 return result; 9244 } 9245 if (wanted_type->data.fn.is_generic != actual_type->data.fn.is_generic) { 9246 result.id = ConstCastResultIdFnIsGeneric; 9247 return result; 9248 } 9249 if (!wanted_type->data.fn.is_generic && 9250 actual_type->data.fn.fn_type_id.return_type->id != ZigTypeIdUnreachable) 9251 { 9252 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.fn.fn_type_id.return_type, 9253 actual_type->data.fn.fn_type_id.return_type, source_node, false); 9254 if (child.id == ConstCastResultIdInvalid) 9255 return child; 9256 if (child.id != ConstCastResultIdOk) { 9257 result.id = ConstCastResultIdFnReturnType; 9258 result.data.return_type = allocate_nonzero<ConstCastOnly>(1); 9259 *result.data.return_type = child; 9260 return result; 9261 } 9262 } 9263 if (!wanted_type->data.fn.is_generic && wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync) { 9264 ConstCastOnly child = types_match_const_cast_only(ira, 9265 actual_type->data.fn.fn_type_id.async_allocator_type, 9266 wanted_type->data.fn.fn_type_id.async_allocator_type, 9267 source_node, false); 9268 if (child.id == ConstCastResultIdInvalid) 9269 return child; 9270 if (child.id != ConstCastResultIdOk) { 9271 result.id = ConstCastResultIdAsyncAllocatorType; 9272 result.data.async_allocator_type = allocate_nonzero<ConstCastOnly>(1); 9273 *result.data.async_allocator_type = child; 9274 return result; 9275 } 9276 } 9277 if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { 9278 result.id = ConstCastResultIdFnArgCount; 9279 return result; 9280 } 9281 if (wanted_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) { 9282 result.id = ConstCastResultIdFnGenericArgCount; 9283 return result; 9284 } 9285 assert(wanted_type->data.fn.is_generic || 9286 wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count); 9287 for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.next_param_index; i += 1) { 9288 // note it's reversed for parameters 9289 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i]; 9290 FnTypeParamInfo *expected_param_info = &wanted_type->data.fn.fn_type_id.param_info[i]; 9291 9292 ConstCastOnly arg_child = types_match_const_cast_only(ira, actual_param_info->type, 9293 expected_param_info->type, source_node, false); 9294 if (arg_child.id == ConstCastResultIdInvalid) 9295 return arg_child; 9296 if (arg_child.id != ConstCastResultIdOk) { 9297 result.id = ConstCastResultIdFnArg; 9298 result.data.fn_arg.arg_index = i; 9299 result.data.fn_arg.actual_param_type = actual_param_info->type; 9300 result.data.fn_arg.expected_param_type = expected_param_info->type; 9301 result.data.fn_arg.child = allocate_nonzero<ConstCastOnly>(1); 9302 *result.data.fn_arg.child = arg_child; 9303 return result; 9304 } 9305 9306 if (expected_param_info->is_noalias != actual_param_info->is_noalias) { 9307 result.id = ConstCastResultIdFnArgNoAlias; 9308 result.data.arg_no_alias.arg_index = i; 9309 return result; 9310 } 9311 } 9312 return result; 9313 } 9314 9315 result.id = ConstCastResultIdType; 9316 result.data.type_mismatch = allocate_nonzero<ConstCastTypeMismatch>(1); 9317 result.data.type_mismatch->wanted_type = wanted_type; 9318 result.data.type_mismatch->actual_type = actual_type; 9319 return result; 9320 } 9321 9322 static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) { 9323 size_t old_errors_count = *errors_count; 9324 *errors_count = g->errors_by_index.length; 9325 *errors = reallocate(*errors, old_errors_count, *errors_count); 9326 } 9327 9328 static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type, 9329 IrInstruction **instructions, size_t instruction_count) 9330 { 9331 Error err; 9332 assert(instruction_count >= 1); 9333 IrInstruction *prev_inst = instructions[0]; 9334 if (type_is_invalid(prev_inst->value.type)) { 9335 return ira->codegen->builtin_types.entry_invalid; 9336 } 9337 ErrorTableEntry **errors = nullptr; 9338 size_t errors_count = 0; 9339 ZigType *err_set_type = nullptr; 9340 if (prev_inst->value.type->id == ZigTypeIdErrorSet) { 9341 if (!resolve_inferred_error_set(ira->codegen, prev_inst->value.type, prev_inst->source_node)) { 9342 return ira->codegen->builtin_types.entry_invalid; 9343 } 9344 if (type_is_global_error_set(prev_inst->value.type)) { 9345 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9346 } else { 9347 err_set_type = prev_inst->value.type; 9348 update_errors_helper(ira->codegen, &errors, &errors_count); 9349 9350 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9351 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9352 assert(errors[error_entry->value] == nullptr); 9353 errors[error_entry->value] = error_entry; 9354 } 9355 } 9356 } 9357 9358 bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull); 9359 bool convert_to_const_slice = false; 9360 for (size_t i = 1; i < instruction_count; i += 1) { 9361 IrInstruction *cur_inst = instructions[i]; 9362 ZigType *cur_type = cur_inst->value.type; 9363 ZigType *prev_type = prev_inst->value.type; 9364 9365 if (type_is_invalid(cur_type)) { 9366 return cur_type; 9367 } 9368 9369 if (prev_type->id == ZigTypeIdUnreachable) { 9370 prev_inst = cur_inst; 9371 continue; 9372 } 9373 9374 if (cur_type->id == ZigTypeIdUnreachable) { 9375 continue; 9376 } 9377 9378 if (prev_type->id == ZigTypeIdErrorSet) { 9379 assert(err_set_type != nullptr); 9380 if (cur_type->id == ZigTypeIdErrorSet) { 9381 if (type_is_global_error_set(err_set_type)) { 9382 continue; 9383 } 9384 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { 9385 return ira->codegen->builtin_types.entry_invalid; 9386 } 9387 if (type_is_global_error_set(cur_type)) { 9388 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9389 prev_inst = cur_inst; 9390 continue; 9391 } 9392 9393 // number of declared errors might have increased now 9394 update_errors_helper(ira->codegen, &errors, &errors_count); 9395 9396 // if err_set_type is a superset of cur_type, keep err_set_type. 9397 // if cur_type is a superset of err_set_type, switch err_set_type to cur_type 9398 bool prev_is_superset = true; 9399 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 9400 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 9401 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9402 if (error_entry == nullptr) { 9403 prev_is_superset = false; 9404 break; 9405 } 9406 } 9407 if (prev_is_superset) { 9408 continue; 9409 } 9410 9411 // unset everything in errors 9412 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9413 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9414 errors[error_entry->value] = nullptr; 9415 } 9416 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 9417 assert(errors[i] == nullptr); 9418 } 9419 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 9420 ErrorTableEntry *error_entry = cur_type->data.error_set.errors[i]; 9421 assert(errors[error_entry->value] == nullptr); 9422 errors[error_entry->value] = error_entry; 9423 } 9424 bool cur_is_superset = true; 9425 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9426 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 9427 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9428 if (error_entry == nullptr) { 9429 cur_is_superset = false; 9430 break; 9431 } 9432 } 9433 if (cur_is_superset) { 9434 err_set_type = cur_type; 9435 prev_inst = cur_inst; 9436 assert(errors != nullptr); 9437 continue; 9438 } 9439 9440 // neither of them are supersets. so we invent a new error set type that is a union of both of them 9441 err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type); 9442 assert(errors != nullptr); 9443 continue; 9444 } else if (cur_type->id == ZigTypeIdErrorUnion) { 9445 if (type_is_global_error_set(err_set_type)) { 9446 prev_inst = cur_inst; 9447 continue; 9448 } 9449 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 9450 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 9451 return ira->codegen->builtin_types.entry_invalid; 9452 } 9453 if (type_is_global_error_set(cur_err_set_type)) { 9454 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9455 prev_inst = cur_inst; 9456 continue; 9457 } 9458 9459 update_errors_helper(ira->codegen, &errors, &errors_count); 9460 9461 // test if err_set_type is a subset of cur_type's error set 9462 // unset everything in errors 9463 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9464 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9465 errors[error_entry->value] = nullptr; 9466 } 9467 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 9468 assert(errors[i] == nullptr); 9469 } 9470 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 9471 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 9472 assert(errors[error_entry->value] == nullptr); 9473 errors[error_entry->value] = error_entry; 9474 } 9475 bool cur_is_superset = true; 9476 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9477 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 9478 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9479 if (error_entry == nullptr) { 9480 cur_is_superset = false; 9481 break; 9482 } 9483 } 9484 if (cur_is_superset) { 9485 err_set_type = cur_err_set_type; 9486 prev_inst = cur_inst; 9487 assert(errors != nullptr); 9488 continue; 9489 } 9490 9491 // not a subset. invent new error set type, union of both of them 9492 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type); 9493 prev_inst = cur_inst; 9494 assert(errors != nullptr); 9495 continue; 9496 } else { 9497 prev_inst = cur_inst; 9498 continue; 9499 } 9500 } 9501 9502 if (cur_type->id == ZigTypeIdErrorSet) { 9503 if (prev_type->id == ZigTypeIdArray) { 9504 convert_to_const_slice = true; 9505 } 9506 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { 9507 return ira->codegen->builtin_types.entry_invalid; 9508 } 9509 if (type_is_global_error_set(cur_type)) { 9510 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9511 continue; 9512 } 9513 if (err_set_type != nullptr && type_is_global_error_set(err_set_type)) { 9514 continue; 9515 } 9516 9517 update_errors_helper(ira->codegen, &errors, &errors_count); 9518 9519 if (err_set_type == nullptr) { 9520 if (prev_type->id == ZigTypeIdErrorUnion) { 9521 err_set_type = prev_type->data.error_union.err_set_type; 9522 } else { 9523 err_set_type = cur_type; 9524 } 9525 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9526 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9527 assert(errors[error_entry->value] == nullptr); 9528 errors[error_entry->value] = error_entry; 9529 } 9530 if (err_set_type == cur_type) { 9531 continue; 9532 } 9533 } 9534 // check if the cur type error set is a subset 9535 bool prev_is_superset = true; 9536 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 9537 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 9538 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9539 if (error_entry == nullptr) { 9540 prev_is_superset = false; 9541 break; 9542 } 9543 } 9544 if (prev_is_superset) { 9545 continue; 9546 } 9547 // not a subset. invent new error set type, union of both of them 9548 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type); 9549 assert(errors != nullptr); 9550 continue; 9551 } 9552 9553 if (prev_type->id == ZigTypeIdErrorUnion && cur_type->id == ZigTypeIdErrorUnion) { 9554 ZigType *prev_payload_type = prev_type->data.error_union.payload_type; 9555 ZigType *cur_payload_type = cur_type->data.error_union.payload_type; 9556 9557 bool const_cast_prev = types_match_const_cast_only(ira, prev_payload_type, cur_payload_type, 9558 source_node, false).id == ConstCastResultIdOk; 9559 bool const_cast_cur = types_match_const_cast_only(ira, cur_payload_type, prev_payload_type, 9560 source_node, false).id == ConstCastResultIdOk; 9561 9562 if (const_cast_prev || const_cast_cur) { 9563 if (const_cast_cur) { 9564 prev_inst = cur_inst; 9565 } 9566 9567 ZigType *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type; 9568 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 9569 9570 if (!resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) { 9571 return ira->codegen->builtin_types.entry_invalid; 9572 } 9573 9574 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 9575 return ira->codegen->builtin_types.entry_invalid; 9576 } 9577 9578 if (type_is_global_error_set(prev_err_set_type) || type_is_global_error_set(cur_err_set_type)) { 9579 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9580 continue; 9581 } 9582 9583 update_errors_helper(ira->codegen, &errors, &errors_count); 9584 9585 if (err_set_type == nullptr) { 9586 err_set_type = prev_err_set_type; 9587 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 9588 ErrorTableEntry *error_entry = prev_err_set_type->data.error_set.errors[i]; 9589 assert(errors[error_entry->value] == nullptr); 9590 errors[error_entry->value] = error_entry; 9591 } 9592 } 9593 bool prev_is_superset = true; 9594 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 9595 ErrorTableEntry *contained_error_entry = cur_err_set_type->data.error_set.errors[i]; 9596 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9597 if (error_entry == nullptr) { 9598 prev_is_superset = false; 9599 break; 9600 } 9601 } 9602 if (prev_is_superset) { 9603 continue; 9604 } 9605 // unset all the errors 9606 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9607 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9608 errors[error_entry->value] = nullptr; 9609 } 9610 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 9611 assert(errors[i] == nullptr); 9612 } 9613 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 9614 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 9615 assert(errors[error_entry->value] == nullptr); 9616 errors[error_entry->value] = error_entry; 9617 } 9618 bool cur_is_superset = true; 9619 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 9620 ErrorTableEntry *contained_error_entry = prev_err_set_type->data.error_set.errors[i]; 9621 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9622 if (error_entry == nullptr) { 9623 cur_is_superset = false; 9624 break; 9625 } 9626 } 9627 if (cur_is_superset) { 9628 err_set_type = cur_err_set_type; 9629 continue; 9630 } 9631 9632 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, prev_err_set_type); 9633 continue; 9634 } 9635 } 9636 9637 if (prev_type->id == ZigTypeIdNull) { 9638 prev_inst = cur_inst; 9639 continue; 9640 } 9641 9642 if (cur_type->id == ZigTypeIdNull) { 9643 any_are_null = true; 9644 continue; 9645 } 9646 9647 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdEnumLiteral) { 9648 TypeEnumField *field = find_enum_type_field(prev_type, cur_inst->value.data.x_enum_literal); 9649 if (field != nullptr) { 9650 continue; 9651 } 9652 } 9653 9654 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdEnumLiteral) { 9655 TypeEnumField *field = find_enum_type_field(cur_type, prev_inst->value.data.x_enum_literal); 9656 if (field != nullptr) { 9657 prev_inst = cur_inst; 9658 continue; 9659 } 9660 } 9661 9662 if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenC && 9663 (cur_type->id == ZigTypeIdComptimeInt || cur_type->id == ZigTypeIdInt)) 9664 { 9665 continue; 9666 } 9667 9668 if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenC && 9669 (prev_type->id == ZigTypeIdComptimeInt || prev_type->id == ZigTypeIdInt)) 9670 { 9671 prev_inst = cur_inst; 9672 continue; 9673 } 9674 9675 if (prev_type->id == ZigTypeIdPointer && cur_type->id == ZigTypeIdPointer) { 9676 if (prev_type->data.pointer.ptr_len == PtrLenC && 9677 types_match_const_cast_only(ira, prev_type->data.pointer.child_type, 9678 cur_type->data.pointer.child_type, source_node, 9679 !prev_type->data.pointer.is_const).id == ConstCastResultIdOk) 9680 { 9681 continue; 9682 } 9683 if (cur_type->data.pointer.ptr_len == PtrLenC && 9684 types_match_const_cast_only(ira, cur_type->data.pointer.child_type, 9685 prev_type->data.pointer.child_type, source_node, 9686 !cur_type->data.pointer.is_const).id == ConstCastResultIdOk) 9687 { 9688 prev_inst = cur_inst; 9689 continue; 9690 } 9691 } 9692 9693 if (types_match_const_cast_only(ira, prev_type, cur_type, source_node, false).id == ConstCastResultIdOk) { 9694 continue; 9695 } 9696 9697 if (types_match_const_cast_only(ira, cur_type, prev_type, source_node, false).id == ConstCastResultIdOk) { 9698 prev_inst = cur_inst; 9699 continue; 9700 } 9701 9702 if (prev_type->id == ZigTypeIdInt && 9703 cur_type->id == ZigTypeIdInt && 9704 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed) 9705 { 9706 if (cur_type->data.integral.bit_count > prev_type->data.integral.bit_count) { 9707 prev_inst = cur_inst; 9708 } 9709 continue; 9710 } 9711 9712 if (prev_type->id == ZigTypeIdFloat && cur_type->id == ZigTypeIdFloat) { 9713 if (cur_type->data.floating.bit_count > prev_type->data.floating.bit_count) { 9714 prev_inst = cur_inst; 9715 } 9716 continue; 9717 } 9718 9719 if (prev_type->id == ZigTypeIdErrorUnion && 9720 types_match_const_cast_only(ira, prev_type->data.error_union.payload_type, cur_type, 9721 source_node, false).id == ConstCastResultIdOk) 9722 { 9723 continue; 9724 } 9725 9726 if (cur_type->id == ZigTypeIdErrorUnion && 9727 types_match_const_cast_only(ira, cur_type->data.error_union.payload_type, prev_type, 9728 source_node, false).id == ConstCastResultIdOk) 9729 { 9730 if (err_set_type != nullptr) { 9731 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 9732 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 9733 return ira->codegen->builtin_types.entry_invalid; 9734 } 9735 if (type_is_global_error_set(cur_err_set_type) || type_is_global_error_set(err_set_type)) { 9736 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9737 prev_inst = cur_inst; 9738 continue; 9739 } 9740 9741 update_errors_helper(ira->codegen, &errors, &errors_count); 9742 9743 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_err_set_type); 9744 } 9745 prev_inst = cur_inst; 9746 continue; 9747 } 9748 9749 if (prev_type->id == ZigTypeIdOptional && 9750 types_match_const_cast_only(ira, prev_type->data.maybe.child_type, cur_type, 9751 source_node, false).id == ConstCastResultIdOk) 9752 { 9753 continue; 9754 } 9755 9756 if (cur_type->id == ZigTypeIdOptional && 9757 types_match_const_cast_only(ira, cur_type->data.maybe.child_type, prev_type, 9758 source_node, false).id == ConstCastResultIdOk) 9759 { 9760 prev_inst = cur_inst; 9761 continue; 9762 } 9763 9764 if (prev_type->id == ZigTypeIdOptional && 9765 types_match_const_cast_only(ira, cur_type, prev_type->data.maybe.child_type, 9766 source_node, false).id == ConstCastResultIdOk) 9767 { 9768 prev_inst = cur_inst; 9769 any_are_null = true; 9770 continue; 9771 } 9772 9773 if (cur_type->id == ZigTypeIdOptional && 9774 types_match_const_cast_only(ira, prev_type, cur_type->data.maybe.child_type, 9775 source_node, false).id == ConstCastResultIdOk) 9776 { 9777 any_are_null = true; 9778 continue; 9779 } 9780 9781 if (cur_type->id == ZigTypeIdUndefined) { 9782 continue; 9783 } 9784 9785 if (prev_type->id == ZigTypeIdUndefined) { 9786 prev_inst = cur_inst; 9787 continue; 9788 } 9789 9790 if (prev_type->id == ZigTypeIdComptimeInt || 9791 prev_type->id == ZigTypeIdComptimeFloat) 9792 { 9793 if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) { 9794 prev_inst = cur_inst; 9795 continue; 9796 } else { 9797 return ira->codegen->builtin_types.entry_invalid; 9798 } 9799 } 9800 9801 if (cur_type->id == ZigTypeIdComptimeInt || 9802 cur_type->id == ZigTypeIdComptimeFloat) 9803 { 9804 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) { 9805 continue; 9806 } else { 9807 return ira->codegen->builtin_types.entry_invalid; 9808 } 9809 } 9810 9811 if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && 9812 cur_type->data.array.len != prev_type->data.array.len && 9813 types_match_const_cast_only(ira, cur_type->data.array.child_type, prev_type->data.array.child_type, 9814 source_node, false).id == ConstCastResultIdOk) 9815 { 9816 convert_to_const_slice = true; 9817 prev_inst = cur_inst; 9818 continue; 9819 } 9820 9821 if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && 9822 cur_type->data.array.len != prev_type->data.array.len && 9823 types_match_const_cast_only(ira, prev_type->data.array.child_type, cur_type->data.array.child_type, 9824 source_node, false).id == ConstCastResultIdOk) 9825 { 9826 convert_to_const_slice = true; 9827 continue; 9828 } 9829 9830 if (cur_type->id == ZigTypeIdArray && is_slice(prev_type) && 9831 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || 9832 cur_type->data.array.len == 0) && 9833 types_match_const_cast_only(ira, 9834 prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, 9835 cur_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 9836 { 9837 convert_to_const_slice = false; 9838 continue; 9839 } 9840 9841 if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) && 9842 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || 9843 prev_type->data.array.len == 0) && 9844 types_match_const_cast_only(ira, 9845 cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, 9846 prev_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 9847 { 9848 prev_inst = cur_inst; 9849 convert_to_const_slice = false; 9850 continue; 9851 } 9852 9853 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdUnion && 9854 (cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 9855 { 9856 if ((err = type_resolve(ira->codegen, cur_type, ResolveStatusZeroBitsKnown))) 9857 return ira->codegen->builtin_types.entry_invalid; 9858 if (cur_type->data.unionation.tag_type == prev_type) { 9859 continue; 9860 } 9861 } 9862 9863 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdUnion && 9864 (prev_type->data.unionation.decl_node->data.container_decl.auto_enum || prev_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 9865 { 9866 if ((err = type_resolve(ira->codegen, prev_type, ResolveStatusZeroBitsKnown))) 9867 return ira->codegen->builtin_types.entry_invalid; 9868 if (prev_type->data.unionation.tag_type == cur_type) { 9869 prev_inst = cur_inst; 9870 continue; 9871 } 9872 } 9873 9874 ErrorMsg *msg = ir_add_error_node(ira, source_node, 9875 buf_sprintf("incompatible types: '%s' and '%s'", 9876 buf_ptr(&prev_type->name), buf_ptr(&cur_type->name))); 9877 add_error_note(ira->codegen, msg, prev_inst->source_node, 9878 buf_sprintf("type '%s' here", buf_ptr(&prev_type->name))); 9879 add_error_note(ira->codegen, msg, cur_inst->source_node, 9880 buf_sprintf("type '%s' here", buf_ptr(&cur_type->name))); 9881 9882 return ira->codegen->builtin_types.entry_invalid; 9883 } 9884 9885 free(errors); 9886 9887 if (convert_to_const_slice) { 9888 assert(prev_inst->value.type->id == ZigTypeIdArray); 9889 ZigType *ptr_type = get_pointer_to_type_extra( 9890 ira->codegen, prev_inst->value.type->data.array.child_type, 9891 true, false, PtrLenUnknown, 9892 0, 0, 0, false); 9893 ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); 9894 if (err_set_type != nullptr) { 9895 return get_error_union_type(ira->codegen, err_set_type, slice_type); 9896 } else { 9897 return slice_type; 9898 } 9899 } else if (err_set_type != nullptr) { 9900 if (prev_inst->value.type->id == ZigTypeIdErrorSet) { 9901 return err_set_type; 9902 } else if (prev_inst->value.type->id == ZigTypeIdErrorUnion) { 9903 ZigType *payload_type = prev_inst->value.type->data.error_union.payload_type; 9904 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 9905 return ira->codegen->builtin_types.entry_invalid; 9906 return get_error_union_type(ira->codegen, err_set_type, payload_type); 9907 } else if (expected_type != nullptr && expected_type->id == ZigTypeIdErrorUnion) { 9908 ZigType *payload_type = expected_type->data.error_union.payload_type; 9909 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 9910 return ira->codegen->builtin_types.entry_invalid; 9911 return get_error_union_type(ira->codegen, err_set_type, payload_type); 9912 } else { 9913 if (prev_inst->value.type->id == ZigTypeIdComptimeInt || 9914 prev_inst->value.type->id == ZigTypeIdComptimeFloat) 9915 { 9916 ir_add_error_node(ira, source_node, 9917 buf_sprintf("unable to make error union out of number literal")); 9918 return ira->codegen->builtin_types.entry_invalid; 9919 } else if (prev_inst->value.type->id == ZigTypeIdNull) { 9920 ir_add_error_node(ira, source_node, 9921 buf_sprintf("unable to make error union out of null literal")); 9922 return ira->codegen->builtin_types.entry_invalid; 9923 } else { 9924 if ((err = type_resolve(ira->codegen, prev_inst->value.type, ResolveStatusSizeKnown))) 9925 return ira->codegen->builtin_types.entry_invalid; 9926 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value.type); 9927 } 9928 } 9929 } else if (any_are_null && prev_inst->value.type->id != ZigTypeIdNull) { 9930 if (prev_inst->value.type->id == ZigTypeIdComptimeInt || 9931 prev_inst->value.type->id == ZigTypeIdComptimeFloat) 9932 { 9933 ir_add_error_node(ira, source_node, 9934 buf_sprintf("unable to make maybe out of number literal")); 9935 return ira->codegen->builtin_types.entry_invalid; 9936 } else if (prev_inst->value.type->id == ZigTypeIdOptional) { 9937 return prev_inst->value.type; 9938 } else { 9939 return get_optional_type(ira->codegen, prev_inst->value.type); 9940 } 9941 } else { 9942 return prev_inst->value.type; 9943 } 9944 } 9945 9946 static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry) { 9947 if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) { 9948 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 9949 if (fn_entry != nullptr) { 9950 fn_entry->alloca_list.append(instruction); 9951 } 9952 } 9953 } 9954 9955 static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { 9956 ConstGlobalRefs *global_refs = dest->global_refs; 9957 assert(!same_global_refs || src->global_refs != nullptr); 9958 *dest = *src; 9959 if (!same_global_refs) { 9960 dest->global_refs = global_refs; 9961 if (dest->type->id == ZigTypeIdStruct) { 9962 dest->data.x_struct.fields = allocate_nonzero<ConstExprValue>(dest->type->data.structure.src_field_count); 9963 memcpy(dest->data.x_struct.fields, src->data.x_struct.fields, sizeof(ConstExprValue) * dest->type->data.structure.src_field_count); 9964 } 9965 } 9966 } 9967 9968 static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_instr, 9969 CastOp cast_op, 9970 ConstExprValue *other_val, ZigType *other_type, 9971 ConstExprValue *const_val, ZigType *new_type) 9972 { 9973 const_val->special = other_val->special; 9974 9975 assert(other_val != const_val); 9976 switch (cast_op) { 9977 case CastOpNoCast: 9978 zig_unreachable(); 9979 case CastOpErrSet: 9980 case CastOpBitCast: 9981 case CastOpPtrOfArrayToSlice: 9982 zig_panic("TODO"); 9983 case CastOpNoop: 9984 { 9985 bool same_global_refs = other_val->special == ConstValSpecialStatic; 9986 copy_const_val(const_val, other_val, same_global_refs); 9987 const_val->type = new_type; 9988 break; 9989 } 9990 case CastOpNumLitToConcrete: 9991 if (other_val->type->id == ZigTypeIdComptimeFloat) { 9992 assert(new_type->id == ZigTypeIdFloat); 9993 switch (new_type->data.floating.bit_count) { 9994 case 16: 9995 const_val->data.x_f16 = bigfloat_to_f16(&other_val->data.x_bigfloat); 9996 break; 9997 case 32: 9998 const_val->data.x_f32 = bigfloat_to_f32(&other_val->data.x_bigfloat); 9999 break; 10000 case 64: 10001 const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat); 10002 break; 10003 case 80: 10004 zig_panic("TODO"); 10005 case 128: 10006 const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat); 10007 break; 10008 default: 10009 zig_unreachable(); 10010 } 10011 } else if (other_val->type->id == ZigTypeIdComptimeInt) { 10012 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint); 10013 } else { 10014 zig_unreachable(); 10015 } 10016 const_val->type = new_type; 10017 break; 10018 case CastOpIntToFloat: 10019 { 10020 assert(new_type->id == ZigTypeIdFloat); 10021 10022 BigFloat bigfloat; 10023 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint); 10024 switch (new_type->data.floating.bit_count) { 10025 case 16: 10026 const_val->data.x_f16 = bigfloat_to_f16(&bigfloat); 10027 break; 10028 case 32: 10029 const_val->data.x_f32 = bigfloat_to_f32(&bigfloat); 10030 break; 10031 case 64: 10032 const_val->data.x_f64 = bigfloat_to_f64(&bigfloat); 10033 break; 10034 case 80: 10035 zig_panic("TODO"); 10036 case 128: 10037 const_val->data.x_f128 = bigfloat_to_f128(&bigfloat); 10038 break; 10039 default: 10040 zig_unreachable(); 10041 } 10042 const_val->special = ConstValSpecialStatic; 10043 break; 10044 } 10045 case CastOpFloatToInt: 10046 float_init_bigint(&const_val->data.x_bigint, other_val); 10047 if (new_type->id == ZigTypeIdInt) { 10048 if (!bigint_fits_in_bits(&const_val->data.x_bigint, new_type->data.integral.bit_count, 10049 new_type->data.integral.is_signed)) 10050 { 10051 Buf *int_buf = buf_alloc(); 10052 bigint_append_buf(int_buf, &const_val->data.x_bigint, 10); 10053 10054 ir_add_error(ira, source_instr, 10055 buf_sprintf("integer value '%s' cannot be stored in type '%s'", 10056 buf_ptr(int_buf), buf_ptr(&new_type->name))); 10057 return false; 10058 } 10059 } 10060 10061 const_val->special = ConstValSpecialStatic; 10062 break; 10063 case CastOpBoolToInt: 10064 bigint_init_unsigned(&const_val->data.x_bigint, other_val->data.x_bool ? 1 : 0); 10065 const_val->special = ConstValSpecialStatic; 10066 break; 10067 } 10068 return true; 10069 } 10070 10071 static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, ZigType *ty) { 10072 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 10073 old_instruction->scope, old_instruction->source_node); 10074 IrInstruction *new_instruction = &const_instruction->base; 10075 new_instruction->value.type = ty; 10076 new_instruction->value.special = ConstValSpecialStatic; 10077 return new_instruction; 10078 } 10079 10080 static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 10081 ZigType *wanted_type, CastOp cast_op, bool need_alloca) 10082 { 10083 if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { 10084 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10085 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, &value->value, value->value.type, 10086 &result->value, wanted_type)) 10087 { 10088 return ira->codegen->invalid_instruction; 10089 } 10090 return result; 10091 } else { 10092 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op); 10093 result->value.type = wanted_type; 10094 if (need_alloca) { 10095 ir_add_alloca(ira, result, wanted_type); 10096 } 10097 return result; 10098 } 10099 } 10100 10101 static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrInstruction *source_instr, 10102 IrInstruction *value, ZigType *wanted_type) 10103 { 10104 assert(value->value.type->id == ZigTypeIdPointer); 10105 10106 Error err; 10107 10108 if ((err = type_resolve(ira->codegen, value->value.type->data.pointer.child_type, 10109 ResolveStatusAlignmentKnown))) 10110 { 10111 return ira->codegen->invalid_instruction; 10112 } 10113 10114 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value.type)); 10115 10116 if (instr_is_comptime(value)) { 10117 ConstExprValue *pointee = const_ptr_pointee(ira, ira->codegen, &value->value, source_instr->source_node); 10118 if (pointee == nullptr) 10119 return ira->codegen->invalid_instruction; 10120 if (pointee->special != ConstValSpecialRuntime) { 10121 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10122 result->value.data.x_ptr.special = ConstPtrSpecialBaseArray; 10123 result->value.data.x_ptr.mut = value->value.data.x_ptr.mut; 10124 result->value.data.x_ptr.data.base_array.array_val = pointee; 10125 result->value.data.x_ptr.data.base_array.elem_index = 0; 10126 result->value.data.x_ptr.data.base_array.is_cstr = false; 10127 return result; 10128 } 10129 } 10130 10131 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 10132 wanted_type, value, CastOpBitCast); 10133 result->value.type = wanted_type; 10134 return result; 10135 } 10136 10137 static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, 10138 IrInstruction *value, ZigType *wanted_type) 10139 { 10140 Error err; 10141 10142 if ((err = type_resolve(ira->codegen, value->value.type->data.pointer.child_type, 10143 ResolveStatusAlignmentKnown))) 10144 { 10145 return ira->codegen->invalid_instruction; 10146 } 10147 10148 wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value.type)); 10149 10150 if (instr_is_comptime(value)) { 10151 ConstExprValue *pointee = const_ptr_pointee(ira, ira->codegen, &value->value, source_instr->source_node); 10152 if (pointee == nullptr) 10153 return ira->codegen->invalid_instruction; 10154 if (pointee->special != ConstValSpecialRuntime) { 10155 assert(value->value.type->id == ZigTypeIdPointer); 10156 ZigType *array_type = value->value.type->data.pointer.child_type; 10157 assert(is_slice(wanted_type)); 10158 bool is_const = wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; 10159 10160 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10161 init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const); 10162 result->value.data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = 10163 value->value.data.x_ptr.mut; 10164 result->value.type = wanted_type; 10165 return result; 10166 } 10167 } 10168 10169 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 10170 wanted_type, value, CastOpPtrOfArrayToSlice); 10171 result->value.type = wanted_type; 10172 ir_add_alloca(ira, result, wanted_type); 10173 return result; 10174 } 10175 10176 static bool is_container(ZigType *type) { 10177 return type->id == ZigTypeIdStruct || 10178 type->id == ZigTypeIdEnum || 10179 type->id == ZigTypeIdUnion; 10180 } 10181 10182 static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { 10183 assert(old_bb); 10184 10185 if (old_bb->other) { 10186 if (ref_old_instruction == nullptr || old_bb->other->ref_instruction != ref_old_instruction) { 10187 return old_bb->other; 10188 } 10189 } 10190 10191 IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb); 10192 new_bb->ref_instruction = ref_old_instruction; 10193 10194 return new_bb; 10195 } 10196 10197 static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { 10198 assert(ref_old_instruction != nullptr); 10199 IrBasicBlock *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction); 10200 if (new_bb->must_be_comptime_source_instr) { 10201 ErrorMsg *msg = ir_add_error(ira, ref_old_instruction, 10202 buf_sprintf("control flow attempts to use compile-time variable at runtime")); 10203 add_error_note(ira->codegen, msg, new_bb->must_be_comptime_source_instr->source_node, 10204 buf_sprintf("compile-time variable assigned here")); 10205 return nullptr; 10206 } 10207 return new_bb; 10208 } 10209 10210 static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { 10211 ira->instruction_index = 0; 10212 ira->old_irb.current_basic_block = old_bb; 10213 ira->const_predecessor_bb = const_predecessor_bb; 10214 } 10215 10216 static void ir_finish_bb(IrAnalyze *ira) { 10217 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); 10218 ira->instruction_index += 1; 10219 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { 10220 IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 10221 if (!next_instruction->is_gen) { 10222 ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); 10223 break; 10224 } 10225 ira->instruction_index += 1; 10226 } 10227 10228 size_t my_old_bb_index = ira->old_bb_index; 10229 ira->old_bb_index += 1; 10230 10231 bool need_repeat = true; 10232 for (;;) { 10233 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 10234 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 10235 if (old_bb->other == nullptr) { 10236 ira->old_bb_index += 1; 10237 continue; 10238 } 10239 if (old_bb->other->instruction_list.length != 0 || ira->old_bb_index == my_old_bb_index) { 10240 ira->old_bb_index += 1; 10241 continue; 10242 } 10243 ira->new_irb.current_basic_block = old_bb->other; 10244 10245 ir_start_bb(ira, old_bb, nullptr); 10246 return; 10247 } 10248 if (!need_repeat) 10249 return; 10250 need_repeat = false; 10251 ira->old_bb_index = 0; 10252 continue; 10253 } 10254 } 10255 10256 static IrInstruction *ir_unreach_error(IrAnalyze *ira) { 10257 ira->old_bb_index = SIZE_MAX; 10258 ira->new_irb.exec->invalid = true; 10259 return ira->codegen->unreach_instruction; 10260 } 10261 10262 static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instruction) { 10263 size_t *bbc = ira->new_irb.exec->backward_branch_count; 10264 size_t *quota = ira->new_irb.exec->backward_branch_quota; 10265 10266 // If we're already over quota, we've already given an error message for this. 10267 if (*bbc > *quota) { 10268 assert(ira->codegen->errors.length > 0); 10269 return false; 10270 } 10271 10272 *bbc += 1; 10273 if (*bbc > *quota) { 10274 ir_add_error(ira, source_instruction, 10275 buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", *quota)); 10276 return false; 10277 } 10278 return true; 10279 } 10280 10281 static IrInstruction *ir_inline_bb(IrAnalyze *ira, IrInstruction *source_instruction, IrBasicBlock *old_bb) { 10282 if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) { 10283 if (!ir_emit_backward_branch(ira, source_instruction)) 10284 return ir_unreach_error(ira); 10285 } 10286 10287 old_bb->other = ira->old_irb.current_basic_block->other; 10288 ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block); 10289 return ira->codegen->unreach_instruction; 10290 } 10291 10292 static IrInstruction *ir_finish_anal(IrAnalyze *ira, IrInstruction *instruction) { 10293 if (instruction->value.type->id == ZigTypeIdUnreachable) 10294 ir_finish_bb(ira); 10295 return instruction; 10296 } 10297 10298 static IrInstruction *ir_const_type(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { 10299 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_type); 10300 result->value.data.x_type = ty; 10301 return result; 10302 } 10303 10304 static IrInstruction *ir_const_bool(IrAnalyze *ira, IrInstruction *source_instruction, bool value) { 10305 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_bool); 10306 result->value.data.x_bool = value; 10307 return result; 10308 } 10309 10310 static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { 10311 IrInstruction *result = ir_const(ira, source_instruction, ty); 10312 result->value.special = ConstValSpecialUndef; 10313 return result; 10314 } 10315 10316 static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { 10317 return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void); 10318 } 10319 10320 static IrInstruction *ir_const_unsigned(IrAnalyze *ira, IrInstruction *source_instruction, uint64_t value) { 10321 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_num_lit_int); 10322 bigint_init_unsigned(&result->value.data.x_bigint, value); 10323 return result; 10324 } 10325 10326 static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instruction, 10327 ConstExprValue *pointee, ZigType *pointee_type, 10328 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align) 10329 { 10330 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type, 10331 ptr_is_const, ptr_is_volatile, PtrLenSingle, ptr_align, 0, 0, false); 10332 IrInstruction *const_instr = ir_const(ira, instruction, ptr_type); 10333 ConstExprValue *const_val = &const_instr->value; 10334 const_val->data.x_ptr.special = ConstPtrSpecialRef; 10335 const_val->data.x_ptr.mut = ptr_mut; 10336 const_val->data.x_ptr.data.ref.pointee = pointee; 10337 return const_instr; 10338 } 10339 10340 static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { 10341 switch (value->value.special) { 10342 case ConstValSpecialStatic: 10343 return &value->value; 10344 case ConstValSpecialRuntime: 10345 if (!type_has_bits(value->value.type)) { 10346 return &value->value; 10347 } 10348 ir_add_error(ira, value, buf_sprintf("unable to evaluate constant expression")); 10349 return nullptr; 10350 case ConstValSpecialUndef: 10351 if (undef_allowed == UndefOk) { 10352 return &value->value; 10353 } else { 10354 ir_add_error(ira, value, buf_sprintf("use of undefined value here causes undefined behavior")); 10355 return nullptr; 10356 } 10357 } 10358 zig_unreachable(); 10359 } 10360 10361 ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, 10362 ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota, 10363 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, 10364 IrExecutable *parent_exec, AstNode *expected_type_source_node) 10365 { 10366 if (expected_type != nullptr && type_is_invalid(expected_type)) 10367 return &codegen->invalid_instruction->value; 10368 10369 IrExecutable *ir_executable = allocate<IrExecutable>(1); 10370 ir_executable->source_node = source_node; 10371 ir_executable->parent_exec = parent_exec; 10372 ir_executable->name = exec_name; 10373 ir_executable->is_inline = true; 10374 ir_executable->fn_entry = fn_entry; 10375 ir_executable->c_import_buf = c_import_buf; 10376 ir_executable->begin_scope = scope; 10377 ir_gen(codegen, node, scope, ir_executable); 10378 10379 if (ir_executable->invalid) 10380 return &codegen->invalid_instruction->value; 10381 10382 if (codegen->verbose_ir) { 10383 fprintf(stderr, "\nSource: "); 10384 ast_render(stderr, node, 4); 10385 fprintf(stderr, "\n{ // (IR)\n"); 10386 ir_print(codegen, stderr, ir_executable, 2); 10387 fprintf(stderr, "}\n"); 10388 } 10389 IrExecutable *analyzed_executable = allocate<IrExecutable>(1); 10390 analyzed_executable->source_node = source_node; 10391 analyzed_executable->parent_exec = parent_exec; 10392 analyzed_executable->source_exec = ir_executable; 10393 analyzed_executable->name = exec_name; 10394 analyzed_executable->is_inline = true; 10395 analyzed_executable->fn_entry = fn_entry; 10396 analyzed_executable->c_import_buf = c_import_buf; 10397 analyzed_executable->backward_branch_count = backward_branch_count; 10398 analyzed_executable->backward_branch_quota = backward_branch_quota; 10399 analyzed_executable->begin_scope = scope; 10400 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, expected_type_source_node); 10401 if (type_is_invalid(result_type)) 10402 return &codegen->invalid_instruction->value; 10403 10404 if (codegen->verbose_ir) { 10405 fprintf(stderr, "{ // (analyzed)\n"); 10406 ir_print(codegen, stderr, analyzed_executable, 2); 10407 fprintf(stderr, "}\n"); 10408 } 10409 10410 return ir_exec_const_result(codegen, analyzed_executable); 10411 } 10412 10413 static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { 10414 if (type_is_invalid(type_value->value.type)) 10415 return ira->codegen->builtin_types.entry_invalid; 10416 10417 if (type_value->value.type->id != ZigTypeIdMetaType) { 10418 ir_add_error(ira, type_value, 10419 buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value.type->name))); 10420 return ira->codegen->builtin_types.entry_invalid; 10421 } 10422 10423 ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad); 10424 if (!const_val) 10425 return ira->codegen->builtin_types.entry_invalid; 10426 10427 assert(const_val->data.x_type != nullptr); 10428 return const_val->data.x_type; 10429 } 10430 10431 static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInstruction *op_source, IrInstruction *type_value) { 10432 if (type_is_invalid(type_value->value.type)) 10433 return ira->codegen->builtin_types.entry_invalid; 10434 10435 if (type_value->value.type->id != ZigTypeIdMetaType) { 10436 ErrorMsg *msg = ir_add_error(ira, type_value, 10437 buf_sprintf("expected error set type, found '%s'", buf_ptr(&type_value->value.type->name))); 10438 add_error_note(ira->codegen, msg, op_source->source_node, 10439 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 10440 return ira->codegen->builtin_types.entry_invalid; 10441 } 10442 10443 ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad); 10444 if (!const_val) 10445 return ira->codegen->builtin_types.entry_invalid; 10446 10447 assert(const_val->data.x_type != nullptr); 10448 ZigType *result_type = const_val->data.x_type; 10449 if (result_type->id != ZigTypeIdErrorSet) { 10450 ErrorMsg *msg = ir_add_error(ira, type_value, 10451 buf_sprintf("expected error set type, found type '%s'", buf_ptr(&result_type->name))); 10452 add_error_note(ira->codegen, msg, op_source->source_node, 10453 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 10454 return ira->codegen->builtin_types.entry_invalid; 10455 } 10456 return result_type; 10457 } 10458 10459 static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { 10460 if (fn_value == ira->codegen->invalid_instruction) 10461 return nullptr; 10462 10463 if (type_is_invalid(fn_value->value.type)) 10464 return nullptr; 10465 10466 if (fn_value->value.type->id != ZigTypeIdFn) { 10467 ir_add_error_node(ira, fn_value->source_node, 10468 buf_sprintf("expected function type, found '%s'", buf_ptr(&fn_value->value.type->name))); 10469 return nullptr; 10470 } 10471 10472 ConstExprValue *const_val = ir_resolve_const(ira, fn_value, UndefBad); 10473 if (!const_val) 10474 return nullptr; 10475 10476 assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction); 10477 return const_val->data.x_ptr.data.fn.fn_entry; 10478 } 10479 10480 static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 10481 ZigType *wanted_type) 10482 { 10483 assert(wanted_type->id == ZigTypeIdOptional); 10484 10485 if (instr_is_comptime(value)) { 10486 ZigType *payload_type = wanted_type->data.maybe.child_type; 10487 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); 10488 if (type_is_invalid(casted_payload->value.type)) 10489 return ira->codegen->invalid_instruction; 10490 10491 ConstExprValue *val = ir_resolve_const(ira, casted_payload, UndefOk); 10492 if (!val) 10493 return ira->codegen->invalid_instruction; 10494 10495 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 10496 source_instr->scope, source_instr->source_node); 10497 const_instruction->base.value.special = ConstValSpecialStatic; 10498 if (types_have_same_zig_comptime_repr(wanted_type, payload_type)) { 10499 copy_const_val(&const_instruction->base.value, val, val->data.x_ptr.mut == ConstPtrMutComptimeConst); 10500 } else { 10501 const_instruction->base.value.data.x_optional = val; 10502 } 10503 const_instruction->base.value.type = wanted_type; 10504 return &const_instruction->base; 10505 } 10506 10507 IrInstruction *result = ir_build_maybe_wrap(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 10508 result->value.type = wanted_type; 10509 result->value.data.rh_maybe = RuntimeHintOptionalNonNull; 10510 ir_add_alloca(ira, result, wanted_type); 10511 return result; 10512 } 10513 10514 static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, 10515 IrInstruction *value, ZigType *wanted_type) 10516 { 10517 assert(wanted_type->id == ZigTypeIdErrorUnion); 10518 10519 if (instr_is_comptime(value)) { 10520 ZigType *payload_type = wanted_type->data.error_union.payload_type; 10521 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); 10522 if (type_is_invalid(casted_payload->value.type)) 10523 return ira->codegen->invalid_instruction; 10524 10525 ConstExprValue *val = ir_resolve_const(ira, casted_payload, UndefBad); 10526 if (!val) 10527 return ira->codegen->invalid_instruction; 10528 10529 ConstExprValue *err_set_val = create_const_vals(1); 10530 err_set_val->type = wanted_type->data.error_union.err_set_type; 10531 err_set_val->special = ConstValSpecialStatic; 10532 err_set_val->data.x_err_set = nullptr; 10533 10534 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 10535 source_instr->scope, source_instr->source_node); 10536 const_instruction->base.value.type = wanted_type; 10537 const_instruction->base.value.special = ConstValSpecialStatic; 10538 const_instruction->base.value.data.x_err_union.error_set = err_set_val; 10539 const_instruction->base.value.data.x_err_union.payload = val; 10540 return &const_instruction->base; 10541 } 10542 10543 IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 10544 result->value.type = wanted_type; 10545 result->value.data.rh_error_union = RuntimeHintErrorUnionNonError; 10546 ir_add_alloca(ira, result, wanted_type); 10547 return result; 10548 } 10549 10550 static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 10551 ZigType *wanted_type) 10552 { 10553 assert(value->value.type->id == ZigTypeIdErrorSet); 10554 assert(wanted_type->id == ZigTypeIdErrorSet); 10555 10556 if (instr_is_comptime(value)) { 10557 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 10558 if (!val) 10559 return ira->codegen->invalid_instruction; 10560 10561 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 10562 return ira->codegen->invalid_instruction; 10563 } 10564 if (!type_is_global_error_set(wanted_type)) { 10565 bool subset = false; 10566 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 10567 if (wanted_type->data.error_set.errors[i]->value == val->data.x_err_set->value) { 10568 subset = true; 10569 break; 10570 } 10571 } 10572 if (!subset) { 10573 ir_add_error(ira, source_instr, 10574 buf_sprintf("error.%s not a member of error set '%s'", 10575 buf_ptr(&val->data.x_err_set->name), buf_ptr(&wanted_type->name))); 10576 return ira->codegen->invalid_instruction; 10577 } 10578 } 10579 10580 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 10581 source_instr->scope, source_instr->source_node); 10582 const_instruction->base.value.type = wanted_type; 10583 const_instruction->base.value.special = ConstValSpecialStatic; 10584 const_instruction->base.value.data.x_err_set = val->data.x_err_set; 10585 return &const_instruction->base; 10586 } 10587 10588 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, CastOpErrSet); 10589 result->value.type = wanted_type; 10590 return result; 10591 } 10592 10593 static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { 10594 assert(wanted_type->id == ZigTypeIdErrorUnion); 10595 10596 IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); 10597 10598 if (instr_is_comptime(casted_value)) { 10599 ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad); 10600 if (!val) 10601 return ira->codegen->invalid_instruction; 10602 10603 ConstExprValue *err_set_val = create_const_vals(1); 10604 err_set_val->special = ConstValSpecialStatic; 10605 err_set_val->type = wanted_type->data.error_union.err_set_type; 10606 err_set_val->data.x_err_set = val->data.x_err_set; 10607 10608 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 10609 source_instr->scope, source_instr->source_node); 10610 const_instruction->base.value.type = wanted_type; 10611 const_instruction->base.value.special = ConstValSpecialStatic; 10612 const_instruction->base.value.data.x_err_union.error_set = err_set_val; 10613 const_instruction->base.value.data.x_err_union.payload = nullptr; 10614 return &const_instruction->base; 10615 } 10616 10617 IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 10618 result->value.type = wanted_type; 10619 result->value.data.rh_error_union = RuntimeHintErrorUnionError; 10620 ir_add_alloca(ira, result, wanted_type); 10621 return result; 10622 } 10623 10624 static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { 10625 assert(wanted_type->id == ZigTypeIdOptional); 10626 assert(instr_is_comptime(value)); 10627 10628 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 10629 assert(val != nullptr); 10630 10631 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10632 result->value.special = ConstValSpecialStatic; 10633 if (get_codegen_ptr_type(wanted_type) != nullptr) { 10634 result->value.data.x_ptr.special = ConstPtrSpecialNull; 10635 } else if (is_opt_err_set(wanted_type)) { 10636 result->value.data.x_err_set = nullptr; 10637 } else { 10638 result->value.data.x_optional = nullptr; 10639 } 10640 return result; 10641 } 10642 10643 static IrInstruction *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInstruction *source_instr, 10644 IrInstruction *value, ZigType *wanted_type) 10645 { 10646 assert(wanted_type->id == ZigTypeIdPointer); 10647 assert(wanted_type->data.pointer.ptr_len == PtrLenC); 10648 assert(instr_is_comptime(value)); 10649 10650 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 10651 assert(val != nullptr); 10652 10653 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10654 result->value.data.x_ptr.special = ConstPtrSpecialNull; 10655 result->value.data.x_ptr.mut = ConstPtrMutComptimeConst; 10656 return result; 10657 } 10658 10659 static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value, 10660 bool is_const, bool is_volatile) 10661 { 10662 Error err; 10663 10664 if (type_is_invalid(value->value.type)) 10665 return ira->codegen->invalid_instruction; 10666 10667 if ((err = type_resolve(ira->codegen, value->value.type, ResolveStatusZeroBitsKnown))) 10668 return ira->codegen->invalid_instruction; 10669 10670 if (instr_is_comptime(value)) { 10671 ConstExprValue *val = ir_resolve_const(ira, value, UndefOk); 10672 if (!val) 10673 return ira->codegen->invalid_instruction; 10674 return ir_get_const_ptr(ira, source_instruction, val, value->value.type, 10675 ConstPtrMutComptimeConst, is_const, is_volatile, 0); 10676 } 10677 10678 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, 10679 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 10680 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope, 10681 source_instruction->source_node, value, is_const, is_volatile); 10682 new_instruction->value.type = ptr_type; 10683 new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; 10684 if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) { 10685 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 10686 assert(fn_entry); 10687 fn_entry->alloca_list.append(new_instruction); 10688 } 10689 return new_instruction; 10690 } 10691 10692 static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, 10693 IrInstruction *array_arg, ZigType *wanted_type) 10694 { 10695 assert(is_slice(wanted_type)); 10696 // In this function we honor the const-ness of wanted_type, because 10697 // we may be casting [0]T to []const T which is perfectly valid. 10698 10699 IrInstruction *array_ptr = nullptr; 10700 IrInstruction *array; 10701 if (array_arg->value.type->id == ZigTypeIdPointer) { 10702 array = ir_get_deref(ira, source_instr, array_arg); 10703 array_ptr = array_arg; 10704 } else { 10705 array = array_arg; 10706 } 10707 ZigType *array_type = array->value.type; 10708 assert(array_type->id == ZigTypeIdArray); 10709 10710 if (instr_is_comptime(array) || array_type->data.array.len == 0) { 10711 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10712 init_const_slice(ira->codegen, &result->value, &array->value, 0, array_type->data.array.len, true); 10713 result->value.type = wanted_type; 10714 return result; 10715 } 10716 10717 IrInstruction *start = ir_const(ira, source_instr, ira->codegen->builtin_types.entry_usize); 10718 init_const_usize(ira->codegen, &start->value, 0); 10719 10720 IrInstruction *end = ir_const(ira, source_instr, ira->codegen->builtin_types.entry_usize); 10721 init_const_usize(ira->codegen, &end->value, array_type->data.array.len); 10722 10723 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false); 10724 10725 IrInstruction *result = ir_build_slice(&ira->new_irb, source_instr->scope, 10726 source_instr->source_node, array_ptr, start, end, false); 10727 result->value.type = wanted_type; 10728 result->value.data.rh_slice.id = RuntimeHintSliceIdLen; 10729 result->value.data.rh_slice.len = array_type->data.array.len; 10730 ir_add_alloca(ira, result, result->value.type); 10731 10732 return result; 10733 } 10734 10735 static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, IrInstruction *source_instr, ZigType *union_type) { 10736 assert(union_type->id == ZigTypeIdUnion); 10737 10738 Error err; 10739 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) 10740 return ira->codegen->builtin_types.entry_invalid; 10741 10742 AstNode *decl_node = union_type->data.unionation.decl_node; 10743 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) { 10744 assert(union_type->data.unionation.tag_type != nullptr); 10745 return union_type->data.unionation.tag_type; 10746 } else { 10747 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union '%s' has no tag", 10748 buf_ptr(&union_type->name))); 10749 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here")); 10750 return ira->codegen->builtin_types.entry_invalid; 10751 } 10752 } 10753 10754 static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target) { 10755 Error err; 10756 10757 IrInstruction *enum_target; 10758 ZigType *enum_type; 10759 if (target->value.type->id == ZigTypeIdUnion) { 10760 enum_type = ir_resolve_union_tag_type(ira, target, target->value.type); 10761 if (type_is_invalid(enum_type)) 10762 return ira->codegen->invalid_instruction; 10763 enum_target = ir_implicit_cast(ira, target, enum_type); 10764 if (type_is_invalid(enum_target->value.type)) 10765 return ira->codegen->invalid_instruction; 10766 } else if (target->value.type->id == ZigTypeIdEnum) { 10767 enum_target = target; 10768 enum_type = target->value.type; 10769 } else { 10770 ir_add_error(ira, target, 10771 buf_sprintf("expected enum, found type '%s'", buf_ptr(&target->value.type->name))); 10772 return ira->codegen->invalid_instruction; 10773 } 10774 10775 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) 10776 return ira->codegen->invalid_instruction; 10777 10778 ZigType *tag_type = enum_type->data.enumeration.tag_int_type; 10779 assert(tag_type->id == ZigTypeIdInt || tag_type->id == ZigTypeIdComptimeInt); 10780 10781 // If there is only one possible tag, then we know at comptime what it is. 10782 if (enum_type->data.enumeration.layout == ContainerLayoutAuto && 10783 enum_type->data.enumeration.src_field_count == 1) 10784 { 10785 assert(tag_type == ira->codegen->builtin_types.entry_num_lit_int); 10786 IrInstruction *result = ir_const(ira, source_instr, tag_type); 10787 init_const_bigint(&result->value, tag_type, 10788 &enum_type->data.enumeration.fields[0].value); 10789 return result; 10790 } 10791 10792 if (instr_is_comptime(enum_target)) { 10793 ConstExprValue *val = ir_resolve_const(ira, enum_target, UndefBad); 10794 if (!val) 10795 return ira->codegen->invalid_instruction; 10796 IrInstruction *result = ir_const(ira, source_instr, tag_type); 10797 init_const_bigint(&result->value, tag_type, &val->data.x_enum_tag); 10798 return result; 10799 } 10800 10801 IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, 10802 source_instr->source_node, enum_target); 10803 result->value.type = tag_type; 10804 return result; 10805 } 10806 10807 static IrInstruction *ir_analyze_union_to_tag(IrAnalyze *ira, IrInstruction *source_instr, 10808 IrInstruction *target, ZigType *wanted_type) 10809 { 10810 assert(target->value.type->id == ZigTypeIdUnion); 10811 assert(wanted_type->id == ZigTypeIdEnum); 10812 assert(wanted_type == target->value.type->data.unionation.tag_type); 10813 10814 if (instr_is_comptime(target)) { 10815 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10816 if (!val) 10817 return ira->codegen->invalid_instruction; 10818 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10819 result->value.special = ConstValSpecialStatic; 10820 result->value.type = wanted_type; 10821 bigint_init_bigint(&result->value.data.x_enum_tag, &val->data.x_union.tag); 10822 return result; 10823 } 10824 10825 // If there is only 1 possible tag, then we know at comptime what it is. 10826 if (wanted_type->data.enumeration.layout == ContainerLayoutAuto && 10827 wanted_type->data.enumeration.src_field_count == 1) 10828 { 10829 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10830 result->value.special = ConstValSpecialStatic; 10831 result->value.type = wanted_type; 10832 TypeEnumField *enum_field = target->value.type->data.unionation.fields[0].enum_field; 10833 bigint_init_bigint(&result->value.data.x_enum_tag, &enum_field->value); 10834 return result; 10835 } 10836 10837 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, 10838 source_instr->source_node, target); 10839 result->value.type = wanted_type; 10840 return result; 10841 } 10842 10843 static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruction *source_instr, 10844 IrInstruction *target, ZigType *wanted_type) 10845 { 10846 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10847 init_const_undefined(ira->codegen, &result->value); 10848 return result; 10849 } 10850 10851 static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *source_instr, 10852 IrInstruction *target, ZigType *wanted_type) 10853 { 10854 Error err; 10855 assert(wanted_type->id == ZigTypeIdUnion); 10856 assert(target->value.type->id == ZigTypeIdEnum); 10857 10858 if (instr_is_comptime(target)) { 10859 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10860 if (!val) 10861 return ira->codegen->invalid_instruction; 10862 TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); 10863 assert(union_field != nullptr); 10864 if ((err = type_resolve(ira->codegen, union_field->type_entry, ResolveStatusZeroBitsKnown))) 10865 return ira->codegen->invalid_instruction; 10866 10867 switch (type_has_one_possible_value(ira->codegen, union_field->type_entry)) { 10868 case OnePossibleValueInvalid: 10869 return ira->codegen->invalid_instruction; 10870 case OnePossibleValueNo: { 10871 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at( 10872 union_field->enum_field->decl_index); 10873 ErrorMsg *msg = ir_add_error(ira, source_instr, 10874 buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", 10875 buf_ptr(&wanted_type->name), 10876 buf_ptr(&union_field->type_entry->name), 10877 buf_ptr(union_field->name))); 10878 add_error_note(ira->codegen, msg, field_node, 10879 buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); 10880 return ira->codegen->invalid_instruction; 10881 } 10882 case OnePossibleValueYes: 10883 break; 10884 } 10885 10886 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10887 result->value.special = ConstValSpecialStatic; 10888 result->value.type = wanted_type; 10889 bigint_init_bigint(&result->value.data.x_union.tag, &val->data.x_enum_tag); 10890 result->value.data.x_union.payload = create_const_vals(1); 10891 result->value.data.x_union.payload->special = ConstValSpecialStatic; 10892 result->value.data.x_union.payload->type = union_field->type_entry; 10893 return result; 10894 } 10895 10896 // if the union has all fields 0 bits, we can do it 10897 // and in fact it's a noop cast because the union value is just the enum value 10898 if (wanted_type->data.unionation.gen_field_count == 0) { 10899 IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, wanted_type, target, CastOpNoop); 10900 result->value.type = wanted_type; 10901 return result; 10902 } 10903 10904 ErrorMsg *msg = ir_add_error(ira, source_instr, 10905 buf_sprintf("runtime cast to union '%s' which has non-void fields", 10906 buf_ptr(&wanted_type->name))); 10907 for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { 10908 TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; 10909 if (type_has_bits(union_field->type_entry)) { 10910 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); 10911 add_error_note(ira->codegen, msg, field_node, 10912 buf_sprintf("field '%s' has type '%s'", 10913 buf_ptr(union_field->name), 10914 buf_ptr(&union_field->type_entry->name))); 10915 } 10916 } 10917 return ira->codegen->invalid_instruction; 10918 } 10919 10920 static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction *source_instr, 10921 IrInstruction *target, ZigType *wanted_type) 10922 { 10923 assert(wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdFloat); 10924 10925 if (instr_is_comptime(target)) { 10926 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10927 if (!val) 10928 return ira->codegen->invalid_instruction; 10929 if (wanted_type->id == ZigTypeIdInt) { 10930 if (bigint_cmp_zero(&val->data.x_bigint) == CmpLT && !wanted_type->data.integral.is_signed) { 10931 ir_add_error(ira, source_instr, 10932 buf_sprintf("attempt to cast negative value to unsigned integer")); 10933 return ira->codegen->invalid_instruction; 10934 } 10935 if (!bigint_fits_in_bits(&val->data.x_bigint, wanted_type->data.integral.bit_count, 10936 wanted_type->data.integral.is_signed)) 10937 { 10938 ir_add_error(ira, source_instr, 10939 buf_sprintf("cast from '%s' to '%s' truncates bits", 10940 buf_ptr(&target->value.type->name), buf_ptr(&wanted_type->name))); 10941 return ira->codegen->invalid_instruction; 10942 } 10943 } 10944 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10945 result->value.type = wanted_type; 10946 if (wanted_type->id == ZigTypeIdInt) { 10947 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); 10948 } else { 10949 float_init_float(&result->value, val); 10950 } 10951 return result; 10952 } 10953 10954 // If the destination integer type has no bits, then we can emit a comptime 10955 // zero. However, we still want to emit a runtime safety check to make sure 10956 // the target is zero. 10957 if (!type_has_bits(wanted_type)) { 10958 assert(wanted_type->id == ZigTypeIdInt); 10959 assert(type_has_bits(target->value.type)); 10960 ir_build_assert_zero(ira, source_instr, target); 10961 IrInstruction *result = ir_const_unsigned(ira, source_instr, 0); 10962 result->value.type = wanted_type; 10963 return result; 10964 } 10965 10966 IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, 10967 source_instr->source_node, target); 10968 result->value.type = wanted_type; 10969 return result; 10970 } 10971 10972 static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *source_instr, 10973 IrInstruction *target, ZigType *wanted_type) 10974 { 10975 Error err; 10976 assert(wanted_type->id == ZigTypeIdEnum); 10977 10978 ZigType *actual_type = target->value.type; 10979 10980 if ((err = ensure_complete_type(ira->codegen, wanted_type))) 10981 return ira->codegen->invalid_instruction; 10982 10983 if (actual_type != wanted_type->data.enumeration.tag_int_type) { 10984 ir_add_error(ira, source_instr, 10985 buf_sprintf("integer to enum cast from '%s' instead of its tag type, '%s'", 10986 buf_ptr(&actual_type->name), 10987 buf_ptr(&wanted_type->data.enumeration.tag_int_type->name))); 10988 return ira->codegen->invalid_instruction; 10989 } 10990 10991 assert(actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt); 10992 10993 if (instr_is_comptime(target)) { 10994 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10995 if (!val) 10996 return ira->codegen->invalid_instruction; 10997 10998 TypeEnumField *field = find_enum_field_by_tag(wanted_type, &val->data.x_bigint); 10999 if (field == nullptr) { 11000 Buf *val_buf = buf_alloc(); 11001 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 11002 ErrorMsg *msg = ir_add_error(ira, source_instr, 11003 buf_sprintf("enum '%s' has no tag matching integer value %s", 11004 buf_ptr(&wanted_type->name), buf_ptr(val_buf))); 11005 add_error_note(ira->codegen, msg, wanted_type->data.enumeration.decl_node, 11006 buf_sprintf("'%s' declared here", buf_ptr(&wanted_type->name))); 11007 return ira->codegen->invalid_instruction; 11008 } 11009 11010 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11011 bigint_init_bigint(&result->value.data.x_enum_tag, &val->data.x_bigint); 11012 return result; 11013 } 11014 11015 IrInstruction *result = ir_build_int_to_enum(&ira->new_irb, source_instr->scope, 11016 source_instr->source_node, nullptr, target); 11017 result->value.type = wanted_type; 11018 return result; 11019 } 11020 11021 static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction *source_instr, 11022 IrInstruction *target, ZigType *wanted_type) 11023 { 11024 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11025 if (!val) 11026 return ira->codegen->invalid_instruction; 11027 11028 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11029 if (wanted_type->id == ZigTypeIdComptimeFloat) { 11030 float_init_float(&result->value, val); 11031 } else if (wanted_type->id == ZigTypeIdComptimeInt) { 11032 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); 11033 } else { 11034 zig_unreachable(); 11035 } 11036 return result; 11037 } 11038 11039 static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 11040 ZigType *wanted_type) 11041 { 11042 assert(target->value.type->id == ZigTypeIdInt); 11043 assert(!target->value.type->data.integral.is_signed); 11044 assert(wanted_type->id == ZigTypeIdErrorSet); 11045 11046 if (instr_is_comptime(target)) { 11047 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11048 if (!val) 11049 return ira->codegen->invalid_instruction; 11050 11051 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11052 11053 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 11054 return ira->codegen->invalid_instruction; 11055 } 11056 11057 if (type_is_global_error_set(wanted_type)) { 11058 BigInt err_count; 11059 bigint_init_unsigned(&err_count, ira->codegen->errors_by_index.length); 11060 11061 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) { 11062 Buf *val_buf = buf_alloc(); 11063 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 11064 ir_add_error(ira, source_instr, 11065 buf_sprintf("integer value %s represents no error", buf_ptr(val_buf))); 11066 return ira->codegen->invalid_instruction; 11067 } 11068 11069 size_t index = bigint_as_unsigned(&val->data.x_bigint); 11070 result->value.data.x_err_set = ira->codegen->errors_by_index.at(index); 11071 return result; 11072 } else { 11073 ErrorTableEntry *err = nullptr; 11074 BigInt err_int; 11075 11076 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 11077 ErrorTableEntry *this_err = wanted_type->data.error_set.errors[i]; 11078 bigint_init_unsigned(&err_int, this_err->value); 11079 if (bigint_cmp(&val->data.x_bigint, &err_int) == CmpEQ) { 11080 err = this_err; 11081 break; 11082 } 11083 } 11084 11085 if (err == nullptr) { 11086 Buf *val_buf = buf_alloc(); 11087 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 11088 ir_add_error(ira, source_instr, 11089 buf_sprintf("integer value %s represents no error in '%s'", buf_ptr(val_buf), buf_ptr(&wanted_type->name))); 11090 return ira->codegen->invalid_instruction; 11091 } 11092 11093 result->value.data.x_err_set = err; 11094 return result; 11095 } 11096 } 11097 11098 IrInstruction *result = ir_build_int_to_err(&ira->new_irb, source_instr->scope, source_instr->source_node, target); 11099 result->value.type = wanted_type; 11100 return result; 11101 } 11102 11103 static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 11104 ZigType *wanted_type) 11105 { 11106 assert(wanted_type->id == ZigTypeIdInt); 11107 11108 ZigType *err_type = target->value.type; 11109 11110 if (instr_is_comptime(target)) { 11111 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11112 if (!val) 11113 return ira->codegen->invalid_instruction; 11114 11115 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11116 11117 ErrorTableEntry *err; 11118 if (err_type->id == ZigTypeIdErrorUnion) { 11119 err = val->data.x_err_union.error_set->data.x_err_set; 11120 } else if (err_type->id == ZigTypeIdErrorSet) { 11121 err = val->data.x_err_set; 11122 } else { 11123 zig_unreachable(); 11124 } 11125 result->value.type = wanted_type; 11126 uint64_t err_value = err ? err->value : 0; 11127 bigint_init_unsigned(&result->value.data.x_bigint, err_value); 11128 11129 if (!bigint_fits_in_bits(&result->value.data.x_bigint, 11130 wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) 11131 { 11132 ir_add_error_node(ira, source_instr->source_node, 11133 buf_sprintf("error code '%s' does not fit in '%s'", 11134 buf_ptr(&err->name), buf_ptr(&wanted_type->name))); 11135 return ira->codegen->invalid_instruction; 11136 } 11137 11138 return result; 11139 } 11140 11141 ZigType *err_set_type; 11142 if (err_type->id == ZigTypeIdErrorUnion) { 11143 err_set_type = err_type->data.error_union.err_set_type; 11144 } else if (err_type->id == ZigTypeIdErrorSet) { 11145 err_set_type = err_type; 11146 } else { 11147 zig_unreachable(); 11148 } 11149 if (!type_is_global_error_set(err_set_type)) { 11150 if (!resolve_inferred_error_set(ira->codegen, err_set_type, source_instr->source_node)) { 11151 return ira->codegen->invalid_instruction; 11152 } 11153 if (err_set_type->data.error_set.err_count == 0) { 11154 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11155 bigint_init_unsigned(&result->value.data.x_bigint, 0); 11156 return result; 11157 } else if (err_set_type->data.error_set.err_count == 1) { 11158 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11159 ErrorTableEntry *err = err_set_type->data.error_set.errors[0]; 11160 bigint_init_unsigned(&result->value.data.x_bigint, err->value); 11161 return result; 11162 } 11163 } 11164 11165 BigInt bn; 11166 bigint_init_unsigned(&bn, ira->codegen->errors_by_index.length); 11167 if (!bigint_fits_in_bits(&bn, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) { 11168 ir_add_error_node(ira, source_instr->source_node, 11169 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name))); 11170 return ira->codegen->invalid_instruction; 11171 } 11172 11173 IrInstruction *result = ir_build_err_to_int(&ira->new_irb, source_instr->scope, source_instr->source_node, target); 11174 result->value.type = wanted_type; 11175 return result; 11176 } 11177 11178 static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 11179 ZigType *wanted_type) 11180 { 11181 assert(wanted_type->id == ZigTypeIdPointer); 11182 Error err; 11183 if ((err = type_resolve(ira->codegen, target->value.type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 11184 return ira->codegen->invalid_instruction; 11185 assert((wanted_type->data.pointer.is_const && target->value.type->data.pointer.is_const) || !target->value.type->data.pointer.is_const); 11186 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, target->value.type)); 11187 ZigType *array_type = wanted_type->data.pointer.child_type; 11188 assert(array_type->id == ZigTypeIdArray); 11189 assert(array_type->data.array.len == 1); 11190 11191 if (instr_is_comptime(target)) { 11192 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11193 if (!val) 11194 return ira->codegen->invalid_instruction; 11195 11196 assert(val->type->id == ZigTypeIdPointer); 11197 ConstExprValue *pointee = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 11198 if (pointee == nullptr) 11199 return ira->codegen->invalid_instruction; 11200 if (pointee->special != ConstValSpecialRuntime) { 11201 ConstExprValue *array_val = create_const_vals(1); 11202 array_val->special = ConstValSpecialStatic; 11203 array_val->type = array_type; 11204 array_val->data.x_array.special = ConstArraySpecialNone; 11205 array_val->data.x_array.data.s_none.elements = pointee; 11206 array_val->parent.id = ConstParentIdScalar; 11207 array_val->parent.data.p_scalar.scalar_val = pointee; 11208 11209 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 11210 source_instr->scope, source_instr->source_node); 11211 const_instruction->base.value.type = wanted_type; 11212 const_instruction->base.value.special = ConstValSpecialStatic; 11213 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialRef; 11214 const_instruction->base.value.data.x_ptr.data.ref.pointee = array_val; 11215 const_instruction->base.value.data.x_ptr.mut = val->data.x_ptr.mut; 11216 return &const_instruction->base; 11217 } 11218 } 11219 11220 // pointer to array and pointer to single item are represented the same way at runtime 11221 IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, 11222 wanted_type, target, CastOpBitCast); 11223 result->value.type = wanted_type; 11224 return result; 11225 } 11226 11227 static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCastOnly *cast_result, 11228 ErrorMsg *parent_msg) 11229 { 11230 switch (cast_result->id) { 11231 case ConstCastResultIdOk: 11232 zig_unreachable(); 11233 case ConstCastResultIdInvalid: 11234 zig_unreachable(); 11235 case ConstCastResultIdOptionalChild: { 11236 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11237 buf_sprintf("optional type child '%s' cannot cast into optional type child '%s'", 11238 buf_ptr(&cast_result->data.optional->actual_child->name), 11239 buf_ptr(&cast_result->data.optional->wanted_child->name))); 11240 report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg); 11241 break; 11242 } 11243 case ConstCastResultIdErrorUnionErrorSet: { 11244 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11245 buf_sprintf("error set '%s' cannot cast into error set '%s'", 11246 buf_ptr(&cast_result->data.error_union_error_set->actual_err_set->name), 11247 buf_ptr(&cast_result->data.error_union_error_set->wanted_err_set->name))); 11248 report_recursive_error(ira, source_node, &cast_result->data.error_union_error_set->child, msg); 11249 break; 11250 } 11251 case ConstCastResultIdErrSet: { 11252 ZigList<ErrorTableEntry *> *missing_errors = &cast_result->data.error_set_mismatch->missing_errors; 11253 for (size_t i = 0; i < missing_errors->length; i += 1) { 11254 ErrorTableEntry *error_entry = missing_errors->at(i); 11255 add_error_note(ira->codegen, parent_msg, error_entry->decl_node, 11256 buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name))); 11257 } 11258 break; 11259 } 11260 case ConstCastResultIdErrSetGlobal: { 11261 add_error_note(ira->codegen, parent_msg, source_node, 11262 buf_sprintf("cannot cast global error set into smaller set")); 11263 break; 11264 } 11265 case ConstCastResultIdPointerChild: { 11266 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11267 buf_sprintf("pointer type child '%s' cannot cast into pointer type child '%s'", 11268 buf_ptr(&cast_result->data.pointer_mismatch->actual_child->name), 11269 buf_ptr(&cast_result->data.pointer_mismatch->wanted_child->name))); 11270 report_recursive_error(ira, source_node, &cast_result->data.pointer_mismatch->child, msg); 11271 break; 11272 } 11273 case ConstCastResultIdSliceChild: { 11274 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11275 buf_sprintf("slice type child '%s' cannot cast into slice type child '%s'", 11276 buf_ptr(&cast_result->data.slice_mismatch->actual_child->name), 11277 buf_ptr(&cast_result->data.slice_mismatch->wanted_child->name))); 11278 report_recursive_error(ira, source_node, &cast_result->data.slice_mismatch->child, msg); 11279 break; 11280 } 11281 case ConstCastResultIdErrorUnionPayload: { 11282 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11283 buf_sprintf("error union payload '%s' cannot cast into error union payload '%s'", 11284 buf_ptr(&cast_result->data.error_union_payload->actual_payload->name), 11285 buf_ptr(&cast_result->data.error_union_payload->wanted_payload->name))); 11286 report_recursive_error(ira, source_node, &cast_result->data.error_union_payload->child, msg); 11287 break; 11288 } 11289 case ConstCastResultIdType: { 11290 AstNode *wanted_decl_node = type_decl_node(cast_result->data.type_mismatch->wanted_type); 11291 AstNode *actual_decl_node = type_decl_node(cast_result->data.type_mismatch->actual_type); 11292 if (wanted_decl_node != nullptr) { 11293 add_error_note(ira->codegen, parent_msg, wanted_decl_node, 11294 buf_sprintf("%s declared here", 11295 buf_ptr(&cast_result->data.type_mismatch->wanted_type->name))); 11296 } 11297 if (actual_decl_node != nullptr) { 11298 add_error_note(ira->codegen, parent_msg, actual_decl_node, 11299 buf_sprintf("%s declared here", 11300 buf_ptr(&cast_result->data.type_mismatch->actual_type->name))); 11301 } 11302 break; 11303 } 11304 case ConstCastResultIdFnArg: { 11305 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11306 buf_sprintf("parameter %" ZIG_PRI_usize ": '%s' cannot cast into '%s'", 11307 cast_result->data.fn_arg.arg_index, 11308 buf_ptr(&cast_result->data.fn_arg.actual_param_type->name), 11309 buf_ptr(&cast_result->data.fn_arg.expected_param_type->name))); 11310 report_recursive_error(ira, source_node, cast_result->data.fn_arg.child, msg); 11311 break; 11312 } 11313 case ConstCastResultIdBadAllowsZero: { 11314 ZigType *wanted_type = cast_result->data.bad_allows_zero->wanted_type; 11315 ZigType *actual_type = cast_result->data.bad_allows_zero->actual_type; 11316 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 11317 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 11318 if (actual_allows_zero && !wanted_allows_zero) { 11319 add_error_note(ira->codegen, parent_msg, source_node, 11320 buf_sprintf("'%s' could have null values which are illegal in type '%s'", 11321 buf_ptr(&actual_type->name), 11322 buf_ptr(&wanted_type->name))); 11323 } else { 11324 add_error_note(ira->codegen, parent_msg, source_node, 11325 buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'", 11326 buf_ptr(&wanted_type->name), 11327 buf_ptr(&actual_type->name))); 11328 } 11329 break; 11330 } 11331 case ConstCastResultIdFnIsGeneric: 11332 add_error_note(ira->codegen, parent_msg, source_node, 11333 buf_sprintf("only one of the functions is generic")); 11334 break; 11335 case ConstCastResultIdFnAlign: // TODO 11336 case ConstCastResultIdFnCC: // TODO 11337 case ConstCastResultIdFnVarArgs: // TODO 11338 case ConstCastResultIdFnReturnType: // TODO 11339 case ConstCastResultIdFnArgCount: // TODO 11340 case ConstCastResultIdFnGenericArgCount: // TODO 11341 case ConstCastResultIdFnArgNoAlias: // TODO 11342 case ConstCastResultIdUnresolvedInferredErrSet: // TODO 11343 case ConstCastResultIdAsyncAllocatorType: // TODO 11344 break; 11345 } 11346 } 11347 11348 static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction *source_instr, 11349 IrInstruction *array, ZigType *vector_type) 11350 { 11351 if (instr_is_comptime(array)) { 11352 // arrays and vectors have the same ConstExprValue representation 11353 IrInstruction *result = ir_const(ira, source_instr, vector_type); 11354 copy_const_val(&result->value, &array->value, false); 11355 result->value.type = vector_type; 11356 return result; 11357 } 11358 return ir_build_array_to_vector(ira, source_instr, array, vector_type); 11359 } 11360 11361 static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr, 11362 IrInstruction *vector, ZigType *array_type) 11363 { 11364 if (instr_is_comptime(vector)) { 11365 // arrays and vectors have the same ConstExprValue representation 11366 IrInstruction *result = ir_const(ira, source_instr, array_type); 11367 copy_const_val(&result->value, &vector->value, false); 11368 result->value.type = array_type; 11369 return result; 11370 } 11371 return ir_build_vector_to_array(ira, source_instr, vector, array_type); 11372 } 11373 11374 static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr, 11375 IrInstruction *integer, ZigType *dest_type) 11376 { 11377 IrInstruction *unsigned_integer; 11378 if (instr_is_comptime(integer)) { 11379 unsigned_integer = integer; 11380 } else { 11381 assert(integer->value.type->id == ZigTypeIdInt); 11382 11383 if (integer->value.type->data.integral.bit_count > 11384 ira->codegen->builtin_types.entry_usize->data.integral.bit_count) 11385 { 11386 ir_add_error(ira, source_instr, 11387 buf_sprintf("integer type '%s' too big for implicit @intToPtr to type '%s'", 11388 buf_ptr(&integer->value.type->name), 11389 buf_ptr(&dest_type->name))); 11390 return ira->codegen->invalid_instruction; 11391 } 11392 11393 if (integer->value.type->data.integral.is_signed) { 11394 ZigType *unsigned_int_type = get_int_type(ira->codegen, false, 11395 integer->value.type->data.integral.bit_count); 11396 unsigned_integer = ir_analyze_bit_cast(ira, source_instr, integer, unsigned_int_type); 11397 if (type_is_invalid(unsigned_integer->value.type)) 11398 return ira->codegen->invalid_instruction; 11399 } else { 11400 unsigned_integer = integer; 11401 } 11402 } 11403 11404 return ir_analyze_int_to_ptr(ira, source_instr, unsigned_integer, dest_type); 11405 } 11406 11407 static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, 11408 ZigType *wanted_type, IrInstruction *value) 11409 { 11410 Error err; 11411 ZigType *actual_type = value->value.type; 11412 AstNode *source_node = source_instr->source_node; 11413 11414 if (type_is_invalid(wanted_type) || type_is_invalid(actual_type)) { 11415 return ira->codegen->invalid_instruction; 11416 } 11417 11418 // perfect match or non-const to const 11419 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, 11420 source_node, false); 11421 if (const_cast_result.id == ConstCastResultIdInvalid) 11422 return ira->codegen->invalid_instruction; 11423 if (const_cast_result.id == ConstCastResultIdOk) { 11424 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); 11425 } 11426 11427 // cast from T to ?T 11428 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism 11429 if (wanted_type->id == ZigTypeIdOptional) { 11430 ZigType *wanted_child_type = wanted_type->data.maybe.child_type; 11431 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, 11432 false).id == ConstCastResultIdOk) 11433 { 11434 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type); 11435 } else if (actual_type->id == ZigTypeIdComptimeInt || 11436 actual_type->id == ZigTypeIdComptimeFloat) 11437 { 11438 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { 11439 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type); 11440 } else { 11441 return ira->codegen->invalid_instruction; 11442 } 11443 } else if ( 11444 wanted_child_type->id == ZigTypeIdPointer && 11445 wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && 11446 actual_type->id == ZigTypeIdPointer && 11447 actual_type->data.pointer.ptr_len == PtrLenSingle && 11448 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 11449 { 11450 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 11451 return ira->codegen->invalid_instruction; 11452 if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 11453 return ira->codegen->invalid_instruction; 11454 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && 11455 types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, 11456 actual_type->data.pointer.child_type->data.array.child_type, source_node, 11457 !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) 11458 { 11459 IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, 11460 wanted_child_type); 11461 if (type_is_invalid(cast1->value.type)) 11462 return ira->codegen->invalid_instruction; 11463 return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type); 11464 } 11465 } 11466 } 11467 11468 // T to E!T 11469 if (wanted_type->id == ZigTypeIdErrorUnion) { 11470 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, 11471 source_node, false).id == ConstCastResultIdOk) 11472 { 11473 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); 11474 } else if (actual_type->id == ZigTypeIdComptimeInt || 11475 actual_type->id == ZigTypeIdComptimeFloat) 11476 { 11477 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { 11478 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); 11479 } else { 11480 return ira->codegen->invalid_instruction; 11481 } 11482 } 11483 } 11484 11485 // cast from T to E!?T 11486 if (wanted_type->id == ZigTypeIdErrorUnion && 11487 wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && 11488 actual_type->id != ZigTypeIdOptional) 11489 { 11490 ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; 11491 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || 11492 actual_type->id == ZigTypeIdNull || 11493 actual_type->id == ZigTypeIdComptimeInt || 11494 actual_type->id == ZigTypeIdComptimeFloat) 11495 { 11496 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); 11497 if (type_is_invalid(cast1->value.type)) 11498 return ira->codegen->invalid_instruction; 11499 11500 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 11501 if (type_is_invalid(cast2->value.type)) 11502 return ira->codegen->invalid_instruction; 11503 11504 return cast2; 11505 } 11506 } 11507 11508 11509 // cast from comptime-known number to another number type 11510 if (instr_is_comptime(value) && 11511 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt || 11512 actual_type->id == ZigTypeIdFloat || actual_type->id == ZigTypeIdComptimeFloat) && 11513 (wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdComptimeInt || 11514 wanted_type->id == ZigTypeIdFloat || wanted_type->id == ZigTypeIdComptimeFloat)) 11515 { 11516 if (value->value.special == ConstValSpecialUndef) { 11517 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11518 result->value.special = ConstValSpecialUndef; 11519 return result; 11520 } 11521 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { 11522 if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { 11523 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11524 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 11525 bigint_init_bigint(&result->value.data.x_bigint, &value->value.data.x_bigint); 11526 } else { 11527 float_init_bigint(&result->value.data.x_bigint, &value->value); 11528 } 11529 return result; 11530 } else if (wanted_type->id == ZigTypeIdComptimeFloat || wanted_type->id == ZigTypeIdFloat) { 11531 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11532 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 11533 BigFloat bf; 11534 bigfloat_init_bigint(&bf, &value->value.data.x_bigint); 11535 float_init_bigfloat(&result->value, &bf); 11536 } else { 11537 float_init_float(&result->value, &value->value); 11538 } 11539 return result; 11540 } 11541 zig_unreachable(); 11542 } else { 11543 return ira->codegen->invalid_instruction; 11544 } 11545 } 11546 11547 // widening conversion 11548 if (wanted_type->id == ZigTypeIdInt && 11549 actual_type->id == ZigTypeIdInt && 11550 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed && 11551 wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count) 11552 { 11553 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 11554 } 11555 11556 // small enough unsigned ints can get casted to large enough signed ints 11557 if (wanted_type->id == ZigTypeIdInt && wanted_type->data.integral.is_signed && 11558 actual_type->id == ZigTypeIdInt && !actual_type->data.integral.is_signed && 11559 wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count) 11560 { 11561 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 11562 } 11563 11564 // float widening conversion 11565 if (wanted_type->id == ZigTypeIdFloat && 11566 actual_type->id == ZigTypeIdFloat && 11567 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count) 11568 { 11569 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 11570 } 11571 11572 11573 // cast from [N]T to []const T 11574 // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this 11575 if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) { 11576 ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 11577 assert(ptr_type->id == ZigTypeIdPointer); 11578 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 11579 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 11580 source_node, false).id == ConstCastResultIdOk) 11581 { 11582 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type); 11583 } 11584 } 11585 11586 // cast from [N]T to ?[]const T 11587 // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this 11588 if (wanted_type->id == ZigTypeIdOptional && 11589 is_slice(wanted_type->data.maybe.child_type) && 11590 actual_type->id == ZigTypeIdArray) 11591 { 11592 ZigType *ptr_type = 11593 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry; 11594 assert(ptr_type->id == ZigTypeIdPointer); 11595 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 11596 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 11597 source_node, false).id == ConstCastResultIdOk) 11598 { 11599 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); 11600 if (type_is_invalid(cast1->value.type)) 11601 return ira->codegen->invalid_instruction; 11602 11603 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 11604 if (type_is_invalid(cast2->value.type)) 11605 return ira->codegen->invalid_instruction; 11606 11607 return cast2; 11608 } 11609 } 11610 11611 // *[N]T to [*]T 11612 if (wanted_type->id == ZigTypeIdPointer && 11613 wanted_type->data.pointer.ptr_len == PtrLenUnknown && 11614 actual_type->id == ZigTypeIdPointer && 11615 actual_type->data.pointer.ptr_len == PtrLenSingle && 11616 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 11617 { 11618 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 11619 return ira->codegen->invalid_instruction; 11620 if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 11621 return ira->codegen->invalid_instruction; 11622 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) && 11623 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 11624 actual_type->data.pointer.child_type->data.array.child_type, source_node, 11625 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 11626 { 11627 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type); 11628 } 11629 } 11630 11631 // *[N]T to []T 11632 if (is_slice(wanted_type) && 11633 actual_type->id == ZigTypeIdPointer && 11634 actual_type->data.pointer.ptr_len == PtrLenSingle && 11635 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 11636 { 11637 ZigType *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 11638 assert(slice_ptr_type->id == ZigTypeIdPointer); 11639 ZigType *array_type = actual_type->data.pointer.child_type; 11640 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 11641 || !actual_type->data.pointer.is_const); 11642 if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 11643 array_type->data.array.child_type, source_node, 11644 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) 11645 { 11646 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type); 11647 } 11648 } 11649 11650 11651 // cast from null literal to maybe type 11652 if (wanted_type->id == ZigTypeIdOptional && 11653 actual_type->id == ZigTypeIdNull) 11654 { 11655 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); 11656 } 11657 11658 // cast from null literal to C pointer 11659 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 11660 actual_type->id == ZigTypeIdNull) 11661 { 11662 return ir_analyze_null_to_c_pointer(ira, source_instr, value, wanted_type); 11663 } 11664 11665 // cast from [N]T to E![]const T 11666 if (wanted_type->id == ZigTypeIdErrorUnion && 11667 is_slice(wanted_type->data.error_union.payload_type) && 11668 actual_type->id == ZigTypeIdArray) 11669 { 11670 ZigType *ptr_type = 11671 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry; 11672 assert(ptr_type->id == ZigTypeIdPointer); 11673 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 11674 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 11675 source_node, false).id == ConstCastResultIdOk) 11676 { 11677 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); 11678 if (type_is_invalid(cast1->value.type)) 11679 return ira->codegen->invalid_instruction; 11680 11681 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 11682 if (type_is_invalid(cast2->value.type)) 11683 return ira->codegen->invalid_instruction; 11684 11685 return cast2; 11686 } 11687 } 11688 11689 // cast from E to E!T 11690 if (wanted_type->id == ZigTypeIdErrorUnion && 11691 actual_type->id == ZigTypeIdErrorSet) 11692 { 11693 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type); 11694 } 11695 11696 // cast from typed number to integer or float literal. 11697 // works when the number is known at compile time 11698 if (instr_is_comptime(value) && 11699 ((actual_type->id == ZigTypeIdInt && wanted_type->id == ZigTypeIdComptimeInt) || 11700 (actual_type->id == ZigTypeIdFloat && wanted_type->id == ZigTypeIdComptimeFloat))) 11701 { 11702 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type); 11703 } 11704 11705 // cast from enum literal to enum with matching field name 11706 if (actual_type->id == ZigTypeIdEnumLiteral && wanted_type->id == ZigTypeIdEnum) { 11707 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) 11708 return ira->codegen->invalid_instruction; 11709 11710 TypeEnumField *field = find_enum_type_field(wanted_type, value->value.data.x_enum_literal); 11711 if (field == nullptr) { 11712 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("enum '%s' has no field named '%s'", 11713 buf_ptr(&wanted_type->name), buf_ptr(value->value.data.x_enum_literal))); 11714 add_error_note(ira->codegen, msg, wanted_type->data.enumeration.decl_node, 11715 buf_sprintf("'%s' declared here", buf_ptr(&wanted_type->name))); 11716 return ira->codegen->invalid_instruction; 11717 } 11718 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11719 bigint_init_bigint(&result->value.data.x_enum_tag, &field->value); 11720 return result; 11721 } 11722 11723 // cast from union to the enum type of the union 11724 if (actual_type->id == ZigTypeIdUnion && wanted_type->id == ZigTypeIdEnum) { 11725 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) 11726 return ira->codegen->invalid_instruction; 11727 11728 if (actual_type->data.unionation.tag_type == wanted_type) { 11729 return ir_analyze_union_to_tag(ira, source_instr, value, wanted_type); 11730 } 11731 } 11732 11733 // enum to union which has the enum as the tag type 11734 if (wanted_type->id == ZigTypeIdUnion && actual_type->id == ZigTypeIdEnum && 11735 (wanted_type->data.unionation.decl_node->data.container_decl.auto_enum || 11736 wanted_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 11737 { 11738 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) 11739 return ira->codegen->invalid_instruction; 11740 11741 if (wanted_type->data.unionation.tag_type == actual_type) { 11742 return ir_analyze_enum_to_union(ira, source_instr, value, wanted_type); 11743 } 11744 } 11745 11746 // cast from *T to *[1]T 11747 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 11748 actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle) 11749 { 11750 ZigType *array_type = wanted_type->data.pointer.child_type; 11751 if (array_type->id == ZigTypeIdArray && array_type->data.array.len == 1 && 11752 types_match_const_cast_only(ira, array_type->data.array.child_type, 11753 actual_type->data.pointer.child_type, source_node, 11754 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk && 11755 // This should be the job of `types_match_const_cast_only` 11756 // but `types_match_const_cast_only` only gets info for child_types 11757 ((wanted_type->data.pointer.is_const && actual_type->data.pointer.is_const) || 11758 !actual_type->data.pointer.is_const)) 11759 { 11760 if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, 11761 ResolveStatusAlignmentKnown))) 11762 { 11763 return ira->codegen->invalid_instruction; 11764 } 11765 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, 11766 ResolveStatusAlignmentKnown))) 11767 { 11768 return ira->codegen->invalid_instruction; 11769 } 11770 uint32_t wanted_align = get_ptr_align(ira->codegen, wanted_type); 11771 uint32_t actual_align = get_ptr_align(ira->codegen, actual_type); 11772 if (wanted_align > actual_align) { 11773 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 11774 add_error_note(ira->codegen, msg, value->source_node, 11775 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&actual_type->name), actual_align)); 11776 add_error_note(ira->codegen, msg, source_instr->source_node, 11777 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&wanted_type->name), wanted_align)); 11778 return ira->codegen->invalid_instruction; 11779 } 11780 return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type); 11781 } 11782 } 11783 11784 // cast from *T and [*]T to *c_void and ?*c_void 11785 // but don't do it if the actual type is a double pointer 11786 if (actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.child_type->id != ZigTypeIdPointer) { 11787 ZigType *dest_ptr_type = nullptr; 11788 if (wanted_type->id == ZigTypeIdPointer && 11789 wanted_type->data.pointer.ptr_len == PtrLenSingle && 11790 wanted_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 11791 { 11792 dest_ptr_type = wanted_type; 11793 } else if (wanted_type->id == ZigTypeIdOptional && 11794 wanted_type->data.maybe.child_type->id == ZigTypeIdPointer && 11795 wanted_type->data.maybe.child_type->data.pointer.ptr_len == PtrLenSingle && 11796 wanted_type->data.maybe.child_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 11797 { 11798 dest_ptr_type = wanted_type->data.maybe.child_type; 11799 } 11800 if (dest_ptr_type != nullptr && 11801 (!actual_type->data.pointer.is_const || dest_ptr_type->data.pointer.is_const) && 11802 (!actual_type->data.pointer.is_volatile || dest_ptr_type->data.pointer.is_volatile) && 11803 actual_type->data.pointer.bit_offset_in_host == dest_ptr_type->data.pointer.bit_offset_in_host && 11804 actual_type->data.pointer.host_int_bytes == dest_ptr_type->data.pointer.host_int_bytes && 11805 get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, dest_ptr_type)) 11806 { 11807 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true); 11808 } 11809 } 11810 11811 // cast from T to *T where T is zero bits 11812 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 11813 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 11814 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 11815 { 11816 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) { 11817 return ira->codegen->invalid_instruction; 11818 } 11819 if (!type_has_bits(actual_type)) { 11820 return ir_get_ref(ira, source_instr, value, false, false); 11821 } 11822 } 11823 11824 // cast from @Vector(N, T) to [N]T 11825 if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdVector && 11826 wanted_type->data.array.len == actual_type->data.vector.len && 11827 types_match_const_cast_only(ira, wanted_type->data.array.child_type, 11828 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 11829 { 11830 return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type); 11831 } 11832 11833 // cast from [N]T to @Vector(N, T) 11834 if (actual_type->id == ZigTypeIdArray && wanted_type->id == ZigTypeIdVector && 11835 actual_type->data.array.len == wanted_type->data.vector.len && 11836 types_match_const_cast_only(ira, actual_type->data.array.child_type, 11837 wanted_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 11838 { 11839 return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type); 11840 } 11841 11842 // casting between C pointers and normal pointers 11843 if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer && 11844 (wanted_type->data.pointer.ptr_len == PtrLenC || actual_type->data.pointer.ptr_len == PtrLenC) && 11845 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 11846 actual_type->data.pointer.child_type, source_node, 11847 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 11848 { 11849 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true); 11850 } 11851 11852 // cast from integer to C pointer 11853 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 11854 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt)) 11855 { 11856 return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type); 11857 } 11858 11859 // cast from undefined to anything 11860 if (actual_type->id == ZigTypeIdUndefined) { 11861 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); 11862 } 11863 11864 ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, 11865 buf_sprintf("expected type '%s', found '%s'", 11866 buf_ptr(&wanted_type->name), 11867 buf_ptr(&actual_type->name))); 11868 report_recursive_error(ira, source_instr->source_node, &const_cast_result, parent_msg); 11869 return ira->codegen->invalid_instruction; 11870 } 11871 11872 static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { 11873 assert(value); 11874 assert(value != ira->codegen->invalid_instruction); 11875 assert(!expected_type || !type_is_invalid(expected_type)); 11876 assert(value->value.type); 11877 assert(!type_is_invalid(value->value.type)); 11878 if (expected_type == nullptr) 11879 return value; // anything will do 11880 if (expected_type == value->value.type) 11881 return value; // match 11882 if (value->value.type->id == ZigTypeIdUnreachable) 11883 return value; 11884 11885 return ir_analyze_cast(ira, value, expected_type, value); 11886 } 11887 11888 static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) { 11889 Error err; 11890 ZigType *type_entry = ptr->value.type; 11891 if (type_is_invalid(type_entry)) { 11892 return ira->codegen->invalid_instruction; 11893 } else if (type_entry->id == ZigTypeIdPointer) { 11894 ZigType *child_type = type_entry->data.pointer.child_type; 11895 // if the child type has one possible value, the deref is comptime 11896 switch (type_has_one_possible_value(ira->codegen, child_type)) { 11897 case OnePossibleValueInvalid: 11898 return ira->codegen->invalid_instruction; 11899 case OnePossibleValueYes: 11900 return ir_const(ira, source_instruction, child_type); 11901 case OnePossibleValueNo: 11902 break; 11903 } 11904 if (instr_is_comptime(ptr)) { 11905 if (ptr->value.special == ConstValSpecialUndef) { 11906 ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); 11907 return ira->codegen->invalid_instruction; 11908 } 11909 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst || 11910 ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) 11911 { 11912 ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); 11913 if (pointee->special != ConstValSpecialRuntime) { 11914 IrInstruction *result = ir_const(ira, source_instruction, child_type); 11915 11916 if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value, 11917 &ptr->value))) 11918 { 11919 return ira->codegen->invalid_instruction; 11920 } 11921 result->value.type = child_type; 11922 return result; 11923 } 11924 } 11925 } 11926 // if the instruction is a const ref instruction we can skip it 11927 if (ptr->id == IrInstructionIdRef) { 11928 IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr); 11929 return ref_inst->value; 11930 } 11931 IrInstruction *result = ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type); 11932 if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { 11933 ir_add_alloca(ira, result, child_type); 11934 } 11935 return result; 11936 } else { 11937 ir_add_error_node(ira, source_instruction->source_node, 11938 buf_sprintf("attempt to dereference non-pointer type '%s'", 11939 buf_ptr(&type_entry->name))); 11940 return ira->codegen->invalid_instruction; 11941 } 11942 } 11943 11944 static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { 11945 if (type_is_invalid(value->value.type)) 11946 return false; 11947 11948 IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); 11949 if (type_is_invalid(casted_value->value.type)) 11950 return false; 11951 11952 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 11953 if (!const_val) 11954 return false; 11955 11956 uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint); 11957 if (align_bytes == 0) { 11958 ir_add_error(ira, value, buf_sprintf("alignment must be >= 1")); 11959 return false; 11960 } 11961 11962 if (!is_power_of_2(align_bytes)) { 11963 ir_add_error(ira, value, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); 11964 return false; 11965 } 11966 11967 *out = align_bytes; 11968 return true; 11969 } 11970 11971 static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { 11972 if (type_is_invalid(value->value.type)) 11973 return false; 11974 11975 IrInstruction *casted_value = ir_implicit_cast(ira, value, int_type); 11976 if (type_is_invalid(casted_value->value.type)) 11977 return false; 11978 11979 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 11980 if (!const_val) 11981 return false; 11982 11983 *out = bigint_as_unsigned(&const_val->data.x_bigint); 11984 return true; 11985 } 11986 11987 static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) { 11988 return ir_resolve_unsigned(ira, value, ira->codegen->builtin_types.entry_usize, out); 11989 } 11990 11991 static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) { 11992 if (type_is_invalid(value->value.type)) 11993 return false; 11994 11995 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_bool); 11996 if (type_is_invalid(casted_value->value.type)) 11997 return false; 11998 11999 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12000 if (!const_val) 12001 return false; 12002 12003 *out = const_val->data.x_bool; 12004 return true; 12005 } 12006 12007 static bool ir_resolve_comptime(IrAnalyze *ira, IrInstruction *value, bool *out) { 12008 if (!value) { 12009 *out = false; 12010 return true; 12011 } 12012 return ir_resolve_bool(ira, value, out); 12013 } 12014 12015 static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, AtomicOrder *out) { 12016 if (type_is_invalid(value->value.type)) 12017 return false; 12018 12019 ConstExprValue *atomic_order_val = get_builtin_value(ira->codegen, "AtomicOrder"); 12020 assert(atomic_order_val->type->id == ZigTypeIdMetaType); 12021 ZigType *atomic_order_type = atomic_order_val->data.x_type; 12022 12023 IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_order_type); 12024 if (type_is_invalid(casted_value->value.type)) 12025 return false; 12026 12027 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12028 if (!const_val) 12029 return false; 12030 12031 *out = (AtomicOrder)bigint_as_unsigned(&const_val->data.x_enum_tag); 12032 return true; 12033 } 12034 12035 static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstruction *value, AtomicRmwOp *out) { 12036 if (type_is_invalid(value->value.type)) 12037 return false; 12038 12039 ConstExprValue *atomic_rmw_op_val = get_builtin_value(ira->codegen, "AtomicRmwOp"); 12040 assert(atomic_rmw_op_val->type->id == ZigTypeIdMetaType); 12041 ZigType *atomic_rmw_op_type = atomic_rmw_op_val->data.x_type; 12042 12043 IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_rmw_op_type); 12044 if (type_is_invalid(casted_value->value.type)) 12045 return false; 12046 12047 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12048 if (!const_val) 12049 return false; 12050 12051 *out = (AtomicRmwOp)bigint_as_unsigned(&const_val->data.x_enum_tag); 12052 return true; 12053 } 12054 12055 static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstruction *value, GlobalLinkageId *out) { 12056 if (type_is_invalid(value->value.type)) 12057 return false; 12058 12059 ConstExprValue *global_linkage_val = get_builtin_value(ira->codegen, "GlobalLinkage"); 12060 assert(global_linkage_val->type->id == ZigTypeIdMetaType); 12061 ZigType *global_linkage_type = global_linkage_val->data.x_type; 12062 12063 IrInstruction *casted_value = ir_implicit_cast(ira, value, global_linkage_type); 12064 if (type_is_invalid(casted_value->value.type)) 12065 return false; 12066 12067 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12068 if (!const_val) 12069 return false; 12070 12071 *out = (GlobalLinkageId)bigint_as_unsigned(&const_val->data.x_enum_tag); 12072 return true; 12073 } 12074 12075 static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMode *out) { 12076 if (type_is_invalid(value->value.type)) 12077 return false; 12078 12079 ConstExprValue *float_mode_val = get_builtin_value(ira->codegen, "FloatMode"); 12080 assert(float_mode_val->type->id == ZigTypeIdMetaType); 12081 ZigType *float_mode_type = float_mode_val->data.x_type; 12082 12083 IrInstruction *casted_value = ir_implicit_cast(ira, value, float_mode_type); 12084 if (type_is_invalid(casted_value->value.type)) 12085 return false; 12086 12087 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12088 if (!const_val) 12089 return false; 12090 12091 *out = (FloatMode)bigint_as_unsigned(&const_val->data.x_enum_tag); 12092 return true; 12093 } 12094 12095 12096 static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { 12097 if (type_is_invalid(value->value.type)) 12098 return nullptr; 12099 12100 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 12101 true, false, PtrLenUnknown, 0, 0, 0, false); 12102 ZigType *str_type = get_slice_type(ira->codegen, ptr_type); 12103 IrInstruction *casted_value = ir_implicit_cast(ira, value, str_type); 12104 if (type_is_invalid(casted_value->value.type)) 12105 return nullptr; 12106 12107 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12108 if (!const_val) 12109 return nullptr; 12110 12111 ConstExprValue *ptr_field = &const_val->data.x_struct.fields[slice_ptr_index]; 12112 ConstExprValue *len_field = &const_val->data.x_struct.fields[slice_len_index]; 12113 12114 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); 12115 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; 12116 if (array_val->data.x_array.special == ConstArraySpecialBuf) { 12117 return array_val->data.x_array.data.s_buf; 12118 } 12119 expand_undef_array(ira->codegen, array_val); 12120 size_t len = bigint_as_unsigned(&len_field->data.x_bigint); 12121 Buf *result = buf_alloc(); 12122 buf_resize(result, len); 12123 for (size_t i = 0; i < len; i += 1) { 12124 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; 12125 ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index]; 12126 if (char_val->special == ConstValSpecialUndef) { 12127 ir_add_error(ira, casted_value, buf_sprintf("use of undefined value")); 12128 return nullptr; 12129 } 12130 uint64_t big_c = bigint_as_unsigned(&char_val->data.x_bigint); 12131 assert(big_c <= UINT8_MAX); 12132 uint8_t c = (uint8_t)big_c; 12133 buf_ptr(result)[i] = c; 12134 } 12135 return result; 12136 } 12137 12138 static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, 12139 IrInstructionAddImplicitReturnType *instruction) 12140 { 12141 IrInstruction *value = instruction->value->child; 12142 if (type_is_invalid(value->value.type)) 12143 return ir_unreach_error(ira); 12144 12145 ira->src_implicit_return_type_list.append(value); 12146 12147 return ir_const_void(ira, &instruction->base); 12148 } 12149 12150 static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructionReturn *instruction) { 12151 IrInstruction *value = instruction->value->child; 12152 if (type_is_invalid(value->value.type)) 12153 return ir_unreach_error(ira); 12154 12155 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type); 12156 if (type_is_invalid(casted_value->value.type)) { 12157 AstNode *source_node = ira->explicit_return_type_source_node; 12158 if (source_node != nullptr) { 12159 ErrorMsg *msg = ira->codegen->errors.last(); 12160 add_error_note(ira->codegen, msg, source_node, 12161 buf_sprintf("return type declared here")); 12162 } 12163 return ir_unreach_error(ira); 12164 } 12165 12166 if (casted_value->value.special == ConstValSpecialRuntime && 12167 casted_value->value.type->id == ZigTypeIdPointer && 12168 casted_value->value.data.rh_ptr == RuntimeHintPtrStack) 12169 { 12170 ir_add_error(ira, casted_value, buf_sprintf("function returns address of local variable")); 12171 return ir_unreach_error(ira); 12172 } 12173 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, 12174 instruction->base.source_node, casted_value); 12175 result->value.type = ira->codegen->builtin_types.entry_unreachable; 12176 return ir_finish_anal(ira, result); 12177 } 12178 12179 static IrInstruction *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *instruction) { 12180 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 12181 copy_const_val(&result->value, &instruction->base.value, true); 12182 return result; 12183 } 12184 12185 static IrInstruction *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 12186 IrInstruction *op1 = bin_op_instruction->op1->child; 12187 if (type_is_invalid(op1->value.type)) 12188 return ira->codegen->invalid_instruction; 12189 12190 IrInstruction *op2 = bin_op_instruction->op2->child; 12191 if (type_is_invalid(op2->value.type)) 12192 return ira->codegen->invalid_instruction; 12193 12194 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 12195 12196 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, bool_type); 12197 if (casted_op1 == ira->codegen->invalid_instruction) 12198 return ira->codegen->invalid_instruction; 12199 12200 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, bool_type); 12201 if (casted_op2 == ira->codegen->invalid_instruction) 12202 return ira->codegen->invalid_instruction; 12203 12204 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 12205 ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 12206 if (op1_val == nullptr) 12207 return ira->codegen->invalid_instruction; 12208 12209 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 12210 if (op2_val == nullptr) 12211 return ira->codegen->invalid_instruction; 12212 12213 assert(casted_op1->value.type->id == ZigTypeIdBool); 12214 assert(casted_op2->value.type->id == ZigTypeIdBool); 12215 bool result_bool; 12216 if (bin_op_instruction->op_id == IrBinOpBoolOr) { 12217 result_bool = op1_val->data.x_bool || op2_val->data.x_bool; 12218 } else if (bin_op_instruction->op_id == IrBinOpBoolAnd) { 12219 result_bool = op1_val->data.x_bool && op2_val->data.x_bool; 12220 } else { 12221 zig_unreachable(); 12222 } 12223 return ir_const_bool(ira, &bin_op_instruction->base, result_bool); 12224 } 12225 12226 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 12227 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 12228 bin_op_instruction->op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 12229 result->value.type = bool_type; 12230 return result; 12231 } 12232 12233 static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) { 12234 switch (op_id) { 12235 case IrBinOpCmpEq: 12236 return cmp == CmpEQ; 12237 case IrBinOpCmpNotEq: 12238 return cmp != CmpEQ; 12239 case IrBinOpCmpLessThan: 12240 return cmp == CmpLT; 12241 case IrBinOpCmpGreaterThan: 12242 return cmp == CmpGT; 12243 case IrBinOpCmpLessOrEq: 12244 return cmp != CmpGT; 12245 case IrBinOpCmpGreaterOrEq: 12246 return cmp != CmpLT; 12247 default: 12248 zig_unreachable(); 12249 } 12250 } 12251 12252 static bool optional_value_is_null(ConstExprValue *val) { 12253 assert(val->special == ConstValSpecialStatic); 12254 if (get_codegen_ptr_type(val->type) != nullptr) { 12255 if (val->data.x_ptr.special == ConstPtrSpecialNull) { 12256 return true; 12257 } else if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 12258 return val->data.x_ptr.data.hard_coded_addr.addr == 0; 12259 } else { 12260 return false; 12261 } 12262 } else if (is_opt_err_set(val->type)) { 12263 return val->data.x_err_set == nullptr; 12264 } else { 12265 return val->data.x_optional == nullptr; 12266 } 12267 } 12268 12269 static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 12270 IrInstruction *op1 = bin_op_instruction->op1->child; 12271 if (type_is_invalid(op1->value.type)) 12272 return ira->codegen->invalid_instruction; 12273 12274 IrInstruction *op2 = bin_op_instruction->op2->child; 12275 if (type_is_invalid(op2->value.type)) 12276 return ira->codegen->invalid_instruction; 12277 12278 AstNode *source_node = bin_op_instruction->base.source_node; 12279 12280 IrBinOp op_id = bin_op_instruction->op_id; 12281 bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 12282 if (is_equality_cmp && op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull) { 12283 return ir_const_bool(ira, &bin_op_instruction->base, (op_id == IrBinOpCmpEq)); 12284 } else if (is_equality_cmp && 12285 ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdOptional) || 12286 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdOptional))) 12287 { 12288 IrInstruction *maybe_op; 12289 if (op1->value.type->id == ZigTypeIdNull) { 12290 maybe_op = op2; 12291 } else if (op2->value.type->id == ZigTypeIdNull) { 12292 maybe_op = op1; 12293 } else { 12294 zig_unreachable(); 12295 } 12296 if (instr_is_comptime(maybe_op)) { 12297 ConstExprValue *maybe_val = ir_resolve_const(ira, maybe_op, UndefBad); 12298 if (!maybe_val) 12299 return ira->codegen->invalid_instruction; 12300 bool is_null = optional_value_is_null(maybe_val); 12301 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 12302 return ir_const_bool(ira, &bin_op_instruction->base, bool_result); 12303 } 12304 12305 IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope, 12306 source_node, maybe_op); 12307 is_non_null->value.type = ira->codegen->builtin_types.entry_bool; 12308 12309 if (op_id == IrBinOpCmpEq) { 12310 IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope, 12311 bin_op_instruction->base.source_node, is_non_null); 12312 result->value.type = ira->codegen->builtin_types.entry_bool; 12313 return result; 12314 } else { 12315 return is_non_null; 12316 } 12317 } else if (is_equality_cmp && 12318 ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer && 12319 op2->value.type->data.pointer.ptr_len == PtrLenC) || 12320 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer && 12321 op1->value.type->data.pointer.ptr_len == PtrLenC))) 12322 { 12323 IrInstruction *c_ptr_op; 12324 if (op1->value.type->id == ZigTypeIdNull) { 12325 c_ptr_op = op2; 12326 } else if (op2->value.type->id == ZigTypeIdNull) { 12327 c_ptr_op = op1; 12328 } else { 12329 zig_unreachable(); 12330 } 12331 if (instr_is_comptime(c_ptr_op)) { 12332 ConstExprValue *c_ptr_val = ir_resolve_const(ira, c_ptr_op, UndefOk); 12333 if (!c_ptr_val) 12334 return ira->codegen->invalid_instruction; 12335 if (c_ptr_val->special == ConstValSpecialUndef) 12336 return ir_const_undef(ira, &bin_op_instruction->base, ira->codegen->builtin_types.entry_bool); 12337 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 12338 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 12339 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 12340 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 12341 return ir_const_bool(ira, &bin_op_instruction->base, bool_result); 12342 } 12343 IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope, 12344 source_node, c_ptr_op); 12345 is_non_null->value.type = ira->codegen->builtin_types.entry_bool; 12346 12347 if (op_id == IrBinOpCmpEq) { 12348 IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope, 12349 bin_op_instruction->base.source_node, is_non_null); 12350 result->value.type = ira->codegen->builtin_types.entry_bool; 12351 return result; 12352 } else { 12353 return is_non_null; 12354 } 12355 } else if (op1->value.type->id == ZigTypeIdNull || op2->value.type->id == ZigTypeIdNull) { 12356 ZigType *non_null_type = (op1->value.type->id == ZigTypeIdNull) ? op2->value.type : op1->value.type; 12357 ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null", 12358 buf_ptr(&non_null_type->name))); 12359 return ira->codegen->invalid_instruction; 12360 } 12361 12362 if (op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) { 12363 if (!is_equality_cmp) { 12364 ir_add_error_node(ira, source_node, buf_sprintf("operator not allowed for errors")); 12365 return ira->codegen->invalid_instruction; 12366 } 12367 ZigType *intersect_type = get_error_set_intersection(ira, op1->value.type, op2->value.type, source_node); 12368 if (type_is_invalid(intersect_type)) { 12369 return ira->codegen->invalid_instruction; 12370 } 12371 12372 if (!resolve_inferred_error_set(ira->codegen, intersect_type, source_node)) { 12373 return ira->codegen->invalid_instruction; 12374 } 12375 12376 // exception if one of the operators has the type of the empty error set, we allow the comparison 12377 // (and make it comptime known) 12378 // this is a function which is evaluated at comptime and returns an inferred error set will have an empty 12379 // error set. 12380 if (op1->value.type->data.error_set.err_count == 0 || op2->value.type->data.error_set.err_count == 0) { 12381 bool are_equal = false; 12382 bool answer; 12383 if (op_id == IrBinOpCmpEq) { 12384 answer = are_equal; 12385 } else if (op_id == IrBinOpCmpNotEq) { 12386 answer = !are_equal; 12387 } else { 12388 zig_unreachable(); 12389 } 12390 return ir_const_bool(ira, &bin_op_instruction->base, answer); 12391 } 12392 12393 if (!type_is_global_error_set(intersect_type)) { 12394 if (intersect_type->data.error_set.err_count == 0) { 12395 ir_add_error_node(ira, source_node, 12396 buf_sprintf("error sets '%s' and '%s' have no common errors", 12397 buf_ptr(&op1->value.type->name), buf_ptr(&op2->value.type->name))); 12398 return ira->codegen->invalid_instruction; 12399 } 12400 if (op1->value.type->data.error_set.err_count == 1 && op2->value.type->data.error_set.err_count == 1) { 12401 bool are_equal = true; 12402 bool answer; 12403 if (op_id == IrBinOpCmpEq) { 12404 answer = are_equal; 12405 } else if (op_id == IrBinOpCmpNotEq) { 12406 answer = !are_equal; 12407 } else { 12408 zig_unreachable(); 12409 } 12410 return ir_const_bool(ira, &bin_op_instruction->base, answer); 12411 } 12412 } 12413 12414 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 12415 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 12416 if (op1_val == nullptr) 12417 return ira->codegen->invalid_instruction; 12418 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 12419 if (op2_val == nullptr) 12420 return ira->codegen->invalid_instruction; 12421 12422 bool answer; 12423 bool are_equal = op1_val->data.x_err_set->value == op2_val->data.x_err_set->value; 12424 if (op_id == IrBinOpCmpEq) { 12425 answer = are_equal; 12426 } else if (op_id == IrBinOpCmpNotEq) { 12427 answer = !are_equal; 12428 } else { 12429 zig_unreachable(); 12430 } 12431 12432 return ir_const_bool(ira, &bin_op_instruction->base, answer); 12433 } 12434 12435 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 12436 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 12437 op_id, op1, op2, bin_op_instruction->safety_check_on); 12438 result->value.type = ira->codegen->builtin_types.entry_bool; 12439 return result; 12440 } 12441 12442 IrInstruction *instructions[] = {op1, op2}; 12443 ZigType *resolved_type = ir_resolve_peer_types(ira, source_node, nullptr, instructions, 2); 12444 if (type_is_invalid(resolved_type)) 12445 return ira->codegen->invalid_instruction; 12446 12447 bool operator_allowed; 12448 switch (resolved_type->id) { 12449 case ZigTypeIdInvalid: 12450 zig_unreachable(); // handled above 12451 12452 case ZigTypeIdComptimeFloat: 12453 case ZigTypeIdComptimeInt: 12454 case ZigTypeIdInt: 12455 case ZigTypeIdFloat: 12456 case ZigTypeIdVector: 12457 operator_allowed = true; 12458 break; 12459 12460 case ZigTypeIdBool: 12461 case ZigTypeIdMetaType: 12462 case ZigTypeIdVoid: 12463 case ZigTypeIdErrorSet: 12464 case ZigTypeIdFn: 12465 case ZigTypeIdOpaque: 12466 case ZigTypeIdBoundFn: 12467 case ZigTypeIdArgTuple: 12468 case ZigTypeIdPromise: 12469 case ZigTypeIdEnum: 12470 case ZigTypeIdEnumLiteral: 12471 operator_allowed = is_equality_cmp; 12472 break; 12473 12474 case ZigTypeIdPointer: 12475 operator_allowed = is_equality_cmp || (resolved_type->data.pointer.ptr_len == PtrLenC); 12476 break; 12477 12478 case ZigTypeIdUnreachable: 12479 case ZigTypeIdArray: 12480 case ZigTypeIdStruct: 12481 case ZigTypeIdUndefined: 12482 case ZigTypeIdNull: 12483 case ZigTypeIdErrorUnion: 12484 case ZigTypeIdUnion: 12485 operator_allowed = false; 12486 break; 12487 case ZigTypeIdOptional: 12488 operator_allowed = is_equality_cmp && get_codegen_ptr_type(resolved_type) != nullptr; 12489 break; 12490 } 12491 if (!operator_allowed) { 12492 ir_add_error_node(ira, source_node, 12493 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); 12494 return ira->codegen->invalid_instruction; 12495 } 12496 12497 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 12498 if (casted_op1 == ira->codegen->invalid_instruction) 12499 return ira->codegen->invalid_instruction; 12500 12501 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 12502 if (casted_op2 == ira->codegen->invalid_instruction) 12503 return ira->codegen->invalid_instruction; 12504 12505 bool one_possible_value; 12506 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 12507 case OnePossibleValueInvalid: 12508 return ira->codegen->invalid_instruction; 12509 case OnePossibleValueYes: 12510 one_possible_value = true; 12511 break; 12512 case OnePossibleValueNo: 12513 one_possible_value = false; 12514 break; 12515 } 12516 12517 if (one_possible_value || (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2))) { 12518 ConstExprValue *op1_val = one_possible_value ? &casted_op1->value : ir_resolve_const(ira, casted_op1, UndefBad); 12519 if (op1_val == nullptr) 12520 return ira->codegen->invalid_instruction; 12521 ConstExprValue *op2_val = one_possible_value ? &casted_op2->value : ir_resolve_const(ira, casted_op2, UndefBad); 12522 if (op2_val == nullptr) 12523 return ira->codegen->invalid_instruction; 12524 12525 if (resolved_type->id == ZigTypeIdComptimeFloat || resolved_type->id == ZigTypeIdFloat) { 12526 if (float_is_nan(op1_val) || float_is_nan(op2_val)) { 12527 return ir_const_bool(ira, &bin_op_instruction->base, op_id == IrBinOpCmpNotEq); 12528 } 12529 Cmp cmp_result = float_cmp(op1_val, op2_val); 12530 bool answer = resolve_cmp_op_id(op_id, cmp_result); 12531 return ir_const_bool(ira, &bin_op_instruction->base, answer); 12532 } else if (resolved_type->id == ZigTypeIdComptimeInt || resolved_type->id == ZigTypeIdInt) { 12533 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); 12534 bool answer = resolve_cmp_op_id(op_id, cmp_result); 12535 return ir_const_bool(ira, &bin_op_instruction->base, answer); 12536 } else if (resolved_type->id == ZigTypeIdPointer && op_id != IrBinOpCmpEq && op_id != IrBinOpCmpNotEq) { 12537 if ((op1_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 12538 op1_val->data.x_ptr.special == ConstPtrSpecialNull) && 12539 (op2_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 12540 op2_val->data.x_ptr.special == ConstPtrSpecialNull)) 12541 { 12542 uint64_t op1_addr = op1_val->data.x_ptr.special == ConstPtrSpecialNull ? 12543 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; 12544 uint64_t op2_addr = op2_val->data.x_ptr.special == ConstPtrSpecialNull ? 12545 0 : op2_val->data.x_ptr.data.hard_coded_addr.addr; 12546 Cmp cmp_result; 12547 if (op1_addr > op2_addr) { 12548 cmp_result = CmpGT; 12549 } else if (op1_addr < op2_addr) { 12550 cmp_result = CmpLT; 12551 } else { 12552 cmp_result = CmpEQ; 12553 } 12554 bool answer = resolve_cmp_op_id(op_id, cmp_result); 12555 return ir_const_bool(ira, &bin_op_instruction->base, answer); 12556 } 12557 } else { 12558 bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val); 12559 bool answer; 12560 if (op_id == IrBinOpCmpEq) { 12561 answer = are_equal; 12562 } else if (op_id == IrBinOpCmpNotEq) { 12563 answer = !are_equal; 12564 } else { 12565 zig_unreachable(); 12566 } 12567 return ir_const_bool(ira, &bin_op_instruction->base, answer); 12568 } 12569 } 12570 12571 // some comparisons with unsigned numbers can be evaluated 12572 if (resolved_type->id == ZigTypeIdInt && !resolved_type->data.integral.is_signed) { 12573 ConstExprValue *known_left_val; 12574 IrBinOp flipped_op_id; 12575 if (instr_is_comptime(casted_op1)) { 12576 known_left_val = ir_resolve_const(ira, casted_op1, UndefBad); 12577 if (known_left_val == nullptr) 12578 return ira->codegen->invalid_instruction; 12579 12580 flipped_op_id = op_id; 12581 } else if (instr_is_comptime(casted_op2)) { 12582 known_left_val = ir_resolve_const(ira, casted_op2, UndefBad); 12583 if (known_left_val == nullptr) 12584 return ira->codegen->invalid_instruction; 12585 12586 if (op_id == IrBinOpCmpLessThan) { 12587 flipped_op_id = IrBinOpCmpGreaterThan; 12588 } else if (op_id == IrBinOpCmpGreaterThan) { 12589 flipped_op_id = IrBinOpCmpLessThan; 12590 } else if (op_id == IrBinOpCmpLessOrEq) { 12591 flipped_op_id = IrBinOpCmpGreaterOrEq; 12592 } else if (op_id == IrBinOpCmpGreaterOrEq) { 12593 flipped_op_id = IrBinOpCmpLessOrEq; 12594 } else { 12595 flipped_op_id = op_id; 12596 } 12597 } else { 12598 known_left_val = nullptr; 12599 } 12600 if (known_left_val != nullptr && bigint_cmp_zero(&known_left_val->data.x_bigint) == CmpEQ && 12601 (flipped_op_id == IrBinOpCmpLessOrEq || flipped_op_id == IrBinOpCmpGreaterThan)) 12602 { 12603 bool answer = (flipped_op_id == IrBinOpCmpLessOrEq); 12604 return ir_const_bool(ira, &bin_op_instruction->base, answer); 12605 } 12606 } 12607 12608 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 12609 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 12610 op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 12611 result->value.type = ira->codegen->builtin_types.entry_bool; 12612 return result; 12613 } 12614 12615 static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *type_entry, 12616 ConstExprValue *op1_val, IrBinOp op_id, ConstExprValue *op2_val, ConstExprValue *out_val) 12617 { 12618 bool is_int; 12619 bool is_float; 12620 Cmp op2_zcmp; 12621 if (type_entry->id == ZigTypeIdInt || type_entry->id == ZigTypeIdComptimeInt) { 12622 is_int = true; 12623 is_float = false; 12624 op2_zcmp = bigint_cmp_zero(&op2_val->data.x_bigint); 12625 } else if (type_entry->id == ZigTypeIdFloat || 12626 type_entry->id == ZigTypeIdComptimeFloat) 12627 { 12628 is_int = false; 12629 is_float = true; 12630 op2_zcmp = float_cmp_zero(op2_val); 12631 } else { 12632 zig_unreachable(); 12633 } 12634 12635 if ((op_id == IrBinOpDivUnspecified || op_id == IrBinOpRemRem || op_id == IrBinOpRemMod || 12636 op_id == IrBinOpDivTrunc || op_id == IrBinOpDivFloor) && op2_zcmp == CmpEQ) 12637 { 12638 return ir_add_error(ira, source_instr, buf_sprintf("division by zero")); 12639 } 12640 if ((op_id == IrBinOpRemRem || op_id == IrBinOpRemMod) && op2_zcmp == CmpLT) { 12641 return ir_add_error(ira, source_instr, buf_sprintf("negative denominator")); 12642 } 12643 12644 switch (op_id) { 12645 case IrBinOpInvalid: 12646 case IrBinOpBoolOr: 12647 case IrBinOpBoolAnd: 12648 case IrBinOpCmpEq: 12649 case IrBinOpCmpNotEq: 12650 case IrBinOpCmpLessThan: 12651 case IrBinOpCmpGreaterThan: 12652 case IrBinOpCmpLessOrEq: 12653 case IrBinOpCmpGreaterOrEq: 12654 case IrBinOpArrayCat: 12655 case IrBinOpArrayMult: 12656 case IrBinOpRemUnspecified: 12657 case IrBinOpMergeErrorSets: 12658 zig_unreachable(); 12659 case IrBinOpBinOr: 12660 assert(is_int); 12661 bigint_or(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12662 break; 12663 case IrBinOpBinXor: 12664 assert(is_int); 12665 bigint_xor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12666 break; 12667 case IrBinOpBinAnd: 12668 assert(is_int); 12669 bigint_and(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12670 break; 12671 case IrBinOpBitShiftLeftExact: 12672 assert(is_int); 12673 bigint_shl(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12674 break; 12675 case IrBinOpBitShiftLeftLossy: 12676 assert(type_entry->id == ZigTypeIdInt); 12677 bigint_shl_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 12678 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 12679 break; 12680 case IrBinOpBitShiftRightExact: 12681 { 12682 assert(is_int); 12683 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12684 BigInt orig_bigint; 12685 bigint_shl(&orig_bigint, &out_val->data.x_bigint, &op2_val->data.x_bigint); 12686 if (bigint_cmp(&op1_val->data.x_bigint, &orig_bigint) != CmpEQ) { 12687 return ir_add_error(ira, source_instr, buf_sprintf("exact shift shifted out 1 bits")); 12688 } 12689 break; 12690 } 12691 case IrBinOpBitShiftRightLossy: 12692 assert(is_int); 12693 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12694 break; 12695 case IrBinOpAdd: 12696 if (is_int) { 12697 bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12698 } else { 12699 float_add(out_val, op1_val, op2_val); 12700 } 12701 break; 12702 case IrBinOpAddWrap: 12703 assert(type_entry->id == ZigTypeIdInt); 12704 bigint_add_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 12705 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 12706 break; 12707 case IrBinOpSub: 12708 if (is_int) { 12709 bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12710 } else { 12711 float_sub(out_val, op1_val, op2_val); 12712 } 12713 break; 12714 case IrBinOpSubWrap: 12715 assert(type_entry->id == ZigTypeIdInt); 12716 bigint_sub_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 12717 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 12718 break; 12719 case IrBinOpMult: 12720 if (is_int) { 12721 bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12722 } else { 12723 float_mul(out_val, op1_val, op2_val); 12724 } 12725 break; 12726 case IrBinOpMultWrap: 12727 assert(type_entry->id == ZigTypeIdInt); 12728 bigint_mul_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 12729 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 12730 break; 12731 case IrBinOpDivUnspecified: 12732 assert(is_float); 12733 float_div(out_val, op1_val, op2_val); 12734 break; 12735 case IrBinOpDivTrunc: 12736 if (is_int) { 12737 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12738 } else { 12739 float_div_trunc(out_val, op1_val, op2_val); 12740 } 12741 break; 12742 case IrBinOpDivFloor: 12743 if (is_int) { 12744 bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12745 } else { 12746 float_div_floor(out_val, op1_val, op2_val); 12747 } 12748 break; 12749 case IrBinOpDivExact: 12750 if (is_int) { 12751 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12752 BigInt remainder; 12753 bigint_rem(&remainder, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12754 if (bigint_cmp_zero(&remainder) != CmpEQ) { 12755 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 12756 } 12757 } else { 12758 float_div_trunc(out_val, op1_val, op2_val); 12759 ConstExprValue remainder; 12760 float_rem(&remainder, op1_val, op2_val); 12761 if (float_cmp_zero(&remainder) != CmpEQ) { 12762 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 12763 } 12764 } 12765 break; 12766 case IrBinOpRemRem: 12767 if (is_int) { 12768 bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12769 } else { 12770 float_rem(out_val, op1_val, op2_val); 12771 } 12772 break; 12773 case IrBinOpRemMod: 12774 if (is_int) { 12775 bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 12776 } else { 12777 float_mod(out_val, op1_val, op2_val); 12778 } 12779 break; 12780 } 12781 12782 if (type_entry->id == ZigTypeIdInt) { 12783 if (!bigint_fits_in_bits(&out_val->data.x_bigint, type_entry->data.integral.bit_count, 12784 type_entry->data.integral.is_signed)) 12785 { 12786 return ir_add_error(ira, source_instr, buf_sprintf("operation caused overflow")); 12787 } 12788 } 12789 12790 out_val->type = type_entry; 12791 out_val->special = ConstValSpecialStatic; 12792 return nullptr; 12793 } 12794 12795 // This works on operands that have already been checked to be comptime known. 12796 static IrInstruction *ir_analyze_math_op(IrAnalyze *ira, IrInstruction *source_instr, 12797 ZigType *type_entry, ConstExprValue *op1_val, IrBinOp op_id, ConstExprValue *op2_val) 12798 { 12799 IrInstruction *result_instruction = ir_const(ira, source_instr, type_entry); 12800 ConstExprValue *out_val = &result_instruction->value; 12801 if (type_entry->id == ZigTypeIdVector) { 12802 expand_undef_array(ira->codegen, op1_val); 12803 expand_undef_array(ira->codegen, op2_val); 12804 out_val->special = ConstValSpecialUndef; 12805 expand_undef_array(ira->codegen, out_val); 12806 size_t len = type_entry->data.vector.len; 12807 ZigType *scalar_type = type_entry->data.vector.elem_type; 12808 for (size_t i = 0; i < len; i += 1) { 12809 ConstExprValue *scalar_op1_val = &op1_val->data.x_array.data.s_none.elements[i]; 12810 ConstExprValue *scalar_op2_val = &op2_val->data.x_array.data.s_none.elements[i]; 12811 ConstExprValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 12812 assert(scalar_op1_val->type == scalar_type); 12813 assert(scalar_op2_val->type == scalar_type); 12814 assert(scalar_out_val->type == scalar_type); 12815 ErrorMsg *msg = ir_eval_math_op_scalar(ira, source_instr, scalar_type, 12816 scalar_op1_val, op_id, scalar_op2_val, scalar_out_val); 12817 if (msg != nullptr) { 12818 add_error_note(ira->codegen, msg, source_instr->source_node, 12819 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 12820 return ira->codegen->invalid_instruction; 12821 } 12822 } 12823 out_val->type = type_entry; 12824 out_val->special = ConstValSpecialStatic; 12825 } else { 12826 if (ir_eval_math_op_scalar(ira, source_instr, type_entry, op1_val, op_id, op2_val, out_val) != nullptr) { 12827 return ira->codegen->invalid_instruction; 12828 } 12829 } 12830 return ir_implicit_cast(ira, result_instruction, type_entry); 12831 } 12832 12833 static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 12834 IrInstruction *op1 = bin_op_instruction->op1->child; 12835 if (type_is_invalid(op1->value.type)) 12836 return ira->codegen->invalid_instruction; 12837 12838 if (op1->value.type->id != ZigTypeIdInt && op1->value.type->id != ZigTypeIdComptimeInt) { 12839 ir_add_error(ira, &bin_op_instruction->base, 12840 buf_sprintf("bit shifting operation expected integer type, found '%s'", 12841 buf_ptr(&op1->value.type->name))); 12842 return ira->codegen->invalid_instruction; 12843 } 12844 12845 IrInstruction *op2 = bin_op_instruction->op2->child; 12846 if (type_is_invalid(op2->value.type)) 12847 return ira->codegen->invalid_instruction; 12848 12849 IrInstruction *casted_op2; 12850 IrBinOp op_id = bin_op_instruction->op_id; 12851 if (op1->value.type->id == ZigTypeIdComptimeInt) { 12852 casted_op2 = op2; 12853 12854 if (op_id == IrBinOpBitShiftLeftLossy) { 12855 op_id = IrBinOpBitShiftLeftExact; 12856 } 12857 12858 if (casted_op2->value.data.x_bigint.is_negative) { 12859 Buf *val_buf = buf_alloc(); 12860 bigint_append_buf(val_buf, &casted_op2->value.data.x_bigint, 10); 12861 ir_add_error(ira, casted_op2, buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); 12862 return ira->codegen->invalid_instruction; 12863 } 12864 } else { 12865 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 12866 op1->value.type->data.integral.bit_count - 1); 12867 if (bin_op_instruction->op_id == IrBinOpBitShiftLeftLossy && 12868 op2->value.type->id == ZigTypeIdComptimeInt) { 12869 if (!bigint_fits_in_bits(&op2->value.data.x_bigint, 12870 shift_amt_type->data.integral.bit_count, 12871 op2->value.data.x_bigint.is_negative)) { 12872 Buf *val_buf = buf_alloc(); 12873 bigint_append_buf(val_buf, &op2->value.data.x_bigint, 10); 12874 ErrorMsg* msg = ir_add_error(ira, 12875 &bin_op_instruction->base, 12876 buf_sprintf("RHS of shift is too large for LHS type")); 12877 add_error_note( 12878 ira->codegen, 12879 msg, 12880 op2->source_node, 12881 buf_sprintf("value %s cannot fit into type %s", 12882 buf_ptr(val_buf), 12883 buf_ptr(&shift_amt_type->name))); 12884 return ira->codegen->invalid_instruction; 12885 } 12886 } 12887 12888 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 12889 if (casted_op2 == ira->codegen->invalid_instruction) 12890 return ira->codegen->invalid_instruction; 12891 } 12892 12893 if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { 12894 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 12895 if (op1_val == nullptr) 12896 return ira->codegen->invalid_instruction; 12897 12898 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 12899 if (op2_val == nullptr) 12900 return ira->codegen->invalid_instruction; 12901 12902 return ir_analyze_math_op(ira, &bin_op_instruction->base, op1->value.type, op1_val, op_id, op2_val); 12903 } else if (op1->value.type->id == ZigTypeIdComptimeInt) { 12904 ir_add_error(ira, &bin_op_instruction->base, 12905 buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known")); 12906 return ira->codegen->invalid_instruction; 12907 } else if (instr_is_comptime(casted_op2) && bigint_cmp_zero(&casted_op2->value.data.x_bigint) == CmpEQ) { 12908 IrInstruction *result = ir_build_cast(&ira->new_irb, bin_op_instruction->base.scope, 12909 bin_op_instruction->base.source_node, op1->value.type, op1, CastOpNoop); 12910 result->value.type = op1->value.type; 12911 return result; 12912 } 12913 12914 IrInstruction *result = ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.scope, 12915 bin_op_instruction->base.source_node, op_id, 12916 op1, casted_op2, bin_op_instruction->safety_check_on); 12917 result->value.type = op1->value.type; 12918 return result; 12919 } 12920 12921 static bool ok_float_op(IrBinOp op) { 12922 switch (op) { 12923 case IrBinOpInvalid: 12924 zig_unreachable(); 12925 case IrBinOpAdd: 12926 case IrBinOpSub: 12927 case IrBinOpMult: 12928 case IrBinOpDivUnspecified: 12929 case IrBinOpDivTrunc: 12930 case IrBinOpDivFloor: 12931 case IrBinOpDivExact: 12932 case IrBinOpRemRem: 12933 case IrBinOpRemMod: 12934 return true; 12935 12936 case IrBinOpBoolOr: 12937 case IrBinOpBoolAnd: 12938 case IrBinOpCmpEq: 12939 case IrBinOpCmpNotEq: 12940 case IrBinOpCmpLessThan: 12941 case IrBinOpCmpGreaterThan: 12942 case IrBinOpCmpLessOrEq: 12943 case IrBinOpCmpGreaterOrEq: 12944 case IrBinOpBinOr: 12945 case IrBinOpBinXor: 12946 case IrBinOpBinAnd: 12947 case IrBinOpBitShiftLeftLossy: 12948 case IrBinOpBitShiftLeftExact: 12949 case IrBinOpBitShiftRightLossy: 12950 case IrBinOpBitShiftRightExact: 12951 case IrBinOpAddWrap: 12952 case IrBinOpSubWrap: 12953 case IrBinOpMultWrap: 12954 case IrBinOpRemUnspecified: 12955 case IrBinOpArrayCat: 12956 case IrBinOpArrayMult: 12957 case IrBinOpMergeErrorSets: 12958 return false; 12959 } 12960 zig_unreachable(); 12961 } 12962 12963 static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { 12964 if (lhs_type->id != ZigTypeIdPointer) 12965 return false; 12966 switch (op) { 12967 case IrBinOpAdd: 12968 case IrBinOpSub: 12969 break; 12970 default: 12971 return false; 12972 } 12973 switch (lhs_type->data.pointer.ptr_len) { 12974 case PtrLenSingle: 12975 return false; 12976 case PtrLenUnknown: 12977 case PtrLenC: 12978 break; 12979 } 12980 return true; 12981 } 12982 12983 static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) { 12984 Error err; 12985 12986 IrInstruction *op1 = instruction->op1->child; 12987 if (type_is_invalid(op1->value.type)) 12988 return ira->codegen->invalid_instruction; 12989 12990 IrInstruction *op2 = instruction->op2->child; 12991 if (type_is_invalid(op2->value.type)) 12992 return ira->codegen->invalid_instruction; 12993 12994 IrBinOp op_id = instruction->op_id; 12995 12996 // look for pointer math 12997 if (is_pointer_arithmetic_allowed(op1->value.type, op_id)) { 12998 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize); 12999 if (type_is_invalid(casted_op2->value.type)) 13000 return ira->codegen->invalid_instruction; 13001 13002 if (op1->value.special == ConstValSpecialUndef || casted_op2->value.special == ConstValSpecialUndef) { 13003 IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type); 13004 result->value.special = ConstValSpecialUndef; 13005 return result; 13006 } 13007 if (casted_op2->value.special == ConstValSpecialStatic && op1->value.special == ConstValSpecialStatic && 13008 (op1->value.data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 13009 op1->value.data.x_ptr.special == ConstPtrSpecialNull)) 13010 { 13011 uint64_t start_addr = (op1->value.data.x_ptr.special == ConstPtrSpecialNull) ? 13012 0 : op1->value.data.x_ptr.data.hard_coded_addr.addr; 13013 uint64_t elem_offset; 13014 if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) 13015 return ira->codegen->invalid_instruction; 13016 ZigType *elem_type = op1->value.type->data.pointer.child_type; 13017 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) 13018 return ira->codegen->invalid_instruction; 13019 uint64_t byte_offset = type_size(ira->codegen, elem_type) * elem_offset; 13020 uint64_t new_addr; 13021 if (op_id == IrBinOpAdd) { 13022 new_addr = start_addr + byte_offset; 13023 } else if (op_id == IrBinOpSub) { 13024 new_addr = start_addr - byte_offset; 13025 } else { 13026 zig_unreachable(); 13027 } 13028 IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type); 13029 result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 13030 result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar; 13031 result->value.data.x_ptr.data.hard_coded_addr.addr = new_addr; 13032 return result; 13033 } 13034 13035 IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope, 13036 instruction->base.source_node, op_id, op1, casted_op2, true); 13037 result->value.type = op1->value.type; 13038 return result; 13039 } 13040 13041 IrInstruction *instructions[] = {op1, op2}; 13042 ZigType *resolved_type = ir_resolve_peer_types(ira, instruction->base.source_node, nullptr, instructions, 2); 13043 if (type_is_invalid(resolved_type)) 13044 return ira->codegen->invalid_instruction; 13045 13046 bool is_int = resolved_type->id == ZigTypeIdInt || resolved_type->id == ZigTypeIdComptimeInt; 13047 bool is_float = resolved_type->id == ZigTypeIdFloat || resolved_type->id == ZigTypeIdComptimeFloat; 13048 bool is_signed_div = ( 13049 (resolved_type->id == ZigTypeIdInt && resolved_type->data.integral.is_signed) || 13050 resolved_type->id == ZigTypeIdFloat || 13051 (resolved_type->id == ZigTypeIdComptimeFloat && 13052 ((bigfloat_cmp_zero(&op1->value.data.x_bigfloat) != CmpGT) != 13053 (bigfloat_cmp_zero(&op2->value.data.x_bigfloat) != CmpGT))) || 13054 (resolved_type->id == ZigTypeIdComptimeInt && 13055 ((bigint_cmp_zero(&op1->value.data.x_bigint) != CmpGT) != 13056 (bigint_cmp_zero(&op2->value.data.x_bigint) != CmpGT))) 13057 ); 13058 if (op_id == IrBinOpDivUnspecified && is_int) { 13059 if (is_signed_div) { 13060 bool ok = false; 13061 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 13062 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 13063 if (op1_val == nullptr) 13064 return ira->codegen->invalid_instruction; 13065 13066 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 13067 if (op2_val == nullptr) 13068 return ira->codegen->invalid_instruction; 13069 13070 if (bigint_cmp_zero(&op2_val->data.x_bigint) == CmpEQ) { 13071 // the division by zero error will be caught later, but we don't have a 13072 // division function ambiguity problem. 13073 op_id = IrBinOpDivTrunc; 13074 ok = true; 13075 } else { 13076 BigInt trunc_result; 13077 BigInt floor_result; 13078 bigint_div_trunc(&trunc_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13079 bigint_div_floor(&floor_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13080 if (bigint_cmp(&trunc_result, &floor_result) == CmpEQ) { 13081 ok = true; 13082 op_id = IrBinOpDivTrunc; 13083 } 13084 } 13085 } 13086 if (!ok) { 13087 ir_add_error(ira, &instruction->base, 13088 buf_sprintf("division with '%s' and '%s': signed integers must use @divTrunc, @divFloor, or @divExact", 13089 buf_ptr(&op1->value.type->name), 13090 buf_ptr(&op2->value.type->name))); 13091 return ira->codegen->invalid_instruction; 13092 } 13093 } else { 13094 op_id = IrBinOpDivTrunc; 13095 } 13096 } else if (op_id == IrBinOpRemUnspecified) { 13097 if (is_signed_div && (is_int || is_float)) { 13098 bool ok = false; 13099 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 13100 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 13101 if (op1_val == nullptr) 13102 return ira->codegen->invalid_instruction; 13103 13104 if (is_int) { 13105 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 13106 if (op2_val == nullptr) 13107 return ira->codegen->invalid_instruction; 13108 13109 if (bigint_cmp_zero(&op2->value.data.x_bigint) == CmpEQ) { 13110 // the division by zero error will be caught later, but we don't 13111 // have a remainder function ambiguity problem 13112 ok = true; 13113 } else { 13114 BigInt rem_result; 13115 BigInt mod_result; 13116 bigint_rem(&rem_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13117 bigint_mod(&mod_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13118 ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ; 13119 } 13120 } else { 13121 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 13122 if (casted_op2 == ira->codegen->invalid_instruction) 13123 return ira->codegen->invalid_instruction; 13124 13125 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 13126 if (op2_val == nullptr) 13127 return ira->codegen->invalid_instruction; 13128 13129 if (float_cmp_zero(&casted_op2->value) == CmpEQ) { 13130 // the division by zero error will be caught later, but we don't 13131 // have a remainder function ambiguity problem 13132 ok = true; 13133 } else { 13134 ConstExprValue rem_result; 13135 ConstExprValue mod_result; 13136 float_rem(&rem_result, op1_val, op2_val); 13137 float_mod(&mod_result, op1_val, op2_val); 13138 ok = float_cmp(&rem_result, &mod_result) == CmpEQ; 13139 } 13140 } 13141 } 13142 if (!ok) { 13143 ir_add_error(ira, &instruction->base, 13144 buf_sprintf("remainder division with '%s' and '%s': signed integers and floats must use @rem or @mod", 13145 buf_ptr(&op1->value.type->name), 13146 buf_ptr(&op2->value.type->name))); 13147 return ira->codegen->invalid_instruction; 13148 } 13149 } 13150 op_id = IrBinOpRemRem; 13151 } 13152 13153 bool ok = false; 13154 if (is_int) { 13155 ok = true; 13156 } else if (is_float && ok_float_op(op_id)) { 13157 ok = true; 13158 } else if (resolved_type->id == ZigTypeIdVector) { 13159 ZigType *elem_type = resolved_type->data.vector.elem_type; 13160 if (elem_type->id == ZigTypeIdInt || elem_type->id == ZigTypeIdComptimeInt) { 13161 ok = true; 13162 } else if ((elem_type->id == ZigTypeIdFloat || elem_type->id == ZigTypeIdComptimeFloat) && ok_float_op(op_id)) { 13163 ok = true; 13164 } 13165 } 13166 if (!ok) { 13167 AstNode *source_node = instruction->base.source_node; 13168 ir_add_error_node(ira, source_node, 13169 buf_sprintf("invalid operands to binary expression: '%s' and '%s'", 13170 buf_ptr(&op1->value.type->name), 13171 buf_ptr(&op2->value.type->name))); 13172 return ira->codegen->invalid_instruction; 13173 } 13174 13175 if (resolved_type->id == ZigTypeIdComptimeInt) { 13176 if (op_id == IrBinOpAddWrap) { 13177 op_id = IrBinOpAdd; 13178 } else if (op_id == IrBinOpSubWrap) { 13179 op_id = IrBinOpSub; 13180 } else if (op_id == IrBinOpMultWrap) { 13181 op_id = IrBinOpMult; 13182 } 13183 } 13184 13185 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 13186 if (casted_op1 == ira->codegen->invalid_instruction) 13187 return ira->codegen->invalid_instruction; 13188 13189 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 13190 if (casted_op2 == ira->codegen->invalid_instruction) 13191 return ira->codegen->invalid_instruction; 13192 13193 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 13194 ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 13195 if (op1_val == nullptr) 13196 return ira->codegen->invalid_instruction; 13197 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 13198 if (op2_val == nullptr) 13199 return ira->codegen->invalid_instruction; 13200 13201 return ir_analyze_math_op(ira, &instruction->base, resolved_type, op1_val, op_id, op2_val); 13202 } 13203 13204 IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope, 13205 instruction->base.source_node, op_id, casted_op1, casted_op2, instruction->safety_check_on); 13206 result->value.type = resolved_type; 13207 return result; 13208 } 13209 13210 static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruction) { 13211 IrInstruction *op1 = instruction->op1->child; 13212 ZigType *op1_type = op1->value.type; 13213 if (type_is_invalid(op1_type)) 13214 return ira->codegen->invalid_instruction; 13215 13216 IrInstruction *op2 = instruction->op2->child; 13217 ZigType *op2_type = op2->value.type; 13218 if (type_is_invalid(op2_type)) 13219 return ira->codegen->invalid_instruction; 13220 13221 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 13222 if (!op1_val) 13223 return ira->codegen->invalid_instruction; 13224 13225 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 13226 if (!op2_val) 13227 return ira->codegen->invalid_instruction; 13228 13229 ConstExprValue *op1_array_val; 13230 size_t op1_array_index; 13231 size_t op1_array_end; 13232 ZigType *child_type; 13233 if (op1_type->id == ZigTypeIdArray) { 13234 child_type = op1_type->data.array.child_type; 13235 op1_array_val = op1_val; 13236 op1_array_index = 0; 13237 op1_array_end = op1_type->data.array.len; 13238 } else if (op1_type->id == ZigTypeIdPointer && 13239 op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 13240 op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray && 13241 op1_val->data.x_ptr.data.base_array.is_cstr) 13242 { 13243 child_type = op1_type->data.pointer.child_type; 13244 op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; 13245 op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; 13246 op1_array_end = op1_array_val->type->data.array.len - 1; 13247 } else if (is_slice(op1_type)) { 13248 ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index].type_entry; 13249 child_type = ptr_type->data.pointer.child_type; 13250 ConstExprValue *ptr_val = &op1_val->data.x_struct.fields[slice_ptr_index]; 13251 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 13252 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 13253 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 13254 ConstExprValue *len_val = &op1_val->data.x_struct.fields[slice_len_index]; 13255 op1_array_end = op1_array_index + bigint_as_unsigned(&len_val->data.x_bigint); 13256 } else { 13257 ir_add_error(ira, op1, 13258 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name))); 13259 return ira->codegen->invalid_instruction; 13260 } 13261 13262 ConstExprValue *op2_array_val; 13263 size_t op2_array_index; 13264 size_t op2_array_end; 13265 bool op2_type_valid; 13266 if (op2_type->id == ZigTypeIdArray) { 13267 op2_type_valid = op2_type->data.array.child_type == child_type; 13268 op2_array_val = op2_val; 13269 op2_array_index = 0; 13270 op2_array_end = op2_array_val->type->data.array.len; 13271 } else if (op2_type->id == ZigTypeIdPointer && 13272 op2_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 13273 op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray && 13274 op2_val->data.x_ptr.data.base_array.is_cstr) 13275 { 13276 op2_type_valid = child_type == ira->codegen->builtin_types.entry_u8; 13277 op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; 13278 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; 13279 op2_array_end = op2_array_val->type->data.array.len - 1; 13280 } else if (is_slice(op2_type)) { 13281 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry; 13282 op2_type_valid = ptr_type->data.pointer.child_type == child_type; 13283 ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index]; 13284 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 13285 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 13286 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 13287 ConstExprValue *len_val = &op2_val->data.x_struct.fields[slice_len_index]; 13288 op2_array_end = op2_array_index + bigint_as_unsigned(&len_val->data.x_bigint); 13289 } else { 13290 ir_add_error(ira, op2, 13291 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name))); 13292 return ira->codegen->invalid_instruction; 13293 } 13294 if (!op2_type_valid) { 13295 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", 13296 buf_ptr(&child_type->name), 13297 buf_ptr(&op2->value.type->name))); 13298 return ira->codegen->invalid_instruction; 13299 } 13300 13301 // The type of result is populated in the following if blocks 13302 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 13303 ConstExprValue *out_val = &result->value; 13304 13305 ConstExprValue *out_array_val; 13306 size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); 13307 if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { 13308 result->value.type = get_array_type(ira->codegen, child_type, new_len); 13309 13310 out_array_val = out_val; 13311 } else if (is_slice(op1_type) || is_slice(op2_type)) { 13312 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, 13313 true, false, PtrLenUnknown, 0, 0, 0, false); 13314 result->value.type = get_slice_type(ira->codegen, ptr_type); 13315 out_array_val = create_const_vals(1); 13316 out_array_val->special = ConstValSpecialStatic; 13317 out_array_val->type = get_array_type(ira->codegen, child_type, new_len); 13318 13319 out_val->data.x_struct.fields = create_const_vals(2); 13320 13321 out_val->data.x_struct.fields[slice_ptr_index].type = ptr_type; 13322 out_val->data.x_struct.fields[slice_ptr_index].special = ConstValSpecialStatic; 13323 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.special = ConstPtrSpecialBaseArray; 13324 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.array_val = out_array_val; 13325 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.elem_index = 0; 13326 13327 out_val->data.x_struct.fields[slice_len_index].type = ira->codegen->builtin_types.entry_usize; 13328 out_val->data.x_struct.fields[slice_len_index].special = ConstValSpecialStatic; 13329 bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index].data.x_bigint, new_len); 13330 } else { 13331 new_len += 1; // null byte 13332 13333 // TODO make this `[*]null T` instead of `[*]T` 13334 result->value.type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, PtrLenUnknown, 0, 0, 0, false); 13335 13336 out_array_val = create_const_vals(1); 13337 out_array_val->special = ConstValSpecialStatic; 13338 out_array_val->type = get_array_type(ira->codegen, child_type, new_len); 13339 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 13340 out_val->data.x_ptr.data.base_array.is_cstr = true; 13341 out_val->data.x_ptr.data.base_array.array_val = out_array_val; 13342 out_val->data.x_ptr.data.base_array.elem_index = 0; 13343 } 13344 13345 if (op1_array_val->data.x_array.special == ConstArraySpecialUndef && 13346 op2_array_val->data.x_array.special == ConstArraySpecialUndef) { 13347 out_array_val->data.x_array.special = ConstArraySpecialUndef; 13348 return result; 13349 } 13350 13351 out_array_val->data.x_array.data.s_none.elements = create_const_vals(new_len); 13352 // TODO handle the buf case here for an optimization 13353 expand_undef_array(ira->codegen, op1_array_val); 13354 expand_undef_array(ira->codegen, op2_array_val); 13355 13356 size_t next_index = 0; 13357 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { 13358 out_array_val->data.x_array.data.s_none.elements[next_index] = op1_array_val->data.x_array.data.s_none.elements[i]; 13359 } 13360 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { 13361 out_array_val->data.x_array.data.s_none.elements[next_index] = op2_array_val->data.x_array.data.s_none.elements[i]; 13362 } 13363 if (next_index < new_len) { 13364 ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; 13365 init_const_unsigned_negative(null_byte, child_type, 0, false); 13366 next_index += 1; 13367 } 13368 assert(next_index == new_len); 13369 13370 return result; 13371 } 13372 13373 static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instruction) { 13374 IrInstruction *op1 = instruction->op1->child; 13375 if (type_is_invalid(op1->value.type)) 13376 return ira->codegen->invalid_instruction; 13377 13378 IrInstruction *op2 = instruction->op2->child; 13379 if (type_is_invalid(op2->value.type)) 13380 return ira->codegen->invalid_instruction; 13381 13382 ConstExprValue *array_val = ir_resolve_const(ira, op1, UndefBad); 13383 if (!array_val) 13384 return ira->codegen->invalid_instruction; 13385 13386 uint64_t mult_amt; 13387 if (!ir_resolve_usize(ira, op2, &mult_amt)) 13388 return ira->codegen->invalid_instruction; 13389 13390 ZigType *array_type = op1->value.type; 13391 if (array_type->id != ZigTypeIdArray) { 13392 ir_add_error(ira, op1, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value.type->name))); 13393 return ira->codegen->invalid_instruction; 13394 } 13395 13396 uint64_t old_array_len = array_type->data.array.len; 13397 uint64_t new_array_len; 13398 13399 if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) 13400 { 13401 ir_add_error(ira, &instruction->base, buf_sprintf("operation results in overflow")); 13402 return ira->codegen->invalid_instruction; 13403 } 13404 13405 ZigType *child_type = array_type->data.array.child_type; 13406 13407 IrInstruction *result = ir_const(ira, &instruction->base, 13408 get_array_type(ira->codegen, child_type, new_array_len)); 13409 ConstExprValue *out_val = &result->value; 13410 if (array_val->data.x_array.special == ConstArraySpecialUndef) { 13411 out_val->data.x_array.special = ConstArraySpecialUndef; 13412 return result; 13413 } 13414 13415 // TODO optimize the buf case 13416 expand_undef_array(ira->codegen, array_val); 13417 out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len); 13418 13419 uint64_t i = 0; 13420 for (uint64_t x = 0; x < mult_amt; x += 1) { 13421 for (uint64_t y = 0; y < old_array_len; y += 1) { 13422 out_val->data.x_array.data.s_none.elements[i] = array_val->data.x_array.data.s_none.elements[y]; 13423 i += 1; 13424 } 13425 } 13426 assert(i == new_array_len); 13427 13428 return result; 13429 } 13430 13431 static IrInstruction *ir_analyze_merge_error_sets(IrAnalyze *ira, IrInstructionBinOp *instruction) { 13432 ZigType *op1_type = ir_resolve_error_set_type(ira, &instruction->base, instruction->op1->child); 13433 if (type_is_invalid(op1_type)) 13434 return ira->codegen->invalid_instruction; 13435 13436 ZigType *op2_type = ir_resolve_error_set_type(ira, &instruction->base, instruction->op2->child); 13437 if (type_is_invalid(op2_type)) 13438 return ira->codegen->invalid_instruction; 13439 13440 if (type_is_global_error_set(op1_type) || 13441 type_is_global_error_set(op2_type)) 13442 { 13443 return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_global_error_set); 13444 } 13445 13446 if (!resolve_inferred_error_set(ira->codegen, op1_type, instruction->op1->child->source_node)) { 13447 return ira->codegen->invalid_instruction; 13448 } 13449 13450 if (!resolve_inferred_error_set(ira->codegen, op2_type, instruction->op2->child->source_node)) { 13451 return ira->codegen->invalid_instruction; 13452 } 13453 13454 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 13455 for (uint32_t i = 0, count = op1_type->data.error_set.err_count; i < count; i += 1) { 13456 ErrorTableEntry *error_entry = op1_type->data.error_set.errors[i]; 13457 assert(errors[error_entry->value] == nullptr); 13458 errors[error_entry->value] = error_entry; 13459 } 13460 ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type); 13461 free(errors); 13462 13463 return ir_const_type(ira, &instruction->base, result_type); 13464 } 13465 13466 static IrInstruction *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 13467 IrBinOp op_id = bin_op_instruction->op_id; 13468 switch (op_id) { 13469 case IrBinOpInvalid: 13470 zig_unreachable(); 13471 case IrBinOpBoolOr: 13472 case IrBinOpBoolAnd: 13473 return ir_analyze_bin_op_bool(ira, bin_op_instruction); 13474 case IrBinOpCmpEq: 13475 case IrBinOpCmpNotEq: 13476 case IrBinOpCmpLessThan: 13477 case IrBinOpCmpGreaterThan: 13478 case IrBinOpCmpLessOrEq: 13479 case IrBinOpCmpGreaterOrEq: 13480 return ir_analyze_bin_op_cmp(ira, bin_op_instruction); 13481 case IrBinOpBitShiftLeftLossy: 13482 case IrBinOpBitShiftLeftExact: 13483 case IrBinOpBitShiftRightLossy: 13484 case IrBinOpBitShiftRightExact: 13485 return ir_analyze_bit_shift(ira, bin_op_instruction); 13486 case IrBinOpBinOr: 13487 case IrBinOpBinXor: 13488 case IrBinOpBinAnd: 13489 case IrBinOpAdd: 13490 case IrBinOpAddWrap: 13491 case IrBinOpSub: 13492 case IrBinOpSubWrap: 13493 case IrBinOpMult: 13494 case IrBinOpMultWrap: 13495 case IrBinOpDivUnspecified: 13496 case IrBinOpDivTrunc: 13497 case IrBinOpDivFloor: 13498 case IrBinOpDivExact: 13499 case IrBinOpRemUnspecified: 13500 case IrBinOpRemRem: 13501 case IrBinOpRemMod: 13502 return ir_analyze_bin_op_math(ira, bin_op_instruction); 13503 case IrBinOpArrayCat: 13504 return ir_analyze_array_cat(ira, bin_op_instruction); 13505 case IrBinOpArrayMult: 13506 return ir_analyze_array_mult(ira, bin_op_instruction); 13507 case IrBinOpMergeErrorSets: 13508 return ir_analyze_merge_error_sets(ira, bin_op_instruction); 13509 } 13510 zig_unreachable(); 13511 } 13512 13513 static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, 13514 IrInstructionDeclVarSrc *decl_var_instruction) 13515 { 13516 Error err; 13517 ZigVar *var = decl_var_instruction->var; 13518 13519 IrInstruction *init_value = decl_var_instruction->init_value->child; 13520 if (type_is_invalid(init_value->value.type)) { 13521 var->var_type = ira->codegen->builtin_types.entry_invalid; 13522 return ira->codegen->invalid_instruction; 13523 } 13524 13525 ZigType *explicit_type = nullptr; 13526 IrInstruction *var_type = nullptr; 13527 if (decl_var_instruction->var_type != nullptr) { 13528 var_type = decl_var_instruction->var_type->child; 13529 ZigType *proposed_type = ir_resolve_type(ira, var_type); 13530 explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type); 13531 if (type_is_invalid(explicit_type)) { 13532 var->var_type = ira->codegen->builtin_types.entry_invalid; 13533 return ira->codegen->invalid_instruction; 13534 } 13535 } 13536 13537 AstNode *source_node = decl_var_instruction->base.source_node; 13538 13539 IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); 13540 bool is_comptime_var = ir_get_var_is_comptime(var); 13541 13542 bool var_class_requires_const = false; 13543 13544 ZigType *result_type = casted_init_value->value.type; 13545 if (type_is_invalid(result_type)) { 13546 result_type = ira->codegen->builtin_types.entry_invalid; 13547 } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { 13548 ir_add_error_node(ira, source_node, 13549 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); 13550 result_type = ira->codegen->builtin_types.entry_invalid; 13551 } 13552 13553 switch (type_requires_comptime(ira->codegen, result_type)) { 13554 case ReqCompTimeInvalid: 13555 result_type = ira->codegen->builtin_types.entry_invalid; 13556 break; 13557 case ReqCompTimeYes: 13558 var_class_requires_const = true; 13559 if (!var->gen_is_const && !is_comptime_var) { 13560 ir_add_error_node(ira, source_node, 13561 buf_sprintf("variable of type '%s' must be const or comptime", 13562 buf_ptr(&result_type->name))); 13563 result_type = ira->codegen->builtin_types.entry_invalid; 13564 } 13565 break; 13566 case ReqCompTimeNo: 13567 if (casted_init_value->value.special == ConstValSpecialStatic && 13568 casted_init_value->value.type->id == ZigTypeIdFn && 13569 casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 13570 casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) 13571 { 13572 var_class_requires_const = true; 13573 if (!var->src_is_const && !is_comptime_var) { 13574 ErrorMsg *msg = ir_add_error_node(ira, source_node, 13575 buf_sprintf("functions marked inline must be stored in const or comptime var")); 13576 AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node; 13577 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); 13578 result_type = ira->codegen->builtin_types.entry_invalid; 13579 } 13580 } 13581 break; 13582 } 13583 13584 if (var->var_type != nullptr && !is_comptime_var) { 13585 // This is at least the second time we've seen this variable declaration during analysis. 13586 // This means that this is actually a different variable due to, e.g. an inline while loop. 13587 // We make a new variable so that it can hold a different type, and so the debug info can 13588 // be distinct. 13589 ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope, 13590 &var->name, var->src_is_const, var->gen_is_const, var->shadowable, var->is_comptime, true); 13591 new_var->owner_exec = var->owner_exec; 13592 new_var->align_bytes = var->align_bytes; 13593 if (var->mem_slot_index != SIZE_MAX) { 13594 ConstExprValue *vals = create_const_vals(1); 13595 new_var->mem_slot_index = ira->exec_context.mem_slot_list.length; 13596 ira->exec_context.mem_slot_list.append(vals); 13597 } 13598 13599 var->next_var = new_var; 13600 var = new_var; 13601 } 13602 13603 // This must be done after possibly creating a new variable above 13604 var->ref_count = 0; 13605 13606 var->var_type = result_type; 13607 assert(var->var_type); 13608 13609 if (type_is_invalid(result_type)) { 13610 return ir_const_void(ira, &decl_var_instruction->base); 13611 } 13612 13613 if (decl_var_instruction->align_value == nullptr) { 13614 if ((err = type_resolve(ira->codegen, result_type, ResolveStatusAlignmentKnown))) { 13615 var->var_type = ira->codegen->builtin_types.entry_invalid; 13616 return ir_const_void(ira, &decl_var_instruction->base); 13617 } 13618 var->align_bytes = get_abi_alignment(ira->codegen, result_type); 13619 } else { 13620 if (!ir_resolve_align(ira, decl_var_instruction->align_value->child, &var->align_bytes)) { 13621 var->var_type = ira->codegen->builtin_types.entry_invalid; 13622 } 13623 } 13624 13625 if (casted_init_value->value.special != ConstValSpecialRuntime) { 13626 if (var->mem_slot_index != SIZE_MAX) { 13627 assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); 13628 ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); 13629 copy_const_val(mem_slot, &casted_init_value->value, !is_comptime_var || var->gen_is_const); 13630 13631 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { 13632 return ir_const_void(ira, &decl_var_instruction->base); 13633 } 13634 } 13635 } else if (is_comptime_var) { 13636 ir_add_error(ira, &decl_var_instruction->base, 13637 buf_sprintf("cannot store runtime value in compile time variable")); 13638 var->var_type = ira->codegen->builtin_types.entry_invalid; 13639 return ira->codegen->invalid_instruction; 13640 } 13641 13642 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 13643 if (fn_entry) 13644 fn_entry->variable_list.append(var); 13645 13646 return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, casted_init_value); 13647 } 13648 13649 static VarLinkage global_linkage_to_var_linkage(GlobalLinkageId id) { 13650 switch (id) { 13651 case GlobalLinkageIdStrong: 13652 return VarLinkageExportStrong; 13653 case GlobalLinkageIdWeak: 13654 return VarLinkageExportWeak; 13655 case GlobalLinkageIdLinkOnce: 13656 return VarLinkageExportLinkOnce; 13657 case GlobalLinkageIdInternal: 13658 return VarLinkageInternal; 13659 } 13660 zig_unreachable(); 13661 } 13662 13663 static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { 13664 IrInstruction *name = instruction->name->child; 13665 Buf *symbol_name = ir_resolve_str(ira, name); 13666 if (symbol_name == nullptr) { 13667 return ira->codegen->invalid_instruction; 13668 } 13669 13670 IrInstruction *target = instruction->target->child; 13671 if (type_is_invalid(target->value.type)) { 13672 return ira->codegen->invalid_instruction; 13673 } 13674 13675 GlobalLinkageId global_linkage_id = GlobalLinkageIdStrong; 13676 if (instruction->linkage != nullptr) { 13677 IrInstruction *linkage_value = instruction->linkage->child; 13678 if (!ir_resolve_global_linkage(ira, linkage_value, &global_linkage_id)) { 13679 return ira->codegen->invalid_instruction; 13680 } 13681 } 13682 13683 // TODO: This function needs to be audited. 13684 // It's not clear how all the different types are supposed to be handled. 13685 // Need comprehensive tests for exporting one thing in one file and declaring an extern var 13686 // in another file. 13687 TldFn *tld_fn = allocate<TldFn>(1); 13688 tld_fn->base.id = TldIdFn; 13689 tld_fn->base.source_node = instruction->base.source_node; 13690 13691 auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, &tld_fn->base); 13692 if (entry) { 13693 AstNode *other_export_node = entry->value->source_node; 13694 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 13695 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name))); 13696 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); 13697 return ira->codegen->invalid_instruction; 13698 } 13699 13700 bool want_var_export = false; 13701 switch (target->value.type->id) { 13702 case ZigTypeIdInvalid: 13703 case ZigTypeIdUnreachable: 13704 zig_unreachable(); 13705 case ZigTypeIdFn: { 13706 assert(target->value.data.x_ptr.special == ConstPtrSpecialFunction); 13707 ZigFn *fn_entry = target->value.data.x_ptr.data.fn.fn_entry; 13708 tld_fn->fn_entry = fn_entry; 13709 CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc; 13710 switch (cc) { 13711 case CallingConventionUnspecified: { 13712 ErrorMsg *msg = ir_add_error(ira, target, 13713 buf_sprintf("exported function must specify calling convention")); 13714 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 13715 } break; 13716 case CallingConventionAsync: { 13717 ErrorMsg *msg = ir_add_error(ira, target, 13718 buf_sprintf("exported function cannot be async")); 13719 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 13720 } break; 13721 case CallingConventionC: 13722 case CallingConventionNaked: 13723 case CallingConventionCold: 13724 case CallingConventionStdcall: 13725 add_fn_export(ira->codegen, fn_entry, symbol_name, global_linkage_id, cc == CallingConventionC); 13726 break; 13727 } 13728 } break; 13729 case ZigTypeIdStruct: 13730 if (is_slice(target->value.type)) { 13731 ir_add_error(ira, target, 13732 buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value.type->name))); 13733 } else if (target->value.type->data.structure.layout != ContainerLayoutExtern) { 13734 ErrorMsg *msg = ir_add_error(ira, target, 13735 buf_sprintf("exported struct value must be declared extern")); 13736 add_error_note(ira->codegen, msg, target->value.type->data.structure.decl_node, buf_sprintf("declared here")); 13737 } else { 13738 want_var_export = true; 13739 } 13740 break; 13741 case ZigTypeIdUnion: 13742 if (target->value.type->data.unionation.layout != ContainerLayoutExtern) { 13743 ErrorMsg *msg = ir_add_error(ira, target, 13744 buf_sprintf("exported union value must be declared extern")); 13745 add_error_note(ira->codegen, msg, target->value.type->data.unionation.decl_node, buf_sprintf("declared here")); 13746 } else { 13747 want_var_export = true; 13748 } 13749 break; 13750 case ZigTypeIdEnum: 13751 if (target->value.type->data.enumeration.layout != ContainerLayoutExtern) { 13752 ErrorMsg *msg = ir_add_error(ira, target, 13753 buf_sprintf("exported enum value must be declared extern")); 13754 add_error_note(ira->codegen, msg, target->value.type->data.enumeration.decl_node, buf_sprintf("declared here")); 13755 } else { 13756 want_var_export = true; 13757 } 13758 break; 13759 case ZigTypeIdMetaType: { 13760 ZigType *type_value = target->value.data.x_type; 13761 switch (type_value->id) { 13762 case ZigTypeIdInvalid: 13763 zig_unreachable(); 13764 case ZigTypeIdStruct: 13765 if (is_slice(type_value)) { 13766 ir_add_error(ira, target, 13767 buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name))); 13768 } else if (type_value->data.structure.layout != ContainerLayoutExtern) { 13769 ErrorMsg *msg = ir_add_error(ira, target, 13770 buf_sprintf("exported struct must be declared extern")); 13771 add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here")); 13772 } 13773 break; 13774 case ZigTypeIdUnion: 13775 if (type_value->data.unionation.layout != ContainerLayoutExtern) { 13776 ErrorMsg *msg = ir_add_error(ira, target, 13777 buf_sprintf("exported union must be declared extern")); 13778 add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here")); 13779 } 13780 break; 13781 case ZigTypeIdEnum: 13782 if (type_value->data.enumeration.layout != ContainerLayoutExtern) { 13783 ErrorMsg *msg = ir_add_error(ira, target, 13784 buf_sprintf("exported enum must be declared extern")); 13785 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); 13786 } 13787 break; 13788 case ZigTypeIdFn: { 13789 if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 13790 ir_add_error(ira, target, 13791 buf_sprintf("exported function type must specify calling convention")); 13792 } 13793 } break; 13794 case ZigTypeIdInt: 13795 case ZigTypeIdFloat: 13796 case ZigTypeIdPointer: 13797 case ZigTypeIdArray: 13798 case ZigTypeIdBool: 13799 case ZigTypeIdVector: 13800 break; 13801 case ZigTypeIdMetaType: 13802 case ZigTypeIdVoid: 13803 case ZigTypeIdUnreachable: 13804 case ZigTypeIdComptimeFloat: 13805 case ZigTypeIdComptimeInt: 13806 case ZigTypeIdEnumLiteral: 13807 case ZigTypeIdUndefined: 13808 case ZigTypeIdNull: 13809 case ZigTypeIdOptional: 13810 case ZigTypeIdErrorUnion: 13811 case ZigTypeIdErrorSet: 13812 case ZigTypeIdBoundFn: 13813 case ZigTypeIdArgTuple: 13814 case ZigTypeIdOpaque: 13815 case ZigTypeIdPromise: 13816 ir_add_error(ira, target, 13817 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); 13818 break; 13819 } 13820 } break; 13821 case ZigTypeIdVoid: 13822 case ZigTypeIdBool: 13823 case ZigTypeIdInt: 13824 case ZigTypeIdFloat: 13825 case ZigTypeIdPointer: 13826 case ZigTypeIdArray: 13827 case ZigTypeIdComptimeFloat: 13828 case ZigTypeIdComptimeInt: 13829 case ZigTypeIdUndefined: 13830 case ZigTypeIdNull: 13831 case ZigTypeIdOptional: 13832 case ZigTypeIdErrorUnion: 13833 case ZigTypeIdErrorSet: 13834 case ZigTypeIdVector: 13835 zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name)); 13836 case ZigTypeIdBoundFn: 13837 case ZigTypeIdArgTuple: 13838 case ZigTypeIdOpaque: 13839 case ZigTypeIdPromise: 13840 case ZigTypeIdEnumLiteral: 13841 ir_add_error(ira, target, 13842 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name))); 13843 break; 13844 } 13845 13846 // TODO audit the various ways to use @export 13847 if (want_var_export && target->id == IrInstructionIdLoadPtrGen) { 13848 IrInstructionLoadPtrGen *load_ptr = reinterpret_cast<IrInstructionLoadPtrGen *>(target); 13849 if (load_ptr->ptr->id == IrInstructionIdVarPtr) { 13850 IrInstructionVarPtr *var_ptr = reinterpret_cast<IrInstructionVarPtr *>(load_ptr->ptr); 13851 ZigVar *var = var_ptr->var; 13852 var->linkage = global_linkage_to_var_linkage(global_linkage_id); 13853 } 13854 } 13855 13856 return ir_const_void(ira, &instruction->base); 13857 } 13858 13859 static bool exec_has_err_ret_trace(CodeGen *g, IrExecutable *exec) { 13860 ZigFn *fn_entry = exec_fn_entry(exec); 13861 return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing; 13862 } 13863 13864 static IrInstruction *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, 13865 IrInstructionErrorReturnTrace *instruction) 13866 { 13867 if (instruction->optional == IrInstructionErrorReturnTrace::Null) { 13868 ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(ira->codegen); 13869 ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type); 13870 if (!exec_has_err_ret_trace(ira->codegen, ira->new_irb.exec)) { 13871 IrInstruction *result = ir_const(ira, &instruction->base, optional_type); 13872 ConstExprValue *out_val = &result->value; 13873 assert(get_codegen_ptr_type(optional_type) != nullptr); 13874 out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 13875 out_val->data.x_ptr.data.hard_coded_addr.addr = 0; 13876 return result; 13877 } 13878 IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, 13879 instruction->base.source_node, instruction->optional); 13880 new_instruction->value.type = optional_type; 13881 return new_instruction; 13882 } else { 13883 assert(ira->codegen->have_err_ret_tracing); 13884 IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, 13885 instruction->base.source_node, instruction->optional); 13886 new_instruction->value.type = get_ptr_to_stack_trace_type(ira->codegen); 13887 return new_instruction; 13888 } 13889 } 13890 13891 static IrInstruction *ir_analyze_instruction_error_union(IrAnalyze *ira, 13892 IrInstructionErrorUnion *instruction) 13893 { 13894 Error err; 13895 13896 ZigType *err_set_type = ir_resolve_type(ira, instruction->err_set->child); 13897 if (type_is_invalid(err_set_type)) 13898 return ira->codegen->invalid_instruction; 13899 13900 ZigType *payload_type = ir_resolve_type(ira, instruction->payload->child); 13901 if (type_is_invalid(payload_type)) 13902 return ira->codegen->invalid_instruction; 13903 13904 if (err_set_type->id != ZigTypeIdErrorSet) { 13905 ir_add_error(ira, instruction->err_set->child, 13906 buf_sprintf("expected error set type, found type '%s'", 13907 buf_ptr(&err_set_type->name))); 13908 return ira->codegen->invalid_instruction; 13909 } 13910 13911 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 13912 return ira->codegen->invalid_instruction; 13913 ZigType *result_type = get_error_union_type(ira->codegen, err_set_type, payload_type); 13914 13915 return ir_const_type(ira, &instruction->base, result_type); 13916 } 13917 13918 IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_instr, ImplicitAllocatorId id) { 13919 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 13920 if (parent_fn_entry == nullptr) { 13921 ir_add_error(ira, source_instr, buf_sprintf("no implicit allocator available")); 13922 return ira->codegen->invalid_instruction; 13923 } 13924 13925 FnTypeId *parent_fn_type = &parent_fn_entry->type_entry->data.fn.fn_type_id; 13926 if (parent_fn_type->cc != CallingConventionAsync) { 13927 ir_add_error(ira, source_instr, buf_sprintf("async function call from non-async caller requires allocator parameter")); 13928 return ira->codegen->invalid_instruction; 13929 } 13930 13931 assert(parent_fn_type->async_allocator_type != nullptr); 13932 13933 switch (id) { 13934 case ImplicitAllocatorIdArg: 13935 { 13936 IrInstruction *result = ir_build_get_implicit_allocator(&ira->new_irb, source_instr->scope, 13937 source_instr->source_node, ImplicitAllocatorIdArg); 13938 result->value.type = parent_fn_type->async_allocator_type; 13939 return result; 13940 } 13941 case ImplicitAllocatorIdLocalVar: 13942 { 13943 ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; 13944 assert(coro_allocator_var != nullptr); 13945 IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var); 13946 IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst); 13947 assert(result->value.type != nullptr); 13948 return result; 13949 } 13950 } 13951 zig_unreachable(); 13952 } 13953 13954 static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry, 13955 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, 13956 IrInstruction *async_allocator_inst) 13957 { 13958 Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME); 13959 ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base); 13960 ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; 13961 IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base, 13962 async_allocator_inst, container_type); 13963 if (type_is_invalid(field_ptr_inst->value.type)) { 13964 return ira->codegen->invalid_instruction; 13965 } 13966 ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type; 13967 ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base); 13968 13969 ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type; 13970 if (realloc_fn_type->id != ZigTypeIdFn) { 13971 ir_add_error(ira, &call_instruction->base, 13972 buf_sprintf("expected reallocation function, found '%s'", buf_ptr(&realloc_fn_type->name))); 13973 return ira->codegen->invalid_instruction; 13974 } 13975 13976 ZigType *realloc_fn_return_type = realloc_fn_type->data.fn.fn_type_id.return_type; 13977 if (realloc_fn_return_type->id != ZigTypeIdErrorUnion) { 13978 ir_add_error(ira, fn_ref, 13979 buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&realloc_fn_return_type->name))); 13980 return ira->codegen->invalid_instruction; 13981 } 13982 ZigType *alloc_fn_error_set_type = realloc_fn_return_type->data.error_union.err_set_type; 13983 ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; 13984 ZigType *promise_type = get_promise_type(ira->codegen, return_type); 13985 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); 13986 13987 IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node, 13988 fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr); 13989 result->value.type = async_return_type; 13990 return result; 13991 } 13992 13993 static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, 13994 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) 13995 { 13996 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 13997 assert(param_decl_node->type == NodeTypeParamDecl); 13998 13999 IrInstruction *casted_arg; 14000 if (param_decl_node->data.param_decl.var_token == nullptr) { 14001 AstNode *param_type_node = param_decl_node->data.param_decl.type; 14002 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); 14003 if (type_is_invalid(param_type)) 14004 return false; 14005 14006 casted_arg = ir_implicit_cast(ira, arg, param_type); 14007 if (type_is_invalid(casted_arg->value.type)) 14008 return false; 14009 } else { 14010 casted_arg = arg; 14011 } 14012 14013 ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad); 14014 if (!arg_val) 14015 return false; 14016 14017 Buf *param_name = param_decl_node->data.param_decl.name; 14018 ZigVar *var = add_variable(ira->codegen, param_decl_node, 14019 *exec_scope, param_name, true, arg_val, nullptr, arg_val->type); 14020 *exec_scope = var->child_scope; 14021 *next_proto_i += 1; 14022 14023 return true; 14024 } 14025 14026 static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, 14027 IrInstruction *arg, Scope **child_scope, size_t *next_proto_i, 14028 GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args, 14029 ZigFn *impl_fn) 14030 { 14031 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 14032 assert(param_decl_node->type == NodeTypeParamDecl); 14033 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 14034 bool arg_part_of_generic_id = false; 14035 IrInstruction *casted_arg; 14036 if (is_var_args) { 14037 arg_part_of_generic_id = true; 14038 casted_arg = arg; 14039 } else { 14040 if (param_decl_node->data.param_decl.var_token == nullptr) { 14041 AstNode *param_type_node = param_decl_node->data.param_decl.type; 14042 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node); 14043 if (type_is_invalid(param_type)) 14044 return false; 14045 14046 casted_arg = ir_implicit_cast(ira, arg, param_type); 14047 if (type_is_invalid(casted_arg->value.type)) 14048 return false; 14049 } else { 14050 arg_part_of_generic_id = true; 14051 casted_arg = arg; 14052 } 14053 } 14054 14055 bool comptime_arg = param_decl_node->data.param_decl.is_inline || 14056 casted_arg->value.type->id == ZigTypeIdComptimeInt || casted_arg->value.type->id == ZigTypeIdComptimeFloat; 14057 14058 ConstExprValue *arg_val; 14059 14060 if (comptime_arg) { 14061 arg_part_of_generic_id = true; 14062 arg_val = ir_resolve_const(ira, casted_arg, UndefBad); 14063 if (!arg_val) 14064 return false; 14065 } else { 14066 arg_val = create_const_runtime(casted_arg->value.type); 14067 } 14068 if (arg_part_of_generic_id) { 14069 generic_id->params[generic_id->param_count] = *arg_val; 14070 generic_id->param_count += 1; 14071 } 14072 14073 Buf *param_name = param_decl_node->data.param_decl.name; 14074 if (!param_name) return false; 14075 if (!is_var_args) { 14076 ZigVar *var = add_variable(ira->codegen, param_decl_node, 14077 *child_scope, param_name, true, arg_val, nullptr, arg_val->type); 14078 *child_scope = var->child_scope; 14079 var->shadowable = !comptime_arg; 14080 14081 *next_proto_i += 1; 14082 } else if (casted_arg->value.type->id == ZigTypeIdComptimeInt || 14083 casted_arg->value.type->id == ZigTypeIdComptimeFloat) 14084 { 14085 ir_add_error(ira, casted_arg, 14086 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557")); 14087 return false; 14088 } 14089 14090 if (!comptime_arg) { 14091 switch (type_requires_comptime(ira->codegen, casted_arg->value.type)) { 14092 case ReqCompTimeYes: 14093 ir_add_error(ira, casted_arg, 14094 buf_sprintf("parameter of type '%s' requires comptime", buf_ptr(&casted_arg->value.type->name))); 14095 return false; 14096 case ReqCompTimeInvalid: 14097 return false; 14098 case ReqCompTimeNo: 14099 break; 14100 } 14101 14102 casted_args[fn_type_id->param_count] = casted_arg; 14103 FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count]; 14104 param_info->type = casted_arg->value.type; 14105 param_info->is_noalias = param_decl_node->data.param_decl.is_noalias; 14106 impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node; 14107 fn_type_id->param_count += 1; 14108 } 14109 14110 return true; 14111 } 14112 14113 static ZigVar *get_fn_var_by_index(ZigFn *fn_entry, size_t index) { 14114 FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[index]; 14115 if (!type_has_bits(src_param_info->type)) 14116 return nullptr; 14117 14118 size_t next_var_i = 0; 14119 for (size_t param_i = 0; param_i < index; param_i += 1) { 14120 FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[param_i]; 14121 if (!type_has_bits(src_param_info->type)) { 14122 continue; 14123 } 14124 14125 next_var_i += 1; 14126 } 14127 return fn_entry->variable_list.at(next_var_i); 14128 } 14129 14130 static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var) { 14131 while (var->next_var != nullptr) { 14132 var = var->next_var; 14133 } 14134 14135 if (var->mem_slot_index != SIZE_MAX && var->owner_exec->analysis == nullptr) { 14136 assert(ira->codegen->errors.length != 0); 14137 return ira->codegen->invalid_instruction; 14138 } 14139 if (var->var_type == nullptr || type_is_invalid(var->var_type)) 14140 return ira->codegen->invalid_instruction; 14141 14142 ConstExprValue *mem_slot = nullptr; 14143 14144 bool comptime_var_mem = ir_get_var_is_comptime(var); 14145 bool linkage_makes_it_runtime = var->linkage == VarLinkageExternal; 14146 bool is_const = var->src_is_const; 14147 bool is_volatile = false; 14148 14149 if (linkage_makes_it_runtime) 14150 goto no_mem_slot; 14151 14152 if (var->const_value->special == ConstValSpecialStatic) { 14153 mem_slot = var->const_value; 14154 } else { 14155 if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { 14156 // find the relevant exec_context 14157 assert(var->owner_exec != nullptr); 14158 assert(var->owner_exec->analysis != nullptr); 14159 IrExecContext *exec_context = &var->owner_exec->analysis->exec_context; 14160 assert(var->mem_slot_index < exec_context->mem_slot_list.length); 14161 mem_slot = exec_context->mem_slot_list.at(var->mem_slot_index); 14162 } 14163 } 14164 14165 if (mem_slot != nullptr) { 14166 switch (mem_slot->special) { 14167 case ConstValSpecialRuntime: 14168 goto no_mem_slot; 14169 case ConstValSpecialStatic: // fallthrough 14170 case ConstValSpecialUndef: { 14171 ConstPtrMut ptr_mut; 14172 if (comptime_var_mem) { 14173 ptr_mut = ConstPtrMutComptimeVar; 14174 } else if (var->gen_is_const) { 14175 ptr_mut = ConstPtrMutComptimeConst; 14176 } else { 14177 assert(!comptime_var_mem); 14178 ptr_mut = ConstPtrMutRuntimeVar; 14179 } 14180 return ir_get_const_ptr(ira, instruction, mem_slot, var->var_type, 14181 ptr_mut, is_const, is_volatile, var->align_bytes); 14182 } 14183 } 14184 zig_unreachable(); 14185 } 14186 14187 no_mem_slot: 14188 14189 IrInstruction *var_ptr_instruction = ir_build_var_ptr(&ira->new_irb, 14190 instruction->scope, instruction->source_node, var); 14191 var_ptr_instruction->value.type = get_pointer_to_type_extra(ira->codegen, var->var_type, 14192 var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0, false); 14193 14194 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr); 14195 var_ptr_instruction->value.data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack; 14196 14197 return var_ptr_instruction; 14198 } 14199 14200 static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, 14201 IrInstruction *ptr, IrInstruction *uncasted_value) 14202 { 14203 assert(ptr->value.type->id == ZigTypeIdPointer); 14204 14205 if (ptr->value.data.x_ptr.special == ConstPtrSpecialDiscard) { 14206 if (uncasted_value->value.type->id == ZigTypeIdErrorUnion || 14207 uncasted_value->value.type->id == ZigTypeIdErrorSet) 14208 { 14209 ir_add_error(ira, source_instr, buf_sprintf("error is discarded")); 14210 return ira->codegen->invalid_instruction; 14211 } 14212 return ir_const_void(ira, source_instr); 14213 } 14214 14215 ZigType *child_type = ptr->value.type->data.pointer.child_type; 14216 14217 if (ptr->value.type->data.pointer.is_const && !source_instr->is_gen) { 14218 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 14219 return ira->codegen->invalid_instruction; 14220 } 14221 14222 IrInstruction *value = ir_implicit_cast(ira, uncasted_value, child_type); 14223 if (value == ira->codegen->invalid_instruction) 14224 return ira->codegen->invalid_instruction; 14225 14226 switch (type_has_one_possible_value(ira->codegen, child_type)) { 14227 case OnePossibleValueInvalid: 14228 return ira->codegen->invalid_instruction; 14229 case OnePossibleValueYes: 14230 return ir_const_void(ira, source_instr); 14231 case OnePossibleValueNo: 14232 break; 14233 } 14234 14235 if (instr_is_comptime(ptr) && ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 14236 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst) { 14237 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 14238 return ira->codegen->invalid_instruction; 14239 } 14240 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) { 14241 if (instr_is_comptime(value)) { 14242 ConstExprValue *dest_val = const_ptr_pointee(ira, ira->codegen, &ptr->value, source_instr->source_node); 14243 if (dest_val == nullptr) 14244 return ira->codegen->invalid_instruction; 14245 if (dest_val->special != ConstValSpecialRuntime) { 14246 // TODO this allows a value stored to have the original value modified and then 14247 // have that affect what should be a copy. We need some kind of advanced copy-on-write 14248 // system to make these two tests pass at the same time: 14249 // * "string literal used as comptime slice is memoized" 14250 // * "comptime modification of const struct field" - except modified to avoid 14251 // ConstPtrMutComptimeVar, thus defeating the logic below. 14252 bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; 14253 copy_const_val(dest_val, &value->value, same_global_refs); 14254 if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) { 14255 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; 14256 } 14257 return ir_const_void(ira, source_instr); 14258 } 14259 } 14260 ir_add_error(ira, source_instr, 14261 buf_sprintf("cannot store runtime value in compile time variable")); 14262 ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); 14263 dest_val->type = ira->codegen->builtin_types.entry_invalid; 14264 14265 return ira->codegen->invalid_instruction; 14266 } 14267 } 14268 14269 switch (type_requires_comptime(ira->codegen, child_type)) { 14270 case ReqCompTimeInvalid: 14271 return ira->codegen->invalid_instruction; 14272 case ReqCompTimeYes: 14273 switch (type_has_one_possible_value(ira->codegen, ptr->value.type)) { 14274 case OnePossibleValueInvalid: 14275 return ira->codegen->invalid_instruction; 14276 case OnePossibleValueNo: 14277 ir_add_error(ira, source_instr, 14278 buf_sprintf("cannot store runtime value in type '%s'", buf_ptr(&child_type->name))); 14279 return ira->codegen->invalid_instruction; 14280 case OnePossibleValueYes: 14281 return ir_const_void(ira, source_instr); 14282 } 14283 zig_unreachable(); 14284 case ReqCompTimeNo: 14285 break; 14286 } 14287 14288 IrInstruction *result = ir_build_store_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, 14289 ptr, value); 14290 result->value.type = ira->codegen->builtin_types.entry_void; 14291 return result; 14292 } 14293 14294 static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction, 14295 ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, 14296 IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) 14297 { 14298 Error err; 14299 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 14300 size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0; 14301 14302 // for extern functions, the var args argument is not counted. 14303 // for zig functions, it is. 14304 size_t var_args_1_or_0; 14305 if (fn_type_id->cc == CallingConventionC) { 14306 var_args_1_or_0 = 0; 14307 } else { 14308 var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0; 14309 } 14310 size_t src_param_count = fn_type_id->param_count - var_args_1_or_0; 14311 14312 size_t call_param_count = call_instruction->arg_count + first_arg_1_or_0; 14313 for (size_t i = 0; i < call_instruction->arg_count; i += 1) { 14314 ConstExprValue *arg_tuple_value = &call_instruction->args[i]->child->value; 14315 if (arg_tuple_value->type->id == ZigTypeIdArgTuple) { 14316 call_param_count -= 1; 14317 call_param_count += arg_tuple_value->data.x_arg_tuple.end_index - 14318 arg_tuple_value->data.x_arg_tuple.start_index; 14319 } 14320 } 14321 AstNode *source_node = call_instruction->base.source_node; 14322 14323 AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;; 14324 14325 if (fn_type_id->cc == CallingConventionNaked) { 14326 ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("unable to call function with naked calling convention")); 14327 if (fn_proto_node) { 14328 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 14329 } 14330 return ira->codegen->invalid_instruction; 14331 } 14332 if (fn_type_id->cc == CallingConventionAsync && !call_instruction->is_async) { 14333 ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("must use async keyword to call async function")); 14334 if (fn_proto_node) { 14335 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 14336 } 14337 return ira->codegen->invalid_instruction; 14338 } 14339 if (fn_type_id->cc != CallingConventionAsync && call_instruction->is_async) { 14340 ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("cannot use async keyword to call non-async function")); 14341 if (fn_proto_node) { 14342 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 14343 } 14344 return ira->codegen->invalid_instruction; 14345 } 14346 14347 14348 if (fn_type_id->is_var_args) { 14349 if (call_param_count < src_param_count) { 14350 ErrorMsg *msg = ir_add_error_node(ira, source_node, 14351 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 14352 if (fn_proto_node) { 14353 add_error_note(ira->codegen, msg, fn_proto_node, 14354 buf_sprintf("declared here")); 14355 } 14356 return ira->codegen->invalid_instruction; 14357 } 14358 } else if (src_param_count != call_param_count) { 14359 ErrorMsg *msg = ir_add_error_node(ira, source_node, 14360 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 14361 if (fn_proto_node) { 14362 add_error_note(ira->codegen, msg, fn_proto_node, 14363 buf_sprintf("declared here")); 14364 } 14365 return ira->codegen->invalid_instruction; 14366 } 14367 14368 if (comptime_fn_call) { 14369 // No special handling is needed for compile time evaluation of generic functions. 14370 if (!fn_entry || fn_entry->body_node == nullptr) { 14371 ir_add_error(ira, fn_ref, buf_sprintf("unable to evaluate constant expression")); 14372 return ira->codegen->invalid_instruction; 14373 } 14374 14375 if (!ir_emit_backward_branch(ira, &call_instruction->base)) 14376 return ira->codegen->invalid_instruction; 14377 14378 // Fork a scope of the function with known values for the parameters. 14379 Scope *exec_scope = &fn_entry->fndef_scope->base; 14380 14381 size_t next_proto_i = 0; 14382 if (first_arg_ptr) { 14383 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 14384 14385 bool first_arg_known_bare = false; 14386 if (fn_type_id->next_param_index >= 1) { 14387 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 14388 if (type_is_invalid(param_type)) 14389 return ira->codegen->invalid_instruction; 14390 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 14391 } 14392 14393 IrInstruction *first_arg; 14394 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { 14395 first_arg = first_arg_ptr; 14396 } else { 14397 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); 14398 if (type_is_invalid(first_arg->value.type)) 14399 return ira->codegen->invalid_instruction; 14400 } 14401 14402 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, first_arg, &exec_scope, &next_proto_i)) 14403 return ira->codegen->invalid_instruction; 14404 } 14405 14406 if (fn_proto_node->data.fn_proto.is_var_args) { 14407 ir_add_error(ira, &call_instruction->base, 14408 buf_sprintf("compiler bug: unable to call var args function at compile time. https://github.com/ziglang/zig/issues/313")); 14409 return ira->codegen->invalid_instruction; 14410 } 14411 14412 14413 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 14414 IrInstruction *old_arg = call_instruction->args[call_i]->child; 14415 if (type_is_invalid(old_arg->value.type)) 14416 return ira->codegen->invalid_instruction; 14417 14418 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i)) 14419 return ira->codegen->invalid_instruction; 14420 } 14421 14422 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 14423 ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node); 14424 if (type_is_invalid(specified_return_type)) 14425 return ira->codegen->invalid_instruction; 14426 ZigType *return_type; 14427 ZigType *inferred_err_set_type = nullptr; 14428 if (fn_proto_node->data.fn_proto.auto_err_set) { 14429 inferred_err_set_type = get_auto_err_set_type(ira->codegen, fn_entry); 14430 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 14431 return ira->codegen->invalid_instruction; 14432 return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 14433 } else { 14434 return_type = specified_return_type; 14435 } 14436 14437 bool cacheable = fn_eval_cacheable(exec_scope, return_type); 14438 ConstExprValue *result = nullptr; 14439 if (cacheable) { 14440 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope); 14441 if (entry) 14442 result = entry->value; 14443 } 14444 14445 if (result == nullptr) { 14446 // Analyze the fn body block like any other constant expression. 14447 AstNode *body_node = fn_entry->body_node; 14448 result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, 14449 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, 14450 nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node); 14451 14452 if (inferred_err_set_type != nullptr) { 14453 inferred_err_set_type->data.error_set.infer_fn = nullptr; 14454 if (result->type->id == ZigTypeIdErrorUnion) { 14455 ErrorTableEntry *err = result->data.x_err_union.error_set->data.x_err_set; 14456 if (err != nullptr) { 14457 inferred_err_set_type->data.error_set.err_count = 1; 14458 inferred_err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1); 14459 inferred_err_set_type->data.error_set.errors[0] = err; 14460 } 14461 ZigType *fn_inferred_err_set_type = result->type->data.error_union.err_set_type; 14462 inferred_err_set_type->data.error_set.err_count = fn_inferred_err_set_type->data.error_set.err_count; 14463 inferred_err_set_type->data.error_set.errors = fn_inferred_err_set_type->data.error_set.errors; 14464 } else if (result->type->id == ZigTypeIdErrorSet) { 14465 inferred_err_set_type->data.error_set.err_count = result->type->data.error_set.err_count; 14466 inferred_err_set_type->data.error_set.errors = result->type->data.error_set.errors; 14467 } 14468 } 14469 14470 if (cacheable) { 14471 ira->codegen->memoized_fn_eval_table.put(exec_scope, result); 14472 } 14473 14474 if (type_is_invalid(result->type)) 14475 return ira->codegen->invalid_instruction; 14476 } 14477 14478 IrInstruction *new_instruction = ir_const(ira, &call_instruction->base, result->type); 14479 copy_const_val(&new_instruction->value, result, true); 14480 new_instruction->value.type = return_type; 14481 return ir_finish_anal(ira, new_instruction); 14482 } 14483 14484 IrInstruction *casted_new_stack = nullptr; 14485 if (call_instruction->new_stack != nullptr) { 14486 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 14487 false, false, PtrLenUnknown, 0, 0, 0, false); 14488 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 14489 IrInstruction *new_stack = call_instruction->new_stack->child; 14490 if (type_is_invalid(new_stack->value.type)) 14491 return ira->codegen->invalid_instruction; 14492 14493 casted_new_stack = ir_implicit_cast(ira, new_stack, u8_slice); 14494 if (type_is_invalid(casted_new_stack->value.type)) 14495 return ira->codegen->invalid_instruction; 14496 } 14497 14498 if (fn_type->data.fn.is_generic) { 14499 if (!fn_entry) { 14500 ir_add_error(ira, call_instruction->fn_ref, 14501 buf_sprintf("calling a generic function requires compile-time known function value")); 14502 return ira->codegen->invalid_instruction; 14503 } 14504 14505 // Count the arguments of the function type id we are creating 14506 size_t new_fn_arg_count = first_arg_1_or_0; 14507 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 14508 IrInstruction *arg = call_instruction->args[call_i]->child; 14509 if (type_is_invalid(arg->value.type)) 14510 return ira->codegen->invalid_instruction; 14511 14512 if (arg->value.type->id == ZigTypeIdArgTuple) { 14513 new_fn_arg_count += arg->value.data.x_arg_tuple.end_index - arg->value.data.x_arg_tuple.start_index; 14514 } else { 14515 new_fn_arg_count += 1; 14516 } 14517 } 14518 14519 IrInstruction **casted_args = allocate<IrInstruction *>(new_fn_arg_count); 14520 14521 // Fork a scope of the function with known values for the parameters. 14522 Scope *parent_scope = fn_entry->fndef_scope->base.parent; 14523 ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node); 14524 impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count); 14525 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); 14526 impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); 14527 impl_fn->child_scope = &impl_fn->fndef_scope->base; 14528 FnTypeId inst_fn_type_id = {0}; 14529 init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count); 14530 inst_fn_type_id.param_count = 0; 14531 inst_fn_type_id.is_var_args = false; 14532 14533 // TODO maybe GenericFnTypeId can be replaced with using the child_scope directly 14534 // as the key in generic_table 14535 GenericFnTypeId *generic_id = allocate<GenericFnTypeId>(1); 14536 generic_id->fn_entry = fn_entry; 14537 generic_id->param_count = 0; 14538 generic_id->params = create_const_vals(new_fn_arg_count); 14539 size_t next_proto_i = 0; 14540 14541 if (first_arg_ptr) { 14542 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 14543 14544 bool first_arg_known_bare = false; 14545 if (fn_type_id->next_param_index >= 1) { 14546 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 14547 if (type_is_invalid(param_type)) 14548 return ira->codegen->invalid_instruction; 14549 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 14550 } 14551 14552 IrInstruction *first_arg; 14553 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { 14554 first_arg = first_arg_ptr; 14555 } else { 14556 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); 14557 if (type_is_invalid(first_arg->value.type)) 14558 return ira->codegen->invalid_instruction; 14559 } 14560 14561 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, &impl_fn->child_scope, 14562 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 14563 { 14564 return ira->codegen->invalid_instruction; 14565 } 14566 } 14567 14568 bool found_first_var_arg = false; 14569 size_t first_var_arg; 14570 14571 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 14572 assert(parent_fn_entry); 14573 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 14574 IrInstruction *arg = call_instruction->args[call_i]->child; 14575 if (type_is_invalid(arg->value.type)) 14576 return ira->codegen->invalid_instruction; 14577 14578 if (arg->value.type->id == ZigTypeIdArgTuple) { 14579 for (size_t arg_tuple_i = arg->value.data.x_arg_tuple.start_index; 14580 arg_tuple_i < arg->value.data.x_arg_tuple.end_index; arg_tuple_i += 1) 14581 { 14582 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 14583 assert(param_decl_node->type == NodeTypeParamDecl); 14584 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 14585 if (is_var_args && !found_first_var_arg) { 14586 first_var_arg = inst_fn_type_id.param_count; 14587 found_first_var_arg = true; 14588 } 14589 14590 ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i); 14591 if (arg_var == nullptr) { 14592 ir_add_error(ira, arg, 14593 buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557")); 14594 return ira->codegen->invalid_instruction; 14595 } 14596 IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, arg, arg_var); 14597 if (type_is_invalid(arg_var_ptr_inst->value.type)) 14598 return ira->codegen->invalid_instruction; 14599 14600 IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst); 14601 if (type_is_invalid(arg_tuple_arg->value.type)) 14602 return ira->codegen->invalid_instruction; 14603 14604 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg_tuple_arg, &impl_fn->child_scope, 14605 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 14606 { 14607 return ira->codegen->invalid_instruction; 14608 } 14609 } 14610 } else { 14611 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 14612 assert(param_decl_node->type == NodeTypeParamDecl); 14613 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 14614 if (is_var_args && !found_first_var_arg) { 14615 first_var_arg = inst_fn_type_id.param_count; 14616 found_first_var_arg = true; 14617 } 14618 14619 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope, 14620 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 14621 { 14622 return ira->codegen->invalid_instruction; 14623 } 14624 } 14625 } 14626 14627 if (fn_proto_node->data.fn_proto.is_var_args) { 14628 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 14629 Buf *param_name = param_decl_node->data.param_decl.name; 14630 14631 if (!found_first_var_arg) { 14632 first_var_arg = inst_fn_type_id.param_count; 14633 } 14634 14635 ConstExprValue *var_args_val = create_const_arg_tuple(ira->codegen, 14636 first_var_arg, inst_fn_type_id.param_count); 14637 ZigVar *var = add_variable(ira->codegen, param_decl_node, 14638 impl_fn->child_scope, param_name, true, var_args_val, nullptr, var_args_val->type); 14639 impl_fn->child_scope = var->child_scope; 14640 } 14641 14642 if (fn_proto_node->data.fn_proto.align_expr != nullptr) { 14643 ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, 14644 fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), 14645 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 14646 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); 14647 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 14648 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); 14649 const_instruction->base.value = *align_result; 14650 14651 uint32_t align_bytes = 0; 14652 ir_resolve_align(ira, &const_instruction->base, &align_bytes); 14653 impl_fn->align_bytes = align_bytes; 14654 inst_fn_type_id.alignment = align_bytes; 14655 } 14656 14657 if (fn_proto_node->data.fn_proto.return_var_token == nullptr) { 14658 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 14659 ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node); 14660 if (type_is_invalid(specified_return_type)) 14661 return ira->codegen->invalid_instruction; 14662 if (fn_proto_node->data.fn_proto.auto_err_set) { 14663 ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn); 14664 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 14665 return ira->codegen->invalid_instruction; 14666 inst_fn_type_id.return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 14667 } else { 14668 inst_fn_type_id.return_type = specified_return_type; 14669 } 14670 14671 switch (type_requires_comptime(ira->codegen, specified_return_type)) { 14672 case ReqCompTimeYes: 14673 // Throw out our work and call the function as if it were comptime. 14674 return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, 14675 true, FnInlineAuto); 14676 case ReqCompTimeInvalid: 14677 return ira->codegen->invalid_instruction; 14678 case ReqCompTimeNo: 14679 break; 14680 } 14681 } 14682 IrInstruction *async_allocator_inst = nullptr; 14683 if (call_instruction->is_async) { 14684 AstNode *async_allocator_type_node = fn_proto_node->data.fn_proto.async_allocator_type; 14685 if (async_allocator_type_node != nullptr) { 14686 ZigType *async_allocator_type = ir_analyze_type_expr(ira, impl_fn->child_scope, async_allocator_type_node); 14687 if (type_is_invalid(async_allocator_type)) 14688 return ira->codegen->invalid_instruction; 14689 inst_fn_type_id.async_allocator_type = async_allocator_type; 14690 } 14691 IrInstruction *uncasted_async_allocator_inst; 14692 if (call_instruction->async_allocator == nullptr) { 14693 uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, 14694 ImplicitAllocatorIdLocalVar); 14695 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 14696 return ira->codegen->invalid_instruction; 14697 } else { 14698 uncasted_async_allocator_inst = call_instruction->async_allocator->child; 14699 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 14700 return ira->codegen->invalid_instruction; 14701 } 14702 if (inst_fn_type_id.async_allocator_type == nullptr) { 14703 inst_fn_type_id.async_allocator_type = uncasted_async_allocator_inst->value.type; 14704 } 14705 async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type); 14706 if (type_is_invalid(async_allocator_inst->value.type)) 14707 return ira->codegen->invalid_instruction; 14708 } 14709 14710 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn); 14711 if (existing_entry) { 14712 // throw away all our work and use the existing function 14713 impl_fn = existing_entry->value; 14714 } else { 14715 // finish instantiating the function 14716 impl_fn->type_entry = get_fn_type(ira->codegen, &inst_fn_type_id); 14717 if (type_is_invalid(impl_fn->type_entry)) 14718 return ira->codegen->invalid_instruction; 14719 14720 impl_fn->ir_executable.source_node = call_instruction->base.source_node; 14721 impl_fn->ir_executable.parent_exec = ira->new_irb.exec; 14722 impl_fn->analyzed_executable.source_node = call_instruction->base.source_node; 14723 impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; 14724 impl_fn->analyzed_executable.backward_branch_quota = ira->new_irb.exec->backward_branch_quota; 14725 impl_fn->analyzed_executable.is_generic_instantiation = true; 14726 14727 ira->codegen->fn_defs.append(impl_fn); 14728 } 14729 14730 FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; 14731 if (fn_type_can_fail(impl_fn_type_id)) { 14732 parent_fn_entry->calls_or_awaits_errorable_fn = true; 14733 } 14734 14735 size_t impl_param_count = impl_fn_type_id->param_count; 14736 if (call_instruction->is_async) { 14737 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, 14738 fn_ref, casted_args, impl_param_count, async_allocator_inst); 14739 ir_add_alloca(ira, result, result->value.type); 14740 return ir_finish_anal(ira, result); 14741 } 14742 14743 assert(async_allocator_inst == nullptr); 14744 IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, 14745 call_instruction->base.scope, call_instruction->base.source_node, 14746 impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline, 14747 call_instruction->is_async, nullptr, casted_new_stack); 14748 new_call_instruction->value.type = impl_fn_type_id->return_type; 14749 14750 ir_add_alloca(ira, new_call_instruction, impl_fn_type_id->return_type); 14751 14752 return ir_finish_anal(ira, new_call_instruction); 14753 } 14754 14755 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 14756 assert(fn_type_id->return_type != nullptr); 14757 assert(parent_fn_entry != nullptr); 14758 if (fn_type_can_fail(fn_type_id)) { 14759 parent_fn_entry->calls_or_awaits_errorable_fn = true; 14760 } 14761 14762 14763 IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count); 14764 size_t next_arg_index = 0; 14765 if (first_arg_ptr) { 14766 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 14767 14768 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 14769 if (type_is_invalid(param_type)) 14770 return ira->codegen->invalid_instruction; 14771 14772 IrInstruction *first_arg; 14773 if (param_type->id == ZigTypeIdPointer && 14774 handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) 14775 { 14776 first_arg = first_arg_ptr; 14777 } else { 14778 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); 14779 if (type_is_invalid(first_arg->value.type)) 14780 return ira->codegen->invalid_instruction; 14781 } 14782 14783 IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type); 14784 if (type_is_invalid(casted_arg->value.type)) 14785 return ira->codegen->invalid_instruction; 14786 14787 casted_args[next_arg_index] = casted_arg; 14788 next_arg_index += 1; 14789 } 14790 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 14791 IrInstruction *old_arg = call_instruction->args[call_i]->child; 14792 if (type_is_invalid(old_arg->value.type)) 14793 return ira->codegen->invalid_instruction; 14794 IrInstruction *casted_arg; 14795 if (next_arg_index < src_param_count) { 14796 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 14797 if (type_is_invalid(param_type)) 14798 return ira->codegen->invalid_instruction; 14799 casted_arg = ir_implicit_cast(ira, old_arg, param_type); 14800 if (type_is_invalid(casted_arg->value.type)) 14801 return ira->codegen->invalid_instruction; 14802 } else { 14803 casted_arg = old_arg; 14804 } 14805 14806 casted_args[next_arg_index] = casted_arg; 14807 next_arg_index += 1; 14808 } 14809 14810 assert(next_arg_index == call_param_count); 14811 14812 ZigType *return_type = fn_type_id->return_type; 14813 if (type_is_invalid(return_type)) 14814 return ira->codegen->invalid_instruction; 14815 14816 if (call_instruction->is_async) { 14817 IrInstruction *uncasted_async_allocator_inst; 14818 if (call_instruction->async_allocator == nullptr) { 14819 uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, 14820 ImplicitAllocatorIdLocalVar); 14821 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 14822 return ira->codegen->invalid_instruction; 14823 } else { 14824 uncasted_async_allocator_inst = call_instruction->async_allocator->child; 14825 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 14826 return ira->codegen->invalid_instruction; 14827 14828 } 14829 IrInstruction *async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, fn_type_id->async_allocator_type); 14830 if (type_is_invalid(async_allocator_inst->value.type)) 14831 return ira->codegen->invalid_instruction; 14832 14833 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, 14834 casted_args, call_param_count, async_allocator_inst); 14835 ir_add_alloca(ira, result, result->value.type); 14836 return ir_finish_anal(ira, result); 14837 } 14838 14839 if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) { 14840 ir_add_error(ira, &call_instruction->base, 14841 buf_sprintf("no-inline call of inline function")); 14842 return ira->codegen->invalid_instruction; 14843 } 14844 14845 IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, 14846 call_instruction->base.scope, call_instruction->base.source_node, 14847 fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack); 14848 new_call_instruction->value.type = return_type; 14849 ir_add_alloca(ira, new_call_instruction, return_type); 14850 return ir_finish_anal(ira, new_call_instruction); 14851 } 14852 14853 static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) { 14854 IrInstruction *fn_ref = call_instruction->fn_ref->child; 14855 if (type_is_invalid(fn_ref->value.type)) 14856 return ira->codegen->invalid_instruction; 14857 14858 bool is_comptime = call_instruction->is_comptime || 14859 ir_should_inline(ira->new_irb.exec, call_instruction->base.scope); 14860 14861 if (is_comptime || instr_is_comptime(fn_ref)) { 14862 if (fn_ref->value.type->id == ZigTypeIdMetaType) { 14863 ZigType *dest_type = ir_resolve_type(ira, fn_ref); 14864 if (type_is_invalid(dest_type)) 14865 return ira->codegen->invalid_instruction; 14866 14867 size_t actual_param_count = call_instruction->arg_count; 14868 14869 if (actual_param_count != 1) { 14870 ir_add_error_node(ira, call_instruction->base.source_node, 14871 buf_sprintf("cast expression expects exactly one parameter")); 14872 return ira->codegen->invalid_instruction; 14873 } 14874 14875 IrInstruction *arg = call_instruction->args[0]->child; 14876 14877 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg); 14878 if (type_is_invalid(cast_instruction->value.type)) 14879 return ira->codegen->invalid_instruction; 14880 return ir_finish_anal(ira, cast_instruction); 14881 } else if (fn_ref->value.type->id == ZigTypeIdFn) { 14882 ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); 14883 if (fn_table_entry == nullptr) 14884 return ira->codegen->invalid_instruction; 14885 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 14886 fn_ref, nullptr, is_comptime, call_instruction->fn_inline); 14887 } else if (fn_ref->value.type->id == ZigTypeIdBoundFn) { 14888 assert(fn_ref->value.special == ConstValSpecialStatic); 14889 ZigFn *fn_table_entry = fn_ref->value.data.x_bound_fn.fn; 14890 IrInstruction *first_arg_ptr = fn_ref->value.data.x_bound_fn.first_arg; 14891 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 14892 fn_ref, first_arg_ptr, is_comptime, call_instruction->fn_inline); 14893 } else { 14894 ir_add_error_node(ira, fn_ref->source_node, 14895 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value.type->name))); 14896 return ira->codegen->invalid_instruction; 14897 } 14898 } 14899 14900 if (fn_ref->value.type->id == ZigTypeIdFn) { 14901 return ir_analyze_fn_call(ira, call_instruction, nullptr, fn_ref->value.type, 14902 fn_ref, nullptr, false, FnInlineAuto); 14903 } else { 14904 ir_add_error_node(ira, fn_ref->source_node, 14905 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value.type->name))); 14906 return ira->codegen->invalid_instruction; 14907 } 14908 } 14909 14910 // out_val->type must be the type to read the pointer as 14911 // if the type is different than the actual type then it does a comptime byte reinterpretation 14912 static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 14913 ConstExprValue *out_val, ConstExprValue *ptr_val) 14914 { 14915 Error err; 14916 assert(out_val->type != nullptr); 14917 14918 ConstExprValue *pointee = const_ptr_pointee_unchecked(codegen, ptr_val); 14919 14920 if ((err = type_resolve(codegen, pointee->type, ResolveStatusSizeKnown))) 14921 return ErrorSemanticAnalyzeFail; 14922 if ((err = type_resolve(codegen, out_val->type, ResolveStatusSizeKnown))) 14923 return ErrorSemanticAnalyzeFail; 14924 14925 size_t src_size = type_size(codegen, pointee->type); 14926 size_t dst_size = type_size(codegen, out_val->type); 14927 14928 if (dst_size <= src_size) { 14929 if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { 14930 copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst); 14931 return ErrorNone; 14932 } 14933 Buf buf = BUF_INIT; 14934 buf_resize(&buf, src_size); 14935 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf), pointee); 14936 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 14937 return err; 14938 return ErrorNone; 14939 } 14940 14941 switch (ptr_val->data.x_ptr.special) { 14942 case ConstPtrSpecialInvalid: 14943 zig_unreachable(); 14944 case ConstPtrSpecialNull: 14945 if (dst_size == 0) 14946 return ErrorNone; 14947 opt_ir_add_error_node(ira, codegen, source_node, 14948 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from null pointer", 14949 dst_size)); 14950 return ErrorSemanticAnalyzeFail; 14951 case ConstPtrSpecialRef: { 14952 opt_ir_add_error_node(ira, codegen, source_node, 14953 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from pointer to %s which is %" ZIG_PRI_usize " bytes", 14954 dst_size, buf_ptr(&pointee->type->name), src_size)); 14955 return ErrorSemanticAnalyzeFail; 14956 } 14957 case ConstPtrSpecialBaseArray: { 14958 ConstExprValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val; 14959 assert(array_val->type->id == ZigTypeIdArray); 14960 if (array_val->data.x_array.special != ConstArraySpecialNone) 14961 zig_panic("TODO"); 14962 size_t elem_size = src_size; 14963 size_t elem_index = ptr_val->data.x_ptr.data.base_array.elem_index; 14964 src_size = elem_size * (array_val->type->data.array.len - elem_index); 14965 if (dst_size > src_size) { 14966 opt_ir_add_error_node(ira, codegen, source_node, 14967 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from %s at index %" ZIG_PRI_usize " which is %" ZIG_PRI_usize " bytes", 14968 dst_size, buf_ptr(&array_val->type->name), elem_index, src_size)); 14969 return ErrorSemanticAnalyzeFail; 14970 } 14971 size_t elem_count = (dst_size % elem_size == 0) ? (dst_size / elem_size) : (dst_size / elem_size + 1); 14972 Buf buf = BUF_INIT; 14973 buf_resize(&buf, elem_count * elem_size); 14974 for (size_t i = 0; i < elem_count; i += 1) { 14975 ConstExprValue *elem_val = &array_val->data.x_array.data.s_none.elements[elem_index + i]; 14976 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); 14977 } 14978 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 14979 return err; 14980 return ErrorNone; 14981 } 14982 case ConstPtrSpecialBaseStruct: 14983 case ConstPtrSpecialBaseErrorUnionCode: 14984 case ConstPtrSpecialBaseErrorUnionPayload: 14985 case ConstPtrSpecialBaseOptionalPayload: 14986 case ConstPtrSpecialDiscard: 14987 case ConstPtrSpecialHardCodedAddr: 14988 case ConstPtrSpecialFunction: 14989 zig_panic("TODO"); 14990 } 14991 zig_unreachable(); 14992 } 14993 14994 static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { 14995 Error err; 14996 IrInstruction *value = un_op_instruction->value->child; 14997 ZigType *type_entry = ir_resolve_type(ira, value); 14998 if (type_is_invalid(type_entry)) 14999 return ira->codegen->invalid_instruction; 15000 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 15001 return ira->codegen->invalid_instruction; 15002 15003 switch (type_entry->id) { 15004 case ZigTypeIdInvalid: 15005 zig_unreachable(); 15006 case ZigTypeIdMetaType: 15007 case ZigTypeIdVoid: 15008 case ZigTypeIdBool: 15009 case ZigTypeIdInt: 15010 case ZigTypeIdVector: 15011 case ZigTypeIdFloat: 15012 case ZigTypeIdPointer: 15013 case ZigTypeIdArray: 15014 case ZigTypeIdStruct: 15015 case ZigTypeIdComptimeFloat: 15016 case ZigTypeIdComptimeInt: 15017 case ZigTypeIdEnumLiteral: 15018 case ZigTypeIdUndefined: 15019 case ZigTypeIdNull: 15020 case ZigTypeIdOptional: 15021 case ZigTypeIdErrorUnion: 15022 case ZigTypeIdErrorSet: 15023 case ZigTypeIdEnum: 15024 case ZigTypeIdUnion: 15025 case ZigTypeIdFn: 15026 case ZigTypeIdBoundFn: 15027 case ZigTypeIdArgTuple: 15028 case ZigTypeIdPromise: 15029 return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry)); 15030 case ZigTypeIdUnreachable: 15031 case ZigTypeIdOpaque: 15032 ir_add_error_node(ira, un_op_instruction->base.source_node, 15033 buf_sprintf("type '%s' not optional", buf_ptr(&type_entry->name))); 15034 return ira->codegen->invalid_instruction; 15035 } 15036 zig_unreachable(); 15037 } 15038 15039 static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *scalar_type, 15040 ConstExprValue *operand_val, ConstExprValue *scalar_out_val, bool is_wrap_op) 15041 { 15042 bool is_float = (scalar_type->id == ZigTypeIdFloat || scalar_type->id == ZigTypeIdComptimeFloat); 15043 15044 bool ok_type = ((scalar_type->id == ZigTypeIdInt && scalar_type->data.integral.is_signed) || 15045 scalar_type->id == ZigTypeIdComptimeInt || (is_float && !is_wrap_op)); 15046 15047 if (!ok_type) { 15048 const char *fmt = is_wrap_op ? "invalid wrapping negation type: '%s'" : "invalid negation type: '%s'"; 15049 return ir_add_error(ira, source_instr, buf_sprintf(fmt, buf_ptr(&scalar_type->name))); 15050 } 15051 15052 if (is_float) { 15053 float_negate(scalar_out_val, operand_val); 15054 } else if (is_wrap_op) { 15055 bigint_negate_wrap(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint, 15056 scalar_type->data.integral.bit_count); 15057 } else { 15058 bigint_negate(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint); 15059 } 15060 15061 scalar_out_val->type = scalar_type; 15062 scalar_out_val->special = ConstValSpecialStatic; 15063 15064 if (is_wrap_op || is_float || scalar_type->id == ZigTypeIdComptimeInt) { 15065 return nullptr; 15066 } 15067 15068 if (!bigint_fits_in_bits(&scalar_out_val->data.x_bigint, scalar_type->data.integral.bit_count, true)) { 15069 return ir_add_error(ira, source_instr, buf_sprintf("negation caused overflow")); 15070 } 15071 return nullptr; 15072 } 15073 15074 static IrInstruction *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *instruction) { 15075 IrInstruction *value = instruction->value->child; 15076 ZigType *expr_type = value->value.type; 15077 if (type_is_invalid(expr_type)) 15078 return ira->codegen->invalid_instruction; 15079 15080 bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap); 15081 15082 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 15083 15084 if (instr_is_comptime(value)) { 15085 ConstExprValue *operand_val = ir_resolve_const(ira, value, UndefBad); 15086 if (!operand_val) 15087 return ira->codegen->invalid_instruction; 15088 15089 IrInstruction *result_instruction = ir_const(ira, &instruction->base, expr_type); 15090 ConstExprValue *out_val = &result_instruction->value; 15091 if (expr_type->id == ZigTypeIdVector) { 15092 expand_undef_array(ira->codegen, operand_val); 15093 out_val->special = ConstValSpecialUndef; 15094 expand_undef_array(ira->codegen, out_val); 15095 size_t len = expr_type->data.vector.len; 15096 for (size_t i = 0; i < len; i += 1) { 15097 ConstExprValue *scalar_operand_val = &operand_val->data.x_array.data.s_none.elements[i]; 15098 ConstExprValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 15099 assert(scalar_operand_val->type == scalar_type); 15100 assert(scalar_out_val->type == scalar_type); 15101 ErrorMsg *msg = ir_eval_negation_scalar(ira, &instruction->base, scalar_type, 15102 scalar_operand_val, scalar_out_val, is_wrap_op); 15103 if (msg != nullptr) { 15104 add_error_note(ira->codegen, msg, instruction->base.source_node, 15105 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 15106 return ira->codegen->invalid_instruction; 15107 } 15108 } 15109 out_val->type = expr_type; 15110 out_val->special = ConstValSpecialStatic; 15111 } else { 15112 if (ir_eval_negation_scalar(ira, &instruction->base, scalar_type, operand_val, out_val, 15113 is_wrap_op) != nullptr) 15114 { 15115 return ira->codegen->invalid_instruction; 15116 } 15117 } 15118 return result_instruction; 15119 } 15120 15121 IrInstruction *result = ir_build_un_op(&ira->new_irb, 15122 instruction->base.scope, instruction->base.source_node, 15123 instruction->op_id, value); 15124 result->value.type = expr_type; 15125 return result; 15126 } 15127 15128 static IrInstruction *ir_analyze_bin_not(IrAnalyze *ira, IrInstructionUnOp *instruction) { 15129 IrInstruction *value = instruction->value->child; 15130 ZigType *expr_type = value->value.type; 15131 if (type_is_invalid(expr_type)) 15132 return ira->codegen->invalid_instruction; 15133 15134 if (expr_type->id == ZigTypeIdInt) { 15135 if (instr_is_comptime(value)) { 15136 ConstExprValue *target_const_val = ir_resolve_const(ira, value, UndefBad); 15137 if (target_const_val == nullptr) 15138 return ira->codegen->invalid_instruction; 15139 15140 IrInstruction *result = ir_const(ira, &instruction->base, expr_type); 15141 bigint_not(&result->value.data.x_bigint, &target_const_val->data.x_bigint, 15142 expr_type->data.integral.bit_count, expr_type->data.integral.is_signed); 15143 return result; 15144 } 15145 15146 IrInstruction *result = ir_build_un_op(&ira->new_irb, instruction->base.scope, 15147 instruction->base.source_node, IrUnOpBinNot, value); 15148 result->value.type = expr_type; 15149 return result; 15150 } 15151 15152 ir_add_error(ira, &instruction->base, 15153 buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name))); 15154 return ira->codegen->invalid_instruction; 15155 } 15156 15157 static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *instruction) { 15158 IrUnOp op_id = instruction->op_id; 15159 switch (op_id) { 15160 case IrUnOpInvalid: 15161 zig_unreachable(); 15162 case IrUnOpBinNot: 15163 return ir_analyze_bin_not(ira, instruction); 15164 case IrUnOpNegation: 15165 case IrUnOpNegationWrap: 15166 return ir_analyze_negation(ira, instruction); 15167 case IrUnOpDereference: { 15168 IrInstruction *ptr = instruction->value->child; 15169 if (type_is_invalid(ptr->value.type)) 15170 return ira->codegen->invalid_instruction; 15171 ZigType *ptr_type = ptr->value.type; 15172 if (ptr_type->id == ZigTypeIdPointer && ptr_type->data.pointer.ptr_len == PtrLenUnknown) { 15173 ir_add_error_node(ira, instruction->base.source_node, 15174 buf_sprintf("index syntax required for unknown-length pointer type '%s'", 15175 buf_ptr(&ptr_type->name))); 15176 return ira->codegen->invalid_instruction; 15177 } 15178 15179 IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr); 15180 if (result == ira->codegen->invalid_instruction) 15181 return ira->codegen->invalid_instruction; 15182 15183 // If the result needs to be an lvalue, type check it 15184 if (instruction->lval == LValPtr && result->value.type->id != ZigTypeIdPointer) { 15185 ir_add_error(ira, &instruction->base, 15186 buf_sprintf("attempt to dereference non-pointer type '%s'", buf_ptr(&result->value.type->name))); 15187 return ira->codegen->invalid_instruction; 15188 } 15189 15190 return result; 15191 } 15192 case IrUnOpOptional: 15193 return ir_analyze_maybe(ira, instruction); 15194 } 15195 zig_unreachable(); 15196 } 15197 15198 static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { 15199 IrBasicBlock *old_dest_block = br_instruction->dest_block; 15200 15201 bool is_comptime; 15202 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) 15203 return ir_unreach_error(ira); 15204 15205 if (is_comptime || old_dest_block->ref_count == 1) 15206 return ir_inline_bb(ira, &br_instruction->base, old_dest_block); 15207 15208 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); 15209 if (new_bb == nullptr) 15210 return ir_unreach_error(ira); 15211 15212 IrInstruction *result = ir_build_br(&ira->new_irb, 15213 br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); 15214 result->value.type = ira->codegen->builtin_types.entry_unreachable; 15215 return ir_finish_anal(ira, result); 15216 } 15217 15218 static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) { 15219 IrInstruction *condition = cond_br_instruction->condition->child; 15220 if (type_is_invalid(condition->value.type)) 15221 return ir_unreach_error(ira); 15222 15223 bool is_comptime; 15224 if (!ir_resolve_comptime(ira, cond_br_instruction->is_comptime->child, &is_comptime)) 15225 return ir_unreach_error(ira); 15226 15227 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 15228 IrInstruction *casted_condition = ir_implicit_cast(ira, condition, bool_type); 15229 if (type_is_invalid(casted_condition->value.type)) 15230 return ir_unreach_error(ira); 15231 15232 if (is_comptime || instr_is_comptime(casted_condition)) { 15233 bool cond_is_true; 15234 if (!ir_resolve_bool(ira, casted_condition, &cond_is_true)) 15235 return ir_unreach_error(ira); 15236 15237 IrBasicBlock *old_dest_block = cond_is_true ? 15238 cond_br_instruction->then_block : cond_br_instruction->else_block; 15239 15240 if (is_comptime || old_dest_block->ref_count == 1) 15241 return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); 15242 15243 IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); 15244 if (new_dest_block == nullptr) 15245 return ir_unreach_error(ira); 15246 15247 IrInstruction *result = ir_build_br(&ira->new_irb, 15248 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); 15249 result->value.type = ira->codegen->builtin_types.entry_unreachable; 15250 return ir_finish_anal(ira, result); 15251 } 15252 15253 assert(cond_br_instruction->then_block != cond_br_instruction->else_block); 15254 IrBasicBlock *new_then_block = ir_get_new_bb_runtime(ira, cond_br_instruction->then_block, &cond_br_instruction->base); 15255 if (new_then_block == nullptr) 15256 return ir_unreach_error(ira); 15257 15258 IrBasicBlock *new_else_block = ir_get_new_bb_runtime(ira, cond_br_instruction->else_block, &cond_br_instruction->base); 15259 if (new_else_block == nullptr) 15260 return ir_unreach_error(ira); 15261 15262 IrInstruction *result = ir_build_cond_br(&ira->new_irb, 15263 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, 15264 casted_condition, new_then_block, new_else_block, nullptr); 15265 result->value.type = ira->codegen->builtin_types.entry_unreachable; 15266 return ir_finish_anal(ira, result); 15267 } 15268 15269 static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira, 15270 IrInstructionUnreachable *unreachable_instruction) 15271 { 15272 IrInstruction *result = ir_build_unreachable(&ira->new_irb, 15273 unreachable_instruction->base.scope, unreachable_instruction->base.source_node); 15274 result->value.type = ira->codegen->builtin_types.entry_unreachable; 15275 return ir_finish_anal(ira, result); 15276 } 15277 15278 static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) { 15279 if (ira->const_predecessor_bb) { 15280 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 15281 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; 15282 if (predecessor != ira->const_predecessor_bb) 15283 continue; 15284 IrInstruction *value = phi_instruction->incoming_values[i]->child; 15285 assert(value->value.type); 15286 if (type_is_invalid(value->value.type)) 15287 return ira->codegen->invalid_instruction; 15288 15289 if (value->value.special != ConstValSpecialRuntime) { 15290 IrInstruction *result = ir_const(ira, &phi_instruction->base, nullptr); 15291 copy_const_val(&result->value, &value->value, true); 15292 return result; 15293 } else { 15294 return value; 15295 } 15296 } 15297 zig_unreachable(); 15298 } 15299 15300 ZigList<IrBasicBlock*> new_incoming_blocks = {0}; 15301 ZigList<IrInstruction*> new_incoming_values = {0}; 15302 15303 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 15304 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; 15305 if (predecessor->ref_count == 0) 15306 continue; 15307 15308 15309 IrInstruction *old_value = phi_instruction->incoming_values[i]; 15310 assert(old_value); 15311 IrInstruction *new_value = old_value->child; 15312 if (!new_value || new_value->value.type->id == ZigTypeIdUnreachable || predecessor->other == nullptr) 15313 continue; 15314 15315 if (type_is_invalid(new_value->value.type)) 15316 return ira->codegen->invalid_instruction; 15317 15318 15319 assert(predecessor->other); 15320 new_incoming_blocks.append(predecessor->other); 15321 new_incoming_values.append(new_value); 15322 } 15323 15324 if (new_incoming_blocks.length == 0) { 15325 IrInstruction *result = ir_build_unreachable(&ira->new_irb, 15326 phi_instruction->base.scope, phi_instruction->base.source_node); 15327 result->value.type = ira->codegen->builtin_types.entry_unreachable; 15328 return ir_finish_anal(ira, result); 15329 } 15330 15331 if (new_incoming_blocks.length == 1) { 15332 return new_incoming_values.at(0); 15333 } 15334 15335 ZigType *resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, 15336 new_incoming_values.items, new_incoming_values.length); 15337 if (type_is_invalid(resolved_type)) 15338 return ira->codegen->invalid_instruction; 15339 15340 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 15341 case OnePossibleValueInvalid: 15342 return ira->codegen->invalid_instruction; 15343 case OnePossibleValueYes: 15344 return ir_const(ira, &phi_instruction->base, resolved_type); 15345 case OnePossibleValueNo: 15346 break; 15347 } 15348 15349 switch (type_requires_comptime(ira->codegen, resolved_type)) { 15350 case ReqCompTimeInvalid: 15351 return ira->codegen->invalid_instruction; 15352 case ReqCompTimeYes: 15353 ir_add_error_node(ira, phi_instruction->base.source_node, 15354 buf_sprintf("values of type '%s' must be comptime known", buf_ptr(&resolved_type->name))); 15355 return ira->codegen->invalid_instruction; 15356 case ReqCompTimeNo: 15357 break; 15358 } 15359 15360 bool all_stack_ptrs = (resolved_type->id == ZigTypeIdPointer); 15361 15362 // cast all values to the resolved type. however we can't put cast instructions in front of the phi instruction. 15363 // so we go back and insert the casts as the last instruction in the corresponding predecessor blocks, and 15364 // then make sure the branch instruction is preserved. 15365 IrBasicBlock *cur_bb = ira->new_irb.current_basic_block; 15366 for (size_t i = 0; i < new_incoming_values.length; i += 1) { 15367 IrInstruction *new_value = new_incoming_values.at(i); 15368 IrBasicBlock *predecessor = new_incoming_blocks.at(i); 15369 IrInstruction *branch_instruction = predecessor->instruction_list.pop(); 15370 ir_set_cursor_at_end(&ira->new_irb, predecessor); 15371 IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); 15372 if (casted_value == ira->codegen->invalid_instruction) { 15373 return ira->codegen->invalid_instruction; 15374 } 15375 new_incoming_values.items[i] = casted_value; 15376 predecessor->instruction_list.append(branch_instruction); 15377 15378 if (all_stack_ptrs && (casted_value->value.special != ConstValSpecialRuntime || 15379 casted_value->value.data.rh_ptr != RuntimeHintPtrStack)) 15380 { 15381 all_stack_ptrs = false; 15382 } 15383 } 15384 ir_set_cursor_at_end(&ira->new_irb, cur_bb); 15385 15386 IrInstruction *result = ir_build_phi(&ira->new_irb, 15387 phi_instruction->base.scope, phi_instruction->base.source_node, 15388 new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items); 15389 result->value.type = resolved_type; 15390 15391 if (all_stack_ptrs) { 15392 assert(result->value.special == ConstValSpecialRuntime); 15393 result->value.data.rh_ptr = RuntimeHintPtrStack; 15394 } 15395 15396 return result; 15397 } 15398 15399 static IrInstruction *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *instruction) { 15400 ZigVar *var = instruction->var; 15401 IrInstruction *result = ir_get_var_ptr(ira, &instruction->base, var); 15402 if (instruction->crossed_fndef_scope != nullptr && !instr_is_comptime(result)) { 15403 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 15404 buf_sprintf("'%s' not accessible from inner function", buf_ptr(&var->name))); 15405 add_error_note(ira->codegen, msg, instruction->crossed_fndef_scope->base.source_node, 15406 buf_sprintf("crossed function definition here")); 15407 add_error_note(ira->codegen, msg, var->decl_node, 15408 buf_sprintf("declared here")); 15409 return ira->codegen->invalid_instruction; 15410 } 15411 return result; 15412 } 15413 15414 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align) { 15415 assert(ptr_type->id == ZigTypeIdPointer); 15416 return get_pointer_to_type_extra(g, 15417 ptr_type->data.pointer.child_type, 15418 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 15419 ptr_type->data.pointer.ptr_len, 15420 new_align, 15421 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 15422 ptr_type->data.pointer.allow_zero); 15423 } 15424 15425 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) { 15426 assert(is_slice(slice_type)); 15427 ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index].type_entry, 15428 new_align); 15429 return get_slice_type(g, ptr_type); 15430 } 15431 15432 static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) { 15433 assert(ptr_type->id == ZigTypeIdPointer); 15434 return get_pointer_to_type_extra(g, 15435 ptr_type->data.pointer.child_type, 15436 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 15437 ptr_len, 15438 ptr_type->data.pointer.explicit_alignment, 15439 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 15440 ptr_type->data.pointer.allow_zero); 15441 } 15442 15443 static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { 15444 Error err; 15445 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->child; 15446 if (type_is_invalid(array_ptr->value.type)) 15447 return ira->codegen->invalid_instruction; 15448 15449 ConstExprValue *orig_array_ptr_val = &array_ptr->value; 15450 15451 IrInstruction *elem_index = elem_ptr_instruction->elem_index->child; 15452 if (type_is_invalid(elem_index->value.type)) 15453 return ira->codegen->invalid_instruction; 15454 15455 ZigType *ptr_type = orig_array_ptr_val->type; 15456 assert(ptr_type->id == ZigTypeIdPointer); 15457 15458 ZigType *array_type = ptr_type->data.pointer.child_type; 15459 15460 // At first return_type will be the pointer type we want to return, except with an optimistic alignment. 15461 // We will adjust return_type's alignment before returning it. 15462 ZigType *return_type; 15463 15464 if (type_is_invalid(array_type)) { 15465 return ira->codegen->invalid_instruction; 15466 } else if (array_type->id == ZigTypeIdArray || 15467 (array_type->id == ZigTypeIdPointer && 15468 array_type->data.pointer.ptr_len == PtrLenSingle && 15469 array_type->data.pointer.child_type->id == ZigTypeIdArray)) 15470 { 15471 if (array_type->id == ZigTypeIdPointer) { 15472 array_type = array_type->data.pointer.child_type; 15473 ptr_type = ptr_type->data.pointer.child_type; 15474 if (orig_array_ptr_val->special != ConstValSpecialRuntime) { 15475 orig_array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val, 15476 elem_ptr_instruction->base.source_node); 15477 if (orig_array_ptr_val == nullptr) 15478 return ira->codegen->invalid_instruction; 15479 } 15480 } 15481 if (array_type->data.array.len == 0) { 15482 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 15483 buf_sprintf("index 0 outside array of size 0")); 15484 return ira->codegen->invalid_instruction; 15485 } 15486 ZigType *child_type = array_type->data.array.child_type; 15487 if (ptr_type->data.pointer.host_int_bytes == 0) { 15488 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 15489 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 15490 elem_ptr_instruction->ptr_len, 15491 ptr_type->data.pointer.explicit_alignment, 0, 0, false); 15492 } else { 15493 uint64_t elem_val_scalar; 15494 if (!ir_resolve_usize(ira, elem_index, &elem_val_scalar)) 15495 return ira->codegen->invalid_instruction; 15496 15497 size_t bit_width = type_size_bits(ira->codegen, child_type); 15498 size_t bit_offset = bit_width * elem_val_scalar; 15499 15500 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 15501 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 15502 elem_ptr_instruction->ptr_len, 15503 1, (uint32_t)bit_offset, ptr_type->data.pointer.host_int_bytes, false); 15504 } 15505 } else if (array_type->id == ZigTypeIdPointer) { 15506 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 15507 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 15508 buf_sprintf("index of single-item pointer")); 15509 return ira->codegen->invalid_instruction; 15510 } 15511 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len); 15512 } else if (is_slice(array_type)) { 15513 return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index].type_entry, 15514 elem_ptr_instruction->ptr_len); 15515 } else if (array_type->id == ZigTypeIdArgTuple) { 15516 ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); 15517 if (!ptr_val) 15518 return ira->codegen->invalid_instruction; 15519 ConstExprValue *args_val = const_ptr_pointee(ira, ira->codegen, ptr_val, elem_ptr_instruction->base.source_node); 15520 if (args_val == nullptr) 15521 return ira->codegen->invalid_instruction; 15522 size_t start = args_val->data.x_arg_tuple.start_index; 15523 size_t end = args_val->data.x_arg_tuple.end_index; 15524 uint64_t elem_index_val; 15525 if (!ir_resolve_usize(ira, elem_index, &elem_index_val)) 15526 return ira->codegen->invalid_instruction; 15527 size_t index = elem_index_val; 15528 size_t len = end - start; 15529 if (index >= len) { 15530 ir_add_error(ira, &elem_ptr_instruction->base, 15531 buf_sprintf("index %" ZIG_PRI_usize " outside argument list of size %" ZIG_PRI_usize "", index, len)); 15532 return ira->codegen->invalid_instruction; 15533 } 15534 size_t abs_index = start + index; 15535 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 15536 assert(fn_entry); 15537 ZigVar *var = get_fn_var_by_index(fn_entry, abs_index); 15538 bool is_const = true; 15539 bool is_volatile = false; 15540 if (var) { 15541 return ir_get_var_ptr(ira, &elem_ptr_instruction->base, var); 15542 } else { 15543 return ir_get_const_ptr(ira, &elem_ptr_instruction->base, &ira->codegen->const_void_val, 15544 ira->codegen->builtin_types.entry_void, ConstPtrMutComptimeConst, is_const, is_volatile, 0); 15545 } 15546 } else { 15547 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 15548 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name))); 15549 return ira->codegen->invalid_instruction; 15550 } 15551 15552 ZigType *usize = ira->codegen->builtin_types.entry_usize; 15553 IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 15554 if (casted_elem_index == ira->codegen->invalid_instruction) 15555 return ira->codegen->invalid_instruction; 15556 15557 bool safety_check_on = elem_ptr_instruction->safety_check_on; 15558 if ((err = ensure_complete_type(ira->codegen, return_type->data.pointer.child_type))) 15559 return ira->codegen->invalid_instruction; 15560 15561 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); 15562 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); 15563 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type); 15564 if (instr_is_comptime(casted_elem_index)) { 15565 uint64_t index = bigint_as_unsigned(&casted_elem_index->value.data.x_bigint); 15566 if (array_type->id == ZigTypeIdArray) { 15567 uint64_t array_len = array_type->data.array.len; 15568 if (index >= array_len) { 15569 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 15570 buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, 15571 index, array_len)); 15572 return ira->codegen->invalid_instruction; 15573 } 15574 safety_check_on = false; 15575 } 15576 15577 { 15578 // figure out the largest alignment possible 15579 uint64_t chosen_align = abi_align; 15580 if (ptr_align >= abi_align) { 15581 while (ptr_align > abi_align) { 15582 if ((index * elem_size) % ptr_align == 0) { 15583 chosen_align = ptr_align; 15584 break; 15585 } 15586 ptr_align >>= 1; 15587 } 15588 } else if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 15589 chosen_align = ptr_align; 15590 } else { 15591 // can't get here because guaranteed elem_size >= abi_align 15592 zig_unreachable(); 15593 } 15594 return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align); 15595 } 15596 15597 if (orig_array_ptr_val->special != ConstValSpecialRuntime && 15598 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || 15599 array_type->id == ZigTypeIdArray)) 15600 { 15601 ConstExprValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val, 15602 elem_ptr_instruction->base.source_node); 15603 if (array_ptr_val == nullptr) 15604 return ira->codegen->invalid_instruction; 15605 15606 if (array_ptr_val->special != ConstValSpecialRuntime && 15607 (array_type->id != ZigTypeIdPointer || 15608 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) 15609 { 15610 if (array_type->id == ZigTypeIdPointer) { 15611 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); 15612 ConstExprValue *out_val = &result->value; 15613 out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 15614 size_t new_index; 15615 size_t mem_size; 15616 size_t old_size; 15617 switch (array_ptr_val->data.x_ptr.special) { 15618 case ConstPtrSpecialInvalid: 15619 case ConstPtrSpecialDiscard: 15620 zig_unreachable(); 15621 case ConstPtrSpecialRef: 15622 mem_size = 1; 15623 old_size = 1; 15624 new_index = index; 15625 15626 out_val->data.x_ptr.special = ConstPtrSpecialRef; 15627 out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee; 15628 break; 15629 case ConstPtrSpecialBaseArray: 15630 { 15631 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; 15632 new_index = offset + index; 15633 mem_size = array_ptr_val->data.x_ptr.data.base_array.array_val->type->data.array.len; 15634 old_size = mem_size - offset; 15635 15636 assert(array_ptr_val->data.x_ptr.data.base_array.array_val); 15637 15638 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 15639 out_val->data.x_ptr.data.base_array.array_val = 15640 array_ptr_val->data.x_ptr.data.base_array.array_val; 15641 out_val->data.x_ptr.data.base_array.elem_index = new_index; 15642 out_val->data.x_ptr.data.base_array.is_cstr = 15643 array_ptr_val->data.x_ptr.data.base_array.is_cstr; 15644 15645 break; 15646 } 15647 case ConstPtrSpecialBaseStruct: 15648 zig_panic("TODO elem ptr on a const inner struct"); 15649 case ConstPtrSpecialBaseErrorUnionCode: 15650 zig_panic("TODO elem ptr on a const inner error union code"); 15651 case ConstPtrSpecialBaseErrorUnionPayload: 15652 zig_panic("TODO elem ptr on a const inner error union payload"); 15653 case ConstPtrSpecialBaseOptionalPayload: 15654 zig_panic("TODO elem ptr on a const inner optional payload"); 15655 case ConstPtrSpecialHardCodedAddr: 15656 zig_unreachable(); 15657 case ConstPtrSpecialFunction: 15658 zig_panic("TODO element ptr of a function casted to a ptr"); 15659 case ConstPtrSpecialNull: 15660 zig_panic("TODO elem ptr on a null pointer"); 15661 } 15662 if (new_index >= mem_size) { 15663 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 15664 buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size)); 15665 return ira->codegen->invalid_instruction; 15666 } 15667 return result; 15668 } else if (is_slice(array_type)) { 15669 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; 15670 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 15671 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, 15672 array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len); 15673 result->value.type = return_type; 15674 return result; 15675 } 15676 ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index]; 15677 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); 15678 ConstExprValue *out_val = &result->value; 15679 uint64_t slice_len = bigint_as_unsigned(&len_field->data.x_bigint); 15680 if (index >= slice_len) { 15681 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 15682 buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64, 15683 index, slice_len)); 15684 return ira->codegen->invalid_instruction; 15685 } 15686 out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut; 15687 switch (ptr_field->data.x_ptr.special) { 15688 case ConstPtrSpecialInvalid: 15689 case ConstPtrSpecialDiscard: 15690 zig_unreachable(); 15691 case ConstPtrSpecialRef: 15692 out_val->data.x_ptr.special = ConstPtrSpecialRef; 15693 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee; 15694 break; 15695 case ConstPtrSpecialBaseArray: 15696 { 15697 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index; 15698 uint64_t new_index = offset + index; 15699 assert(new_index < ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len); 15700 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 15701 out_val->data.x_ptr.data.base_array.array_val = 15702 ptr_field->data.x_ptr.data.base_array.array_val; 15703 out_val->data.x_ptr.data.base_array.elem_index = new_index; 15704 out_val->data.x_ptr.data.base_array.is_cstr = 15705 ptr_field->data.x_ptr.data.base_array.is_cstr; 15706 break; 15707 } 15708 case ConstPtrSpecialBaseStruct: 15709 zig_panic("TODO elem ptr on a slice backed by const inner struct"); 15710 case ConstPtrSpecialBaseErrorUnionCode: 15711 zig_panic("TODO elem ptr on a slice backed by const inner error union code"); 15712 case ConstPtrSpecialBaseErrorUnionPayload: 15713 zig_panic("TODO elem ptr on a slice backed by const inner error union payload"); 15714 case ConstPtrSpecialBaseOptionalPayload: 15715 zig_panic("TODO elem ptr on a slice backed by const optional payload"); 15716 case ConstPtrSpecialHardCodedAddr: 15717 zig_unreachable(); 15718 case ConstPtrSpecialFunction: 15719 zig_panic("TODO elem ptr on a slice that was ptrcast from a function"); 15720 case ConstPtrSpecialNull: 15721 zig_panic("TODO elem ptr on a slice has a null pointer"); 15722 } 15723 return result; 15724 } else if (array_type->id == ZigTypeIdArray) { 15725 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); 15726 ConstExprValue *out_val = &result->value; 15727 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 15728 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; 15729 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val; 15730 out_val->data.x_ptr.data.base_array.elem_index = index; 15731 return result; 15732 } else { 15733 zig_unreachable(); 15734 } 15735 } 15736 } 15737 15738 } else { 15739 // runtime known element index 15740 switch (type_requires_comptime(ira->codegen, return_type)) { 15741 case ReqCompTimeYes: 15742 ir_add_error(ira, elem_index, 15743 buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known", 15744 buf_ptr(&return_type->data.pointer.child_type->name))); 15745 return ira->codegen->invalid_instruction; 15746 case ReqCompTimeInvalid: 15747 return ira->codegen->invalid_instruction; 15748 case ReqCompTimeNo: 15749 break; 15750 } 15751 if (ptr_align < abi_align) { 15752 if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 15753 return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align); 15754 } else { 15755 // can't get here because guaranteed elem_size >= abi_align 15756 zig_unreachable(); 15757 } 15758 } else { 15759 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align); 15760 } 15761 } 15762 15763 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, 15764 array_ptr, casted_elem_index, safety_check_on, elem_ptr_instruction->ptr_len); 15765 result->value.type = return_type; 15766 return result; 15767 } 15768 15769 static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, 15770 ZigType *bare_struct_type, Buf *field_name, IrInstruction *source_instr, 15771 IrInstruction *container_ptr, ZigType *container_type) 15772 { 15773 if (!is_slice(bare_struct_type)) { 15774 ScopeDecls *container_scope = get_container_scope(bare_struct_type); 15775 assert(container_scope != nullptr); 15776 auto entry = container_scope->decl_table.maybe_get(field_name); 15777 Tld *tld = entry ? entry->value : nullptr; 15778 if (tld && tld->id == TldIdFn) { 15779 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node); 15780 if (tld->resolution == TldResolutionInvalid) 15781 return ira->codegen->invalid_instruction; 15782 TldFn *tld_fn = (TldFn *)tld; 15783 ZigFn *fn_entry = tld_fn->fn_entry; 15784 if (type_is_invalid(fn_entry->type_entry)) 15785 return ira->codegen->invalid_instruction; 15786 15787 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope, 15788 source_instr->source_node, fn_entry, container_ptr); 15789 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 15790 } 15791 } 15792 const char *prefix_name; 15793 if (is_slice(bare_struct_type)) { 15794 prefix_name = ""; 15795 } else if (bare_struct_type->id == ZigTypeIdStruct) { 15796 prefix_name = "struct "; 15797 } else if (bare_struct_type->id == ZigTypeIdEnum) { 15798 prefix_name = "enum "; 15799 } else if (bare_struct_type->id == ZigTypeIdUnion) { 15800 prefix_name = "union "; 15801 } else { 15802 prefix_name = ""; 15803 } 15804 ir_add_error_node(ira, source_instr->source_node, 15805 buf_sprintf("no member named '%s' in %s'%s'", buf_ptr(field_name), prefix_name, buf_ptr(&bare_struct_type->name))); 15806 return ira->codegen->invalid_instruction; 15807 } 15808 15809 static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 15810 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type) 15811 { 15812 Error err; 15813 15814 ZigType *bare_type = container_ref_type(container_type); 15815 if ((err = ensure_complete_type(ira->codegen, bare_type))) 15816 return ira->codegen->invalid_instruction; 15817 15818 assert(container_ptr->value.type->id == ZigTypeIdPointer); 15819 bool is_const = container_ptr->value.type->data.pointer.is_const; 15820 bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; 15821 if (bare_type->id == ZigTypeIdStruct) { 15822 TypeStructField *field = find_struct_type_field(bare_type, field_name); 15823 if (field) { 15824 switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { 15825 case OnePossibleValueInvalid: 15826 return ira->codegen->invalid_instruction; 15827 case OnePossibleValueYes: { 15828 IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); 15829 return ir_get_ref(ira, source_instr, elem, false, false); 15830 } 15831 case OnePossibleValueNo: 15832 break; 15833 } 15834 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked); 15835 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 15836 uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host; 15837 uint32_t ptr_host_int_bytes = container_ptr->value.type->data.pointer.host_int_bytes; 15838 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? 15839 get_host_int_bytes(ira->codegen, bare_type, field) : ptr_host_int_bytes; 15840 if (instr_is_comptime(container_ptr)) { 15841 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 15842 if (!ptr_val) 15843 return ira->codegen->invalid_instruction; 15844 15845 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 15846 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 15847 if (struct_val == nullptr) 15848 return ira->codegen->invalid_instruction; 15849 if (type_is_invalid(struct_val->type)) 15850 return ira->codegen->invalid_instruction; 15851 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, 15852 is_const, is_volatile, PtrLenSingle, align_bytes, 15853 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), 15854 (uint32_t)host_int_bytes_for_result_type, false); 15855 IrInstruction *result = ir_const(ira, source_instr, ptr_type); 15856 ConstExprValue *const_val = &result->value; 15857 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; 15858 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; 15859 const_val->data.x_ptr.data.base_struct.struct_val = struct_val; 15860 const_val->data.x_ptr.data.base_struct.field_index = field->src_index; 15861 return result; 15862 } 15863 } 15864 IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, 15865 container_ptr, field); 15866 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, 15867 PtrLenSingle, 15868 align_bytes, 15869 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), 15870 host_int_bytes_for_result_type, false); 15871 return result; 15872 } else { 15873 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 15874 source_instr, container_ptr, container_type); 15875 } 15876 } else if (bare_type->id == ZigTypeIdEnum) { 15877 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 15878 source_instr, container_ptr, container_type); 15879 } else if (bare_type->id == ZigTypeIdUnion) { 15880 TypeUnionField *field = find_union_type_field(bare_type, field_name); 15881 if (field) { 15882 if (instr_is_comptime(container_ptr)) { 15883 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 15884 if (!ptr_val) 15885 return ira->codegen->invalid_instruction; 15886 15887 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 15888 ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 15889 if (union_val == nullptr) 15890 return ira->codegen->invalid_instruction; 15891 if (type_is_invalid(union_val->type)) 15892 return ira->codegen->invalid_instruction; 15893 15894 TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); 15895 if (actual_field == nullptr) 15896 zig_unreachable(); 15897 15898 if (field != actual_field) { 15899 ir_add_error_node(ira, source_instr->source_node, 15900 buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), 15901 buf_ptr(actual_field->name))); 15902 return ira->codegen->invalid_instruction; 15903 } 15904 15905 ConstExprValue *payload_val = union_val->data.x_union.payload; 15906 15907 ZigType *field_type = field->type_entry; 15908 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 15909 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 15910 15911 IrInstruction *result = ir_const(ira, source_instr, ptr_type); 15912 ConstExprValue *const_val = &result->value; 15913 const_val->data.x_ptr.special = ConstPtrSpecialRef; 15914 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; 15915 const_val->data.x_ptr.data.ref.pointee = payload_val; 15916 return result; 15917 } 15918 } 15919 15920 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); 15921 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, 15922 PtrLenSingle, 0, 0, 0, false); 15923 return result; 15924 } else { 15925 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 15926 source_instr, container_ptr, container_type); 15927 } 15928 } else { 15929 zig_unreachable(); 15930 } 15931 } 15932 15933 static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { 15934 bool is_libc = target_is_libc_lib_name(ira->codegen->zig_target, buf_ptr(lib_name)); 15935 if (is_libc && ira->codegen->libc_link_lib == nullptr && !ira->codegen->reported_bad_link_libc_error) { 15936 ir_add_error_node(ira, source_node, 15937 buf_sprintf("dependency on library c must be explicitly specified in the build command")); 15938 ira->codegen->reported_bad_link_libc_error = true; 15939 } 15940 15941 LinkLib *link_lib = add_link_lib(ira->codegen, lib_name); 15942 for (size_t i = 0; i < link_lib->symbols.length; i += 1) { 15943 Buf *existing_symbol_name = link_lib->symbols.at(i); 15944 if (buf_eql_buf(existing_symbol_name, symbol_name)) { 15945 return; 15946 } 15947 } 15948 15949 if (!is_libc && !target_is_wasm(ira->codegen->zig_target) && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) { 15950 ErrorMsg *msg = ir_add_error_node(ira, source_node, 15951 buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code", 15952 buf_ptr(lib_name))); 15953 add_error_note(ira->codegen, msg, source_node, 15954 buf_sprintf("fixed by `--library %s` or `--enable-pic`", buf_ptr(lib_name))); 15955 ira->codegen->reported_bad_link_libc_error = true; 15956 } 15957 15958 for (size_t i = 0; i < ira->codegen->forbidden_libs.length; i += 1) { 15959 Buf *forbidden_lib_name = ira->codegen->forbidden_libs.at(i); 15960 if (buf_eql_buf(lib_name, forbidden_lib_name)) { 15961 ir_add_error_node(ira, source_node, 15962 buf_sprintf("linking against forbidden library '%s'", buf_ptr(symbol_name))); 15963 } 15964 } 15965 link_lib->symbols.append(symbol_name); 15966 } 15967 15968 15969 static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { 15970 resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); 15971 if (tld->resolution == TldResolutionInvalid) 15972 return ira->codegen->invalid_instruction; 15973 15974 switch (tld->id) { 15975 case TldIdContainer: 15976 case TldIdCompTime: 15977 zig_unreachable(); 15978 case TldIdVar: 15979 { 15980 TldVar *tld_var = (TldVar *)tld; 15981 ZigVar *var = tld_var->var; 15982 if (tld_var->extern_lib_name != nullptr) { 15983 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node); 15984 } 15985 15986 return ir_get_var_ptr(ira, source_instruction, var); 15987 } 15988 case TldIdFn: 15989 { 15990 TldFn *tld_fn = (TldFn *)tld; 15991 ZigFn *fn_entry = tld_fn->fn_entry; 15992 assert(fn_entry->type_entry); 15993 15994 if (type_is_invalid(fn_entry->type_entry)) 15995 return ira->codegen->invalid_instruction; 15996 15997 // TODO instead of allocating this every time, put it in the tld value and we can reference 15998 // the same one every time 15999 ConstExprValue *const_val = create_const_vals(1); 16000 const_val->special = ConstValSpecialStatic; 16001 const_val->type = fn_entry->type_entry; 16002 const_val->data.x_ptr.data.fn.fn_entry = fn_entry; 16003 const_val->data.x_ptr.special = ConstPtrSpecialFunction; 16004 const_val->data.x_ptr.mut = ConstPtrMutComptimeConst; 16005 16006 if (tld_fn->extern_lib_name != nullptr) { 16007 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); 16008 } 16009 16010 bool ptr_is_const = true; 16011 bool ptr_is_volatile = false; 16012 return ir_get_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, 16013 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16014 } 16015 } 16016 zig_unreachable(); 16017 } 16018 16019 static ErrorTableEntry *find_err_table_entry(ZigType *err_set_type, Buf *field_name) { 16020 assert(err_set_type->id == ZigTypeIdErrorSet); 16021 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 16022 ErrorTableEntry *err_table_entry = err_set_type->data.error_set.errors[i]; 16023 if (buf_eql_buf(&err_table_entry->name, field_name)) { 16024 return err_table_entry; 16025 } 16026 } 16027 return nullptr; 16028 } 16029 16030 static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) { 16031 Error err; 16032 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->child; 16033 if (type_is_invalid(container_ptr->value.type)) 16034 return ira->codegen->invalid_instruction; 16035 16036 ZigType *container_type = container_ptr->value.type->data.pointer.child_type; 16037 16038 Buf *field_name = field_ptr_instruction->field_name_buffer; 16039 if (!field_name) { 16040 IrInstruction *field_name_expr = field_ptr_instruction->field_name_expr->child; 16041 field_name = ir_resolve_str(ira, field_name_expr); 16042 if (!field_name) 16043 return ira->codegen->invalid_instruction; 16044 } 16045 16046 16047 AstNode *source_node = field_ptr_instruction->base.source_node; 16048 16049 if (type_is_invalid(container_type)) { 16050 return ira->codegen->invalid_instruction; 16051 } else if (is_container_ref(container_type)) { 16052 assert(container_ptr->value.type->id == ZigTypeIdPointer); 16053 if (container_type->id == ZigTypeIdPointer) { 16054 ZigType *bare_type = container_ref_type(container_type); 16055 IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr); 16056 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type); 16057 return result; 16058 } else { 16059 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type); 16060 return result; 16061 } 16062 } else if (is_array_ref(container_type)) { 16063 if (buf_eql_str(field_name, "len")) { 16064 ConstExprValue *len_val = create_const_vals(1); 16065 if (container_type->id == ZigTypeIdPointer) { 16066 init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len); 16067 } else { 16068 init_const_usize(ira->codegen, len_val, container_type->data.array.len); 16069 } 16070 16071 ZigType *usize = ira->codegen->builtin_types.entry_usize; 16072 bool ptr_is_const = true; 16073 bool ptr_is_volatile = false; 16074 return ir_get_const_ptr(ira, &field_ptr_instruction->base, len_val, 16075 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16076 } else { 16077 ir_add_error_node(ira, source_node, 16078 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), 16079 buf_ptr(&container_type->name))); 16080 return ira->codegen->invalid_instruction; 16081 } 16082 } else if (container_type->id == ZigTypeIdArgTuple) { 16083 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 16084 if (!container_ptr_val) 16085 return ira->codegen->invalid_instruction; 16086 16087 assert(container_ptr->value.type->id == ZigTypeIdPointer); 16088 ConstExprValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node); 16089 if (child_val == nullptr) 16090 return ira->codegen->invalid_instruction; 16091 16092 if (buf_eql_str(field_name, "len")) { 16093 ConstExprValue *len_val = create_const_vals(1); 16094 size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index; 16095 init_const_usize(ira->codegen, len_val, len); 16096 16097 ZigType *usize = ira->codegen->builtin_types.entry_usize; 16098 bool ptr_is_const = true; 16099 bool ptr_is_volatile = false; 16100 return ir_get_const_ptr(ira, &field_ptr_instruction->base, len_val, 16101 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16102 } else { 16103 ir_add_error_node(ira, source_node, 16104 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), 16105 buf_ptr(&container_type->name))); 16106 return ira->codegen->invalid_instruction; 16107 } 16108 } else if (container_type->id == ZigTypeIdMetaType) { 16109 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 16110 if (!container_ptr_val) 16111 return ira->codegen->invalid_instruction; 16112 16113 assert(container_ptr->value.type->id == ZigTypeIdPointer); 16114 ConstExprValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node); 16115 if (child_val == nullptr) 16116 return ira->codegen->invalid_instruction; 16117 ZigType *child_type = child_val->data.x_type; 16118 16119 if (type_is_invalid(child_type)) { 16120 return ira->codegen->invalid_instruction; 16121 } else if (is_container(child_type)) { 16122 if (is_slice(child_type) && buf_eql_str(field_name, "Child")) { 16123 bool ptr_is_const = true; 16124 bool ptr_is_volatile = false; 16125 TypeStructField *ptr_field = &child_type->data.structure.fields[slice_ptr_index]; 16126 assert(ptr_field->type_entry->id == ZigTypeIdPointer); 16127 ZigType *child_type = ptr_field->type_entry->data.pointer.child_type; 16128 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16129 create_const_type(ira->codegen, child_type), 16130 ira->codegen->builtin_types.entry_type, 16131 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16132 } 16133 if (child_type->id == ZigTypeIdEnum) { 16134 if ((err = ensure_complete_type(ira->codegen, child_type))) 16135 return ira->codegen->invalid_instruction; 16136 16137 TypeEnumField *field = find_enum_type_field(child_type, field_name); 16138 if (field) { 16139 bool ptr_is_const = true; 16140 bool ptr_is_volatile = false; 16141 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16142 create_const_enum(child_type, &field->value), child_type, 16143 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16144 } 16145 } 16146 ScopeDecls *container_scope = get_container_scope(child_type); 16147 Tld *tld = find_container_decl(ira->codegen, container_scope, field_name); 16148 if (tld) { 16149 if (tld->visib_mod == VisibModPrivate && 16150 tld->import != get_scope_import(field_ptr_instruction->base.scope)) 16151 { 16152 ErrorMsg *msg = ir_add_error(ira, &field_ptr_instruction->base, 16153 buf_sprintf("'%s' is private", buf_ptr(field_name))); 16154 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); 16155 return ira->codegen->invalid_instruction; 16156 } 16157 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld); 16158 } 16159 if (child_type->id == ZigTypeIdUnion && 16160 (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr || 16161 child_type->data.unionation.decl_node->data.container_decl.auto_enum)) 16162 { 16163 if ((err = ensure_complete_type(ira->codegen, child_type))) 16164 return ira->codegen->invalid_instruction; 16165 TypeUnionField *field = find_union_type_field(child_type, field_name); 16166 if (field) { 16167 ZigType *enum_type = child_type->data.unionation.tag_type; 16168 bool ptr_is_const = true; 16169 bool ptr_is_volatile = false; 16170 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16171 create_const_enum(enum_type, &field->enum_field->value), enum_type, 16172 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16173 } 16174 } 16175 const char *container_name = (child_type == ira->codegen->root_import) ? 16176 "root source file" : buf_ptr(buf_sprintf("container '%s'", buf_ptr(&child_type->name))); 16177 ir_add_error(ira, &field_ptr_instruction->base, 16178 buf_sprintf("%s has no member called '%s'", 16179 container_name, buf_ptr(field_name))); 16180 return ira->codegen->invalid_instruction; 16181 } else if (child_type->id == ZigTypeIdErrorSet) { 16182 ErrorTableEntry *err_entry; 16183 ZigType *err_set_type; 16184 if (type_is_global_error_set(child_type)) { 16185 auto existing_entry = ira->codegen->error_table.maybe_get(field_name); 16186 if (existing_entry) { 16187 err_entry = existing_entry->value; 16188 } else { 16189 err_entry = allocate<ErrorTableEntry>(1); 16190 err_entry->decl_node = field_ptr_instruction->base.source_node; 16191 buf_init_from_buf(&err_entry->name, field_name); 16192 size_t error_value_count = ira->codegen->errors_by_index.length; 16193 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); 16194 err_entry->value = error_value_count; 16195 ira->codegen->errors_by_index.append(err_entry); 16196 ira->codegen->error_table.put(field_name, err_entry); 16197 } 16198 if (err_entry->set_with_only_this_in_it == nullptr) { 16199 err_entry->set_with_only_this_in_it = make_err_set_with_one_item(ira->codegen, 16200 field_ptr_instruction->base.scope, field_ptr_instruction->base.source_node, 16201 err_entry); 16202 } 16203 err_set_type = err_entry->set_with_only_this_in_it; 16204 } else { 16205 if (!resolve_inferred_error_set(ira->codegen, child_type, field_ptr_instruction->base.source_node)) { 16206 return ira->codegen->invalid_instruction; 16207 } 16208 err_entry = find_err_table_entry(child_type, field_name); 16209 if (err_entry == nullptr) { 16210 ir_add_error(ira, &field_ptr_instruction->base, 16211 buf_sprintf("no error named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&child_type->name))); 16212 return ira->codegen->invalid_instruction; 16213 } 16214 err_set_type = child_type; 16215 } 16216 ConstExprValue *const_val = create_const_vals(1); 16217 const_val->special = ConstValSpecialStatic; 16218 const_val->type = err_set_type; 16219 const_val->data.x_err_set = err_entry; 16220 16221 bool ptr_is_const = true; 16222 bool ptr_is_volatile = false; 16223 return ir_get_const_ptr(ira, &field_ptr_instruction->base, const_val, 16224 err_set_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16225 } else if (child_type->id == ZigTypeIdInt) { 16226 if (buf_eql_str(field_name, "bit_count")) { 16227 bool ptr_is_const = true; 16228 bool ptr_is_volatile = false; 16229 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16230 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 16231 child_type->data.integral.bit_count, false), 16232 ira->codegen->builtin_types.entry_num_lit_int, 16233 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16234 } else if (buf_eql_str(field_name, "is_signed")) { 16235 bool ptr_is_const = true; 16236 bool ptr_is_volatile = false; 16237 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16238 create_const_bool(ira->codegen, child_type->data.integral.is_signed), 16239 ira->codegen->builtin_types.entry_bool, 16240 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16241 } else { 16242 ir_add_error(ira, &field_ptr_instruction->base, 16243 buf_sprintf("type '%s' has no member called '%s'", 16244 buf_ptr(&child_type->name), buf_ptr(field_name))); 16245 return ira->codegen->invalid_instruction; 16246 } 16247 } else if (child_type->id == ZigTypeIdFloat) { 16248 if (buf_eql_str(field_name, "bit_count")) { 16249 bool ptr_is_const = true; 16250 bool ptr_is_volatile = false; 16251 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16252 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 16253 child_type->data.floating.bit_count, false), 16254 ira->codegen->builtin_types.entry_num_lit_int, 16255 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16256 } else { 16257 ir_add_error(ira, &field_ptr_instruction->base, 16258 buf_sprintf("type '%s' has no member called '%s'", 16259 buf_ptr(&child_type->name), buf_ptr(field_name))); 16260 return ira->codegen->invalid_instruction; 16261 } 16262 } else if (child_type->id == ZigTypeIdPointer) { 16263 if (buf_eql_str(field_name, "Child")) { 16264 bool ptr_is_const = true; 16265 bool ptr_is_volatile = false; 16266 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16267 create_const_type(ira->codegen, child_type->data.pointer.child_type), 16268 ira->codegen->builtin_types.entry_type, 16269 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16270 } else if (buf_eql_str(field_name, "alignment")) { 16271 bool ptr_is_const = true; 16272 bool ptr_is_volatile = false; 16273 if ((err = type_resolve(ira->codegen, child_type->data.pointer.child_type, 16274 ResolveStatusAlignmentKnown))) 16275 { 16276 return ira->codegen->invalid_instruction; 16277 } 16278 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16279 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 16280 get_ptr_align(ira->codegen, child_type), false), 16281 ira->codegen->builtin_types.entry_num_lit_int, 16282 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16283 } else { 16284 ir_add_error(ira, &field_ptr_instruction->base, 16285 buf_sprintf("type '%s' has no member called '%s'", 16286 buf_ptr(&child_type->name), buf_ptr(field_name))); 16287 return ira->codegen->invalid_instruction; 16288 } 16289 } else if (child_type->id == ZigTypeIdArray) { 16290 if (buf_eql_str(field_name, "Child")) { 16291 bool ptr_is_const = true; 16292 bool ptr_is_volatile = false; 16293 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16294 create_const_type(ira->codegen, child_type->data.array.child_type), 16295 ira->codegen->builtin_types.entry_type, 16296 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16297 } else if (buf_eql_str(field_name, "len")) { 16298 bool ptr_is_const = true; 16299 bool ptr_is_volatile = false; 16300 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16301 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 16302 child_type->data.array.len, false), 16303 ira->codegen->builtin_types.entry_num_lit_int, 16304 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16305 } else { 16306 ir_add_error(ira, &field_ptr_instruction->base, 16307 buf_sprintf("type '%s' has no member called '%s'", 16308 buf_ptr(&child_type->name), buf_ptr(field_name))); 16309 return ira->codegen->invalid_instruction; 16310 } 16311 } else if (child_type->id == ZigTypeIdErrorUnion) { 16312 if (buf_eql_str(field_name, "Payload")) { 16313 bool ptr_is_const = true; 16314 bool ptr_is_volatile = false; 16315 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16316 create_const_type(ira->codegen, child_type->data.error_union.payload_type), 16317 ira->codegen->builtin_types.entry_type, 16318 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16319 } else if (buf_eql_str(field_name, "ErrorSet")) { 16320 bool ptr_is_const = true; 16321 bool ptr_is_volatile = false; 16322 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16323 create_const_type(ira->codegen, child_type->data.error_union.err_set_type), 16324 ira->codegen->builtin_types.entry_type, 16325 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16326 } else { 16327 ir_add_error(ira, &field_ptr_instruction->base, 16328 buf_sprintf("type '%s' has no member called '%s'", 16329 buf_ptr(&child_type->name), buf_ptr(field_name))); 16330 return ira->codegen->invalid_instruction; 16331 } 16332 } else if (child_type->id == ZigTypeIdOptional) { 16333 if (buf_eql_str(field_name, "Child")) { 16334 bool ptr_is_const = true; 16335 bool ptr_is_volatile = false; 16336 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16337 create_const_type(ira->codegen, child_type->data.maybe.child_type), 16338 ira->codegen->builtin_types.entry_type, 16339 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16340 } else { 16341 ir_add_error(ira, &field_ptr_instruction->base, 16342 buf_sprintf("type '%s' has no member called '%s'", 16343 buf_ptr(&child_type->name), buf_ptr(field_name))); 16344 return ira->codegen->invalid_instruction; 16345 } 16346 } else if (child_type->id == ZigTypeIdFn) { 16347 if (buf_eql_str(field_name, "ReturnType")) { 16348 if (child_type->data.fn.fn_type_id.return_type == nullptr) { 16349 // Return type can only ever be null, if the function is generic 16350 assert(child_type->data.fn.is_generic); 16351 16352 ir_add_error(ira, &field_ptr_instruction->base, 16353 buf_sprintf("ReturnType has not been resolved because '%s' is generic", buf_ptr(&child_type->name))); 16354 return ira->codegen->invalid_instruction; 16355 } 16356 16357 bool ptr_is_const = true; 16358 bool ptr_is_volatile = false; 16359 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16360 create_const_type(ira->codegen, child_type->data.fn.fn_type_id.return_type), 16361 ira->codegen->builtin_types.entry_type, 16362 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16363 } else if (buf_eql_str(field_name, "is_var_args")) { 16364 bool ptr_is_const = true; 16365 bool ptr_is_volatile = false; 16366 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16367 create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), 16368 ira->codegen->builtin_types.entry_bool, 16369 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16370 } else if (buf_eql_str(field_name, "arg_count")) { 16371 bool ptr_is_const = true; 16372 bool ptr_is_volatile = false; 16373 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 16374 create_const_usize(ira->codegen, child_type->data.fn.fn_type_id.param_count), 16375 ira->codegen->builtin_types.entry_usize, 16376 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 16377 } else { 16378 ir_add_error(ira, &field_ptr_instruction->base, 16379 buf_sprintf("type '%s' has no member called '%s'", 16380 buf_ptr(&child_type->name), buf_ptr(field_name))); 16381 return ira->codegen->invalid_instruction; 16382 } 16383 } else { 16384 ir_add_error(ira, &field_ptr_instruction->base, 16385 buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); 16386 return ira->codegen->invalid_instruction; 16387 } 16388 } else { 16389 ir_add_error_node(ira, field_ptr_instruction->base.source_node, 16390 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); 16391 return ira->codegen->invalid_instruction; 16392 } 16393 } 16394 16395 static IrInstruction *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstructionStorePtr *instruction) { 16396 IrInstruction *ptr = instruction->ptr->child; 16397 if (type_is_invalid(ptr->value.type)) 16398 return ira->codegen->invalid_instruction; 16399 16400 IrInstruction *value = instruction->value->child; 16401 if (type_is_invalid(value->value.type)) 16402 return ira->codegen->invalid_instruction; 16403 16404 return ir_analyze_store_ptr(ira, &instruction->base, ptr, value); 16405 } 16406 16407 static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *instruction) { 16408 IrInstruction *ptr = instruction->ptr->child; 16409 if (type_is_invalid(ptr->value.type)) 16410 return ira->codegen->invalid_instruction; 16411 return ir_get_deref(ira, &instruction->base, ptr); 16412 } 16413 16414 static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { 16415 IrInstruction *expr_value = typeof_instruction->value->child; 16416 ZigType *type_entry = expr_value->value.type; 16417 if (type_is_invalid(type_entry)) 16418 return ira->codegen->invalid_instruction; 16419 return ir_const_type(ira, &typeof_instruction->base, type_entry); 16420 } 16421 16422 static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, 16423 IrInstructionToPtrType *to_ptr_type_instruction) 16424 { 16425 Error err; 16426 IrInstruction *ptr_ptr = to_ptr_type_instruction->ptr->child; 16427 if (type_is_invalid(ptr_ptr->value.type)) 16428 return ira->codegen->invalid_instruction; 16429 16430 ZigType *ptr_ptr_type = ptr_ptr->value.type; 16431 assert(ptr_ptr_type->id == ZigTypeIdPointer); 16432 ZigType *type_entry = ptr_ptr_type->data.pointer.child_type; 16433 16434 ZigType *ptr_type; 16435 if (type_entry->id == ZigTypeIdArray) { 16436 ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, ptr_ptr_type->data.pointer.is_const); 16437 } else if (is_array_ref(type_entry)) { 16438 ptr_type = get_pointer_to_type(ira->codegen, 16439 type_entry->data.pointer.child_type->data.array.child_type, type_entry->data.pointer.is_const); 16440 } else if (is_slice(type_entry)) { 16441 ZigType *slice_ptr_type = type_entry->data.structure.fields[0].type_entry; 16442 ptr_type = adjust_ptr_len(ira->codegen, slice_ptr_type, PtrLenSingle); 16443 // If the pointer is over-aligned, we may have to reduce it based on the alignment of the element type. 16444 if (slice_ptr_type->data.pointer.explicit_alignment != 0) { 16445 ZigType *elem_type = slice_ptr_type->data.pointer.child_type; 16446 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) 16447 return ira->codegen->invalid_instruction; 16448 uint32_t elem_align = get_abi_alignment(ira->codegen, elem_type); 16449 uint32_t reduced_align = min(elem_align, slice_ptr_type->data.pointer.explicit_alignment); 16450 ptr_type = adjust_ptr_align(ira->codegen, ptr_type, reduced_align); 16451 } 16452 } else if (type_entry->id == ZigTypeIdArgTuple) { 16453 zig_panic("TODO for loop on var args"); 16454 } else { 16455 ir_add_error_node(ira, to_ptr_type_instruction->base.source_node, 16456 buf_sprintf("expected array type, found '%s'", buf_ptr(&type_entry->name))); 16457 return ira->codegen->invalid_instruction; 16458 } 16459 16460 return ir_const_type(ira, &to_ptr_type_instruction->base, ptr_type); 16461 } 16462 16463 static IrInstruction *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, 16464 IrInstructionPtrTypeChild *ptr_type_child_instruction) 16465 { 16466 IrInstruction *type_value = ptr_type_child_instruction->value->child; 16467 ZigType *type_entry = ir_resolve_type(ira, type_value); 16468 if (type_is_invalid(type_entry)) 16469 return ira->codegen->invalid_instruction; 16470 16471 if (type_entry->id != ZigTypeIdPointer) { 16472 ir_add_error_node(ira, ptr_type_child_instruction->base.source_node, 16473 buf_sprintf("expected pointer type, found '%s'", buf_ptr(&type_entry->name))); 16474 return ira->codegen->invalid_instruction; 16475 } 16476 16477 return ir_const_type(ira, &ptr_type_child_instruction->base, type_entry->data.pointer.child_type); 16478 } 16479 16480 static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { 16481 if (ira->new_irb.exec->is_inline) { 16482 // ignore setCold when running functions at compile time 16483 return ir_const_void(ira, &instruction->base); 16484 } 16485 16486 IrInstruction *is_cold_value = instruction->is_cold->child; 16487 bool want_cold; 16488 if (!ir_resolve_bool(ira, is_cold_value, &want_cold)) 16489 return ira->codegen->invalid_instruction; 16490 16491 ZigFn *fn_entry = scope_fn_entry(instruction->base.scope); 16492 if (fn_entry == nullptr) { 16493 ir_add_error(ira, &instruction->base, buf_sprintf("@setCold outside function")); 16494 return ira->codegen->invalid_instruction; 16495 } 16496 16497 if (fn_entry->set_cold_node != nullptr) { 16498 ErrorMsg *msg = ir_add_error(ira, &instruction->base, buf_sprintf("cold set twice in same function")); 16499 add_error_note(ira->codegen, msg, fn_entry->set_cold_node, buf_sprintf("first set here")); 16500 return ira->codegen->invalid_instruction; 16501 } 16502 16503 fn_entry->set_cold_node = instruction->base.source_node; 16504 fn_entry->is_cold = want_cold; 16505 16506 return ir_const_void(ira, &instruction->base); 16507 } 16508 16509 static IrInstruction *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira, 16510 IrInstructionSetRuntimeSafety *set_runtime_safety_instruction) 16511 { 16512 if (ira->new_irb.exec->is_inline) { 16513 // ignore setRuntimeSafety when running functions at compile time 16514 return ir_const_void(ira, &set_runtime_safety_instruction->base); 16515 } 16516 16517 bool *safety_off_ptr; 16518 AstNode **safety_set_node_ptr; 16519 16520 Scope *scope = set_runtime_safety_instruction->base.scope; 16521 while (scope != nullptr) { 16522 if (scope->id == ScopeIdBlock) { 16523 ScopeBlock *block_scope = (ScopeBlock *)scope; 16524 safety_off_ptr = &block_scope->safety_off; 16525 safety_set_node_ptr = &block_scope->safety_set_node; 16526 break; 16527 } else if (scope->id == ScopeIdFnDef) { 16528 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 16529 ZigFn *target_fn = def_scope->fn_entry; 16530 assert(target_fn->def_scope != nullptr); 16531 safety_off_ptr = &target_fn->def_scope->safety_off; 16532 safety_set_node_ptr = &target_fn->def_scope->safety_set_node; 16533 break; 16534 } else if (scope->id == ScopeIdDecls) { 16535 ScopeDecls *decls_scope = (ScopeDecls *)scope; 16536 safety_off_ptr = &decls_scope->safety_off; 16537 safety_set_node_ptr = &decls_scope->safety_set_node; 16538 break; 16539 } else { 16540 scope = scope->parent; 16541 continue; 16542 } 16543 } 16544 assert(scope != nullptr); 16545 16546 IrInstruction *safety_on_value = set_runtime_safety_instruction->safety_on->child; 16547 bool want_runtime_safety; 16548 if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety)) 16549 return ira->codegen->invalid_instruction; 16550 16551 AstNode *source_node = set_runtime_safety_instruction->base.source_node; 16552 if (*safety_set_node_ptr) { 16553 ErrorMsg *msg = ir_add_error_node(ira, source_node, 16554 buf_sprintf("runtime safety set twice for same scope")); 16555 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here")); 16556 return ira->codegen->invalid_instruction; 16557 } 16558 *safety_set_node_ptr = source_node; 16559 *safety_off_ptr = !want_runtime_safety; 16560 16561 return ir_const_void(ira, &set_runtime_safety_instruction->base); 16562 } 16563 16564 static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, 16565 IrInstructionSetFloatMode *instruction) 16566 { 16567 if (ira->new_irb.exec->is_inline) { 16568 // ignore setFloatMode when running functions at compile time 16569 return ir_const_void(ira, &instruction->base); 16570 } 16571 16572 bool *fast_math_on_ptr; 16573 AstNode **fast_math_set_node_ptr; 16574 16575 Scope *scope = instruction->base.scope; 16576 while (scope != nullptr) { 16577 if (scope->id == ScopeIdBlock) { 16578 ScopeBlock *block_scope = (ScopeBlock *)scope; 16579 fast_math_on_ptr = &block_scope->fast_math_on; 16580 fast_math_set_node_ptr = &block_scope->fast_math_set_node; 16581 break; 16582 } else if (scope->id == ScopeIdFnDef) { 16583 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 16584 ZigFn *target_fn = def_scope->fn_entry; 16585 assert(target_fn->def_scope != nullptr); 16586 fast_math_on_ptr = &target_fn->def_scope->fast_math_on; 16587 fast_math_set_node_ptr = &target_fn->def_scope->fast_math_set_node; 16588 break; 16589 } else if (scope->id == ScopeIdDecls) { 16590 ScopeDecls *decls_scope = (ScopeDecls *)scope; 16591 fast_math_on_ptr = &decls_scope->fast_math_on; 16592 fast_math_set_node_ptr = &decls_scope->fast_math_set_node; 16593 break; 16594 } else { 16595 scope = scope->parent; 16596 continue; 16597 } 16598 } 16599 assert(scope != nullptr); 16600 16601 IrInstruction *float_mode_value = instruction->mode_value->child; 16602 FloatMode float_mode_scalar; 16603 if (!ir_resolve_float_mode(ira, float_mode_value, &float_mode_scalar)) 16604 return ira->codegen->invalid_instruction; 16605 16606 AstNode *source_node = instruction->base.source_node; 16607 if (*fast_math_set_node_ptr) { 16608 ErrorMsg *msg = ir_add_error_node(ira, source_node, 16609 buf_sprintf("float mode set twice for same scope")); 16610 add_error_note(ira->codegen, msg, *fast_math_set_node_ptr, buf_sprintf("first set here")); 16611 return ira->codegen->invalid_instruction; 16612 } 16613 *fast_math_set_node_ptr = source_node; 16614 *fast_math_on_ptr = (float_mode_scalar == FloatModeOptimized); 16615 16616 return ir_const_void(ira, &instruction->base); 16617 } 16618 16619 static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, 16620 IrInstructionSliceType *slice_type_instruction) 16621 { 16622 Error err; 16623 uint32_t align_bytes = 0; 16624 if (slice_type_instruction->align_value != nullptr) { 16625 if (!ir_resolve_align(ira, slice_type_instruction->align_value->child, &align_bytes)) 16626 return ira->codegen->invalid_instruction; 16627 } 16628 16629 ZigType *child_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); 16630 if (type_is_invalid(child_type)) 16631 return ira->codegen->invalid_instruction; 16632 16633 bool is_const = slice_type_instruction->is_const; 16634 bool is_volatile = slice_type_instruction->is_volatile; 16635 bool is_allow_zero = slice_type_instruction->is_allow_zero; 16636 16637 switch (child_type->id) { 16638 case ZigTypeIdInvalid: // handled above 16639 zig_unreachable(); 16640 case ZigTypeIdUnreachable: 16641 case ZigTypeIdUndefined: 16642 case ZigTypeIdNull: 16643 case ZigTypeIdArgTuple: 16644 case ZigTypeIdOpaque: 16645 ir_add_error_node(ira, slice_type_instruction->base.source_node, 16646 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&child_type->name))); 16647 return ira->codegen->invalid_instruction; 16648 case ZigTypeIdMetaType: 16649 case ZigTypeIdVoid: 16650 case ZigTypeIdBool: 16651 case ZigTypeIdInt: 16652 case ZigTypeIdFloat: 16653 case ZigTypeIdPointer: 16654 case ZigTypeIdArray: 16655 case ZigTypeIdStruct: 16656 case ZigTypeIdComptimeFloat: 16657 case ZigTypeIdComptimeInt: 16658 case ZigTypeIdEnumLiteral: 16659 case ZigTypeIdOptional: 16660 case ZigTypeIdErrorUnion: 16661 case ZigTypeIdErrorSet: 16662 case ZigTypeIdEnum: 16663 case ZigTypeIdUnion: 16664 case ZigTypeIdFn: 16665 case ZigTypeIdBoundFn: 16666 case ZigTypeIdPromise: 16667 case ZigTypeIdVector: 16668 { 16669 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) 16670 return ira->codegen->invalid_instruction; 16671 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, 16672 is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0, is_allow_zero); 16673 ZigType *result_type = get_slice_type(ira->codegen, slice_ptr_type); 16674 return ir_const_type(ira, &slice_type_instruction->base, result_type); 16675 } 16676 } 16677 zig_unreachable(); 16678 } 16679 16680 static IrInstruction *ir_analyze_instruction_global_asm(IrAnalyze *ira, IrInstructionGlobalAsm *instruction) { 16681 buf_append_char(&ira->codegen->global_asm, '\n'); 16682 buf_append_buf(&ira->codegen->global_asm, instruction->asm_code); 16683 16684 return ir_const_void(ira, &instruction->base); 16685 } 16686 16687 static IrInstruction *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsm *asm_instruction) { 16688 assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr); 16689 16690 AstNodeAsmExpr *asm_expr = &asm_instruction->base.source_node->data.asm_expr; 16691 16692 if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base)) 16693 return ira->codegen->invalid_instruction; 16694 16695 // TODO validate the output types and variable types 16696 16697 IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length); 16698 IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length); 16699 16700 ZigType *return_type = ira->codegen->builtin_types.entry_void; 16701 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 16702 AsmOutput *asm_output = asm_expr->output_list.at(i); 16703 if (asm_output->return_type) { 16704 output_types[i] = asm_instruction->output_types[i]->child; 16705 return_type = ir_resolve_type(ira, output_types[i]); 16706 if (type_is_invalid(return_type)) 16707 return ira->codegen->invalid_instruction; 16708 } 16709 } 16710 16711 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 16712 IrInstruction *const input_value = asm_instruction->input_list[i]->child; 16713 if (type_is_invalid(input_value->value.type)) 16714 return ira->codegen->invalid_instruction; 16715 16716 if (instr_is_comptime(input_value) && 16717 (input_value->value.type->id == ZigTypeIdComptimeInt || 16718 input_value->value.type->id == ZigTypeIdComptimeFloat)) { 16719 ir_add_error_node(ira, input_value->source_node, 16720 buf_sprintf("expected sized integer or sized float, found %s", buf_ptr(&input_value->value.type->name))); 16721 return ira->codegen->invalid_instruction; 16722 } 16723 16724 input_list[i] = input_value; 16725 } 16726 16727 IrInstruction *result = ir_build_asm(&ira->new_irb, 16728 asm_instruction->base.scope, asm_instruction->base.source_node, 16729 asm_instruction->asm_template, asm_instruction->token_list, asm_instruction->token_list_len, 16730 input_list, output_types, asm_instruction->output_vars, asm_instruction->return_count, 16731 asm_instruction->has_side_effects); 16732 result->value.type = return_type; 16733 return result; 16734 } 16735 16736 static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, 16737 IrInstructionArrayType *array_type_instruction) 16738 { 16739 Error err; 16740 16741 IrInstruction *size_value = array_type_instruction->size->child; 16742 uint64_t size; 16743 if (!ir_resolve_usize(ira, size_value, &size)) 16744 return ira->codegen->invalid_instruction; 16745 16746 IrInstruction *child_type_value = array_type_instruction->child_type->child; 16747 ZigType *child_type = ir_resolve_type(ira, child_type_value); 16748 if (type_is_invalid(child_type)) 16749 return ira->codegen->invalid_instruction; 16750 switch (child_type->id) { 16751 case ZigTypeIdInvalid: // handled above 16752 zig_unreachable(); 16753 case ZigTypeIdUnreachable: 16754 case ZigTypeIdUndefined: 16755 case ZigTypeIdNull: 16756 case ZigTypeIdArgTuple: 16757 case ZigTypeIdOpaque: 16758 ir_add_error_node(ira, array_type_instruction->base.source_node, 16759 buf_sprintf("array of type '%s' not allowed", buf_ptr(&child_type->name))); 16760 return ira->codegen->invalid_instruction; 16761 case ZigTypeIdMetaType: 16762 case ZigTypeIdVoid: 16763 case ZigTypeIdBool: 16764 case ZigTypeIdInt: 16765 case ZigTypeIdFloat: 16766 case ZigTypeIdPointer: 16767 case ZigTypeIdArray: 16768 case ZigTypeIdStruct: 16769 case ZigTypeIdComptimeFloat: 16770 case ZigTypeIdComptimeInt: 16771 case ZigTypeIdEnumLiteral: 16772 case ZigTypeIdOptional: 16773 case ZigTypeIdErrorUnion: 16774 case ZigTypeIdErrorSet: 16775 case ZigTypeIdEnum: 16776 case ZigTypeIdUnion: 16777 case ZigTypeIdFn: 16778 case ZigTypeIdBoundFn: 16779 case ZigTypeIdPromise: 16780 case ZigTypeIdVector: 16781 { 16782 if ((err = ensure_complete_type(ira->codegen, child_type))) 16783 return ira->codegen->invalid_instruction; 16784 ZigType *result_type = get_array_type(ira->codegen, child_type, size); 16785 return ir_const_type(ira, &array_type_instruction->base, result_type); 16786 } 16787 } 16788 zig_unreachable(); 16789 } 16790 16791 static IrInstruction *ir_analyze_instruction_promise_type(IrAnalyze *ira, IrInstructionPromiseType *instruction) { 16792 ZigType *promise_type; 16793 16794 if (instruction->payload_type == nullptr) { 16795 promise_type = ira->codegen->builtin_types.entry_promise; 16796 } else { 16797 ZigType *payload_type = ir_resolve_type(ira, instruction->payload_type->child); 16798 if (type_is_invalid(payload_type)) 16799 return ira->codegen->invalid_instruction; 16800 16801 promise_type = get_promise_type(ira->codegen, payload_type); 16802 } 16803 16804 return ir_const_type(ira, &instruction->base, promise_type); 16805 } 16806 16807 static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, 16808 IrInstructionSizeOf *size_of_instruction) 16809 { 16810 Error err; 16811 IrInstruction *type_value = size_of_instruction->type_value->child; 16812 ZigType *type_entry = ir_resolve_type(ira, type_value); 16813 16814 if ((err = ensure_complete_type(ira->codegen, type_entry))) 16815 return ira->codegen->invalid_instruction; 16816 16817 switch (type_entry->id) { 16818 case ZigTypeIdInvalid: // handled above 16819 zig_unreachable(); 16820 case ZigTypeIdUnreachable: 16821 case ZigTypeIdUndefined: 16822 case ZigTypeIdNull: 16823 case ZigTypeIdBoundFn: 16824 case ZigTypeIdArgTuple: 16825 case ZigTypeIdOpaque: 16826 ir_add_error_node(ira, type_value->source_node, 16827 buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name))); 16828 return ira->codegen->invalid_instruction; 16829 case ZigTypeIdMetaType: 16830 case ZigTypeIdEnumLiteral: 16831 case ZigTypeIdComptimeFloat: 16832 case ZigTypeIdComptimeInt: 16833 case ZigTypeIdVoid: 16834 case ZigTypeIdBool: 16835 case ZigTypeIdInt: 16836 case ZigTypeIdFloat: 16837 case ZigTypeIdPointer: 16838 case ZigTypeIdArray: 16839 case ZigTypeIdStruct: 16840 case ZigTypeIdOptional: 16841 case ZigTypeIdErrorUnion: 16842 case ZigTypeIdErrorSet: 16843 case ZigTypeIdEnum: 16844 case ZigTypeIdUnion: 16845 case ZigTypeIdFn: 16846 case ZigTypeIdPromise: 16847 case ZigTypeIdVector: 16848 { 16849 uint64_t size_in_bytes = type_size(ira->codegen, type_entry); 16850 return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes); 16851 } 16852 } 16853 zig_unreachable(); 16854 } 16855 16856 static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) { 16857 ZigType *type_entry = value->value.type; 16858 16859 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) { 16860 if (instr_is_comptime(value)) { 16861 ConstExprValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk); 16862 if (c_ptr_val == nullptr) 16863 return ira->codegen->invalid_instruction; 16864 if (c_ptr_val->special == ConstValSpecialUndef) 16865 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 16866 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 16867 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 16868 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 16869 return ir_const_bool(ira, source_inst, !is_null); 16870 } 16871 16872 IrInstruction *result = ir_build_test_nonnull(&ira->new_irb, 16873 source_inst->scope, source_inst->source_node, value); 16874 result->value.type = ira->codegen->builtin_types.entry_bool; 16875 return result; 16876 } else if (type_entry->id == ZigTypeIdOptional) { 16877 if (instr_is_comptime(value)) { 16878 ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefOk); 16879 if (maybe_val == nullptr) 16880 return ira->codegen->invalid_instruction; 16881 if (maybe_val->special == ConstValSpecialUndef) 16882 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 16883 16884 return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val)); 16885 } 16886 16887 IrInstruction *result = ir_build_test_nonnull(&ira->new_irb, 16888 source_inst->scope, source_inst->source_node, value); 16889 result->value.type = ira->codegen->builtin_types.entry_bool; 16890 return result; 16891 } else if (type_entry->id == ZigTypeIdNull) { 16892 return ir_const_bool(ira, source_inst, false); 16893 } else { 16894 return ir_const_bool(ira, source_inst, true); 16895 } 16896 } 16897 16898 static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrInstructionTestNonNull *instruction) { 16899 IrInstruction *value = instruction->value->child; 16900 if (type_is_invalid(value->value.type)) 16901 return ira->codegen->invalid_instruction; 16902 16903 return ir_analyze_test_non_null(ira, &instruction->base, value); 16904 } 16905 16906 static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, 16907 IrInstruction *base_ptr, bool safety_check_on) 16908 { 16909 ZigType *ptr_type = base_ptr->value.type; 16910 assert(ptr_type->id == ZigTypeIdPointer); 16911 16912 ZigType *type_entry = ptr_type->data.pointer.child_type; 16913 if (type_is_invalid(type_entry)) 16914 return ira->codegen->invalid_instruction; 16915 16916 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.ptr_len == PtrLenC) { 16917 if (instr_is_comptime(base_ptr)) { 16918 ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad); 16919 if (!val) 16920 return ira->codegen->invalid_instruction; 16921 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 16922 ConstExprValue *c_ptr_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 16923 if (c_ptr_val == nullptr) 16924 return ira->codegen->invalid_instruction; 16925 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 16926 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 16927 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 16928 if (is_null) { 16929 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 16930 return ira->codegen->invalid_instruction; 16931 } 16932 return base_ptr; 16933 } 16934 } 16935 if (!safety_check_on) 16936 return base_ptr; 16937 IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr); 16938 ir_build_assert_non_null(ira, source_instr, c_ptr_val); 16939 return base_ptr; 16940 } 16941 16942 if (type_entry->id != ZigTypeIdOptional) { 16943 ir_add_error_node(ira, base_ptr->source_node, 16944 buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name))); 16945 return ira->codegen->invalid_instruction; 16946 } 16947 16948 ZigType *child_type = type_entry->data.maybe.child_type; 16949 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, 16950 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); 16951 16952 if (instr_is_comptime(base_ptr)) { 16953 ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad); 16954 if (!val) 16955 return ira->codegen->invalid_instruction; 16956 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 16957 ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 16958 if (maybe_val == nullptr) 16959 return ira->codegen->invalid_instruction; 16960 16961 if (optional_value_is_null(maybe_val)) { 16962 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 16963 return ira->codegen->invalid_instruction; 16964 } 16965 IrInstruction *result = ir_const(ira, source_instr, result_type); 16966 ConstExprValue *out_val = &result->value; 16967 out_val->data.x_ptr.special = ConstPtrSpecialRef; 16968 out_val->data.x_ptr.mut = val->data.x_ptr.mut; 16969 if (types_have_same_zig_comptime_repr(type_entry, child_type)) { 16970 out_val->data.x_ptr.data.ref.pointee = maybe_val; 16971 } else { 16972 out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_optional; 16973 } 16974 return result; 16975 } 16976 } 16977 16978 IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, 16979 source_instr->source_node, base_ptr, safety_check_on); 16980 result->value.type = result_type; 16981 return result; 16982 } 16983 16984 static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, 16985 IrInstructionOptionalUnwrapPtr *instruction) 16986 { 16987 IrInstruction *base_ptr = instruction->base_ptr->child; 16988 if (type_is_invalid(base_ptr->value.type)) 16989 return ira->codegen->invalid_instruction; 16990 16991 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on); 16992 } 16993 16994 static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *ctz_instruction) { 16995 IrInstruction *value = ctz_instruction->value->child; 16996 if (type_is_invalid(value->value.type)) { 16997 return ira->codegen->invalid_instruction; 16998 } else if (value->value.type->id == ZigTypeIdInt) { 16999 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, 17000 value->value.type->data.integral.bit_count); 17001 if (value->value.special != ConstValSpecialRuntime) { 17002 size_t result_usize = bigint_ctz(&value->value.data.x_bigint, 17003 value->value.type->data.integral.bit_count); 17004 IrInstruction *result = ir_const(ira, &ctz_instruction->base, return_type); 17005 bigint_init_unsigned(&result->value.data.x_bigint, result_usize); 17006 return result; 17007 } 17008 17009 IrInstruction *result = ir_build_ctz(&ira->new_irb, 17010 ctz_instruction->base.scope, ctz_instruction->base.source_node, value); 17011 result->value.type = return_type; 17012 return result; 17013 } else { 17014 ir_add_error_node(ira, ctz_instruction->base.source_node, 17015 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); 17016 return ira->codegen->invalid_instruction; 17017 } 17018 } 17019 17020 static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *clz_instruction) { 17021 IrInstruction *value = clz_instruction->value->child; 17022 if (type_is_invalid(value->value.type)) { 17023 return ira->codegen->invalid_instruction; 17024 } else if (value->value.type->id == ZigTypeIdInt) { 17025 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, 17026 value->value.type->data.integral.bit_count); 17027 if (value->value.special != ConstValSpecialRuntime) { 17028 size_t result_usize = bigint_clz(&value->value.data.x_bigint, 17029 value->value.type->data.integral.bit_count); 17030 IrInstruction *result = ir_const(ira, &clz_instruction->base, return_type); 17031 bigint_init_unsigned(&result->value.data.x_bigint, result_usize); 17032 return result; 17033 } 17034 17035 IrInstruction *result = ir_build_clz(&ira->new_irb, 17036 clz_instruction->base.scope, clz_instruction->base.source_node, value); 17037 result->value.type = return_type; 17038 return result; 17039 } else { 17040 ir_add_error_node(ira, clz_instruction->base.source_node, 17041 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); 17042 return ira->codegen->invalid_instruction; 17043 } 17044 } 17045 17046 static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) { 17047 IrInstruction *value = instruction->value->child; 17048 if (type_is_invalid(value->value.type)) 17049 return ira->codegen->invalid_instruction; 17050 17051 if (value->value.type->id != ZigTypeIdInt && value->value.type->id != ZigTypeIdComptimeInt) { 17052 ir_add_error(ira, value, 17053 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); 17054 return ira->codegen->invalid_instruction; 17055 } 17056 17057 if (instr_is_comptime(value)) { 17058 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 17059 if (!val) 17060 return ira->codegen->invalid_instruction; 17061 if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { 17062 size_t result = bigint_popcount_unsigned(&val->data.x_bigint); 17063 return ir_const_unsigned(ira, &instruction->base, result); 17064 } 17065 if (value->value.type->id == ZigTypeIdComptimeInt) { 17066 Buf *val_buf = buf_alloc(); 17067 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 17068 ir_add_error(ira, &instruction->base, 17069 buf_sprintf("@popCount on negative %s value %s", 17070 buf_ptr(&value->value.type->name), buf_ptr(val_buf))); 17071 return ira->codegen->invalid_instruction; 17072 } 17073 size_t result = bigint_popcount_signed(&val->data.x_bigint, value->value.type->data.integral.bit_count); 17074 return ir_const_unsigned(ira, &instruction->base, result); 17075 } 17076 17077 IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope, 17078 instruction->base.source_node, value); 17079 result->value.type = get_smallest_unsigned_int_type(ira->codegen, value->value.type->data.integral.bit_count); 17080 return result; 17081 } 17082 17083 static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value) { 17084 if (type_is_invalid(value->value.type)) 17085 return ira->codegen->invalid_instruction; 17086 17087 if (value->value.type->id == ZigTypeIdEnum) { 17088 return value; 17089 } 17090 17091 if (value->value.type->id != ZigTypeIdUnion) { 17092 ir_add_error(ira, value, 17093 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value.type->name))); 17094 return ira->codegen->invalid_instruction; 17095 } 17096 if (!value->value.type->data.unionation.have_explicit_tag_type && !source_instr->is_gen) { 17097 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum")); 17098 if (value->value.type->data.unionation.decl_node != nullptr) { 17099 add_error_note(ira->codegen, msg, value->value.type->data.unionation.decl_node, 17100 buf_sprintf("declared here")); 17101 } 17102 return ira->codegen->invalid_instruction; 17103 } 17104 17105 ZigType *tag_type = value->value.type->data.unionation.tag_type; 17106 assert(tag_type->id == ZigTypeIdEnum); 17107 17108 if (instr_is_comptime(value)) { 17109 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 17110 if (!val) 17111 return ira->codegen->invalid_instruction; 17112 17113 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 17114 source_instr->scope, source_instr->source_node); 17115 const_instruction->base.value.type = tag_type; 17116 const_instruction->base.value.special = ConstValSpecialStatic; 17117 bigint_init_bigint(&const_instruction->base.value.data.x_enum_tag, &val->data.x_union.tag); 17118 return &const_instruction->base; 17119 } 17120 17121 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 17122 result->value.type = tag_type; 17123 return result; 17124 } 17125 17126 static IrInstruction *ir_analyze_instruction_switch_br(IrAnalyze *ira, 17127 IrInstructionSwitchBr *switch_br_instruction) 17128 { 17129 IrInstruction *target_value = switch_br_instruction->target_value->child; 17130 if (type_is_invalid(target_value->value.type)) 17131 return ir_unreach_error(ira); 17132 17133 if (switch_br_instruction->switch_prongs_void != nullptr) { 17134 if (type_is_invalid(switch_br_instruction->switch_prongs_void->child->value.type)) { 17135 return ir_unreach_error(ira); 17136 } 17137 } 17138 17139 17140 size_t case_count = switch_br_instruction->case_count; 17141 17142 bool is_comptime; 17143 if (!ir_resolve_comptime(ira, switch_br_instruction->is_comptime->child, &is_comptime)) 17144 return ira->codegen->invalid_instruction; 17145 17146 if (is_comptime || instr_is_comptime(target_value)) { 17147 ConstExprValue *target_val = ir_resolve_const(ira, target_value, UndefBad); 17148 if (!target_val) 17149 return ir_unreach_error(ira); 17150 17151 IrBasicBlock *old_dest_block = switch_br_instruction->else_block; 17152 for (size_t i = 0; i < case_count; i += 1) { 17153 IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 17154 IrInstruction *case_value = old_case->value->child; 17155 if (type_is_invalid(case_value->value.type)) 17156 return ir_unreach_error(ira); 17157 17158 if (case_value->value.type->id == ZigTypeIdEnum) { 17159 case_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, case_value); 17160 if (type_is_invalid(case_value->value.type)) 17161 return ir_unreach_error(ira); 17162 } 17163 17164 IrInstruction *casted_case_value = ir_implicit_cast(ira, case_value, target_value->value.type); 17165 if (type_is_invalid(casted_case_value->value.type)) 17166 return ir_unreach_error(ira); 17167 17168 ConstExprValue *case_val = ir_resolve_const(ira, casted_case_value, UndefBad); 17169 if (!case_val) 17170 return ir_unreach_error(ira); 17171 17172 if (const_values_equal(ira->codegen, target_val, case_val)) { 17173 old_dest_block = old_case->block; 17174 break; 17175 } 17176 } 17177 17178 if (is_comptime || old_dest_block->ref_count == 1) { 17179 return ir_inline_bb(ira, &switch_br_instruction->base, old_dest_block); 17180 } else { 17181 IrBasicBlock *new_dest_block = ir_get_new_bb(ira, old_dest_block, &switch_br_instruction->base); 17182 IrInstruction *result = ir_build_br(&ira->new_irb, 17183 switch_br_instruction->base.scope, switch_br_instruction->base.source_node, 17184 new_dest_block, nullptr); 17185 result->value.type = ira->codegen->builtin_types.entry_unreachable; 17186 return ir_finish_anal(ira, result); 17187 } 17188 } 17189 17190 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(case_count); 17191 for (size_t i = 0; i < case_count; i += 1) { 17192 IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 17193 IrInstructionSwitchBrCase *new_case = &cases[i]; 17194 new_case->block = ir_get_new_bb(ira, old_case->block, &switch_br_instruction->base); 17195 new_case->value = ira->codegen->invalid_instruction; 17196 17197 // Calling ir_get_new_bb set the ref_instruction on the new basic block. 17198 // However a switch br may branch to the same basic block which would trigger an 17199 // incorrect re-generation of the block. So we set it to null here and assign 17200 // it back after the loop. 17201 new_case->block->ref_instruction = nullptr; 17202 17203 IrInstruction *old_value = old_case->value; 17204 IrInstruction *new_value = old_value->child; 17205 if (type_is_invalid(new_value->value.type)) 17206 continue; 17207 17208 if (new_value->value.type->id == ZigTypeIdEnum) { 17209 new_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, new_value); 17210 if (type_is_invalid(new_value->value.type)) 17211 continue; 17212 } 17213 17214 IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, target_value->value.type); 17215 if (type_is_invalid(casted_new_value->value.type)) 17216 continue; 17217 17218 if (!ir_resolve_const(ira, casted_new_value, UndefBad)) 17219 continue; 17220 17221 new_case->value = casted_new_value; 17222 } 17223 17224 for (size_t i = 0; i < case_count; i += 1) { 17225 IrInstructionSwitchBrCase *new_case = &cases[i]; 17226 if (new_case->value == ira->codegen->invalid_instruction) 17227 return ir_unreach_error(ira); 17228 new_case->block->ref_instruction = &switch_br_instruction->base; 17229 } 17230 17231 IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); 17232 IrInstruction *result = ir_build_switch_br(&ira->new_irb, 17233 switch_br_instruction->base.scope, switch_br_instruction->base.source_node, 17234 target_value, new_else_block, case_count, cases, nullptr, nullptr); 17235 result->value.type = ira->codegen->builtin_types.entry_unreachable; 17236 return ir_finish_anal(ira, result); 17237 } 17238 17239 static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, 17240 IrInstructionSwitchTarget *switch_target_instruction) 17241 { 17242 Error err; 17243 IrInstruction *target_value_ptr = switch_target_instruction->target_value_ptr->child; 17244 if (type_is_invalid(target_value_ptr->value.type)) 17245 return ira->codegen->invalid_instruction; 17246 17247 if (target_value_ptr->value.type->id == ZigTypeIdMetaType) { 17248 assert(instr_is_comptime(target_value_ptr)); 17249 ZigType *ptr_type = target_value_ptr->value.data.x_type; 17250 assert(ptr_type->id == ZigTypeIdPointer); 17251 return ir_const_type(ira, &switch_target_instruction->base, ptr_type->data.pointer.child_type); 17252 } 17253 17254 ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type; 17255 ConstExprValue *pointee_val = nullptr; 17256 if (instr_is_comptime(target_value_ptr)) { 17257 pointee_val = const_ptr_pointee(ira, ira->codegen, &target_value_ptr->value, target_value_ptr->source_node); 17258 if (pointee_val == nullptr) 17259 return ira->codegen->invalid_instruction; 17260 17261 if (pointee_val->special == ConstValSpecialRuntime) 17262 pointee_val = nullptr; 17263 } 17264 if ((err = ensure_complete_type(ira->codegen, target_type))) 17265 return ira->codegen->invalid_instruction; 17266 17267 switch (target_type->id) { 17268 case ZigTypeIdInvalid: 17269 zig_unreachable(); 17270 case ZigTypeIdMetaType: 17271 case ZigTypeIdVoid: 17272 case ZigTypeIdBool: 17273 case ZigTypeIdInt: 17274 case ZigTypeIdFloat: 17275 case ZigTypeIdComptimeFloat: 17276 case ZigTypeIdComptimeInt: 17277 case ZigTypeIdEnumLiteral: 17278 case ZigTypeIdPointer: 17279 case ZigTypeIdPromise: 17280 case ZigTypeIdFn: 17281 case ZigTypeIdErrorSet: { 17282 if (pointee_val) { 17283 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, nullptr); 17284 copy_const_val(&result->value, pointee_val, true); 17285 result->value.type = target_type; 17286 return result; 17287 } 17288 17289 IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); 17290 result->value.type = target_type; 17291 return result; 17292 } 17293 case ZigTypeIdUnion: { 17294 AstNode *decl_node = target_type->data.unionation.decl_node; 17295 if (!decl_node->data.container_decl.auto_enum && 17296 decl_node->data.container_decl.init_arg_expr == nullptr) 17297 { 17298 ErrorMsg *msg = ir_add_error(ira, target_value_ptr, 17299 buf_sprintf("switch on union which has no attached enum")); 17300 add_error_note(ira->codegen, msg, decl_node, 17301 buf_sprintf("consider 'union(enum)' here")); 17302 return ira->codegen->invalid_instruction; 17303 } 17304 ZigType *tag_type = target_type->data.unionation.tag_type; 17305 assert(tag_type != nullptr); 17306 assert(tag_type->id == ZigTypeIdEnum); 17307 if (pointee_val) { 17308 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, tag_type); 17309 bigint_init_bigint(&result->value.data.x_enum_tag, &pointee_val->data.x_union.tag); 17310 return result; 17311 } 17312 if (tag_type->data.enumeration.src_field_count == 1) { 17313 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, tag_type); 17314 TypeEnumField *only_field = &tag_type->data.enumeration.fields[0]; 17315 bigint_init_bigint(&result->value.data.x_enum_tag, &only_field->value); 17316 return result; 17317 } 17318 17319 IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); 17320 union_value->value.type = target_type; 17321 17322 IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, 17323 switch_target_instruction->base.source_node, union_value); 17324 union_tag_inst->value.type = tag_type; 17325 return union_tag_inst; 17326 } 17327 case ZigTypeIdEnum: { 17328 if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown))) 17329 return ira->codegen->invalid_instruction; 17330 if (target_type->data.enumeration.src_field_count < 2) { 17331 TypeEnumField *only_field = &target_type->data.enumeration.fields[0]; 17332 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type); 17333 bigint_init_bigint(&result->value.data.x_enum_tag, &only_field->value); 17334 return result; 17335 } 17336 17337 if (pointee_val) { 17338 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type); 17339 bigint_init_bigint(&result->value.data.x_enum_tag, &pointee_val->data.x_enum_tag); 17340 return result; 17341 } 17342 17343 IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr); 17344 enum_value->value.type = target_type; 17345 return enum_value; 17346 } 17347 case ZigTypeIdErrorUnion: 17348 case ZigTypeIdUnreachable: 17349 case ZigTypeIdArray: 17350 case ZigTypeIdStruct: 17351 case ZigTypeIdUndefined: 17352 case ZigTypeIdNull: 17353 case ZigTypeIdOptional: 17354 case ZigTypeIdBoundFn: 17355 case ZigTypeIdArgTuple: 17356 case ZigTypeIdOpaque: 17357 case ZigTypeIdVector: 17358 ir_add_error(ira, &switch_target_instruction->base, 17359 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); 17360 return ira->codegen->invalid_instruction; 17361 } 17362 zig_unreachable(); 17363 } 17364 17365 static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstructionSwitchVar *instruction) { 17366 IrInstruction *target_value_ptr = instruction->target_value_ptr->child; 17367 if (type_is_invalid(target_value_ptr->value.type)) 17368 return ira->codegen->invalid_instruction; 17369 17370 IrInstruction *prong_value = instruction->prong_value->child; 17371 if (type_is_invalid(prong_value->value.type)) 17372 return ira->codegen->invalid_instruction; 17373 17374 assert(target_value_ptr->value.type->id == ZigTypeIdPointer); 17375 ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type; 17376 if (target_type->id == ZigTypeIdUnion) { 17377 ZigType *enum_type = target_type->data.unionation.tag_type; 17378 assert(enum_type != nullptr); 17379 assert(enum_type->id == ZigTypeIdEnum); 17380 17381 IrInstruction *casted_prong_value = ir_implicit_cast(ira, prong_value, enum_type); 17382 if (type_is_invalid(casted_prong_value->value.type)) 17383 return ira->codegen->invalid_instruction; 17384 17385 ConstExprValue *prong_val = ir_resolve_const(ira, casted_prong_value, UndefBad); 17386 if (!prong_val) 17387 return ira->codegen->invalid_instruction; 17388 17389 TypeUnionField *field = find_union_field_by_tag(target_type, &prong_val->data.x_enum_tag); 17390 17391 if (instr_is_comptime(target_value_ptr)) { 17392 ConstExprValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad); 17393 if (!target_value_ptr) 17394 return ira->codegen->invalid_instruction; 17395 17396 ConstExprValue *pointee_val = const_ptr_pointee(ira, ira->codegen, target_val_ptr, instruction->base.source_node); 17397 if (pointee_val == nullptr) 17398 return ira->codegen->invalid_instruction; 17399 17400 IrInstruction *result = ir_const(ira, &instruction->base, 17401 get_pointer_to_type(ira->codegen, field->type_entry, 17402 target_val_ptr->type->data.pointer.is_const)); 17403 ConstExprValue *out_val = &result->value; 17404 out_val->data.x_ptr.special = ConstPtrSpecialRef; 17405 out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut; 17406 out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_union.payload; 17407 return result; 17408 } 17409 17410 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, 17411 instruction->base.scope, instruction->base.source_node, target_value_ptr, field); 17412 result->value.type = get_pointer_to_type(ira->codegen, field->type_entry, 17413 target_value_ptr->value.type->data.pointer.is_const); 17414 return result; 17415 } else { 17416 ir_add_error(ira, &instruction->base, 17417 buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); 17418 return ira->codegen->invalid_instruction; 17419 } 17420 } 17421 17422 static IrInstruction *ir_analyze_instruction_union_tag(IrAnalyze *ira, IrInstructionUnionTag *instruction) { 17423 IrInstruction *value = instruction->value->child; 17424 return ir_analyze_union_tag(ira, &instruction->base, value); 17425 } 17426 17427 static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) { 17428 Error err; 17429 17430 IrInstruction *name_value = import_instruction->name->child; 17431 Buf *import_target_str = ir_resolve_str(ira, name_value); 17432 if (!import_target_str) 17433 return ira->codegen->invalid_instruction; 17434 17435 AstNode *source_node = import_instruction->base.source_node; 17436 ZigType *import = source_node->owner; 17437 17438 Buf *import_target_path; 17439 Buf *search_dir; 17440 assert(import->data.structure.root_struct->package); 17441 ZigPackage *target_package; 17442 auto package_entry = import->data.structure.root_struct->package->package_table.maybe_get(import_target_str); 17443 SourceKind source_kind; 17444 if (package_entry) { 17445 target_package = package_entry->value; 17446 import_target_path = &target_package->root_src_path; 17447 search_dir = &target_package->root_src_dir; 17448 source_kind = SourceKindPkgMain; 17449 } else { 17450 // try it as a filename 17451 target_package = import->data.structure.root_struct->package; 17452 import_target_path = import_target_str; 17453 17454 // search relative to importing file 17455 search_dir = buf_alloc(); 17456 os_path_dirname(import->data.structure.root_struct->path, search_dir); 17457 17458 source_kind = SourceKindNonRoot; 17459 } 17460 17461 Buf full_path = BUF_INIT; 17462 os_path_join(search_dir, import_target_path, &full_path); 17463 17464 Buf *import_code = buf_alloc(); 17465 Buf *resolved_path = buf_alloc(); 17466 17467 Buf *resolve_paths[] = { &full_path, }; 17468 *resolved_path = os_path_resolve(resolve_paths, 1); 17469 17470 auto import_entry = ira->codegen->import_table.maybe_get(resolved_path); 17471 if (import_entry) { 17472 return ir_const_type(ira, &import_instruction->base, import_entry->value); 17473 } 17474 17475 if (source_kind == SourceKindNonRoot) { 17476 ZigPackage *cur_scope_pkg = scope_package(import_instruction->base.scope); 17477 Buf *pkg_root_src_dir = &cur_scope_pkg->root_src_dir; 17478 Buf resolved_root_src_dir = os_path_resolve(&pkg_root_src_dir, 1); 17479 if (!buf_starts_with_buf(resolved_path, &resolved_root_src_dir)) { 17480 ir_add_error_node(ira, source_node, 17481 buf_sprintf("import of file outside package path: '%s'", 17482 buf_ptr(import_target_path))); 17483 return ira->codegen->invalid_instruction; 17484 } 17485 } 17486 17487 if ((err = file_fetch(ira->codegen, resolved_path, import_code))) { 17488 if (err == ErrorFileNotFound) { 17489 ir_add_error_node(ira, source_node, 17490 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); 17491 return ira->codegen->invalid_instruction; 17492 } else { 17493 ir_add_error_node(ira, source_node, 17494 buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); 17495 return ira->codegen->invalid_instruction; 17496 } 17497 } 17498 17499 ZigType *target_import = add_source_file(ira->codegen, target_package, resolved_path, import_code, source_kind); 17500 17501 return ir_const_type(ira, &import_instruction->base, target_import); 17502 } 17503 17504 static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) { 17505 IrInstruction *value = ref_instruction->value->child; 17506 if (type_is_invalid(value->value.type)) 17507 return ira->codegen->invalid_instruction; 17508 return ir_get_ref(ira, &ref_instruction->base, value, ref_instruction->is_const, ref_instruction->is_volatile); 17509 } 17510 17511 static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, 17512 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) 17513 { 17514 Error err; 17515 assert(container_type->id == ZigTypeIdUnion); 17516 17517 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 17518 return ira->codegen->invalid_instruction; 17519 17520 if (instr_field_count != 1) { 17521 ir_add_error(ira, instruction, 17522 buf_sprintf("union initialization expects exactly one field")); 17523 return ira->codegen->invalid_instruction; 17524 } 17525 17526 IrInstructionContainerInitFieldsField *field = &fields[0]; 17527 IrInstruction *field_value = field->value->child; 17528 if (type_is_invalid(field_value->value.type)) 17529 return ira->codegen->invalid_instruction; 17530 17531 TypeUnionField *type_field = find_union_type_field(container_type, field->name); 17532 if (!type_field) { 17533 ir_add_error_node(ira, field->source_node, 17534 buf_sprintf("no member named '%s' in union '%s'", 17535 buf_ptr(field->name), buf_ptr(&container_type->name))); 17536 return ira->codegen->invalid_instruction; 17537 } 17538 17539 if (type_is_invalid(type_field->type_entry)) 17540 return ira->codegen->invalid_instruction; 17541 17542 IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); 17543 if (casted_field_value == ira->codegen->invalid_instruction) 17544 return ira->codegen->invalid_instruction; 17545 17546 if ((err = type_resolve(ira->codegen, casted_field_value->value.type, ResolveStatusZeroBitsKnown))) 17547 return ira->codegen->invalid_instruction; 17548 17549 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) 17550 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; 17551 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime || 17552 !type_has_bits(casted_field_value->value.type)) 17553 { 17554 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); 17555 if (!field_val) 17556 return ira->codegen->invalid_instruction; 17557 17558 IrInstruction *result = ir_const(ira, instruction, container_type); 17559 ConstExprValue *out_val = &result->value; 17560 out_val->data.x_union.payload = field_val; 17561 out_val->data.x_union.tag = type_field->enum_field->value; 17562 out_val->parent.id = ConstParentIdUnion; 17563 out_val->parent.data.p_union.union_val = out_val; 17564 17565 return result; 17566 } 17567 17568 IrInstruction *new_instruction = ir_build_union_init(&ira->new_irb, 17569 instruction->scope, instruction->source_node, 17570 container_type, type_field, casted_field_value); 17571 new_instruction->value.type = container_type; 17572 ir_add_alloca(ira, new_instruction, container_type); 17573 return new_instruction; 17574 } 17575 17576 static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, 17577 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) 17578 { 17579 Error err; 17580 if (container_type->id == ZigTypeIdUnion) { 17581 return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, fields); 17582 } 17583 if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { 17584 ir_add_error(ira, instruction, 17585 buf_sprintf("type '%s' does not support struct initialization syntax", 17586 buf_ptr(&container_type->name))); 17587 return ira->codegen->invalid_instruction; 17588 } 17589 17590 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 17591 return ira->codegen->invalid_instruction; 17592 17593 size_t actual_field_count = container_type->data.structure.src_field_count; 17594 17595 IrInstruction *first_non_const_instruction = nullptr; 17596 17597 AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); 17598 17599 IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count); 17600 17601 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) 17602 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; 17603 17604 ConstExprValue const_val = {}; 17605 const_val.special = ConstValSpecialStatic; 17606 const_val.type = container_type; 17607 // const_val.global_refs = allocate<ConstGlobalRefs>(1); 17608 const_val.data.x_struct.fields = create_const_vals(actual_field_count); 17609 for (size_t i = 0; i < instr_field_count; i += 1) { 17610 IrInstructionContainerInitFieldsField *field = &fields[i]; 17611 17612 IrInstruction *field_value = field->value->child; 17613 if (type_is_invalid(field_value->value.type)) 17614 return ira->codegen->invalid_instruction; 17615 17616 TypeStructField *type_field = find_struct_type_field(container_type, field->name); 17617 if (!type_field) { 17618 ir_add_error_node(ira, field->source_node, 17619 buf_sprintf("no member named '%s' in struct '%s'", 17620 buf_ptr(field->name), buf_ptr(&container_type->name))); 17621 return ira->codegen->invalid_instruction; 17622 } 17623 17624 if (type_is_invalid(type_field->type_entry)) 17625 return ira->codegen->invalid_instruction; 17626 17627 IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); 17628 if (casted_field_value == ira->codegen->invalid_instruction) 17629 return ira->codegen->invalid_instruction; 17630 17631 size_t field_index = type_field->src_index; 17632 AstNode *existing_assign_node = field_assign_nodes[field_index]; 17633 if (existing_assign_node) { 17634 ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field")); 17635 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); 17636 return ira->codegen->invalid_instruction; 17637 } 17638 field_assign_nodes[field_index] = field->source_node; 17639 17640 new_fields[field_index].value = casted_field_value; 17641 new_fields[field_index].type_struct_field = type_field; 17642 17643 if (const_val.special == ConstValSpecialStatic) { 17644 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) { 17645 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); 17646 if (!field_val) 17647 return ira->codegen->invalid_instruction; 17648 17649 copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true); 17650 } else { 17651 first_non_const_instruction = casted_field_value; 17652 const_val.special = ConstValSpecialRuntime; 17653 } 17654 } 17655 } 17656 17657 bool any_missing = false; 17658 for (size_t i = 0; i < actual_field_count; i += 1) { 17659 if (!field_assign_nodes[i]) { 17660 ir_add_error_node(ira, instruction->source_node, 17661 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name))); 17662 any_missing = true; 17663 } 17664 } 17665 if (any_missing) 17666 return ira->codegen->invalid_instruction; 17667 17668 if (const_val.special == ConstValSpecialStatic) { 17669 IrInstruction *result = ir_const(ira, instruction, nullptr); 17670 ConstExprValue *out_val = &result->value; 17671 copy_const_val(out_val, &const_val, false); 17672 out_val->type = container_type; 17673 17674 for (size_t i = 0; i < instr_field_count; i += 1) { 17675 ConstExprValue *field_val = &out_val->data.x_struct.fields[i]; 17676 ConstParent *parent = get_const_val_parent(ira->codegen, field_val); 17677 if (parent != nullptr) { 17678 parent->id = ConstParentIdStruct; 17679 parent->data.p_struct.field_index = i; 17680 parent->data.p_struct.struct_val = out_val; 17681 } 17682 } 17683 17684 return result; 17685 } 17686 17687 if (is_comptime) { 17688 ir_add_error_node(ira, first_non_const_instruction->source_node, 17689 buf_sprintf("unable to evaluate constant expression")); 17690 return ira->codegen->invalid_instruction; 17691 } 17692 17693 IrInstruction *new_instruction = ir_build_struct_init(&ira->new_irb, 17694 instruction->scope, instruction->source_node, 17695 container_type, actual_field_count, new_fields); 17696 new_instruction->value.type = container_type; 17697 ir_add_alloca(ira, new_instruction, container_type); 17698 return new_instruction; 17699 } 17700 17701 static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, 17702 IrInstructionContainerInitList *instruction) 17703 { 17704 Error err; 17705 17706 ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); 17707 if (type_is_invalid(container_type)) 17708 return ira->codegen->invalid_instruction; 17709 17710 size_t elem_count = instruction->item_count; 17711 17712 if (container_type->id == ZigTypeIdStruct && !is_slice(container_type) && elem_count == 0) { 17713 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 17714 0, nullptr); 17715 } else if (is_slice(container_type) || container_type->id == ZigTypeIdArray) { 17716 // array is same as slice init but we make a compile error if the length is wrong 17717 ZigType *child_type; 17718 if (container_type->id == ZigTypeIdArray) { 17719 child_type = container_type->data.array.child_type; 17720 if (container_type->data.array.len != elem_count) { 17721 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); 17722 17723 ir_add_error(ira, &instruction->base, 17724 buf_sprintf("expected %s literal, found %s literal", 17725 buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); 17726 return ira->codegen->invalid_instruction; 17727 } 17728 } else { 17729 ZigType *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry; 17730 assert(pointer_type->id == ZigTypeIdPointer); 17731 child_type = pointer_type->data.pointer.child_type; 17732 } 17733 17734 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) { 17735 return ira->codegen->invalid_instruction; 17736 } 17737 17738 ZigType *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count); 17739 17740 ConstExprValue const_val = {}; 17741 const_val.special = ConstValSpecialStatic; 17742 const_val.type = fixed_size_array_type; 17743 // const_val.global_refs = allocate<ConstGlobalRefs>(1); 17744 const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count); 17745 17746 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); 17747 17748 IrInstruction **new_items = allocate<IrInstruction *>(elem_count); 17749 17750 IrInstruction *first_non_const_instruction = nullptr; 17751 17752 for (size_t i = 0; i < elem_count; i += 1) { 17753 IrInstruction *arg_value = instruction->items[i]->child; 17754 if (type_is_invalid(arg_value->value.type)) 17755 return ira->codegen->invalid_instruction; 17756 17757 IrInstruction *casted_arg = ir_implicit_cast(ira, arg_value, child_type); 17758 if (casted_arg == ira->codegen->invalid_instruction) 17759 return ira->codegen->invalid_instruction; 17760 17761 new_items[i] = casted_arg; 17762 17763 if (const_val.special == ConstValSpecialStatic) { 17764 if (is_comptime || casted_arg->value.special != ConstValSpecialRuntime) { 17765 ConstExprValue *elem_val = ir_resolve_const(ira, casted_arg, UndefBad); 17766 if (!elem_val) 17767 return ira->codegen->invalid_instruction; 17768 17769 copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true); 17770 } else { 17771 first_non_const_instruction = casted_arg; 17772 const_val.special = ConstValSpecialRuntime; 17773 } 17774 } 17775 } 17776 17777 if (const_val.special == ConstValSpecialStatic) { 17778 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 17779 ConstExprValue *out_val = &result->value; 17780 copy_const_val(out_val, &const_val, false); 17781 result->value.type = fixed_size_array_type; 17782 for (size_t i = 0; i < elem_count; i += 1) { 17783 ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i]; 17784 ConstParent *parent = get_const_val_parent(ira->codegen, elem_val); 17785 if (parent != nullptr) { 17786 parent->id = ConstParentIdArray; 17787 parent->data.p_array.array_val = out_val; 17788 parent->data.p_array.elem_index = i; 17789 } 17790 } 17791 return result; 17792 } 17793 17794 if (is_comptime) { 17795 ir_add_error_node(ira, first_non_const_instruction->source_node, 17796 buf_sprintf("unable to evaluate constant expression")); 17797 return ira->codegen->invalid_instruction; 17798 } 17799 17800 IrInstruction *new_instruction = ir_build_container_init_list(&ira->new_irb, 17801 instruction->base.scope, instruction->base.source_node, 17802 nullptr, elem_count, new_items); 17803 new_instruction->value.type = fixed_size_array_type; 17804 ir_add_alloca(ira, new_instruction, fixed_size_array_type); 17805 return new_instruction; 17806 } else if (container_type->id == ZigTypeIdVoid) { 17807 if (elem_count != 0) { 17808 ir_add_error_node(ira, instruction->base.source_node, 17809 buf_sprintf("void expression expects no arguments")); 17810 return ira->codegen->invalid_instruction; 17811 } 17812 return ir_const_void(ira, &instruction->base); 17813 } else { 17814 ir_add_error_node(ira, instruction->base.source_node, 17815 buf_sprintf("type '%s' does not support array initialization", 17816 buf_ptr(&container_type->name))); 17817 return ira->codegen->invalid_instruction; 17818 } 17819 } 17820 17821 static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, 17822 IrInstructionContainerInitFields *instruction) 17823 { 17824 IrInstruction *container_type_value = instruction->container_type->child; 17825 ZigType *container_type = ir_resolve_type(ira, container_type_value); 17826 if (type_is_invalid(container_type)) 17827 return ira->codegen->invalid_instruction; 17828 17829 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 17830 instruction->field_count, instruction->fields); 17831 } 17832 17833 static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, 17834 IrInstructionCompileErr *instruction) 17835 { 17836 IrInstruction *msg_value = instruction->msg->child; 17837 Buf *msg_buf = ir_resolve_str(ira, msg_value); 17838 if (!msg_buf) 17839 return ira->codegen->invalid_instruction; 17840 17841 ErrorMsg *msg = ir_add_error(ira, &instruction->base, msg_buf); 17842 emit_error_notes_for_ref_stack(ira->codegen, msg); 17843 17844 return ira->codegen->invalid_instruction; 17845 } 17846 17847 static IrInstruction *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstructionCompileLog *instruction) { 17848 Buf buf = BUF_INIT; 17849 fprintf(stderr, "| "); 17850 for (size_t i = 0; i < instruction->msg_count; i += 1) { 17851 IrInstruction *msg = instruction->msg_list[i]->child; 17852 if (type_is_invalid(msg->value.type)) 17853 return ira->codegen->invalid_instruction; 17854 buf_resize(&buf, 0); 17855 render_const_value(ira->codegen, &buf, &msg->value); 17856 const char *comma_str = (i != 0) ? ", " : ""; 17857 fprintf(stderr, "%s%s", comma_str, buf_ptr(&buf)); 17858 } 17859 fprintf(stderr, "\n"); 17860 17861 auto *expr = &instruction->base.source_node->data.fn_call_expr; 17862 if (!expr->seen) { 17863 // Here we bypass higher level functions such as ir_add_error because we do not want 17864 // invalidate_exec to be called. 17865 add_node_error(ira->codegen, instruction->base.source_node, buf_sprintf("found compile log statement")); 17866 } 17867 expr->seen = true; 17868 17869 return ir_const_void(ira, &instruction->base); 17870 } 17871 17872 static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstructionErrName *instruction) { 17873 IrInstruction *value = instruction->value->child; 17874 if (type_is_invalid(value->value.type)) 17875 return ira->codegen->invalid_instruction; 17876 17877 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_global_error_set); 17878 if (type_is_invalid(casted_value->value.type)) 17879 return ira->codegen->invalid_instruction; 17880 17881 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 17882 true, false, PtrLenUnknown, 0, 0, 0, false); 17883 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 17884 if (casted_value->value.special == ConstValSpecialStatic) { 17885 ErrorTableEntry *err = casted_value->value.data.x_err_set; 17886 if (!err->cached_error_name_val) { 17887 ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name); 17888 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); 17889 } 17890 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 17891 copy_const_val(&result->value, err->cached_error_name_val, true); 17892 result->value.type = str_type; 17893 return result; 17894 } 17895 17896 ira->codegen->generate_error_name_table = true; 17897 17898 IrInstruction *result = ir_build_err_name(&ira->new_irb, 17899 instruction->base.scope, instruction->base.source_node, value); 17900 result->value.type = str_type; 17901 return result; 17902 } 17903 17904 static IrInstruction *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionTagName *instruction) { 17905 Error err; 17906 IrInstruction *target = instruction->target->child; 17907 if (type_is_invalid(target->value.type)) 17908 return ira->codegen->invalid_instruction; 17909 17910 assert(target->value.type->id == ZigTypeIdEnum); 17911 17912 if (instr_is_comptime(target)) { 17913 if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusZeroBitsKnown))) 17914 return ira->codegen->invalid_instruction; 17915 TypeEnumField *field = find_enum_field_by_tag(target->value.type, &target->value.data.x_bigint); 17916 ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name); 17917 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 17918 init_const_slice(ira->codegen, &result->value, array_val, 0, buf_len(field->name), true); 17919 return result; 17920 } 17921 17922 IrInstruction *result = ir_build_tag_name(&ira->new_irb, instruction->base.scope, 17923 instruction->base.source_node, target); 17924 ZigType *u8_ptr_type = get_pointer_to_type_extra( 17925 ira->codegen, ira->codegen->builtin_types.entry_u8, 17926 true, false, PtrLenUnknown, 17927 0, 0, 0, false); 17928 result->value.type = get_slice_type(ira->codegen, u8_ptr_type); 17929 return result; 17930 } 17931 17932 static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, 17933 IrInstructionFieldParentPtr *instruction) 17934 { 17935 Error err; 17936 IrInstruction *type_value = instruction->type_value->child; 17937 ZigType *container_type = ir_resolve_type(ira, type_value); 17938 if (type_is_invalid(container_type)) 17939 return ira->codegen->invalid_instruction; 17940 17941 IrInstruction *field_name_value = instruction->field_name->child; 17942 Buf *field_name = ir_resolve_str(ira, field_name_value); 17943 if (!field_name) 17944 return ira->codegen->invalid_instruction; 17945 17946 IrInstruction *field_ptr = instruction->field_ptr->child; 17947 if (type_is_invalid(field_ptr->value.type)) 17948 return ira->codegen->invalid_instruction; 17949 17950 if (container_type->id != ZigTypeIdStruct) { 17951 ir_add_error(ira, type_value, 17952 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 17953 return ira->codegen->invalid_instruction; 17954 } 17955 17956 if ((err = ensure_complete_type(ira->codegen, container_type))) 17957 return ira->codegen->invalid_instruction; 17958 17959 TypeStructField *field = find_struct_type_field(container_type, field_name); 17960 if (field == nullptr) { 17961 ir_add_error(ira, field_name_value, 17962 buf_sprintf("struct '%s' has no field '%s'", 17963 buf_ptr(&container_type->name), buf_ptr(field_name))); 17964 return ira->codegen->invalid_instruction; 17965 } 17966 17967 if (field_ptr->value.type->id != ZigTypeIdPointer) { 17968 ir_add_error(ira, field_ptr, 17969 buf_sprintf("expected pointer, found '%s'", buf_ptr(&field_ptr->value.type->name))); 17970 return ira->codegen->invalid_instruction; 17971 } 17972 17973 bool is_packed = (container_type->data.structure.layout == ContainerLayoutPacked); 17974 uint32_t field_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 17975 uint32_t parent_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, container_type); 17976 17977 ZigType *field_ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, 17978 field_ptr->value.type->data.pointer.is_const, 17979 field_ptr->value.type->data.pointer.is_volatile, 17980 PtrLenSingle, 17981 field_ptr_align, 0, 0, false); 17982 IrInstruction *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type); 17983 if (type_is_invalid(casted_field_ptr->value.type)) 17984 return ira->codegen->invalid_instruction; 17985 17986 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, container_type, 17987 casted_field_ptr->value.type->data.pointer.is_const, 17988 casted_field_ptr->value.type->data.pointer.is_volatile, 17989 PtrLenSingle, 17990 parent_ptr_align, 0, 0, false); 17991 17992 if (instr_is_comptime(casted_field_ptr)) { 17993 ConstExprValue *field_ptr_val = ir_resolve_const(ira, casted_field_ptr, UndefBad); 17994 if (!field_ptr_val) 17995 return ira->codegen->invalid_instruction; 17996 17997 if (field_ptr_val->data.x_ptr.special != ConstPtrSpecialBaseStruct) { 17998 ir_add_error(ira, field_ptr, buf_sprintf("pointer value not based on parent struct")); 17999 return ira->codegen->invalid_instruction; 18000 } 18001 18002 size_t ptr_field_index = field_ptr_val->data.x_ptr.data.base_struct.field_index; 18003 if (ptr_field_index != field->src_index) { 18004 ir_add_error(ira, &instruction->base, 18005 buf_sprintf("field '%s' has index %" ZIG_PRI_usize " but pointer value is index %" ZIG_PRI_usize " of struct '%s'", 18006 buf_ptr(field->name), field->src_index, 18007 ptr_field_index, buf_ptr(&container_type->name))); 18008 return ira->codegen->invalid_instruction; 18009 } 18010 18011 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 18012 ConstExprValue *out_val = &result->value; 18013 out_val->data.x_ptr.special = ConstPtrSpecialRef; 18014 out_val->data.x_ptr.data.ref.pointee = field_ptr_val->data.x_ptr.data.base_struct.struct_val; 18015 out_val->data.x_ptr.mut = field_ptr_val->data.x_ptr.mut; 18016 return result; 18017 } 18018 18019 IrInstruction *result = ir_build_field_parent_ptr(&ira->new_irb, instruction->base.scope, 18020 instruction->base.source_node, type_value, field_name_value, casted_field_ptr, field); 18021 result->value.type = result_type; 18022 return result; 18023 } 18024 18025 static TypeStructField *validate_byte_offset(IrAnalyze *ira, 18026 IrInstruction *type_value, 18027 IrInstruction *field_name_value, 18028 size_t *byte_offset) 18029 { 18030 ZigType *container_type = ir_resolve_type(ira, type_value); 18031 if (type_is_invalid(container_type)) 18032 return nullptr; 18033 18034 Error err; 18035 if ((err = ensure_complete_type(ira->codegen, container_type))) 18036 return nullptr; 18037 18038 Buf *field_name = ir_resolve_str(ira, field_name_value); 18039 if (!field_name) 18040 return nullptr; 18041 18042 if (container_type->id != ZigTypeIdStruct) { 18043 ir_add_error(ira, type_value, 18044 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 18045 return nullptr; 18046 } 18047 18048 TypeStructField *field = find_struct_type_field(container_type, field_name); 18049 if (field == nullptr) { 18050 ir_add_error(ira, field_name_value, 18051 buf_sprintf("struct '%s' has no field '%s'", 18052 buf_ptr(&container_type->name), buf_ptr(field_name))); 18053 return nullptr; 18054 } 18055 18056 if (!type_has_bits(field->type_entry)) { 18057 ir_add_error(ira, field_name_value, 18058 buf_sprintf("zero-bit field '%s' in struct '%s' has no offset", 18059 buf_ptr(field_name), buf_ptr(&container_type->name))); 18060 return nullptr; 18061 } 18062 18063 *byte_offset = field->offset; 18064 return field; 18065 } 18066 18067 static IrInstruction *ir_analyze_instruction_byte_offset_of(IrAnalyze *ira, 18068 IrInstructionByteOffsetOf *instruction) 18069 { 18070 IrInstruction *type_value = instruction->type_value->child; 18071 if (type_is_invalid(type_value->value.type)) 18072 return ira->codegen->invalid_instruction; 18073 18074 IrInstruction *field_name_value = instruction->field_name->child; 18075 size_t byte_offset = 0; 18076 if (!validate_byte_offset(ira, type_value, field_name_value, &byte_offset)) 18077 return ira->codegen->invalid_instruction; 18078 18079 18080 return ir_const_unsigned(ira, &instruction->base, byte_offset); 18081 } 18082 18083 static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, 18084 IrInstructionBitOffsetOf *instruction) 18085 { 18086 IrInstruction *type_value = instruction->type_value->child; 18087 if (type_is_invalid(type_value->value.type)) 18088 return ira->codegen->invalid_instruction; 18089 IrInstruction *field_name_value = instruction->field_name->child; 18090 size_t byte_offset = 0; 18091 TypeStructField *field = nullptr; 18092 if (!(field = validate_byte_offset(ira, type_value, field_name_value, &byte_offset))) 18093 return ira->codegen->invalid_instruction; 18094 18095 size_t bit_offset = byte_offset * 8 + field->bit_offset_in_host; 18096 return ir_const_unsigned(ira, &instruction->base, bit_offset); 18097 } 18098 18099 static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { 18100 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); 18101 emit_error_notes_for_ref_stack(ira->codegen, msg); 18102 return ira->codegen->invalid_instruction; 18103 } 18104 18105 static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { 18106 Buf *field_name_buf; 18107 18108 assert(type != nullptr && !type_is_invalid(type)); 18109 // Check for our field by creating a buffer in place then using the comma operator to free it so that we don't 18110 // leak memory in debug mode. 18111 assert(find_struct_type_field(type, field_name_buf = buf_create_from_str(field_name))->src_index == index && 18112 (buf_deinit(field_name_buf), true)); 18113 } 18114 18115 static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) { 18116 Error err; 18117 ConstExprValue *type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); 18118 assert(type_info_var->type->id == ZigTypeIdMetaType); 18119 ZigType *type_info_type = type_info_var->data.x_type; 18120 assert(type_info_type->id == ZigTypeIdUnion); 18121 if ((err = type_resolve(ira->codegen, type_info_type, ResolveStatusSizeKnown))) { 18122 zig_unreachable(); 18123 } 18124 18125 if (type_name == nullptr && root == nullptr) 18126 return type_info_type; 18127 else if (type_name == nullptr) 18128 return root; 18129 18130 ZigType *root_type = (root == nullptr) ? type_info_type : root; 18131 18132 ScopeDecls *type_info_scope = get_container_scope(root_type); 18133 assert(type_info_scope != nullptr); 18134 18135 Buf field_name = BUF_INIT; 18136 buf_init_from_str(&field_name, type_name); 18137 auto entry = type_info_scope->decl_table.get(&field_name); 18138 buf_deinit(&field_name); 18139 18140 TldVar *tld = (TldVar *)entry; 18141 assert(tld->base.id == TldIdVar); 18142 18143 ZigVar *var = tld->var; 18144 18145 if ((err = ensure_complete_type(ira->codegen, var->const_value->type))) 18146 return ira->codegen->builtin_types.entry_invalid; 18147 18148 assert(var->const_value->type->id == ZigTypeIdMetaType); 18149 return var->const_value->data.x_type; 18150 } 18151 18152 static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val, 18153 ScopeDecls *decls_scope) 18154 { 18155 Error err; 18156 ZigType *type_info_definition_type = ir_type_info_get_type(ira, "Definition", nullptr); 18157 if ((err = type_resolve(ira->codegen, type_info_definition_type, ResolveStatusSizeKnown))) 18158 return err; 18159 18160 ensure_field_index(type_info_definition_type, "name", 0); 18161 ensure_field_index(type_info_definition_type, "is_pub", 1); 18162 ensure_field_index(type_info_definition_type, "data", 2); 18163 18164 ZigType *type_info_definition_data_type = ir_type_info_get_type(ira, "Data", type_info_definition_type); 18165 if ((err = ensure_complete_type(ira->codegen, type_info_definition_data_type))) 18166 return err; 18167 18168 ZigType *type_info_fn_def_type = ir_type_info_get_type(ira, "FnDef", type_info_definition_data_type); 18169 if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_type))) 18170 return err; 18171 18172 ZigType *type_info_fn_def_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_def_type); 18173 if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_inline_type))) 18174 return err; 18175 18176 // Loop through our definitions once to figure out how many definitions we will generate info for. 18177 auto decl_it = decls_scope->decl_table.entry_iterator(); 18178 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; 18179 int definition_count = 0; 18180 18181 while ((curr_entry = decl_it.next()) != nullptr) { 18182 // If the definition is unresolved, force it to be resolved again. 18183 if (curr_entry->value->resolution == TldResolutionUnresolved) { 18184 resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node); 18185 if (curr_entry->value->resolution != TldResolutionOk) { 18186 return ErrorSemanticAnalyzeFail; 18187 } 18188 } 18189 18190 // Skip comptime blocks and test functions. 18191 if (curr_entry->value->id != TldIdCompTime) { 18192 if (curr_entry->value->id == TldIdFn) { 18193 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 18194 if (fn_entry->is_test) 18195 continue; 18196 } 18197 18198 definition_count += 1; 18199 } 18200 } 18201 18202 ConstExprValue *definition_array = create_const_vals(1); 18203 definition_array->special = ConstValSpecialStatic; 18204 definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count); 18205 definition_array->data.x_array.special = ConstArraySpecialNone; 18206 definition_array->data.x_array.data.s_none.elements = create_const_vals(definition_count); 18207 init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false); 18208 18209 // Loop through the definitions and generate info. 18210 decl_it = decls_scope->decl_table.entry_iterator(); 18211 curr_entry = nullptr; 18212 int definition_index = 0; 18213 while ((curr_entry = decl_it.next()) != nullptr) { 18214 // Skip comptime blocks and test functions. 18215 if (curr_entry->value->id == TldIdCompTime) { 18216 continue; 18217 } else if (curr_entry->value->id == TldIdFn) { 18218 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 18219 if (fn_entry->is_test) 18220 continue; 18221 } 18222 18223 ConstExprValue *definition_val = &definition_array->data.x_array.data.s_none.elements[definition_index]; 18224 18225 definition_val->special = ConstValSpecialStatic; 18226 definition_val->type = type_info_definition_type; 18227 18228 ConstExprValue *inner_fields = create_const_vals(3); 18229 ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key); 18230 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(curr_entry->key), true); 18231 inner_fields[1].special = ConstValSpecialStatic; 18232 inner_fields[1].type = ira->codegen->builtin_types.entry_bool; 18233 inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub; 18234 inner_fields[2].special = ConstValSpecialStatic; 18235 inner_fields[2].type = type_info_definition_data_type; 18236 inner_fields[2].parent.id = ConstParentIdStruct; 18237 inner_fields[2].parent.data.p_struct.struct_val = definition_val; 18238 inner_fields[2].parent.data.p_struct.field_index = 1; 18239 18240 switch (curr_entry->value->id) { 18241 case TldIdVar: 18242 { 18243 ZigVar *var = ((TldVar *)curr_entry->value)->var; 18244 if ((err = ensure_complete_type(ira->codegen, var->const_value->type))) 18245 return ErrorSemanticAnalyzeFail; 18246 18247 if (var->const_value->type->id == ZigTypeIdMetaType) { 18248 // We have a variable of type 'type', so it's actually a type definition. 18249 // 0: Data.Type: type 18250 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); 18251 inner_fields[2].data.x_union.payload = var->const_value; 18252 } else { 18253 // We have a variable of another type, so we store the type of the variable. 18254 // 1: Data.Var: type 18255 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 1); 18256 18257 ConstExprValue *payload = create_const_vals(1); 18258 payload->type = ira->codegen->builtin_types.entry_type; 18259 payload->data.x_type = var->const_value->type; 18260 18261 inner_fields[2].data.x_union.payload = payload; 18262 } 18263 18264 break; 18265 } 18266 case TldIdFn: 18267 { 18268 // 2: Data.Fn: Data.FnDef 18269 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2); 18270 18271 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 18272 assert(!fn_entry->is_test); 18273 18274 if (fn_entry->type_entry == nullptr) { 18275 ir_error_dependency_loop(ira, source_instr); 18276 return ErrorSemanticAnalyzeFail; 18277 } 18278 18279 AstNodeFnProto *fn_node = (AstNodeFnProto *)(fn_entry->proto_node); 18280 18281 ConstExprValue *fn_def_val = create_const_vals(1); 18282 fn_def_val->special = ConstValSpecialStatic; 18283 fn_def_val->type = type_info_fn_def_type; 18284 fn_def_val->parent.id = ConstParentIdUnion; 18285 fn_def_val->parent.data.p_union.union_val = &inner_fields[2]; 18286 18287 ConstExprValue *fn_def_fields = create_const_vals(9); 18288 fn_def_val->data.x_struct.fields = fn_def_fields; 18289 18290 // fn_type: type 18291 ensure_field_index(fn_def_val->type, "fn_type", 0); 18292 fn_def_fields[0].special = ConstValSpecialStatic; 18293 fn_def_fields[0].type = ira->codegen->builtin_types.entry_type; 18294 fn_def_fields[0].data.x_type = fn_entry->type_entry; 18295 // inline_type: Data.FnDef.Inline 18296 ensure_field_index(fn_def_val->type, "inline_type", 1); 18297 fn_def_fields[1].special = ConstValSpecialStatic; 18298 fn_def_fields[1].type = type_info_fn_def_inline_type; 18299 bigint_init_unsigned(&fn_def_fields[1].data.x_enum_tag, fn_entry->fn_inline); 18300 // calling_convention: TypeInfo.CallingConvention 18301 ensure_field_index(fn_def_val->type, "calling_convention", 2); 18302 fn_def_fields[2].special = ConstValSpecialStatic; 18303 fn_def_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); 18304 bigint_init_unsigned(&fn_def_fields[2].data.x_enum_tag, fn_node->cc); 18305 // is_var_args: bool 18306 ensure_field_index(fn_def_val->type, "is_var_args", 3); 18307 bool is_varargs = fn_node->is_var_args; 18308 fn_def_fields[3].special = ConstValSpecialStatic; 18309 fn_def_fields[3].type = ira->codegen->builtin_types.entry_bool; 18310 fn_def_fields[3].data.x_bool = is_varargs; 18311 // is_extern: bool 18312 ensure_field_index(fn_def_val->type, "is_extern", 4); 18313 fn_def_fields[4].special = ConstValSpecialStatic; 18314 fn_def_fields[4].type = ira->codegen->builtin_types.entry_bool; 18315 fn_def_fields[4].data.x_bool = fn_node->is_extern; 18316 // is_export: bool 18317 ensure_field_index(fn_def_val->type, "is_export", 5); 18318 fn_def_fields[5].special = ConstValSpecialStatic; 18319 fn_def_fields[5].type = ira->codegen->builtin_types.entry_bool; 18320 fn_def_fields[5].data.x_bool = fn_node->is_export; 18321 // lib_name: ?[]const u8 18322 ensure_field_index(fn_def_val->type, "lib_name", 6); 18323 fn_def_fields[6].special = ConstValSpecialStatic; 18324 ZigType *u8_ptr = get_pointer_to_type_extra( 18325 ira->codegen, ira->codegen->builtin_types.entry_u8, 18326 true, false, PtrLenUnknown, 18327 0, 0, 0, false); 18328 fn_def_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); 18329 if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) { 18330 fn_def_fields[6].data.x_optional = create_const_vals(1); 18331 ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name); 18332 init_const_slice(ira->codegen, fn_def_fields[6].data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true); 18333 } else { 18334 fn_def_fields[6].data.x_optional = nullptr; 18335 } 18336 // return_type: type 18337 ensure_field_index(fn_def_val->type, "return_type", 7); 18338 fn_def_fields[7].special = ConstValSpecialStatic; 18339 fn_def_fields[7].type = ira->codegen->builtin_types.entry_type; 18340 fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; 18341 // arg_names: [][] const u8 18342 ensure_field_index(fn_def_val->type, "arg_names", 8); 18343 size_t fn_arg_count = fn_entry->variable_list.length; 18344 ConstExprValue *fn_arg_name_array = create_const_vals(1); 18345 fn_arg_name_array->special = ConstValSpecialStatic; 18346 fn_arg_name_array->type = get_array_type(ira->codegen, 18347 get_slice_type(ira->codegen, u8_ptr), fn_arg_count); 18348 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; 18349 fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); 18350 18351 init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false); 18352 18353 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { 18354 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); 18355 ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index]; 18356 ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name); 18357 init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true); 18358 fn_arg_name_val->parent.id = ConstParentIdArray; 18359 fn_arg_name_val->parent.data.p_array.array_val = fn_arg_name_array; 18360 fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index; 18361 } 18362 18363 inner_fields[2].data.x_union.payload = fn_def_val; 18364 break; 18365 } 18366 case TldIdContainer: 18367 { 18368 ZigType *type_entry = ((TldContainer *)curr_entry->value)->type_entry; 18369 if ((err = ensure_complete_type(ira->codegen, type_entry))) 18370 return ErrorSemanticAnalyzeFail; 18371 18372 // This is a type. 18373 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); 18374 18375 ConstExprValue *payload = create_const_vals(1); 18376 payload->type = ira->codegen->builtin_types.entry_type; 18377 payload->data.x_type = type_entry; 18378 18379 inner_fields[2].data.x_union.payload = payload; 18380 18381 break; 18382 } 18383 default: 18384 zig_unreachable(); 18385 } 18386 18387 definition_val->data.x_struct.fields = inner_fields; 18388 definition_index++; 18389 } 18390 18391 assert(definition_index == definition_count); 18392 return ErrorNone; 18393 } 18394 18395 static uint32_t ptr_len_to_size_enum_index(PtrLen ptr_len) { 18396 switch (ptr_len) { 18397 case PtrLenSingle: 18398 return 0; 18399 case PtrLenUnknown: 18400 return 1; 18401 case PtrLenC: 18402 return 3; 18403 } 18404 zig_unreachable(); 18405 } 18406 18407 static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) { 18408 Error err; 18409 ZigType *attrs_type; 18410 uint32_t size_enum_index; 18411 if (is_slice(ptr_type_entry)) { 18412 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index].type_entry; 18413 size_enum_index = 2; 18414 } else if (ptr_type_entry->id == ZigTypeIdPointer) { 18415 attrs_type = ptr_type_entry; 18416 size_enum_index = ptr_len_to_size_enum_index(ptr_type_entry->data.pointer.ptr_len); 18417 } else { 18418 zig_unreachable(); 18419 } 18420 18421 if ((err = type_resolve(ira->codegen, attrs_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 18422 return nullptr; 18423 18424 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 18425 assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_type)); 18426 18427 ConstExprValue *result = create_const_vals(1); 18428 result->special = ConstValSpecialStatic; 18429 result->type = type_info_pointer_type; 18430 18431 ConstExprValue *fields = create_const_vals(6); 18432 result->data.x_struct.fields = fields; 18433 18434 // size: Size 18435 ensure_field_index(result->type, "size", 0); 18436 ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); 18437 assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_size_type)); 18438 fields[0].special = ConstValSpecialStatic; 18439 fields[0].type = type_info_pointer_size_type; 18440 bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index); 18441 18442 // is_const: bool 18443 ensure_field_index(result->type, "is_const", 1); 18444 fields[1].special = ConstValSpecialStatic; 18445 fields[1].type = ira->codegen->builtin_types.entry_bool; 18446 fields[1].data.x_bool = attrs_type->data.pointer.is_const; 18447 // is_volatile: bool 18448 ensure_field_index(result->type, "is_volatile", 2); 18449 fields[2].special = ConstValSpecialStatic; 18450 fields[2].type = ira->codegen->builtin_types.entry_bool; 18451 fields[2].data.x_bool = attrs_type->data.pointer.is_volatile; 18452 // alignment: u32 18453 ensure_field_index(result->type, "alignment", 3); 18454 fields[3].special = ConstValSpecialStatic; 18455 fields[3].type = ira->codegen->builtin_types.entry_num_lit_int; 18456 bigint_init_unsigned(&fields[3].data.x_bigint, get_ptr_align(ira->codegen, attrs_type)); 18457 // child: type 18458 ensure_field_index(result->type, "child", 4); 18459 fields[4].special = ConstValSpecialStatic; 18460 fields[4].type = ira->codegen->builtin_types.entry_type; 18461 fields[4].data.x_type = attrs_type->data.pointer.child_type; 18462 // is_allowzero: bool 18463 ensure_field_index(result->type, "is_allowzero", 5); 18464 fields[5].special = ConstValSpecialStatic; 18465 fields[5].type = ira->codegen->builtin_types.entry_bool; 18466 fields[5].data.x_bool = attrs_type->data.pointer.allow_zero; 18467 18468 return result; 18469 }; 18470 18471 static void make_enum_field_val(IrAnalyze *ira, ConstExprValue *enum_field_val, TypeEnumField *enum_field, 18472 ZigType *type_info_enum_field_type) 18473 { 18474 enum_field_val->special = ConstValSpecialStatic; 18475 enum_field_val->type = type_info_enum_field_type; 18476 18477 ConstExprValue *inner_fields = create_const_vals(2); 18478 inner_fields[1].special = ConstValSpecialStatic; 18479 inner_fields[1].type = ira->codegen->builtin_types.entry_num_lit_int; 18480 18481 ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name); 18482 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(enum_field->name), true); 18483 18484 bigint_init_bigint(&inner_fields[1].data.x_bigint, &enum_field->value); 18485 18486 enum_field_val->data.x_struct.fields = inner_fields; 18487 } 18488 18489 static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr, ZigType *type_entry, 18490 ConstExprValue **out) 18491 { 18492 Error err; 18493 assert(type_entry != nullptr); 18494 assert(!type_is_invalid(type_entry)); 18495 18496 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 18497 return err; 18498 18499 auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); 18500 if (entry != nullptr) { 18501 *out = entry->value; 18502 return ErrorNone; 18503 } 18504 18505 ConstExprValue *result = nullptr; 18506 switch (type_entry->id) { 18507 case ZigTypeIdInvalid: 18508 zig_unreachable(); 18509 case ZigTypeIdMetaType: 18510 case ZigTypeIdVoid: 18511 case ZigTypeIdBool: 18512 case ZigTypeIdUnreachable: 18513 case ZigTypeIdComptimeFloat: 18514 case ZigTypeIdComptimeInt: 18515 case ZigTypeIdEnumLiteral: 18516 case ZigTypeIdUndefined: 18517 case ZigTypeIdNull: 18518 case ZigTypeIdArgTuple: 18519 case ZigTypeIdOpaque: 18520 result = &ira->codegen->const_void_val; 18521 break; 18522 case ZigTypeIdInt: 18523 { 18524 result = create_const_vals(1); 18525 result->special = ConstValSpecialStatic; 18526 result->type = ir_type_info_get_type(ira, "Int", nullptr); 18527 18528 ConstExprValue *fields = create_const_vals(2); 18529 result->data.x_struct.fields = fields; 18530 18531 // is_signed: bool 18532 ensure_field_index(result->type, "is_signed", 0); 18533 fields[0].special = ConstValSpecialStatic; 18534 fields[0].type = ira->codegen->builtin_types.entry_bool; 18535 fields[0].data.x_bool = type_entry->data.integral.is_signed; 18536 // bits: u8 18537 ensure_field_index(result->type, "bits", 1); 18538 fields[1].special = ConstValSpecialStatic; 18539 fields[1].type = ira->codegen->builtin_types.entry_num_lit_int; 18540 bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); 18541 18542 break; 18543 } 18544 case ZigTypeIdFloat: 18545 { 18546 result = create_const_vals(1); 18547 result->special = ConstValSpecialStatic; 18548 result->type = ir_type_info_get_type(ira, "Float", nullptr); 18549 18550 ConstExprValue *fields = create_const_vals(1); 18551 result->data.x_struct.fields = fields; 18552 18553 // bits: u8 18554 ensure_field_index(result->type, "bits", 0); 18555 fields[0].special = ConstValSpecialStatic; 18556 fields[0].type = ira->codegen->builtin_types.entry_num_lit_int; 18557 bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); 18558 18559 break; 18560 } 18561 case ZigTypeIdPointer: 18562 { 18563 result = create_ptr_like_type_info(ira, type_entry); 18564 if (result == nullptr) 18565 return ErrorSemanticAnalyzeFail; 18566 break; 18567 } 18568 case ZigTypeIdArray: 18569 { 18570 result = create_const_vals(1); 18571 result->special = ConstValSpecialStatic; 18572 result->type = ir_type_info_get_type(ira, "Array", nullptr); 18573 18574 ConstExprValue *fields = create_const_vals(2); 18575 result->data.x_struct.fields = fields; 18576 18577 // len: usize 18578 ensure_field_index(result->type, "len", 0); 18579 fields[0].special = ConstValSpecialStatic; 18580 fields[0].type = ira->codegen->builtin_types.entry_num_lit_int; 18581 bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); 18582 // child: type 18583 ensure_field_index(result->type, "child", 1); 18584 fields[1].special = ConstValSpecialStatic; 18585 fields[1].type = ira->codegen->builtin_types.entry_type; 18586 fields[1].data.x_type = type_entry->data.array.child_type; 18587 18588 break; 18589 } 18590 case ZigTypeIdVector: { 18591 result = create_const_vals(1); 18592 result->special = ConstValSpecialStatic; 18593 result->type = ir_type_info_get_type(ira, "Vector", nullptr); 18594 18595 ConstExprValue *fields = create_const_vals(2); 18596 result->data.x_struct.fields = fields; 18597 18598 // len: usize 18599 ensure_field_index(result->type, "len", 0); 18600 fields[0].special = ConstValSpecialStatic; 18601 fields[0].type = ira->codegen->builtin_types.entry_num_lit_int; 18602 bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.vector.len); 18603 // child: type 18604 ensure_field_index(result->type, "child", 1); 18605 fields[1].special = ConstValSpecialStatic; 18606 fields[1].type = ira->codegen->builtin_types.entry_type; 18607 fields[1].data.x_type = type_entry->data.vector.elem_type; 18608 18609 break; 18610 } 18611 case ZigTypeIdOptional: 18612 { 18613 result = create_const_vals(1); 18614 result->special = ConstValSpecialStatic; 18615 result->type = ir_type_info_get_type(ira, "Optional", nullptr); 18616 18617 ConstExprValue *fields = create_const_vals(1); 18618 result->data.x_struct.fields = fields; 18619 18620 // child: type 18621 ensure_field_index(result->type, "child", 0); 18622 fields[0].special = ConstValSpecialStatic; 18623 fields[0].type = ira->codegen->builtin_types.entry_type; 18624 fields[0].data.x_type = type_entry->data.maybe.child_type; 18625 18626 break; 18627 } 18628 case ZigTypeIdPromise: 18629 { 18630 result = create_const_vals(1); 18631 result->special = ConstValSpecialStatic; 18632 result->type = ir_type_info_get_type(ira, "Promise", nullptr); 18633 18634 ConstExprValue *fields = create_const_vals(1); 18635 result->data.x_struct.fields = fields; 18636 18637 // child: ?type 18638 ensure_field_index(result->type, "child", 0); 18639 fields[0].special = ConstValSpecialStatic; 18640 fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 18641 18642 if (type_entry->data.promise.result_type == nullptr) 18643 fields[0].data.x_optional = nullptr; 18644 else { 18645 ConstExprValue *child_type = create_const_vals(1); 18646 child_type->special = ConstValSpecialStatic; 18647 child_type->type = ira->codegen->builtin_types.entry_type; 18648 child_type->data.x_type = type_entry->data.promise.result_type; 18649 fields[0].data.x_optional = child_type; 18650 } 18651 18652 break; 18653 } 18654 case ZigTypeIdEnum: 18655 { 18656 result = create_const_vals(1); 18657 result->special = ConstValSpecialStatic; 18658 result->type = ir_type_info_get_type(ira, "Enum", nullptr); 18659 18660 ConstExprValue *fields = create_const_vals(4); 18661 result->data.x_struct.fields = fields; 18662 18663 // layout: ContainerLayout 18664 ensure_field_index(result->type, "layout", 0); 18665 fields[0].special = ConstValSpecialStatic; 18666 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 18667 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.enumeration.layout); 18668 // tag_type: type 18669 ensure_field_index(result->type, "tag_type", 1); 18670 fields[1].special = ConstValSpecialStatic; 18671 fields[1].type = ira->codegen->builtin_types.entry_type; 18672 fields[1].data.x_type = type_entry->data.enumeration.tag_int_type; 18673 // fields: []TypeInfo.EnumField 18674 ensure_field_index(result->type, "fields", 2); 18675 18676 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 18677 if ((err = type_resolve(ira->codegen, type_info_enum_field_type, ResolveStatusSizeKnown))) { 18678 zig_unreachable(); 18679 } 18680 uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; 18681 18682 ConstExprValue *enum_field_array = create_const_vals(1); 18683 enum_field_array->special = ConstValSpecialStatic; 18684 enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count); 18685 enum_field_array->data.x_array.special = ConstArraySpecialNone; 18686 enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count); 18687 18688 init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false); 18689 18690 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) 18691 { 18692 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; 18693 ConstExprValue *enum_field_val = &enum_field_array->data.x_array.data.s_none.elements[enum_field_index]; 18694 make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type); 18695 enum_field_val->parent.id = ConstParentIdArray; 18696 enum_field_val->parent.data.p_array.array_val = enum_field_array; 18697 enum_field_val->parent.data.p_array.elem_index = enum_field_index; 18698 } 18699 // defs: []TypeInfo.Definition 18700 ensure_field_index(result->type, "defs", 3); 18701 if ((err = ir_make_type_info_defs(ira, source_instr, &fields[3], 18702 type_entry->data.enumeration.decls_scope))) 18703 { 18704 return err; 18705 } 18706 18707 break; 18708 } 18709 case ZigTypeIdErrorSet: 18710 { 18711 result = create_const_vals(1); 18712 result->special = ConstValSpecialStatic; 18713 result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr); 18714 18715 ZigType *type_info_error_type = ir_type_info_get_type(ira, "Error", nullptr); 18716 if (!resolve_inferred_error_set(ira->codegen, type_entry, source_instr->source_node)) { 18717 return ErrorSemanticAnalyzeFail; 18718 } 18719 if (type_is_global_error_set(type_entry)) { 18720 result->data.x_optional = nullptr; 18721 break; 18722 } 18723 if ((err = type_resolve(ira->codegen, type_info_error_type, ResolveStatusSizeKnown))) { 18724 zig_unreachable(); 18725 } 18726 ConstExprValue *slice_val = create_const_vals(1); 18727 result->data.x_optional = slice_val; 18728 18729 uint32_t error_count = type_entry->data.error_set.err_count; 18730 ConstExprValue *error_array = create_const_vals(1); 18731 error_array->special = ConstValSpecialStatic; 18732 error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count); 18733 error_array->data.x_array.special = ConstArraySpecialNone; 18734 error_array->data.x_array.data.s_none.elements = create_const_vals(error_count); 18735 18736 init_const_slice(ira->codegen, slice_val, error_array, 0, error_count, false); 18737 for (uint32_t error_index = 0; error_index < error_count; error_index++) { 18738 ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; 18739 ConstExprValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index]; 18740 18741 error_val->special = ConstValSpecialStatic; 18742 error_val->type = type_info_error_type; 18743 18744 ConstExprValue *inner_fields = create_const_vals(2); 18745 inner_fields[1].special = ConstValSpecialStatic; 18746 inner_fields[1].type = ira->codegen->builtin_types.entry_num_lit_int; 18747 18748 ConstExprValue *name = nullptr; 18749 if (error->cached_error_name_val != nullptr) 18750 name = error->cached_error_name_val; 18751 if (name == nullptr) 18752 name = create_const_str_lit(ira->codegen, &error->name); 18753 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(&error->name), true); 18754 bigint_init_unsigned(&inner_fields[1].data.x_bigint, error->value); 18755 18756 error_val->data.x_struct.fields = inner_fields; 18757 error_val->parent.id = ConstParentIdArray; 18758 error_val->parent.data.p_array.array_val = error_array; 18759 error_val->parent.data.p_array.elem_index = error_index; 18760 } 18761 18762 break; 18763 } 18764 case ZigTypeIdErrorUnion: 18765 { 18766 result = create_const_vals(1); 18767 result->special = ConstValSpecialStatic; 18768 result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr); 18769 18770 ConstExprValue *fields = create_const_vals(2); 18771 result->data.x_struct.fields = fields; 18772 18773 // error_set: type 18774 ensure_field_index(result->type, "error_set", 0); 18775 fields[0].special = ConstValSpecialStatic; 18776 fields[0].type = ira->codegen->builtin_types.entry_type; 18777 fields[0].data.x_type = type_entry->data.error_union.err_set_type; 18778 18779 // payload: type 18780 ensure_field_index(result->type, "payload", 1); 18781 fields[1].special = ConstValSpecialStatic; 18782 fields[1].type = ira->codegen->builtin_types.entry_type; 18783 fields[1].data.x_type = type_entry->data.error_union.payload_type; 18784 18785 break; 18786 } 18787 case ZigTypeIdUnion: 18788 { 18789 result = create_const_vals(1); 18790 result->special = ConstValSpecialStatic; 18791 result->type = ir_type_info_get_type(ira, "Union", nullptr); 18792 18793 ConstExprValue *fields = create_const_vals(4); 18794 result->data.x_struct.fields = fields; 18795 18796 // layout: ContainerLayout 18797 ensure_field_index(result->type, "layout", 0); 18798 fields[0].special = ConstValSpecialStatic; 18799 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 18800 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout); 18801 // tag_type: ?type 18802 ensure_field_index(result->type, "tag_type", 1); 18803 fields[1].special = ConstValSpecialStatic; 18804 fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 18805 18806 AstNode *union_decl_node = type_entry->data.unionation.decl_node; 18807 if (union_decl_node->data.container_decl.auto_enum || 18808 union_decl_node->data.container_decl.init_arg_expr != nullptr) 18809 { 18810 ConstExprValue *tag_type = create_const_vals(1); 18811 tag_type->special = ConstValSpecialStatic; 18812 tag_type->type = ira->codegen->builtin_types.entry_type; 18813 tag_type->data.x_type = type_entry->data.unionation.tag_type; 18814 fields[1].data.x_optional = tag_type; 18815 } else { 18816 fields[1].data.x_optional = nullptr; 18817 } 18818 // fields: []TypeInfo.UnionField 18819 ensure_field_index(result->type, "fields", 2); 18820 18821 ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); 18822 if ((err = type_resolve(ira->codegen, type_info_union_field_type, ResolveStatusSizeKnown))) 18823 zig_unreachable(); 18824 uint32_t union_field_count = type_entry->data.unionation.src_field_count; 18825 18826 ConstExprValue *union_field_array = create_const_vals(1); 18827 union_field_array->special = ConstValSpecialStatic; 18828 union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count); 18829 union_field_array->data.x_array.special = ConstArraySpecialNone; 18830 union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count); 18831 18832 init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false); 18833 18834 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 18835 18836 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { 18837 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; 18838 ConstExprValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index]; 18839 18840 union_field_val->special = ConstValSpecialStatic; 18841 union_field_val->type = type_info_union_field_type; 18842 18843 ConstExprValue *inner_fields = create_const_vals(3); 18844 inner_fields[1].special = ConstValSpecialStatic; 18845 inner_fields[1].type = get_optional_type(ira->codegen, type_info_enum_field_type); 18846 18847 if (fields[1].data.x_optional == nullptr) { 18848 inner_fields[1].data.x_optional = nullptr; 18849 } else { 18850 inner_fields[1].data.x_optional = create_const_vals(1); 18851 make_enum_field_val(ira, inner_fields[1].data.x_optional, union_field->enum_field, type_info_enum_field_type); 18852 } 18853 18854 inner_fields[2].special = ConstValSpecialStatic; 18855 inner_fields[2].type = ira->codegen->builtin_types.entry_type; 18856 inner_fields[2].data.x_type = union_field->type_entry; 18857 18858 ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name); 18859 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(union_field->name), true); 18860 18861 union_field_val->data.x_struct.fields = inner_fields; 18862 union_field_val->parent.id = ConstParentIdArray; 18863 union_field_val->parent.data.p_array.array_val = union_field_array; 18864 union_field_val->parent.data.p_array.elem_index = union_field_index; 18865 } 18866 // defs: []TypeInfo.Definition 18867 ensure_field_index(result->type, "defs", 3); 18868 if ((err = ir_make_type_info_defs(ira, source_instr, &fields[3], 18869 type_entry->data.unionation.decls_scope))) 18870 { 18871 return err; 18872 } 18873 18874 break; 18875 } 18876 case ZigTypeIdStruct: 18877 { 18878 if (type_entry->data.structure.is_slice) { 18879 result = create_ptr_like_type_info(ira, type_entry); 18880 if (result == nullptr) 18881 return ErrorSemanticAnalyzeFail; 18882 break; 18883 } 18884 18885 result = create_const_vals(1); 18886 result->special = ConstValSpecialStatic; 18887 result->type = ir_type_info_get_type(ira, "Struct", nullptr); 18888 18889 ConstExprValue *fields = create_const_vals(3); 18890 result->data.x_struct.fields = fields; 18891 18892 // layout: ContainerLayout 18893 ensure_field_index(result->type, "layout", 0); 18894 fields[0].special = ConstValSpecialStatic; 18895 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 18896 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.structure.layout); 18897 // fields: []TypeInfo.StructField 18898 ensure_field_index(result->type, "fields", 1); 18899 18900 ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); 18901 if ((err = type_resolve(ira->codegen, type_info_struct_field_type, ResolveStatusSizeKnown))) { 18902 zig_unreachable(); 18903 } 18904 uint32_t struct_field_count = type_entry->data.structure.src_field_count; 18905 18906 ConstExprValue *struct_field_array = create_const_vals(1); 18907 struct_field_array->special = ConstValSpecialStatic; 18908 struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count); 18909 struct_field_array->data.x_array.special = ConstArraySpecialNone; 18910 struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count); 18911 18912 init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false); 18913 18914 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { 18915 TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index]; 18916 ConstExprValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index]; 18917 18918 struct_field_val->special = ConstValSpecialStatic; 18919 struct_field_val->type = type_info_struct_field_type; 18920 18921 ConstExprValue *inner_fields = create_const_vals(3); 18922 inner_fields[1].special = ConstValSpecialStatic; 18923 inner_fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int); 18924 18925 if (!type_has_bits(struct_field->type_entry)) { 18926 inner_fields[1].data.x_optional = nullptr; 18927 } else { 18928 size_t byte_offset = struct_field->offset; 18929 inner_fields[1].data.x_optional = create_const_vals(1); 18930 inner_fields[1].data.x_optional->special = ConstValSpecialStatic; 18931 inner_fields[1].data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int; 18932 bigint_init_unsigned(&inner_fields[1].data.x_optional->data.x_bigint, byte_offset); 18933 } 18934 18935 inner_fields[2].special = ConstValSpecialStatic; 18936 inner_fields[2].type = ira->codegen->builtin_types.entry_type; 18937 inner_fields[2].data.x_type = struct_field->type_entry; 18938 18939 ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name); 18940 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(struct_field->name), true); 18941 18942 struct_field_val->data.x_struct.fields = inner_fields; 18943 struct_field_val->parent.id = ConstParentIdArray; 18944 struct_field_val->parent.data.p_array.array_val = struct_field_array; 18945 struct_field_val->parent.data.p_array.elem_index = struct_field_index; 18946 } 18947 // defs: []TypeInfo.Definition 18948 ensure_field_index(result->type, "defs", 2); 18949 if ((err = ir_make_type_info_defs(ira, source_instr, &fields[2], 18950 type_entry->data.structure.decls_scope))) 18951 { 18952 return err; 18953 } 18954 18955 break; 18956 } 18957 case ZigTypeIdFn: 18958 { 18959 result = create_const_vals(1); 18960 result->special = ConstValSpecialStatic; 18961 result->type = ir_type_info_get_type(ira, "Fn", nullptr); 18962 18963 ConstExprValue *fields = create_const_vals(6); 18964 result->data.x_struct.fields = fields; 18965 18966 // calling_convention: TypeInfo.CallingConvention 18967 ensure_field_index(result->type, "calling_convention", 0); 18968 fields[0].special = ConstValSpecialStatic; 18969 fields[0].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); 18970 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); 18971 // is_generic: bool 18972 ensure_field_index(result->type, "is_generic", 1); 18973 bool is_generic = type_entry->data.fn.is_generic; 18974 fields[1].special = ConstValSpecialStatic; 18975 fields[1].type = ira->codegen->builtin_types.entry_bool; 18976 fields[1].data.x_bool = is_generic; 18977 // is_varargs: bool 18978 ensure_field_index(result->type, "is_var_args", 2); 18979 bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; 18980 fields[2].special = ConstValSpecialStatic; 18981 fields[2].type = ira->codegen->builtin_types.entry_bool; 18982 fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; 18983 // return_type: ?type 18984 ensure_field_index(result->type, "return_type", 3); 18985 fields[3].special = ConstValSpecialStatic; 18986 fields[3].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 18987 if (type_entry->data.fn.fn_type_id.return_type == nullptr) 18988 fields[3].data.x_optional = nullptr; 18989 else { 18990 ConstExprValue *return_type = create_const_vals(1); 18991 return_type->special = ConstValSpecialStatic; 18992 return_type->type = ira->codegen->builtin_types.entry_type; 18993 return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; 18994 fields[3].data.x_optional = return_type; 18995 } 18996 // async_allocator_type: type 18997 ensure_field_index(result->type, "async_allocator_type", 4); 18998 fields[4].special = ConstValSpecialStatic; 18999 fields[4].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 19000 if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr) 19001 fields[4].data.x_optional = nullptr; 19002 else { 19003 ConstExprValue *async_alloc_type = create_const_vals(1); 19004 async_alloc_type->special = ConstValSpecialStatic; 19005 async_alloc_type->type = ira->codegen->builtin_types.entry_type; 19006 async_alloc_type->data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type; 19007 fields[4].data.x_optional = async_alloc_type; 19008 } 19009 // args: []TypeInfo.FnArg 19010 ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); 19011 if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { 19012 zig_unreachable(); 19013 } 19014 size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - 19015 (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); 19016 19017 ConstExprValue *fn_arg_array = create_const_vals(1); 19018 fn_arg_array->special = ConstValSpecialStatic; 19019 fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count); 19020 fn_arg_array->data.x_array.special = ConstArraySpecialNone; 19021 fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); 19022 19023 init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false); 19024 19025 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) 19026 { 19027 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; 19028 ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index]; 19029 19030 fn_arg_val->special = ConstValSpecialStatic; 19031 fn_arg_val->type = type_info_fn_arg_type; 19032 19033 bool arg_is_generic = fn_param_info->type == nullptr; 19034 if (arg_is_generic) assert(is_generic); 19035 19036 ConstExprValue *inner_fields = create_const_vals(3); 19037 inner_fields[0].special = ConstValSpecialStatic; 19038 inner_fields[0].type = ira->codegen->builtin_types.entry_bool; 19039 inner_fields[0].data.x_bool = arg_is_generic; 19040 inner_fields[1].special = ConstValSpecialStatic; 19041 inner_fields[1].type = ira->codegen->builtin_types.entry_bool; 19042 inner_fields[1].data.x_bool = fn_param_info->is_noalias; 19043 inner_fields[2].special = ConstValSpecialStatic; 19044 inner_fields[2].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 19045 19046 if (arg_is_generic) 19047 inner_fields[2].data.x_optional = nullptr; 19048 else { 19049 ConstExprValue *arg_type = create_const_vals(1); 19050 arg_type->special = ConstValSpecialStatic; 19051 arg_type->type = ira->codegen->builtin_types.entry_type; 19052 arg_type->data.x_type = fn_param_info->type; 19053 inner_fields[2].data.x_optional = arg_type; 19054 } 19055 19056 fn_arg_val->data.x_struct.fields = inner_fields; 19057 fn_arg_val->parent.id = ConstParentIdArray; 19058 fn_arg_val->parent.data.p_array.array_val = fn_arg_array; 19059 fn_arg_val->parent.data.p_array.elem_index = fn_arg_index; 19060 } 19061 19062 break; 19063 } 19064 case ZigTypeIdBoundFn: 19065 { 19066 ZigType *fn_type = type_entry->data.bound_fn.fn_type; 19067 assert(fn_type->id == ZigTypeIdFn); 19068 if ((err = ir_make_type_info_value(ira, source_instr, fn_type, &result))) 19069 return err; 19070 19071 break; 19072 } 19073 } 19074 19075 assert(result != nullptr); 19076 ira->codegen->type_info_cache.put(type_entry, result); 19077 *out = result; 19078 return ErrorNone; 19079 } 19080 19081 static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira, 19082 IrInstructionTypeInfo *instruction) 19083 { 19084 Error err; 19085 IrInstruction *type_value = instruction->type_value->child; 19086 ZigType *type_entry = ir_resolve_type(ira, type_value); 19087 if (type_is_invalid(type_entry)) 19088 return ira->codegen->invalid_instruction; 19089 19090 ZigType *result_type = ir_type_info_get_type(ira, nullptr, nullptr); 19091 19092 ConstExprValue *payload; 19093 if ((err = ir_make_type_info_value(ira, &instruction->base, type_entry, &payload))) 19094 return ira->codegen->invalid_instruction; 19095 19096 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 19097 ConstExprValue *out_val = &result->value; 19098 bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry)); 19099 out_val->data.x_union.payload = payload; 19100 19101 if (payload != nullptr) { 19102 payload->parent.id = ConstParentIdUnion; 19103 payload->parent.data.p_union.union_val = out_val; 19104 } 19105 19106 return result; 19107 } 19108 19109 static IrInstruction *ir_analyze_instruction_type_id(IrAnalyze *ira, 19110 IrInstructionTypeId *instruction) 19111 { 19112 IrInstruction *type_value = instruction->type_value->child; 19113 ZigType *type_entry = ir_resolve_type(ira, type_value); 19114 if (type_is_invalid(type_entry)) 19115 return ira->codegen->invalid_instruction; 19116 19117 ConstExprValue *var_value = get_builtin_value(ira->codegen, "TypeId"); 19118 assert(var_value->type->id == ZigTypeIdMetaType); 19119 ZigType *result_type = var_value->data.x_type; 19120 19121 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 19122 bigint_init_unsigned(&result->value.data.x_enum_tag, type_id_index(type_entry)); 19123 return result; 19124 } 19125 19126 static IrInstruction *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira, 19127 IrInstructionSetEvalBranchQuota *instruction) 19128 { 19129 uint64_t new_quota; 19130 if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota)) 19131 return ira->codegen->invalid_instruction; 19132 19133 if (new_quota > *ira->new_irb.exec->backward_branch_quota) { 19134 *ira->new_irb.exec->backward_branch_quota = new_quota; 19135 } 19136 19137 return ir_const_void(ira, &instruction->base); 19138 } 19139 19140 static IrInstruction *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) { 19141 IrInstruction *type_value = instruction->type_value->child; 19142 ZigType *type_entry = ir_resolve_type(ira, type_value); 19143 if (type_is_invalid(type_entry)) 19144 return ira->codegen->invalid_instruction; 19145 19146 if (!type_entry->cached_const_name_val) { 19147 type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, type_bare_name(type_entry)); 19148 } 19149 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 19150 copy_const_val(&result->value, type_entry->cached_const_name_val, true); 19151 return result; 19152 } 19153 19154 static void ir_cimport_cache_paths(Buf *cache_dir, Buf *tmp_c_file_digest, Buf *out_zig_dir, Buf *out_zig_path) { 19155 buf_resize(out_zig_dir, 0); 19156 buf_resize(out_zig_path, 0); 19157 buf_appendf(out_zig_dir, "%s" OS_SEP "o" OS_SEP "%s", 19158 buf_ptr(cache_dir), buf_ptr(tmp_c_file_digest)); 19159 buf_appendf(out_zig_path, "%s" OS_SEP "cimport.zig", buf_ptr(out_zig_dir)); 19160 } 19161 static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCImport *instruction) { 19162 Error err; 19163 AstNode *node = instruction->base.source_node; 19164 assert(node->type == NodeTypeFnCallExpr); 19165 AstNode *block_node = node->data.fn_call_expr.params.at(0); 19166 19167 ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.scope); 19168 19169 // Execute the C import block like an inline function 19170 ZigType *void_type = ira->codegen->builtin_types.entry_void; 19171 ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, 19172 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, 19173 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr); 19174 if (type_is_invalid(cimport_result->type)) 19175 return ira->codegen->invalid_instruction; 19176 19177 ZigPackage *cur_scope_pkg = scope_package(instruction->base.scope); 19178 Buf *namespace_name = buf_sprintf("%s.cimport:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, 19179 buf_ptr(&cur_scope_pkg->pkg_path), node->line + 1, node->column + 1); 19180 19181 ZigPackage *cimport_pkg = new_anonymous_package(); 19182 cimport_pkg->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package); 19183 cimport_pkg->package_table.put(buf_create_from_str("std"), ira->codegen->std_package); 19184 buf_init_from_buf(&cimport_pkg->pkg_path, namespace_name); 19185 19186 CacheHash *cache_hash; 19187 if ((err = create_c_object_cache(ira->codegen, &cache_hash, false))) { 19188 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to create cache: %s", err_str(err))); 19189 return ira->codegen->invalid_instruction; 19190 } 19191 cache_buf(cache_hash, &cimport_scope->buf); 19192 19193 // Set this because we're not adding any files before checking for a hit. 19194 cache_hash->force_check_manifest = true; 19195 19196 Buf tmp_c_file_digest = BUF_INIT; 19197 buf_resize(&tmp_c_file_digest, 0); 19198 if ((err = cache_hit(cache_hash, &tmp_c_file_digest))) { 19199 if (err != ErrorInvalidFormat) { 19200 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to check cache: %s", err_str(err))); 19201 return ira->codegen->invalid_instruction; 19202 } 19203 } 19204 ira->codegen->caches_to_release.append(cache_hash); 19205 19206 Buf *out_zig_dir = buf_alloc(); 19207 Buf *out_zig_path = buf_alloc(); 19208 if (buf_len(&tmp_c_file_digest) == 0 || cache_hash->files.length == 0) { 19209 // Cache Miss 19210 Buf *tmp_c_file_dir = buf_sprintf("%s" OS_SEP "o" OS_SEP "%s", 19211 buf_ptr(ira->codegen->cache_dir), buf_ptr(&cache_hash->b64_digest)); 19212 Buf *resolve_paths[] = { 19213 tmp_c_file_dir, 19214 buf_create_from_str("cimport.h"), 19215 }; 19216 Buf tmp_c_file_path = os_path_resolve(resolve_paths, 2); 19217 19218 if ((err = os_make_path(tmp_c_file_dir))) { 19219 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); 19220 return ira->codegen->invalid_instruction; 19221 } 19222 19223 if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { 19224 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); 19225 return ira->codegen->invalid_instruction; 19226 } 19227 if (ira->codegen->verbose_cimport) { 19228 fprintf(stderr, "@cImport source: %s\n", buf_ptr(&tmp_c_file_path)); 19229 } 19230 19231 Buf *tmp_dep_file = buf_sprintf("%s.d", buf_ptr(&tmp_c_file_path)); 19232 19233 ZigList<const char *> clang_argv = {0}; 19234 19235 add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true); 19236 19237 clang_argv.append(buf_ptr(&tmp_c_file_path)); 19238 19239 if (ira->codegen->verbose_cc) { 19240 fprintf(stderr, "clang"); 19241 for (size_t i = 0; i < clang_argv.length; i += 1) { 19242 fprintf(stderr, " %s", clang_argv.at(i)); 19243 } 19244 fprintf(stderr, "\n"); 19245 } 19246 19247 clang_argv.append(nullptr); // to make the [start...end] argument work 19248 19249 AstNode *root_node; 19250 Stage2ErrorMsg *errors_ptr; 19251 size_t errors_len; 19252 19253 const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir); 19254 19255 if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len, 19256 &clang_argv.at(0), &clang_argv.last(), Stage2TranslateModeImport, resources_path))) 19257 { 19258 if (err != ErrorCCompileErrors) { 19259 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); 19260 return ira->codegen->invalid_instruction; 19261 } 19262 19263 ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed")); 19264 if (ira->codegen->libc_link_lib == nullptr) { 19265 add_error_note(ira->codegen, parent_err_msg, node, 19266 buf_sprintf("libc headers not available; compilation does not link against libc")); 19267 } 19268 for (size_t i = 0; i < errors_len; i += 1) { 19269 Stage2ErrorMsg *clang_err = &errors_ptr[i]; 19270 ErrorMsg *err_msg = err_msg_create_with_offset( 19271 clang_err->filename_ptr ? 19272 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), 19273 clang_err->line, clang_err->column, clang_err->offset, clang_err->source, 19274 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); 19275 err_msg_add_note(parent_err_msg, err_msg); 19276 } 19277 19278 return ira->codegen->invalid_instruction; 19279 } 19280 if (ira->codegen->verbose_cimport) { 19281 fprintf(stderr, "@cImport .d file: %s\n", buf_ptr(tmp_dep_file)); 19282 } 19283 19284 if ((err = cache_add_dep_file(cache_hash, tmp_dep_file, false))) { 19285 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to parse .d file: %s", err_str(err))); 19286 return ira->codegen->invalid_instruction; 19287 } 19288 if ((err = cache_final(cache_hash, &tmp_c_file_digest))) { 19289 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to finalize cache: %s", err_str(err))); 19290 return ira->codegen->invalid_instruction; 19291 } 19292 19293 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 19294 if ((err = os_make_path(out_zig_dir))) { 19295 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make output dir: %s", err_str(err))); 19296 return ira->codegen->invalid_instruction; 19297 } 19298 FILE *out_file = fopen(buf_ptr(out_zig_path), "wb"); 19299 if (out_file == nullptr) { 19300 ir_add_error_node(ira, node, 19301 buf_sprintf("C import failed: unable to open output file: %s", strerror(errno))); 19302 return ira->codegen->invalid_instruction; 19303 } 19304 ast_render(out_file, root_node, 4); 19305 if (fclose(out_file) != 0) { 19306 ir_add_error_node(ira, node, 19307 buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno))); 19308 return ira->codegen->invalid_instruction; 19309 } 19310 19311 if (ira->codegen->verbose_cimport) { 19312 fprintf(stderr, "@cImport output: %s\n", buf_ptr(out_zig_path)); 19313 } 19314 19315 } else { 19316 // Cache Hit 19317 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 19318 if (ira->codegen->verbose_cimport) { 19319 fprintf(stderr, "@cImport cache hit: %s\n", buf_ptr(out_zig_path)); 19320 } 19321 } 19322 19323 Buf *import_code = buf_alloc(); 19324 if ((err = file_fetch(ira->codegen, out_zig_path, import_code))) { 19325 ir_add_error_node(ira, node, 19326 buf_sprintf("unable to open '%s': %s", buf_ptr(out_zig_path), err_str(err))); 19327 return ira->codegen->invalid_instruction; 19328 } 19329 ZigType *child_import = add_source_file(ira->codegen, cimport_pkg, out_zig_path, 19330 import_code, SourceKindCImport); 19331 return ir_const_type(ira, &instruction->base, child_import); 19332 } 19333 19334 static IrInstruction *ir_analyze_instruction_c_include(IrAnalyze *ira, IrInstructionCInclude *instruction) { 19335 IrInstruction *name_value = instruction->name->child; 19336 if (type_is_invalid(name_value->value.type)) 19337 return ira->codegen->invalid_instruction; 19338 19339 Buf *include_name = ir_resolve_str(ira, name_value); 19340 if (!include_name) 19341 return ira->codegen->invalid_instruction; 19342 19343 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 19344 // We check for this error in pass1 19345 assert(c_import_buf); 19346 19347 buf_appendf(c_import_buf, "#include <%s>\n", buf_ptr(include_name)); 19348 19349 return ir_const_void(ira, &instruction->base); 19350 } 19351 19352 static IrInstruction *ir_analyze_instruction_c_define(IrAnalyze *ira, IrInstructionCDefine *instruction) { 19353 IrInstruction *name = instruction->name->child; 19354 if (type_is_invalid(name->value.type)) 19355 return ira->codegen->invalid_instruction; 19356 19357 Buf *define_name = ir_resolve_str(ira, name); 19358 if (!define_name) 19359 return ira->codegen->invalid_instruction; 19360 19361 IrInstruction *value = instruction->value->child; 19362 if (type_is_invalid(value->value.type)) 19363 return ira->codegen->invalid_instruction; 19364 19365 Buf *define_value = ir_resolve_str(ira, value); 19366 if (!define_value) 19367 return ira->codegen->invalid_instruction; 19368 19369 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 19370 // We check for this error in pass1 19371 assert(c_import_buf); 19372 19373 buf_appendf(c_import_buf, "#define %s %s\n", buf_ptr(define_name), buf_ptr(define_value)); 19374 19375 return ir_const_void(ira, &instruction->base); 19376 } 19377 19378 static IrInstruction *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstructionCUndef *instruction) { 19379 IrInstruction *name = instruction->name->child; 19380 if (type_is_invalid(name->value.type)) 19381 return ira->codegen->invalid_instruction; 19382 19383 Buf *undef_name = ir_resolve_str(ira, name); 19384 if (!undef_name) 19385 return ira->codegen->invalid_instruction; 19386 19387 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 19388 // We check for this error in pass1 19389 assert(c_import_buf); 19390 19391 buf_appendf(c_import_buf, "#undef %s\n", buf_ptr(undef_name)); 19392 19393 return ir_const_void(ira, &instruction->base); 19394 } 19395 19396 static IrInstruction *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionEmbedFile *instruction) { 19397 IrInstruction *name = instruction->name->child; 19398 if (type_is_invalid(name->value.type)) 19399 return ira->codegen->invalid_instruction; 19400 19401 Buf *rel_file_path = ir_resolve_str(ira, name); 19402 if (!rel_file_path) 19403 return ira->codegen->invalid_instruction; 19404 19405 ZigType *import = get_scope_import(instruction->base.scope); 19406 // figure out absolute path to resource 19407 Buf source_dir_path = BUF_INIT; 19408 os_path_dirname(import->data.structure.root_struct->path, &source_dir_path); 19409 19410 Buf *resolve_paths[] = { 19411 &source_dir_path, 19412 rel_file_path, 19413 }; 19414 Buf *file_path = buf_alloc(); 19415 *file_path = os_path_resolve(resolve_paths, 2); 19416 19417 // load from file system into const expr 19418 Buf *file_contents = buf_alloc(); 19419 Error err; 19420 if ((err = file_fetch(ira->codegen, file_path, file_contents))) { 19421 if (err == ErrorFileNotFound) { 19422 ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(file_path))); 19423 return ira->codegen->invalid_instruction; 19424 } else { 19425 ir_add_error(ira, instruction->name, buf_sprintf("unable to open '%s': %s", buf_ptr(file_path), err_str(err))); 19426 return ira->codegen->invalid_instruction; 19427 } 19428 } 19429 19430 ZigType *result_type = get_array_type(ira->codegen, 19431 ira->codegen->builtin_types.entry_u8, buf_len(file_contents)); 19432 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 19433 init_const_str_lit(ira->codegen, &result->value, file_contents); 19434 return result; 19435 } 19436 19437 static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructionCmpxchgSrc *instruction) { 19438 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child); 19439 if (type_is_invalid(operand_type)) 19440 return ira->codegen->invalid_instruction; 19441 19442 IrInstruction *ptr = instruction->ptr->child; 19443 if (type_is_invalid(ptr->value.type)) 19444 return ira->codegen->invalid_instruction; 19445 19446 // TODO let this be volatile 19447 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 19448 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr, ptr_type); 19449 if (type_is_invalid(casted_ptr->value.type)) 19450 return ira->codegen->invalid_instruction; 19451 19452 IrInstruction *cmp_value = instruction->cmp_value->child; 19453 if (type_is_invalid(cmp_value->value.type)) 19454 return ira->codegen->invalid_instruction; 19455 19456 IrInstruction *new_value = instruction->new_value->child; 19457 if (type_is_invalid(new_value->value.type)) 19458 return ira->codegen->invalid_instruction; 19459 19460 IrInstruction *success_order_value = instruction->success_order_value->child; 19461 if (type_is_invalid(success_order_value->value.type)) 19462 return ira->codegen->invalid_instruction; 19463 19464 AtomicOrder success_order; 19465 if (!ir_resolve_atomic_order(ira, success_order_value, &success_order)) 19466 return ira->codegen->invalid_instruction; 19467 19468 IrInstruction *failure_order_value = instruction->failure_order_value->child; 19469 if (type_is_invalid(failure_order_value->value.type)) 19470 return ira->codegen->invalid_instruction; 19471 19472 AtomicOrder failure_order; 19473 if (!ir_resolve_atomic_order(ira, failure_order_value, &failure_order)) 19474 return ira->codegen->invalid_instruction; 19475 19476 IrInstruction *casted_cmp_value = ir_implicit_cast(ira, cmp_value, operand_type); 19477 if (type_is_invalid(casted_cmp_value->value.type)) 19478 return ira->codegen->invalid_instruction; 19479 19480 IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, operand_type); 19481 if (type_is_invalid(casted_new_value->value.type)) 19482 return ira->codegen->invalid_instruction; 19483 19484 if (success_order < AtomicOrderMonotonic) { 19485 ir_add_error(ira, success_order_value, 19486 buf_sprintf("success atomic ordering must be Monotonic or stricter")); 19487 return ira->codegen->invalid_instruction; 19488 } 19489 if (failure_order < AtomicOrderMonotonic) { 19490 ir_add_error(ira, failure_order_value, 19491 buf_sprintf("failure atomic ordering must be Monotonic or stricter")); 19492 return ira->codegen->invalid_instruction; 19493 } 19494 if (failure_order > success_order) { 19495 ir_add_error(ira, failure_order_value, 19496 buf_sprintf("failure atomic ordering must be no stricter than success")); 19497 return ira->codegen->invalid_instruction; 19498 } 19499 if (failure_order == AtomicOrderRelease || failure_order == AtomicOrderAcqRel) { 19500 ir_add_error(ira, failure_order_value, 19501 buf_sprintf("failure atomic ordering must not be Release or AcqRel")); 19502 return ira->codegen->invalid_instruction; 19503 } 19504 19505 if (instr_is_comptime(casted_ptr) && instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) { 19506 zig_panic("TODO compile-time execution of cmpxchg"); 19507 } 19508 19509 IrInstruction *result = ir_build_cmpxchg_gen(ira, &instruction->base, 19510 casted_ptr, casted_cmp_value, casted_new_value, 19511 success_order, failure_order, instruction->is_weak); 19512 result->value.type = get_optional_type(ira->codegen, operand_type); 19513 ir_add_alloca(ira, result, result->value.type); 19514 return result; 19515 } 19516 19517 static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { 19518 IrInstruction *order_value = instruction->order_value->child; 19519 if (type_is_invalid(order_value->value.type)) 19520 return ira->codegen->invalid_instruction; 19521 19522 AtomicOrder order; 19523 if (!ir_resolve_atomic_order(ira, order_value, &order)) 19524 return ira->codegen->invalid_instruction; 19525 19526 IrInstruction *result = ir_build_fence(&ira->new_irb, 19527 instruction->base.scope, instruction->base.source_node, order_value, order); 19528 result->value.type = ira->codegen->builtin_types.entry_void; 19529 return result; 19530 } 19531 19532 static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstructionTruncate *instruction) { 19533 IrInstruction *dest_type_value = instruction->dest_type->child; 19534 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 19535 if (type_is_invalid(dest_type)) 19536 return ira->codegen->invalid_instruction; 19537 19538 if (dest_type->id != ZigTypeIdInt && 19539 dest_type->id != ZigTypeIdComptimeInt) 19540 { 19541 ir_add_error(ira, dest_type_value, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 19542 return ira->codegen->invalid_instruction; 19543 } 19544 19545 IrInstruction *target = instruction->target->child; 19546 ZigType *src_type = target->value.type; 19547 if (type_is_invalid(src_type)) 19548 return ira->codegen->invalid_instruction; 19549 19550 if (src_type->id != ZigTypeIdInt && 19551 src_type->id != ZigTypeIdComptimeInt) 19552 { 19553 ir_add_error(ira, target, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name))); 19554 return ira->codegen->invalid_instruction; 19555 } 19556 19557 if (dest_type->id == ZigTypeIdComptimeInt) { 19558 return ir_implicit_cast(ira, target, dest_type); 19559 } 19560 19561 if (instr_is_comptime(target)) { 19562 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 19563 if (val == nullptr) 19564 return ira->codegen->invalid_instruction; 19565 19566 IrInstruction *result = ir_const(ira, &instruction->base, dest_type); 19567 bigint_truncate(&result->value.data.x_bigint, &val->data.x_bigint, 19568 dest_type->data.integral.bit_count, dest_type->data.integral.is_signed); 19569 return result; 19570 } 19571 19572 if (src_type->data.integral.bit_count == 0 || dest_type->data.integral.bit_count == 0) { 19573 IrInstruction *result = ir_const(ira, &instruction->base, dest_type); 19574 bigint_init_unsigned(&result->value.data.x_bigint, 0); 19575 return result; 19576 } 19577 19578 if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { 19579 const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; 19580 ir_add_error(ira, target, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); 19581 return ira->codegen->invalid_instruction; 19582 } else if (src_type->data.integral.bit_count < dest_type->data.integral.bit_count) { 19583 ir_add_error(ira, target, buf_sprintf("type '%s' has fewer bits than destination type '%s'", 19584 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 19585 return ira->codegen->invalid_instruction; 19586 } 19587 19588 IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope, 19589 instruction->base.source_node, dest_type_value, target); 19590 new_instruction->value.type = dest_type; 19591 return new_instruction; 19592 } 19593 19594 static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstructionIntCast *instruction) { 19595 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 19596 if (type_is_invalid(dest_type)) 19597 return ira->codegen->invalid_instruction; 19598 19599 if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { 19600 ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 19601 return ira->codegen->invalid_instruction; 19602 } 19603 19604 IrInstruction *target = instruction->target->child; 19605 if (type_is_invalid(target->value.type)) 19606 return ira->codegen->invalid_instruction; 19607 19608 if (target->value.type->id != ZigTypeIdInt && target->value.type->id != ZigTypeIdComptimeInt) { 19609 ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", 19610 buf_ptr(&target->value.type->name))); 19611 return ira->codegen->invalid_instruction; 19612 } 19613 19614 if (instr_is_comptime(target)) { 19615 return ir_implicit_cast(ira, target, dest_type); 19616 } 19617 19618 if (dest_type->id == ZigTypeIdComptimeInt) { 19619 ir_add_error(ira, instruction->target, buf_sprintf("attempt to cast runtime value to '%s'", 19620 buf_ptr(&dest_type->name))); 19621 return ira->codegen->invalid_instruction; 19622 } 19623 19624 return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); 19625 } 19626 19627 static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstructionFloatCast *instruction) { 19628 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 19629 if (type_is_invalid(dest_type)) 19630 return ira->codegen->invalid_instruction; 19631 19632 if (dest_type->id != ZigTypeIdFloat) { 19633 ir_add_error(ira, instruction->dest_type, 19634 buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); 19635 return ira->codegen->invalid_instruction; 19636 } 19637 19638 IrInstruction *target = instruction->target->child; 19639 if (type_is_invalid(target->value.type)) 19640 return ira->codegen->invalid_instruction; 19641 19642 if (target->value.type->id == ZigTypeIdComptimeInt || 19643 target->value.type->id == ZigTypeIdComptimeFloat) 19644 { 19645 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { 19646 CastOp op; 19647 if (target->value.type->id == ZigTypeIdComptimeInt) { 19648 op = CastOpIntToFloat; 19649 } else { 19650 op = CastOpNumLitToConcrete; 19651 } 19652 return ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false); 19653 } else { 19654 return ira->codegen->invalid_instruction; 19655 } 19656 } 19657 19658 if (target->value.type->id != ZigTypeIdFloat) { 19659 ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", 19660 buf_ptr(&target->value.type->name))); 19661 return ira->codegen->invalid_instruction; 19662 } 19663 19664 return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); 19665 } 19666 19667 static IrInstruction *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstructionErrSetCast *instruction) { 19668 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 19669 if (type_is_invalid(dest_type)) 19670 return ira->codegen->invalid_instruction; 19671 19672 if (dest_type->id != ZigTypeIdErrorSet) { 19673 ir_add_error(ira, instruction->dest_type, 19674 buf_sprintf("expected error set type, found '%s'", buf_ptr(&dest_type->name))); 19675 return ira->codegen->invalid_instruction; 19676 } 19677 19678 IrInstruction *target = instruction->target->child; 19679 if (type_is_invalid(target->value.type)) 19680 return ira->codegen->invalid_instruction; 19681 19682 if (target->value.type->id != ZigTypeIdErrorSet) { 19683 ir_add_error(ira, instruction->target, 19684 buf_sprintf("expected error set type, found '%s'", buf_ptr(&target->value.type->name))); 19685 return ira->codegen->invalid_instruction; 19686 } 19687 19688 return ir_analyze_err_set_cast(ira, &instruction->base, target, dest_type); 19689 } 19690 19691 static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstructionFromBytes *instruction) { 19692 Error err; 19693 19694 ZigType *dest_child_type = ir_resolve_type(ira, instruction->dest_child_type->child); 19695 if (type_is_invalid(dest_child_type)) 19696 return ira->codegen->invalid_instruction; 19697 19698 IrInstruction *target = instruction->target->child; 19699 if (type_is_invalid(target->value.type)) 19700 return ira->codegen->invalid_instruction; 19701 19702 bool src_ptr_const; 19703 bool src_ptr_volatile; 19704 uint32_t src_ptr_align; 19705 if (target->value.type->id == ZigTypeIdPointer) { 19706 src_ptr_const = target->value.type->data.pointer.is_const; 19707 src_ptr_volatile = target->value.type->data.pointer.is_volatile; 19708 19709 if ((err = resolve_ptr_align(ira, target->value.type, &src_ptr_align))) 19710 return ira->codegen->invalid_instruction; 19711 } else if (is_slice(target->value.type)) { 19712 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry; 19713 src_ptr_const = src_ptr_type->data.pointer.is_const; 19714 src_ptr_volatile = src_ptr_type->data.pointer.is_volatile; 19715 19716 if ((err = resolve_ptr_align(ira, src_ptr_type, &src_ptr_align))) 19717 return ira->codegen->invalid_instruction; 19718 } else { 19719 src_ptr_const = true; 19720 src_ptr_volatile = false; 19721 19722 if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusAlignmentKnown))) 19723 return ira->codegen->invalid_instruction; 19724 19725 src_ptr_align = get_abi_alignment(ira->codegen, target->value.type); 19726 } 19727 19728 if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusSizeKnown))) 19729 return ira->codegen->invalid_instruction; 19730 19731 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_child_type, 19732 src_ptr_const, src_ptr_volatile, PtrLenUnknown, 19733 src_ptr_align, 0, 0, false); 19734 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); 19735 19736 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 19737 src_ptr_const, src_ptr_volatile, PtrLenUnknown, 19738 src_ptr_align, 0, 0, false); 19739 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 19740 19741 IrInstruction *casted_value = ir_implicit_cast(ira, target, u8_slice); 19742 if (type_is_invalid(casted_value->value.type)) 19743 return ira->codegen->invalid_instruction; 19744 19745 bool have_known_len = false; 19746 uint64_t known_len; 19747 19748 if (instr_is_comptime(casted_value)) { 19749 ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad); 19750 if (!val) 19751 return ira->codegen->invalid_instruction; 19752 19753 ConstExprValue *len_val = &val->data.x_struct.fields[slice_len_index]; 19754 if (value_is_comptime(len_val)) { 19755 known_len = bigint_as_unsigned(&len_val->data.x_bigint); 19756 have_known_len = true; 19757 } 19758 } 19759 19760 if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) { 19761 known_len = casted_value->value.data.rh_slice.len; 19762 have_known_len = true; 19763 } 19764 19765 if (have_known_len) { 19766 uint64_t child_type_size = type_size(ira->codegen, dest_child_type); 19767 uint64_t remainder = known_len % child_type_size; 19768 if (remainder != 0) { 19769 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 19770 buf_sprintf("unable to convert [%" ZIG_PRI_u64 "]u8 to %s: size mismatch", 19771 known_len, buf_ptr(&dest_slice_type->name))); 19772 add_error_note(ira->codegen, msg, instruction->dest_child_type->source_node, 19773 buf_sprintf("%s has size %" ZIG_PRI_u64 "; remaining bytes: %" ZIG_PRI_u64, 19774 buf_ptr(&dest_child_type->name), child_type_size, remainder)); 19775 return ira->codegen->invalid_instruction; 19776 } 19777 } 19778 19779 IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type); 19780 ir_add_alloca(ira, result, dest_slice_type); 19781 return result; 19782 } 19783 19784 static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { 19785 Error err; 19786 19787 IrInstruction *target = instruction->target->child; 19788 if (type_is_invalid(target->value.type)) 19789 return ira->codegen->invalid_instruction; 19790 19791 if (!is_slice(target->value.type)) { 19792 ir_add_error(ira, instruction->target, 19793 buf_sprintf("expected slice, found '%s'", buf_ptr(&target->value.type->name))); 19794 return ira->codegen->invalid_instruction; 19795 } 19796 19797 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry; 19798 19799 uint32_t alignment; 19800 if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment))) 19801 return ira->codegen->invalid_instruction; 19802 19803 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 19804 src_ptr_type->data.pointer.is_const, src_ptr_type->data.pointer.is_volatile, PtrLenUnknown, 19805 alignment, 0, 0, false); 19806 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); 19807 19808 if (instr_is_comptime(target)) { 19809 ConstExprValue *target_val = ir_resolve_const(ira, target, UndefBad); 19810 if (target_val == nullptr) 19811 return ira->codegen->invalid_instruction; 19812 19813 IrInstruction *result = ir_const(ira, &instruction->base, dest_slice_type); 19814 result->value.data.x_struct.fields = create_const_vals(2); 19815 19816 ConstExprValue *ptr_val = &result->value.data.x_struct.fields[slice_ptr_index]; 19817 ConstExprValue *target_ptr_val = &target_val->data.x_struct.fields[slice_ptr_index]; 19818 copy_const_val(ptr_val, target_ptr_val, false); 19819 ptr_val->type = dest_ptr_type; 19820 19821 ConstExprValue *len_val = &result->value.data.x_struct.fields[slice_len_index]; 19822 len_val->special = ConstValSpecialStatic; 19823 len_val->type = ira->codegen->builtin_types.entry_usize; 19824 ConstExprValue *target_len_val = &target_val->data.x_struct.fields[slice_len_index]; 19825 ZigType *elem_type = src_ptr_type->data.pointer.child_type; 19826 BigInt elem_size_bigint; 19827 bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type)); 19828 bigint_mul(&len_val->data.x_bigint, &target_len_val->data.x_bigint, &elem_size_bigint); 19829 19830 return result; 19831 } 19832 19833 IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type); 19834 ir_add_alloca(ira, result, dest_slice_type); 19835 return result; 19836 } 19837 19838 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { 19839 Error err; 19840 19841 ZigType *ptr_type = get_src_ptr_type(ty); 19842 assert(ptr_type != nullptr); 19843 if (ptr_type->id == ZigTypeIdPointer) { 19844 if ((err = type_resolve(ira->codegen, ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 19845 return err; 19846 } 19847 19848 *result_align = get_ptr_align(ira->codegen, ty); 19849 return ErrorNone; 19850 } 19851 19852 static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) { 19853 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 19854 if (type_is_invalid(dest_type)) 19855 return ira->codegen->invalid_instruction; 19856 19857 IrInstruction *target = instruction->target->child; 19858 if (type_is_invalid(target->value.type)) 19859 return ira->codegen->invalid_instruction; 19860 19861 if (target->value.type->id != ZigTypeIdInt && target->value.type->id != ZigTypeIdComptimeInt) { 19862 ir_add_error(ira, instruction->target, buf_sprintf("expected int type, found '%s'", 19863 buf_ptr(&target->value.type->name))); 19864 return ira->codegen->invalid_instruction; 19865 } 19866 19867 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false); 19868 } 19869 19870 static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { 19871 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 19872 if (type_is_invalid(dest_type)) 19873 return ira->codegen->invalid_instruction; 19874 19875 IrInstruction *target = instruction->target->child; 19876 if (type_is_invalid(target->value.type)) 19877 return ira->codegen->invalid_instruction; 19878 19879 if (target->value.type->id == ZigTypeIdComptimeInt) { 19880 return ir_implicit_cast(ira, target, dest_type); 19881 } 19882 19883 if (target->value.type->id != ZigTypeIdFloat && target->value.type->id != ZigTypeIdComptimeFloat) { 19884 ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", 19885 buf_ptr(&target->value.type->name))); 19886 return ira->codegen->invalid_instruction; 19887 } 19888 19889 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false); 19890 } 19891 19892 static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { 19893 IrInstruction *target = instruction->target->child; 19894 if (type_is_invalid(target->value.type)) 19895 return ira->codegen->invalid_instruction; 19896 19897 IrInstruction *casted_target; 19898 if (target->value.type->id == ZigTypeIdErrorSet) { 19899 casted_target = target; 19900 } else { 19901 casted_target = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_global_error_set); 19902 if (type_is_invalid(casted_target->value.type)) 19903 return ira->codegen->invalid_instruction; 19904 } 19905 19906 return ir_analyze_err_to_int(ira, &instruction->base, casted_target, ira->codegen->err_tag_type); 19907 } 19908 19909 static IrInstruction *ir_analyze_instruction_int_to_err(IrAnalyze *ira, IrInstructionIntToErr *instruction) { 19910 IrInstruction *target = instruction->target->child; 19911 if (type_is_invalid(target->value.type)) 19912 return ira->codegen->invalid_instruction; 19913 19914 IrInstruction *casted_target = ir_implicit_cast(ira, target, ira->codegen->err_tag_type); 19915 if (type_is_invalid(casted_target->value.type)) 19916 return ira->codegen->invalid_instruction; 19917 19918 return ir_analyze_int_to_err(ira, &instruction->base, casted_target, ira->codegen->builtin_types.entry_global_error_set); 19919 } 19920 19921 static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstructionBoolToInt *instruction) { 19922 IrInstruction *target = instruction->target->child; 19923 if (type_is_invalid(target->value.type)) 19924 return ira->codegen->invalid_instruction; 19925 19926 if (target->value.type->id != ZigTypeIdBool) { 19927 ir_add_error(ira, instruction->target, buf_sprintf("expected bool, found '%s'", 19928 buf_ptr(&target->value.type->name))); 19929 return ira->codegen->invalid_instruction; 19930 } 19931 19932 if (instr_is_comptime(target)) { 19933 bool is_true; 19934 if (!ir_resolve_bool(ira, target, &is_true)) 19935 return ira->codegen->invalid_instruction; 19936 19937 return ir_const_unsigned(ira, &instruction->base, is_true ? 1 : 0); 19938 } 19939 19940 ZigType *u1_type = get_int_type(ira->codegen, false, 1); 19941 return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false); 19942 } 19943 19944 static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { 19945 IrInstruction *is_signed_value = instruction->is_signed->child; 19946 bool is_signed; 19947 if (!ir_resolve_bool(ira, is_signed_value, &is_signed)) 19948 return ira->codegen->invalid_instruction; 19949 19950 IrInstruction *bit_count_value = instruction->bit_count->child; 19951 uint64_t bit_count; 19952 if (!ir_resolve_unsigned(ira, bit_count_value, ira->codegen->builtin_types.entry_u16, &bit_count)) 19953 return ira->codegen->invalid_instruction; 19954 19955 return ir_const_type(ira, &instruction->base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count)); 19956 } 19957 19958 static IrInstruction *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstructionVectorType *instruction) { 19959 uint64_t len; 19960 if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len)) 19961 return ira->codegen->invalid_instruction; 19962 19963 ZigType *elem_type = ir_resolve_type(ira, instruction->elem_type->child); 19964 if (type_is_invalid(elem_type)) 19965 return ira->codegen->invalid_instruction; 19966 19967 if (!is_valid_vector_elem_type(elem_type)) { 19968 ir_add_error(ira, instruction->elem_type, 19969 buf_sprintf("vector element type must be integer, float, or pointer; '%s' is invalid", 19970 buf_ptr(&elem_type->name))); 19971 return ira->codegen->invalid_instruction; 19972 } 19973 19974 ZigType *vector_type = get_vector_type(ira->codegen, len, elem_type); 19975 19976 return ir_const_type(ira, &instruction->base, vector_type); 19977 } 19978 19979 static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { 19980 IrInstruction *value = instruction->value->child; 19981 if (type_is_invalid(value->value.type)) 19982 return ira->codegen->invalid_instruction; 19983 19984 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 19985 19986 IrInstruction *casted_value = ir_implicit_cast(ira, value, bool_type); 19987 if (type_is_invalid(casted_value->value.type)) 19988 return ira->codegen->invalid_instruction; 19989 19990 if (instr_is_comptime(casted_value)) { 19991 ConstExprValue *value = ir_resolve_const(ira, casted_value, UndefBad); 19992 if (value == nullptr) 19993 return ira->codegen->invalid_instruction; 19994 19995 return ir_const_bool(ira, &instruction->base, !value->data.x_bool); 19996 } 19997 19998 IrInstruction *result = ir_build_bool_not(&ira->new_irb, instruction->base.scope, 19999 instruction->base.source_node, casted_value); 20000 result->value.type = bool_type; 20001 return result; 20002 } 20003 20004 static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemset *instruction) { 20005 Error err; 20006 20007 IrInstruction *dest_ptr = instruction->dest_ptr->child; 20008 if (type_is_invalid(dest_ptr->value.type)) 20009 return ira->codegen->invalid_instruction; 20010 20011 IrInstruction *byte_value = instruction->byte->child; 20012 if (type_is_invalid(byte_value->value.type)) 20013 return ira->codegen->invalid_instruction; 20014 20015 IrInstruction *count_value = instruction->count->child; 20016 if (type_is_invalid(count_value->value.type)) 20017 return ira->codegen->invalid_instruction; 20018 20019 ZigType *dest_uncasted_type = dest_ptr->value.type; 20020 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 20021 dest_uncasted_type->data.pointer.is_volatile; 20022 20023 ZigType *usize = ira->codegen->builtin_types.entry_usize; 20024 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 20025 uint32_t dest_align; 20026 if (dest_uncasted_type->id == ZigTypeIdPointer) { 20027 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 20028 return ira->codegen->invalid_instruction; 20029 } else { 20030 dest_align = get_abi_alignment(ira->codegen, u8); 20031 } 20032 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 20033 PtrLenUnknown, dest_align, 0, 0, false); 20034 20035 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr); 20036 if (type_is_invalid(casted_dest_ptr->value.type)) 20037 return ira->codegen->invalid_instruction; 20038 20039 IrInstruction *casted_byte = ir_implicit_cast(ira, byte_value, u8); 20040 if (type_is_invalid(casted_byte->value.type)) 20041 return ira->codegen->invalid_instruction; 20042 20043 IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); 20044 if (type_is_invalid(casted_count->value.type)) 20045 return ira->codegen->invalid_instruction; 20046 20047 // TODO test this at comptime with u8 and non-u8 types 20048 if (casted_dest_ptr->value.special == ConstValSpecialStatic && 20049 casted_byte->value.special == ConstValSpecialStatic && 20050 casted_count->value.special == ConstValSpecialStatic && 20051 casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 20052 casted_dest_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) 20053 { 20054 ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; 20055 20056 ConstExprValue *dest_elements; 20057 size_t start; 20058 size_t bound_end; 20059 switch (dest_ptr_val->data.x_ptr.special) { 20060 case ConstPtrSpecialInvalid: 20061 case ConstPtrSpecialDiscard: 20062 zig_unreachable(); 20063 case ConstPtrSpecialRef: 20064 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 20065 start = 0; 20066 bound_end = 1; 20067 break; 20068 case ConstPtrSpecialBaseArray: 20069 { 20070 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 20071 expand_undef_array(ira->codegen, array_val); 20072 dest_elements = array_val->data.x_array.data.s_none.elements; 20073 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 20074 bound_end = array_val->type->data.array.len; 20075 break; 20076 } 20077 case ConstPtrSpecialBaseStruct: 20078 zig_panic("TODO memset on const inner struct"); 20079 case ConstPtrSpecialBaseErrorUnionCode: 20080 zig_panic("TODO memset on const inner error union code"); 20081 case ConstPtrSpecialBaseErrorUnionPayload: 20082 zig_panic("TODO memset on const inner error union payload"); 20083 case ConstPtrSpecialBaseOptionalPayload: 20084 zig_panic("TODO memset on const inner optional payload"); 20085 case ConstPtrSpecialHardCodedAddr: 20086 zig_unreachable(); 20087 case ConstPtrSpecialFunction: 20088 zig_panic("TODO memset on ptr cast from function"); 20089 case ConstPtrSpecialNull: 20090 zig_panic("TODO memset on null ptr"); 20091 } 20092 20093 size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); 20094 size_t end = start + count; 20095 if (end > bound_end) { 20096 ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); 20097 return ira->codegen->invalid_instruction; 20098 } 20099 20100 ConstExprValue *byte_val = &casted_byte->value; 20101 for (size_t i = start; i < end; i += 1) { 20102 dest_elements[i] = *byte_val; 20103 } 20104 20105 return ir_const_void(ira, &instruction->base); 20106 } 20107 20108 IrInstruction *result = ir_build_memset(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 20109 casted_dest_ptr, casted_byte, casted_count); 20110 result->value.type = ira->codegen->builtin_types.entry_void; 20111 return result; 20112 } 20113 20114 static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcpy *instruction) { 20115 Error err; 20116 20117 IrInstruction *dest_ptr = instruction->dest_ptr->child; 20118 if (type_is_invalid(dest_ptr->value.type)) 20119 return ira->codegen->invalid_instruction; 20120 20121 IrInstruction *src_ptr = instruction->src_ptr->child; 20122 if (type_is_invalid(src_ptr->value.type)) 20123 return ira->codegen->invalid_instruction; 20124 20125 IrInstruction *count_value = instruction->count->child; 20126 if (type_is_invalid(count_value->value.type)) 20127 return ira->codegen->invalid_instruction; 20128 20129 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 20130 ZigType *dest_uncasted_type = dest_ptr->value.type; 20131 ZigType *src_uncasted_type = src_ptr->value.type; 20132 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 20133 dest_uncasted_type->data.pointer.is_volatile; 20134 bool src_is_volatile = (src_uncasted_type->id == ZigTypeIdPointer) && 20135 src_uncasted_type->data.pointer.is_volatile; 20136 20137 uint32_t dest_align; 20138 if (dest_uncasted_type->id == ZigTypeIdPointer) { 20139 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 20140 return ira->codegen->invalid_instruction; 20141 } else { 20142 dest_align = get_abi_alignment(ira->codegen, u8); 20143 } 20144 20145 uint32_t src_align; 20146 if (src_uncasted_type->id == ZigTypeIdPointer) { 20147 if ((err = resolve_ptr_align(ira, src_uncasted_type, &src_align))) 20148 return ira->codegen->invalid_instruction; 20149 } else { 20150 src_align = get_abi_alignment(ira->codegen, u8); 20151 } 20152 20153 ZigType *usize = ira->codegen->builtin_types.entry_usize; 20154 ZigType *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 20155 PtrLenUnknown, dest_align, 0, 0, false); 20156 ZigType *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, 20157 PtrLenUnknown, src_align, 0, 0, false); 20158 20159 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut); 20160 if (type_is_invalid(casted_dest_ptr->value.type)) 20161 return ira->codegen->invalid_instruction; 20162 20163 IrInstruction *casted_src_ptr = ir_implicit_cast(ira, src_ptr, u8_ptr_const); 20164 if (type_is_invalid(casted_src_ptr->value.type)) 20165 return ira->codegen->invalid_instruction; 20166 20167 IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); 20168 if (type_is_invalid(casted_count->value.type)) 20169 return ira->codegen->invalid_instruction; 20170 20171 // TODO test this at comptime with u8 and non-u8 types 20172 // TODO test with dest ptr being a global runtime variable 20173 if (casted_dest_ptr->value.special == ConstValSpecialStatic && 20174 casted_src_ptr->value.special == ConstValSpecialStatic && 20175 casted_count->value.special == ConstValSpecialStatic && 20176 casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) 20177 { 20178 size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); 20179 20180 ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; 20181 ConstExprValue *dest_elements; 20182 size_t dest_start; 20183 size_t dest_end; 20184 switch (dest_ptr_val->data.x_ptr.special) { 20185 case ConstPtrSpecialInvalid: 20186 case ConstPtrSpecialDiscard: 20187 zig_unreachable(); 20188 case ConstPtrSpecialRef: 20189 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 20190 dest_start = 0; 20191 dest_end = 1; 20192 break; 20193 case ConstPtrSpecialBaseArray: 20194 { 20195 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 20196 expand_undef_array(ira->codegen, array_val); 20197 dest_elements = array_val->data.x_array.data.s_none.elements; 20198 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 20199 dest_end = array_val->type->data.array.len; 20200 break; 20201 } 20202 case ConstPtrSpecialBaseStruct: 20203 zig_panic("TODO memcpy on const inner struct"); 20204 case ConstPtrSpecialBaseErrorUnionCode: 20205 zig_panic("TODO memcpy on const inner error union code"); 20206 case ConstPtrSpecialBaseErrorUnionPayload: 20207 zig_panic("TODO memcpy on const inner error union payload"); 20208 case ConstPtrSpecialBaseOptionalPayload: 20209 zig_panic("TODO memcpy on const inner optional payload"); 20210 case ConstPtrSpecialHardCodedAddr: 20211 zig_unreachable(); 20212 case ConstPtrSpecialFunction: 20213 zig_panic("TODO memcpy on ptr cast from function"); 20214 case ConstPtrSpecialNull: 20215 zig_panic("TODO memcpy on null ptr"); 20216 } 20217 20218 if (dest_start + count > dest_end) { 20219 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); 20220 return ira->codegen->invalid_instruction; 20221 } 20222 20223 ConstExprValue *src_ptr_val = &casted_src_ptr->value; 20224 ConstExprValue *src_elements; 20225 size_t src_start; 20226 size_t src_end; 20227 20228 switch (src_ptr_val->data.x_ptr.special) { 20229 case ConstPtrSpecialInvalid: 20230 case ConstPtrSpecialDiscard: 20231 zig_unreachable(); 20232 case ConstPtrSpecialRef: 20233 src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; 20234 src_start = 0; 20235 src_end = 1; 20236 break; 20237 case ConstPtrSpecialBaseArray: 20238 { 20239 ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; 20240 expand_undef_array(ira->codegen, array_val); 20241 src_elements = array_val->data.x_array.data.s_none.elements; 20242 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; 20243 src_end = array_val->type->data.array.len; 20244 break; 20245 } 20246 case ConstPtrSpecialBaseStruct: 20247 zig_panic("TODO memcpy on const inner struct"); 20248 case ConstPtrSpecialBaseErrorUnionCode: 20249 zig_panic("TODO memcpy on const inner error union code"); 20250 case ConstPtrSpecialBaseErrorUnionPayload: 20251 zig_panic("TODO memcpy on const inner error union payload"); 20252 case ConstPtrSpecialBaseOptionalPayload: 20253 zig_panic("TODO memcpy on const inner optional payload"); 20254 case ConstPtrSpecialHardCodedAddr: 20255 zig_unreachable(); 20256 case ConstPtrSpecialFunction: 20257 zig_panic("TODO memcpy on ptr cast from function"); 20258 case ConstPtrSpecialNull: 20259 zig_panic("TODO memcpy on null ptr"); 20260 } 20261 20262 if (src_start + count > src_end) { 20263 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); 20264 return ira->codegen->invalid_instruction; 20265 } 20266 20267 // TODO check for noalias violations - this should be generalized to work for any function 20268 20269 for (size_t i = 0; i < count; i += 1) { 20270 dest_elements[dest_start + i] = src_elements[src_start + i]; 20271 } 20272 20273 return ir_const_void(ira, &instruction->base); 20274 } 20275 20276 IrInstruction *result = ir_build_memcpy(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 20277 casted_dest_ptr, casted_src_ptr, casted_count); 20278 result->value.type = ira->codegen->builtin_types.entry_void; 20279 return result; 20280 } 20281 20282 static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) { 20283 IrInstruction *ptr_ptr = instruction->ptr->child; 20284 if (type_is_invalid(ptr_ptr->value.type)) 20285 return ira->codegen->invalid_instruction; 20286 20287 ZigType *ptr_ptr_type = ptr_ptr->value.type; 20288 assert(ptr_ptr_type->id == ZigTypeIdPointer); 20289 ZigType *array_type = ptr_ptr_type->data.pointer.child_type; 20290 20291 IrInstruction *start = instruction->start->child; 20292 if (type_is_invalid(start->value.type)) 20293 return ira->codegen->invalid_instruction; 20294 20295 ZigType *usize = ira->codegen->builtin_types.entry_usize; 20296 IrInstruction *casted_start = ir_implicit_cast(ira, start, usize); 20297 if (type_is_invalid(casted_start->value.type)) 20298 return ira->codegen->invalid_instruction; 20299 20300 IrInstruction *end; 20301 if (instruction->end) { 20302 end = instruction->end->child; 20303 if (type_is_invalid(end->value.type)) 20304 return ira->codegen->invalid_instruction; 20305 end = ir_implicit_cast(ira, end, usize); 20306 if (type_is_invalid(end->value.type)) 20307 return ira->codegen->invalid_instruction; 20308 } else { 20309 end = nullptr; 20310 } 20311 20312 ZigType *return_type; 20313 20314 if (array_type->id == ZigTypeIdArray) { 20315 bool is_comptime_const = ptr_ptr->value.special == ConstValSpecialStatic && 20316 ptr_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst; 20317 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type, 20318 ptr_ptr_type->data.pointer.is_const || is_comptime_const, 20319 ptr_ptr_type->data.pointer.is_volatile, 20320 PtrLenUnknown, 20321 ptr_ptr_type->data.pointer.explicit_alignment, 0, 0, false); 20322 return_type = get_slice_type(ira->codegen, slice_ptr_type); 20323 } else if (array_type->id == ZigTypeIdPointer) { 20324 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 20325 ZigType *main_type = array_type->data.pointer.child_type; 20326 if (main_type->id == ZigTypeIdArray) { 20327 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, 20328 main_type->data.pointer.child_type, 20329 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile, 20330 PtrLenUnknown, 20331 array_type->data.pointer.explicit_alignment, 0, 0, false); 20332 return_type = get_slice_type(ira->codegen, slice_ptr_type); 20333 } else { 20334 ir_add_error(ira, &instruction->base, buf_sprintf("slice of single-item pointer")); 20335 return ira->codegen->invalid_instruction; 20336 } 20337 } else { 20338 if (array_type->data.pointer.ptr_len == PtrLenC) { 20339 array_type = adjust_ptr_len(ira->codegen, array_type, PtrLenUnknown); 20340 } 20341 return_type = get_slice_type(ira->codegen, array_type); 20342 if (!end) { 20343 ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value")); 20344 return ira->codegen->invalid_instruction; 20345 } 20346 } 20347 } else if (is_slice(array_type)) { 20348 ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index].type_entry; 20349 return_type = get_slice_type(ira->codegen, ptr_type); 20350 } else { 20351 ir_add_error(ira, &instruction->base, 20352 buf_sprintf("slice of non-array type '%s'", buf_ptr(&array_type->name))); 20353 return ira->codegen->invalid_instruction; 20354 } 20355 20356 if (instr_is_comptime(ptr_ptr) && 20357 value_is_comptime(&casted_start->value) && 20358 (!end || value_is_comptime(&end->value))) 20359 { 20360 ConstExprValue *array_val; 20361 ConstExprValue *parent_ptr; 20362 size_t abs_offset; 20363 size_t rel_end; 20364 bool ptr_is_undef = false; 20365 if (array_type->id == ZigTypeIdArray || 20366 (array_type->id == ZigTypeIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) 20367 { 20368 if (array_type->id == ZigTypeIdPointer) { 20369 ZigType *child_array_type = array_type->data.pointer.child_type; 20370 assert(child_array_type->id == ZigTypeIdArray); 20371 parent_ptr = const_ptr_pointee(ira, ira->codegen, &ptr_ptr->value, instruction->base.source_node); 20372 if (parent_ptr == nullptr) 20373 return ira->codegen->invalid_instruction; 20374 20375 array_val = const_ptr_pointee(ira, ira->codegen, parent_ptr, instruction->base.source_node); 20376 if (array_val == nullptr) 20377 return ira->codegen->invalid_instruction; 20378 20379 rel_end = child_array_type->data.array.len; 20380 abs_offset = 0; 20381 } else { 20382 array_val = const_ptr_pointee(ira, ira->codegen, &ptr_ptr->value, instruction->base.source_node); 20383 if (array_val == nullptr) 20384 return ira->codegen->invalid_instruction; 20385 rel_end = array_type->data.array.len; 20386 parent_ptr = nullptr; 20387 abs_offset = 0; 20388 } 20389 } else if (array_type->id == ZigTypeIdPointer) { 20390 assert(array_type->data.pointer.ptr_len == PtrLenUnknown); 20391 parent_ptr = const_ptr_pointee(ira, ira->codegen, &ptr_ptr->value, instruction->base.source_node); 20392 if (parent_ptr == nullptr) 20393 return ira->codegen->invalid_instruction; 20394 20395 if (parent_ptr->special == ConstValSpecialUndef) { 20396 array_val = nullptr; 20397 abs_offset = 0; 20398 rel_end = SIZE_MAX; 20399 ptr_is_undef = true; 20400 } else switch (parent_ptr->data.x_ptr.special) { 20401 case ConstPtrSpecialInvalid: 20402 case ConstPtrSpecialDiscard: 20403 zig_unreachable(); 20404 case ConstPtrSpecialRef: 20405 if (parent_ptr->data.x_ptr.data.ref.pointee->type->id == ZigTypeIdArray) { 20406 array_val = parent_ptr->data.x_ptr.data.ref.pointee; 20407 abs_offset = 0; 20408 rel_end = array_val->type->data.array.len; 20409 } else { 20410 array_val = nullptr; 20411 abs_offset = SIZE_MAX; 20412 rel_end = 1; 20413 } 20414 break; 20415 case ConstPtrSpecialBaseArray: 20416 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 20417 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 20418 rel_end = array_val->type->data.array.len - abs_offset; 20419 break; 20420 case ConstPtrSpecialBaseStruct: 20421 zig_panic("TODO slice const inner struct"); 20422 case ConstPtrSpecialBaseErrorUnionCode: 20423 zig_panic("TODO slice const inner error union code"); 20424 case ConstPtrSpecialBaseErrorUnionPayload: 20425 zig_panic("TODO slice const inner error union payload"); 20426 case ConstPtrSpecialBaseOptionalPayload: 20427 zig_panic("TODO slice const inner optional payload"); 20428 case ConstPtrSpecialHardCodedAddr: 20429 array_val = nullptr; 20430 abs_offset = 0; 20431 rel_end = SIZE_MAX; 20432 break; 20433 case ConstPtrSpecialFunction: 20434 zig_panic("TODO slice of ptr cast from function"); 20435 case ConstPtrSpecialNull: 20436 zig_panic("TODO slice of null ptr"); 20437 } 20438 } else if (is_slice(array_type)) { 20439 ConstExprValue *slice_ptr = const_ptr_pointee(ira, ira->codegen, &ptr_ptr->value, instruction->base.source_node); 20440 if (slice_ptr == nullptr) 20441 return ira->codegen->invalid_instruction; 20442 20443 parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index]; 20444 if (parent_ptr->special == ConstValSpecialUndef) { 20445 ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); 20446 return ira->codegen->invalid_instruction; 20447 } 20448 20449 ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index]; 20450 20451 switch (parent_ptr->data.x_ptr.special) { 20452 case ConstPtrSpecialInvalid: 20453 case ConstPtrSpecialDiscard: 20454 zig_unreachable(); 20455 case ConstPtrSpecialRef: 20456 array_val = nullptr; 20457 abs_offset = SIZE_MAX; 20458 rel_end = 1; 20459 break; 20460 case ConstPtrSpecialBaseArray: 20461 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 20462 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 20463 rel_end = bigint_as_unsigned(&len_val->data.x_bigint); 20464 break; 20465 case ConstPtrSpecialBaseStruct: 20466 zig_panic("TODO slice const inner struct"); 20467 case ConstPtrSpecialBaseErrorUnionCode: 20468 zig_panic("TODO slice const inner error union code"); 20469 case ConstPtrSpecialBaseErrorUnionPayload: 20470 zig_panic("TODO slice const inner error union payload"); 20471 case ConstPtrSpecialBaseOptionalPayload: 20472 zig_panic("TODO slice const inner optional payload"); 20473 case ConstPtrSpecialHardCodedAddr: 20474 array_val = nullptr; 20475 abs_offset = 0; 20476 rel_end = bigint_as_unsigned(&len_val->data.x_bigint); 20477 break; 20478 case ConstPtrSpecialFunction: 20479 zig_panic("TODO slice of slice cast from function"); 20480 case ConstPtrSpecialNull: 20481 zig_panic("TODO slice of null"); 20482 } 20483 } else { 20484 zig_unreachable(); 20485 } 20486 20487 uint64_t start_scalar = bigint_as_unsigned(&casted_start->value.data.x_bigint); 20488 if (!ptr_is_undef && start_scalar > rel_end) { 20489 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); 20490 return ira->codegen->invalid_instruction; 20491 } 20492 20493 uint64_t end_scalar; 20494 if (end) { 20495 end_scalar = bigint_as_unsigned(&end->value.data.x_bigint); 20496 } else { 20497 end_scalar = rel_end; 20498 } 20499 if (!ptr_is_undef) { 20500 if (end_scalar > rel_end) { 20501 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); 20502 return ira->codegen->invalid_instruction; 20503 } 20504 if (start_scalar > end_scalar) { 20505 ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); 20506 return ira->codegen->invalid_instruction; 20507 } 20508 } 20509 if (ptr_is_undef && start_scalar != end_scalar) { 20510 ir_add_error(ira, &instruction->base, buf_sprintf("non-zero length slice of undefined pointer")); 20511 return ira->codegen->invalid_instruction; 20512 } 20513 20514 IrInstruction *result = ir_const(ira, &instruction->base, return_type); 20515 ConstExprValue *out_val = &result->value; 20516 out_val->data.x_struct.fields = create_const_vals(2); 20517 20518 ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; 20519 20520 if (array_val) { 20521 size_t index = abs_offset + start_scalar; 20522 bool is_const = slice_is_const(return_type); 20523 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const, PtrLenUnknown); 20524 if (array_type->id == ZigTypeIdArray) { 20525 ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut; 20526 } else if (is_slice(array_type)) { 20527 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 20528 } else if (array_type->id == ZigTypeIdPointer) { 20529 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 20530 } 20531 } else if (ptr_is_undef) { 20532 ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type, 20533 slice_is_const(return_type)); 20534 ptr_val->special = ConstValSpecialUndef; 20535 } else switch (parent_ptr->data.x_ptr.special) { 20536 case ConstPtrSpecialInvalid: 20537 case ConstPtrSpecialDiscard: 20538 zig_unreachable(); 20539 case ConstPtrSpecialRef: 20540 init_const_ptr_ref(ira->codegen, ptr_val, 20541 parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); 20542 break; 20543 case ConstPtrSpecialBaseArray: 20544 zig_unreachable(); 20545 case ConstPtrSpecialBaseStruct: 20546 zig_panic("TODO"); 20547 case ConstPtrSpecialBaseErrorUnionCode: 20548 zig_panic("TODO"); 20549 case ConstPtrSpecialBaseErrorUnionPayload: 20550 zig_panic("TODO"); 20551 case ConstPtrSpecialBaseOptionalPayload: 20552 zig_panic("TODO"); 20553 case ConstPtrSpecialHardCodedAddr: 20554 init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, 20555 parent_ptr->type->data.pointer.child_type, 20556 parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, 20557 slice_is_const(return_type)); 20558 break; 20559 case ConstPtrSpecialFunction: 20560 zig_panic("TODO"); 20561 case ConstPtrSpecialNull: 20562 zig_panic("TODO"); 20563 } 20564 20565 ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; 20566 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); 20567 20568 return result; 20569 } 20570 20571 IrInstruction *new_instruction = ir_build_slice(&ira->new_irb, 20572 instruction->base.scope, instruction->base.source_node, 20573 ptr_ptr, casted_start, end, instruction->safety_check_on); 20574 new_instruction->value.type = return_type; 20575 ir_add_alloca(ira, new_instruction, return_type); 20576 return new_instruction; 20577 } 20578 20579 static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { 20580 Error err; 20581 IrInstruction *container = instruction->container->child; 20582 if (type_is_invalid(container->value.type)) 20583 return ira->codegen->invalid_instruction; 20584 ZigType *container_type = ir_resolve_type(ira, container); 20585 20586 if ((err = ensure_complete_type(ira->codegen, container_type))) 20587 return ira->codegen->invalid_instruction; 20588 20589 uint64_t result; 20590 if (type_is_invalid(container_type)) { 20591 return ira->codegen->invalid_instruction; 20592 } else if (container_type->id == ZigTypeIdEnum) { 20593 result = container_type->data.enumeration.src_field_count; 20594 } else if (container_type->id == ZigTypeIdStruct) { 20595 result = container_type->data.structure.src_field_count; 20596 } else if (container_type->id == ZigTypeIdUnion) { 20597 result = container_type->data.unionation.src_field_count; 20598 } else if (container_type->id == ZigTypeIdErrorSet) { 20599 if (!resolve_inferred_error_set(ira->codegen, container_type, instruction->base.source_node)) { 20600 return ira->codegen->invalid_instruction; 20601 } 20602 if (type_is_global_error_set(container_type)) { 20603 ir_add_error(ira, &instruction->base, buf_sprintf("global error set member count not available at comptime")); 20604 return ira->codegen->invalid_instruction; 20605 } 20606 result = container_type->data.error_set.err_count; 20607 } else { 20608 ir_add_error(ira, &instruction->base, buf_sprintf("no value count available for type '%s'", buf_ptr(&container_type->name))); 20609 return ira->codegen->invalid_instruction; 20610 } 20611 20612 return ir_const_unsigned(ira, &instruction->base, result); 20613 } 20614 20615 static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstructionMemberType *instruction) { 20616 Error err; 20617 IrInstruction *container_type_value = instruction->container_type->child; 20618 ZigType *container_type = ir_resolve_type(ira, container_type_value); 20619 if (type_is_invalid(container_type)) 20620 return ira->codegen->invalid_instruction; 20621 20622 if ((err = ensure_complete_type(ira->codegen, container_type))) 20623 return ira->codegen->invalid_instruction; 20624 20625 20626 uint64_t member_index; 20627 IrInstruction *index_value = instruction->member_index->child; 20628 if (!ir_resolve_usize(ira, index_value, &member_index)) 20629 return ira->codegen->invalid_instruction; 20630 20631 if (container_type->id == ZigTypeIdStruct) { 20632 if (member_index >= container_type->data.structure.src_field_count) { 20633 ir_add_error(ira, index_value, 20634 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 20635 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); 20636 return ira->codegen->invalid_instruction; 20637 } 20638 TypeStructField *field = &container_type->data.structure.fields[member_index]; 20639 20640 return ir_const_type(ira, &instruction->base, field->type_entry); 20641 } else if (container_type->id == ZigTypeIdUnion) { 20642 if (member_index >= container_type->data.unionation.src_field_count) { 20643 ir_add_error(ira, index_value, 20644 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 20645 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); 20646 return ira->codegen->invalid_instruction; 20647 } 20648 TypeUnionField *field = &container_type->data.unionation.fields[member_index]; 20649 20650 return ir_const_type(ira, &instruction->base, field->type_entry); 20651 } else { 20652 ir_add_error(ira, container_type_value, 20653 buf_sprintf("type '%s' does not support @memberType", buf_ptr(&container_type->name))); 20654 return ira->codegen->invalid_instruction; 20655 } 20656 } 20657 20658 static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstructionMemberName *instruction) { 20659 Error err; 20660 IrInstruction *container_type_value = instruction->container_type->child; 20661 ZigType *container_type = ir_resolve_type(ira, container_type_value); 20662 if (type_is_invalid(container_type)) 20663 return ira->codegen->invalid_instruction; 20664 20665 if ((err = ensure_complete_type(ira->codegen, container_type))) 20666 return ira->codegen->invalid_instruction; 20667 20668 uint64_t member_index; 20669 IrInstruction *index_value = instruction->member_index->child; 20670 if (!ir_resolve_usize(ira, index_value, &member_index)) 20671 return ira->codegen->invalid_instruction; 20672 20673 if (container_type->id == ZigTypeIdStruct) { 20674 if (member_index >= container_type->data.structure.src_field_count) { 20675 ir_add_error(ira, index_value, 20676 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 20677 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); 20678 return ira->codegen->invalid_instruction; 20679 } 20680 TypeStructField *field = &container_type->data.structure.fields[member_index]; 20681 20682 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 20683 init_const_str_lit(ira->codegen, &result->value, field->name); 20684 return result; 20685 } else if (container_type->id == ZigTypeIdEnum) { 20686 if (member_index >= container_type->data.enumeration.src_field_count) { 20687 ir_add_error(ira, index_value, 20688 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 20689 member_index, buf_ptr(&container_type->name), container_type->data.enumeration.src_field_count)); 20690 return ira->codegen->invalid_instruction; 20691 } 20692 TypeEnumField *field = &container_type->data.enumeration.fields[member_index]; 20693 20694 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 20695 init_const_str_lit(ira->codegen, &result->value, field->name); 20696 return result; 20697 } else if (container_type->id == ZigTypeIdUnion) { 20698 if (member_index >= container_type->data.unionation.src_field_count) { 20699 ir_add_error(ira, index_value, 20700 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 20701 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); 20702 return ira->codegen->invalid_instruction; 20703 } 20704 TypeUnionField *field = &container_type->data.unionation.fields[member_index]; 20705 20706 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 20707 init_const_str_lit(ira->codegen, &result->value, field->name); 20708 return result; 20709 } else { 20710 ir_add_error(ira, container_type_value, 20711 buf_sprintf("type '%s' does not support @memberName", buf_ptr(&container_type->name))); 20712 return ira->codegen->invalid_instruction; 20713 } 20714 } 20715 20716 static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) { 20717 IrInstruction *result = ir_build_breakpoint(&ira->new_irb, 20718 instruction->base.scope, instruction->base.source_node); 20719 result->value.type = ira->codegen->builtin_types.entry_void; 20720 return result; 20721 } 20722 20723 static IrInstruction *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstructionReturnAddress *instruction) { 20724 IrInstruction *result = ir_build_return_address(&ira->new_irb, 20725 instruction->base.scope, instruction->base.source_node); 20726 result->value.type = ira->codegen->builtin_types.entry_usize; 20727 return result; 20728 } 20729 20730 static IrInstruction *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstructionFrameAddress *instruction) { 20731 IrInstruction *result = ir_build_frame_address(&ira->new_irb, 20732 instruction->base.scope, instruction->base.source_node); 20733 result->value.type = ira->codegen->builtin_types.entry_usize; 20734 return result; 20735 } 20736 20737 static IrInstruction *ir_analyze_instruction_handle(IrAnalyze *ira, IrInstructionHandle *instruction) { 20738 IrInstruction *result = ir_build_handle(&ira->new_irb, instruction->base.scope, instruction->base.source_node); 20739 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 20740 assert(fn_entry != nullptr); 20741 result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type); 20742 return result; 20743 } 20744 20745 static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { 20746 Error err; 20747 IrInstruction *type_value = instruction->type_value->child; 20748 if (type_is_invalid(type_value->value.type)) 20749 return ira->codegen->invalid_instruction; 20750 ZigType *type_entry = ir_resolve_type(ira, type_value); 20751 20752 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusAlignmentKnown))) 20753 return ira->codegen->invalid_instruction; 20754 20755 switch (type_entry->id) { 20756 case ZigTypeIdInvalid: 20757 zig_unreachable(); 20758 case ZigTypeIdMetaType: 20759 case ZigTypeIdUnreachable: 20760 case ZigTypeIdComptimeFloat: 20761 case ZigTypeIdComptimeInt: 20762 case ZigTypeIdEnumLiteral: 20763 case ZigTypeIdUndefined: 20764 case ZigTypeIdNull: 20765 case ZigTypeIdBoundFn: 20766 case ZigTypeIdArgTuple: 20767 case ZigTypeIdVoid: 20768 case ZigTypeIdOpaque: 20769 ir_add_error(ira, instruction->type_value, 20770 buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); 20771 return ira->codegen->invalid_instruction; 20772 case ZigTypeIdBool: 20773 case ZigTypeIdInt: 20774 case ZigTypeIdFloat: 20775 case ZigTypeIdPointer: 20776 case ZigTypeIdPromise: 20777 case ZigTypeIdArray: 20778 case ZigTypeIdStruct: 20779 case ZigTypeIdOptional: 20780 case ZigTypeIdErrorUnion: 20781 case ZigTypeIdErrorSet: 20782 case ZigTypeIdEnum: 20783 case ZigTypeIdUnion: 20784 case ZigTypeIdFn: 20785 case ZigTypeIdVector: 20786 { 20787 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); 20788 return ir_const_unsigned(ira, &instruction->base, align_in_bytes); 20789 } 20790 } 20791 zig_unreachable(); 20792 } 20793 20794 static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { 20795 Error err; 20796 20797 IrInstruction *type_value = instruction->type_value->child; 20798 if (type_is_invalid(type_value->value.type)) 20799 return ira->codegen->invalid_instruction; 20800 20801 ZigType *dest_type = ir_resolve_type(ira, type_value); 20802 if (type_is_invalid(dest_type)) 20803 return ira->codegen->invalid_instruction; 20804 20805 if (dest_type->id != ZigTypeIdInt) { 20806 ir_add_error(ira, type_value, 20807 buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 20808 return ira->codegen->invalid_instruction; 20809 } 20810 20811 IrInstruction *op1 = instruction->op1->child; 20812 if (type_is_invalid(op1->value.type)) 20813 return ira->codegen->invalid_instruction; 20814 20815 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 20816 if (type_is_invalid(casted_op1->value.type)) 20817 return ira->codegen->invalid_instruction; 20818 20819 IrInstruction *op2 = instruction->op2->child; 20820 if (type_is_invalid(op2->value.type)) 20821 return ira->codegen->invalid_instruction; 20822 20823 IrInstruction *casted_op2; 20824 if (instruction->op == IrOverflowOpShl) { 20825 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 20826 dest_type->data.integral.bit_count - 1); 20827 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 20828 } else { 20829 casted_op2 = ir_implicit_cast(ira, op2, dest_type); 20830 } 20831 if (type_is_invalid(casted_op2->value.type)) 20832 return ira->codegen->invalid_instruction; 20833 20834 IrInstruction *result_ptr = instruction->result_ptr->child; 20835 if (type_is_invalid(result_ptr->value.type)) 20836 return ira->codegen->invalid_instruction; 20837 20838 ZigType *expected_ptr_type; 20839 if (result_ptr->value.type->id == ZigTypeIdPointer) { 20840 uint32_t alignment; 20841 if ((err = resolve_ptr_align(ira, result_ptr->value.type, &alignment))) 20842 return ira->codegen->invalid_instruction; 20843 expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type, 20844 false, result_ptr->value.type->data.pointer.is_volatile, 20845 PtrLenSingle, 20846 alignment, 0, 0, false); 20847 } else { 20848 expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false); 20849 } 20850 20851 IrInstruction *casted_result_ptr = ir_implicit_cast(ira, result_ptr, expected_ptr_type); 20852 if (type_is_invalid(casted_result_ptr->value.type)) 20853 return ira->codegen->invalid_instruction; 20854 20855 if (casted_op1->value.special == ConstValSpecialStatic && 20856 casted_op2->value.special == ConstValSpecialStatic && 20857 casted_result_ptr->value.special == ConstValSpecialStatic) 20858 { 20859 BigInt *op1_bigint = &casted_op1->value.data.x_bigint; 20860 BigInt *op2_bigint = &casted_op2->value.data.x_bigint; 20861 ConstExprValue *pointee_val = const_ptr_pointee(ira, ira->codegen, &casted_result_ptr->value, casted_result_ptr->source_node); 20862 if (pointee_val == nullptr) 20863 return ira->codegen->invalid_instruction; 20864 BigInt *dest_bigint = &pointee_val->data.x_bigint; 20865 switch (instruction->op) { 20866 case IrOverflowOpAdd: 20867 bigint_add(dest_bigint, op1_bigint, op2_bigint); 20868 break; 20869 case IrOverflowOpSub: 20870 bigint_sub(dest_bigint, op1_bigint, op2_bigint); 20871 break; 20872 case IrOverflowOpMul: 20873 bigint_mul(dest_bigint, op1_bigint, op2_bigint); 20874 break; 20875 case IrOverflowOpShl: 20876 bigint_shl(dest_bigint, op1_bigint, op2_bigint); 20877 break; 20878 } 20879 bool result_bool = false; 20880 if (!bigint_fits_in_bits(dest_bigint, dest_type->data.integral.bit_count, 20881 dest_type->data.integral.is_signed)) 20882 { 20883 result_bool = true; 20884 BigInt tmp_bigint; 20885 bigint_init_bigint(&tmp_bigint, dest_bigint); 20886 bigint_truncate(dest_bigint, &tmp_bigint, dest_type->data.integral.bit_count, 20887 dest_type->data.integral.is_signed); 20888 } 20889 pointee_val->special = ConstValSpecialStatic; 20890 return ir_const_bool(ira, &instruction->base, result_bool); 20891 } 20892 20893 IrInstruction *result = ir_build_overflow_op(&ira->new_irb, 20894 instruction->base.scope, instruction->base.source_node, 20895 instruction->op, type_value, casted_op1, casted_op2, casted_result_ptr, dest_type); 20896 result->value.type = ira->codegen->builtin_types.entry_bool; 20897 return result; 20898 } 20899 20900 static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErr *instruction) { 20901 IrInstruction *value = instruction->value->child; 20902 if (type_is_invalid(value->value.type)) 20903 return ira->codegen->invalid_instruction; 20904 20905 ZigType *type_entry = value->value.type; 20906 if (type_is_invalid(type_entry)) { 20907 return ira->codegen->invalid_instruction; 20908 } else if (type_entry->id == ZigTypeIdErrorUnion) { 20909 if (instr_is_comptime(value)) { 20910 ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); 20911 if (!err_union_val) 20912 return ira->codegen->invalid_instruction; 20913 20914 if (err_union_val->special != ConstValSpecialRuntime) { 20915 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 20916 return ir_const_bool(ira, &instruction->base, (err != nullptr)); 20917 } 20918 } 20919 20920 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 20921 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { 20922 return ira->codegen->invalid_instruction; 20923 } 20924 if (!type_is_global_error_set(err_set_type) && 20925 err_set_type->data.error_set.err_count == 0) 20926 { 20927 assert(err_set_type->data.error_set.infer_fn == nullptr); 20928 return ir_const_bool(ira, &instruction->base, false); 20929 } 20930 20931 IrInstruction *result = ir_build_test_err(&ira->new_irb, 20932 instruction->base.scope, instruction->base.source_node, value); 20933 result->value.type = ira->codegen->builtin_types.entry_bool; 20934 return result; 20935 } else if (type_entry->id == ZigTypeIdErrorSet) { 20936 return ir_const_bool(ira, &instruction->base, true); 20937 } else { 20938 return ir_const_bool(ira, &instruction->base, false); 20939 } 20940 } 20941 20942 static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstructionUnwrapErrCode *instruction) { 20943 IrInstruction *base_ptr = instruction->err_union->child; 20944 if (type_is_invalid(base_ptr->value.type)) 20945 return ira->codegen->invalid_instruction; 20946 ZigType *ptr_type = base_ptr->value.type; 20947 20948 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 20949 assert(ptr_type->id == ZigTypeIdPointer); 20950 20951 ZigType *type_entry = ptr_type->data.pointer.child_type; 20952 if (type_is_invalid(type_entry)) 20953 return ira->codegen->invalid_instruction; 20954 20955 if (type_entry->id != ZigTypeIdErrorUnion) { 20956 ir_add_error(ira, base_ptr, 20957 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 20958 return ira->codegen->invalid_instruction; 20959 } 20960 20961 if (instr_is_comptime(base_ptr)) { 20962 ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 20963 if (!ptr_val) 20964 return ira->codegen->invalid_instruction; 20965 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); 20966 if (err_union_val == nullptr) 20967 return ira->codegen->invalid_instruction; 20968 if (err_union_val->special != ConstValSpecialRuntime) { 20969 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 20970 assert(err); 20971 20972 IrInstruction *result = ir_const(ira, &instruction->base, 20973 type_entry->data.error_union.err_set_type); 20974 result->value.data.x_err_set = err; 20975 return result; 20976 } 20977 } 20978 20979 IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, 20980 instruction->base.scope, instruction->base.source_node, base_ptr); 20981 result->value.type = type_entry->data.error_union.err_set_type; 20982 return result; 20983 } 20984 20985 static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, 20986 IrInstructionUnwrapErrPayload *instruction) 20987 { 20988 assert(instruction->value->child); 20989 IrInstruction *value = instruction->value->child; 20990 if (type_is_invalid(value->value.type)) 20991 return ira->codegen->invalid_instruction; 20992 ZigType *ptr_type = value->value.type; 20993 20994 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 20995 assert(ptr_type->id == ZigTypeIdPointer); 20996 20997 ZigType *type_entry = ptr_type->data.pointer.child_type; 20998 if (type_is_invalid(type_entry)) 20999 return ira->codegen->invalid_instruction; 21000 21001 if (type_entry->id != ZigTypeIdErrorUnion) { 21002 ir_add_error(ira, value, 21003 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 21004 return ira->codegen->invalid_instruction; 21005 } 21006 21007 ZigType *payload_type = type_entry->data.error_union.payload_type; 21008 if (type_is_invalid(payload_type)) 21009 return ira->codegen->invalid_instruction; 21010 21011 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, 21012 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21013 PtrLenSingle, 0, 0, 0, false); 21014 if (instr_is_comptime(value)) { 21015 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); 21016 if (!ptr_val) 21017 return ira->codegen->invalid_instruction; 21018 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); 21019 if (err_union_val == nullptr) 21020 return ira->codegen->invalid_instruction; 21021 if (err_union_val->special != ConstValSpecialRuntime) { 21022 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 21023 if (err != nullptr) { 21024 ir_add_error(ira, &instruction->base, 21025 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); 21026 return ira->codegen->invalid_instruction; 21027 } 21028 21029 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 21030 result->value.data.x_ptr.special = ConstPtrSpecialRef; 21031 result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; 21032 return result; 21033 } 21034 } 21035 21036 IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, 21037 instruction->base.scope, instruction->base.source_node, value, instruction->safety_check_on); 21038 result->value.type = result_type; 21039 return result; 21040 } 21041 21042 static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { 21043 AstNode *proto_node = instruction->base.source_node; 21044 assert(proto_node->type == NodeTypeFnProto); 21045 21046 if (proto_node->data.fn_proto.auto_err_set) { 21047 ir_add_error(ira, &instruction->base, 21048 buf_sprintf("inferring error set of return type valid only for function definitions")); 21049 return ira->codegen->invalid_instruction; 21050 } 21051 21052 FnTypeId fn_type_id = {0}; 21053 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); 21054 21055 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { 21056 AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); 21057 assert(param_node->type == NodeTypeParamDecl); 21058 21059 bool param_is_var_args = param_node->data.param_decl.is_var_args; 21060 if (param_is_var_args) { 21061 if (fn_type_id.cc == CallingConventionC) { 21062 fn_type_id.param_count = fn_type_id.next_param_index; 21063 continue; 21064 } else if (fn_type_id.cc == CallingConventionUnspecified) { 21065 return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); 21066 } else { 21067 zig_unreachable(); 21068 } 21069 } 21070 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; 21071 param_info->is_noalias = param_node->data.param_decl.is_noalias; 21072 21073 if (instruction->param_types[fn_type_id.next_param_index] == nullptr) { 21074 param_info->type = nullptr; 21075 return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); 21076 } else { 21077 IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->child; 21078 if (type_is_invalid(param_type_value->value.type)) 21079 return ira->codegen->invalid_instruction; 21080 ZigType *param_type = ir_resolve_type(ira, param_type_value); 21081 switch (type_requires_comptime(ira->codegen, param_type)) { 21082 case ReqCompTimeYes: 21083 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 21084 ir_add_error(ira, param_type_value, 21085 buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", 21086 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 21087 return ira->codegen->invalid_instruction; 21088 } 21089 param_info->type = param_type; 21090 fn_type_id.next_param_index += 1; 21091 return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); 21092 case ReqCompTimeInvalid: 21093 return ira->codegen->invalid_instruction; 21094 case ReqCompTimeNo: 21095 break; 21096 } 21097 if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { 21098 ir_add_error(ira, param_type_value, 21099 buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", 21100 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 21101 return ira->codegen->invalid_instruction; 21102 } 21103 param_info->type = param_type; 21104 } 21105 21106 } 21107 21108 if (instruction->align_value != nullptr) { 21109 if (!ir_resolve_align(ira, instruction->align_value->child, &fn_type_id.alignment)) 21110 return ira->codegen->invalid_instruction; 21111 } 21112 21113 IrInstruction *return_type_value = instruction->return_type->child; 21114 fn_type_id.return_type = ir_resolve_type(ira, return_type_value); 21115 if (type_is_invalid(fn_type_id.return_type)) 21116 return ira->codegen->invalid_instruction; 21117 if (fn_type_id.return_type->id == ZigTypeIdOpaque) { 21118 ir_add_error(ira, instruction->return_type, 21119 buf_sprintf("return type cannot be opaque")); 21120 return ira->codegen->invalid_instruction; 21121 } 21122 21123 if (fn_type_id.cc == CallingConventionAsync) { 21124 if (instruction->async_allocator_type_value == nullptr) { 21125 ir_add_error(ira, &instruction->base, 21126 buf_sprintf("async fn proto missing allocator type")); 21127 return ira->codegen->invalid_instruction; 21128 } 21129 IrInstruction *async_allocator_type_value = instruction->async_allocator_type_value->child; 21130 fn_type_id.async_allocator_type = ir_resolve_type(ira, async_allocator_type_value); 21131 if (type_is_invalid(fn_type_id.async_allocator_type)) 21132 return ira->codegen->invalid_instruction; 21133 } 21134 21135 return ir_const_type(ira, &instruction->base, get_fn_type(ira->codegen, &fn_type_id)); 21136 } 21137 21138 static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { 21139 IrInstruction *value = instruction->value->child; 21140 if (type_is_invalid(value->value.type)) 21141 return ira->codegen->invalid_instruction; 21142 21143 return ir_const_bool(ira, &instruction->base, instr_is_comptime(value)); 21144 } 21145 21146 static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, 21147 IrInstructionCheckSwitchProngs *instruction) 21148 { 21149 IrInstruction *target_value = instruction->target_value->child; 21150 ZigType *switch_type = target_value->value.type; 21151 if (type_is_invalid(switch_type)) 21152 return ira->codegen->invalid_instruction; 21153 21154 if (switch_type->id == ZigTypeIdEnum) { 21155 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> field_prev_uses = {}; 21156 field_prev_uses.init(switch_type->data.enumeration.src_field_count); 21157 21158 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 21159 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 21160 21161 IrInstruction *start_value_uncasted = range->start->child; 21162 if (type_is_invalid(start_value_uncasted->value.type)) 21163 return ira->codegen->invalid_instruction; 21164 IrInstruction *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 21165 if (type_is_invalid(start_value->value.type)) 21166 return ira->codegen->invalid_instruction; 21167 21168 IrInstruction *end_value_uncasted = range->end->child; 21169 if (type_is_invalid(end_value_uncasted->value.type)) 21170 return ira->codegen->invalid_instruction; 21171 IrInstruction *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 21172 if (type_is_invalid(end_value->value.type)) 21173 return ira->codegen->invalid_instruction; 21174 21175 BigInt start_index; 21176 bigint_init_bigint(&start_index, &start_value->value.data.x_enum_tag); 21177 21178 assert(end_value->value.type->id == ZigTypeIdEnum); 21179 BigInt end_index; 21180 bigint_init_bigint(&end_index, &end_value->value.data.x_enum_tag); 21181 21182 BigInt field_index; 21183 bigint_init_bigint(&field_index, &start_index); 21184 for (;;) { 21185 Cmp cmp = bigint_cmp(&field_index, &end_index); 21186 if (cmp == CmpGT) { 21187 break; 21188 } 21189 auto entry = field_prev_uses.put_unique(field_index, start_value->source_node); 21190 if (entry) { 21191 AstNode *prev_node = entry->value; 21192 TypeEnumField *enum_field = find_enum_field_by_tag(switch_type, &field_index); 21193 assert(enum_field != nullptr); 21194 ErrorMsg *msg = ir_add_error(ira, start_value, 21195 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), 21196 buf_ptr(enum_field->name))); 21197 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 21198 } 21199 bigint_incr(&field_index); 21200 } 21201 } 21202 if (!instruction->have_else_prong) { 21203 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { 21204 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; 21205 21206 auto entry = field_prev_uses.maybe_get(enum_field->value); 21207 if (!entry) { 21208 ir_add_error(ira, &instruction->base, 21209 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), 21210 buf_ptr(enum_field->name))); 21211 } 21212 } 21213 } 21214 } else if (switch_type->id == ZigTypeIdErrorSet) { 21215 if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->source_node)) { 21216 return ira->codegen->invalid_instruction; 21217 } 21218 21219 AstNode **field_prev_uses = allocate<AstNode *>(ira->codegen->errors_by_index.length); 21220 21221 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 21222 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 21223 21224 IrInstruction *start_value_uncasted = range->start->child; 21225 if (type_is_invalid(start_value_uncasted->value.type)) 21226 return ira->codegen->invalid_instruction; 21227 IrInstruction *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 21228 if (type_is_invalid(start_value->value.type)) 21229 return ira->codegen->invalid_instruction; 21230 21231 IrInstruction *end_value_uncasted = range->end->child; 21232 if (type_is_invalid(end_value_uncasted->value.type)) 21233 return ira->codegen->invalid_instruction; 21234 IrInstruction *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 21235 if (type_is_invalid(end_value->value.type)) 21236 return ira->codegen->invalid_instruction; 21237 21238 ir_assert(start_value->value.type->id == ZigTypeIdErrorSet, &instruction->base); 21239 uint32_t start_index = start_value->value.data.x_err_set->value; 21240 21241 ir_assert(end_value->value.type->id == ZigTypeIdErrorSet, &instruction->base); 21242 uint32_t end_index = end_value->value.data.x_err_set->value; 21243 21244 if (start_index != end_index) { 21245 ir_add_error(ira, end_value, buf_sprintf("ranges not allowed when switching on errors")); 21246 return ira->codegen->invalid_instruction; 21247 } 21248 21249 AstNode *prev_node = field_prev_uses[start_index]; 21250 if (prev_node != nullptr) { 21251 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name; 21252 ErrorMsg *msg = ir_add_error(ira, start_value, 21253 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name))); 21254 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 21255 } 21256 field_prev_uses[start_index] = start_value->source_node; 21257 } 21258 if (!instruction->have_else_prong) { 21259 if (type_is_global_error_set(switch_type)) { 21260 ir_add_error(ira, &instruction->base, 21261 buf_sprintf("else prong required when switching on type 'anyerror'")); 21262 return ira->codegen->invalid_instruction; 21263 } else { 21264 for (uint32_t i = 0; i < switch_type->data.error_set.err_count; i += 1) { 21265 ErrorTableEntry *err_entry = switch_type->data.error_set.errors[i]; 21266 21267 AstNode *prev_node = field_prev_uses[err_entry->value]; 21268 if (prev_node == nullptr) { 21269 ir_add_error(ira, &instruction->base, 21270 buf_sprintf("error.%s not handled in switch", buf_ptr(&err_entry->name))); 21271 } 21272 } 21273 } 21274 } 21275 21276 free(field_prev_uses); 21277 } else if (switch_type->id == ZigTypeIdInt) { 21278 RangeSet rs = {0}; 21279 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 21280 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 21281 21282 IrInstruction *start_value = range->start->child; 21283 if (type_is_invalid(start_value->value.type)) 21284 return ira->codegen->invalid_instruction; 21285 IrInstruction *casted_start_value = ir_implicit_cast(ira, start_value, switch_type); 21286 if (type_is_invalid(casted_start_value->value.type)) 21287 return ira->codegen->invalid_instruction; 21288 21289 IrInstruction *end_value = range->end->child; 21290 if (type_is_invalid(end_value->value.type)) 21291 return ira->codegen->invalid_instruction; 21292 IrInstruction *casted_end_value = ir_implicit_cast(ira, end_value, switch_type); 21293 if (type_is_invalid(casted_end_value->value.type)) 21294 return ira->codegen->invalid_instruction; 21295 21296 ConstExprValue *start_val = ir_resolve_const(ira, casted_start_value, UndefBad); 21297 if (!start_val) 21298 return ira->codegen->invalid_instruction; 21299 21300 ConstExprValue *end_val = ir_resolve_const(ira, casted_end_value, UndefBad); 21301 if (!end_val) 21302 return ira->codegen->invalid_instruction; 21303 21304 assert(start_val->type->id == ZigTypeIdInt || start_val->type->id == ZigTypeIdComptimeInt); 21305 assert(end_val->type->id == ZigTypeIdInt || end_val->type->id == ZigTypeIdComptimeInt); 21306 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint, 21307 start_value->source_node); 21308 if (prev_node != nullptr) { 21309 ErrorMsg *msg = ir_add_error(ira, start_value, buf_sprintf("duplicate switch value")); 21310 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("previous value is here")); 21311 return ira->codegen->invalid_instruction; 21312 } 21313 } 21314 if (!instruction->have_else_prong) { 21315 BigInt min_val; 21316 eval_min_max_value_int(ira->codegen, switch_type, &min_val, false); 21317 BigInt max_val; 21318 eval_min_max_value_int(ira->codegen, switch_type, &max_val, true); 21319 if (!rangeset_spans(&rs, &min_val, &max_val)) { 21320 ir_add_error(ira, &instruction->base, buf_sprintf("switch must handle all possibilities")); 21321 return ira->codegen->invalid_instruction; 21322 } 21323 } 21324 } else if (switch_type->id == ZigTypeIdBool) { 21325 int seenTrue = 0; 21326 int seenFalse = 0; 21327 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 21328 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 21329 21330 IrInstruction *value = range->start->child; 21331 21332 IrInstruction *casted_value = ir_implicit_cast(ira, value, switch_type); 21333 if (type_is_invalid(casted_value->value.type)) 21334 return ira->codegen->invalid_instruction; 21335 21336 ConstExprValue *const_expr_val = ir_resolve_const(ira, casted_value, UndefBad); 21337 if (!const_expr_val) 21338 return ira->codegen->invalid_instruction; 21339 21340 assert(const_expr_val->type->id == ZigTypeIdBool); 21341 21342 if (const_expr_val->data.x_bool == true) { 21343 seenTrue += 1; 21344 } else { 21345 seenFalse += 1; 21346 } 21347 21348 if ((seenTrue > 1) || (seenFalse > 1)) { 21349 ir_add_error(ira, value, buf_sprintf("duplicate switch value")); 21350 return ira->codegen->invalid_instruction; 21351 } 21352 } 21353 if (((seenTrue < 1) || (seenFalse < 1)) && !instruction->have_else_prong) { 21354 ir_add_error(ira, &instruction->base, buf_sprintf("switch must handle all possibilities")); 21355 return ira->codegen->invalid_instruction; 21356 } 21357 } else if (!instruction->have_else_prong) { 21358 ir_add_error(ira, &instruction->base, 21359 buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); 21360 return ira->codegen->invalid_instruction; 21361 } 21362 return ir_const_void(ira, &instruction->base); 21363 } 21364 21365 static IrInstruction *ir_analyze_instruction_check_statement_is_void(IrAnalyze *ira, 21366 IrInstructionCheckStatementIsVoid *instruction) 21367 { 21368 IrInstruction *statement_value = instruction->statement_value->child; 21369 ZigType *statement_type = statement_value->value.type; 21370 if (type_is_invalid(statement_type)) 21371 return ira->codegen->invalid_instruction; 21372 21373 if (statement_type->id != ZigTypeIdVoid) { 21374 ir_add_error(ira, &instruction->base, buf_sprintf("expression value is ignored")); 21375 } 21376 21377 return ir_const_void(ira, &instruction->base); 21378 } 21379 21380 static IrInstruction *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructionPanic *instruction) { 21381 IrInstruction *msg = instruction->msg->child; 21382 if (type_is_invalid(msg->value.type)) 21383 return ir_unreach_error(ira); 21384 21385 if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) { 21386 ir_add_error(ira, &instruction->base, buf_sprintf("encountered @panic at compile-time")); 21387 return ir_unreach_error(ira); 21388 } 21389 21390 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 21391 true, false, PtrLenUnknown, 0, 0, 0, false); 21392 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 21393 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type); 21394 if (type_is_invalid(casted_msg->value.type)) 21395 return ir_unreach_error(ira); 21396 21397 IrInstruction *new_instruction = ir_build_panic(&ira->new_irb, instruction->base.scope, 21398 instruction->base.source_node, casted_msg); 21399 return ir_finish_anal(ira, new_instruction); 21400 } 21401 21402 static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint32_t align_bytes, bool safety_check_on) { 21403 Error err; 21404 21405 ZigType *target_type = target->value.type; 21406 assert(!type_is_invalid(target_type)); 21407 21408 ZigType *result_type; 21409 uint32_t old_align_bytes; 21410 21411 if (target_type->id == ZigTypeIdPointer) { 21412 result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes); 21413 if ((err = resolve_ptr_align(ira, target_type, &old_align_bytes))) 21414 return ira->codegen->invalid_instruction; 21415 } else if (target_type->id == ZigTypeIdFn) { 21416 FnTypeId fn_type_id = target_type->data.fn.fn_type_id; 21417 old_align_bytes = fn_type_id.alignment; 21418 fn_type_id.alignment = align_bytes; 21419 result_type = get_fn_type(ira->codegen, &fn_type_id); 21420 } else if (target_type->id == ZigTypeIdOptional && 21421 target_type->data.maybe.child_type->id == ZigTypeIdPointer) 21422 { 21423 ZigType *ptr_type = target_type->data.maybe.child_type; 21424 if ((err = resolve_ptr_align(ira, ptr_type, &old_align_bytes))) 21425 return ira->codegen->invalid_instruction; 21426 ZigType *better_ptr_type = adjust_ptr_align(ira->codegen, ptr_type, align_bytes); 21427 21428 result_type = get_optional_type(ira->codegen, better_ptr_type); 21429 } else if (target_type->id == ZigTypeIdOptional && 21430 target_type->data.maybe.child_type->id == ZigTypeIdFn) 21431 { 21432 FnTypeId fn_type_id = target_type->data.maybe.child_type->data.fn.fn_type_id; 21433 old_align_bytes = fn_type_id.alignment; 21434 fn_type_id.alignment = align_bytes; 21435 ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id); 21436 result_type = get_optional_type(ira->codegen, fn_type); 21437 } else if (is_slice(target_type)) { 21438 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry; 21439 if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes))) 21440 return ira->codegen->invalid_instruction; 21441 ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes); 21442 result_type = get_slice_type(ira->codegen, result_ptr_type); 21443 } else { 21444 ir_add_error(ira, target, 21445 buf_sprintf("expected pointer or slice, found '%s'", buf_ptr(&target_type->name))); 21446 return ira->codegen->invalid_instruction; 21447 } 21448 21449 if (instr_is_comptime(target)) { 21450 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 21451 if (!val) 21452 return ira->codegen->invalid_instruction; 21453 21454 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 21455 val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0) 21456 { 21457 ir_add_error(ira, target, 21458 buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes", 21459 val->data.x_ptr.data.hard_coded_addr.addr, align_bytes)); 21460 return ira->codegen->invalid_instruction; 21461 } 21462 21463 IrInstruction *result = ir_const(ira, target, result_type); 21464 copy_const_val(&result->value, val, true); 21465 result->value.type = result_type; 21466 return result; 21467 } 21468 21469 IrInstruction *result; 21470 if (safety_check_on && align_bytes > old_align_bytes && align_bytes != 1) { 21471 result = ir_build_align_cast(&ira->new_irb, target->scope, target->source_node, nullptr, target); 21472 } else { 21473 result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, result_type, target, CastOpNoop); 21474 } 21475 result->value.type = result_type; 21476 return result; 21477 } 21478 21479 static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, 21480 ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on) 21481 { 21482 Error err; 21483 21484 ZigType *src_type = ptr->value.type; 21485 assert(!type_is_invalid(src_type)); 21486 21487 // We have a check for zero bits later so we use get_src_ptr_type to 21488 // validate src_type and dest_type. 21489 21490 ZigType *src_ptr_type = get_src_ptr_type(src_type); 21491 if (src_ptr_type == nullptr) { 21492 ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); 21493 return ira->codegen->invalid_instruction; 21494 } 21495 21496 ZigType *dest_ptr_type = get_src_ptr_type(dest_type); 21497 if (dest_ptr_type == nullptr) { 21498 ir_add_error(ira, dest_type_src, 21499 buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 21500 return ira->codegen->invalid_instruction; 21501 } 21502 21503 if (get_ptr_const(src_type) && !get_ptr_const(dest_type)) { 21504 ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); 21505 return ira->codegen->invalid_instruction; 21506 } 21507 uint32_t src_align_bytes; 21508 if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) 21509 return ira->codegen->invalid_instruction; 21510 21511 uint32_t dest_align_bytes; 21512 if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) 21513 return ira->codegen->invalid_instruction; 21514 21515 if (instr_is_comptime(ptr)) { 21516 bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); 21517 UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad; 21518 ConstExprValue *val = ir_resolve_const(ira, ptr, is_undef_allowed); 21519 if (!val) 21520 return ira->codegen->invalid_instruction; 21521 21522 if (val->special == ConstValSpecialStatic) { 21523 bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || 21524 (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 21525 val->data.x_ptr.data.hard_coded_addr.addr == 0); 21526 if (is_addr_zero && !dest_allows_addr_zero) { 21527 ir_add_error(ira, source_instr, 21528 buf_sprintf("null pointer casted to type '%s'", buf_ptr(&dest_type->name))); 21529 return ira->codegen->invalid_instruction; 21530 } 21531 } 21532 21533 IrInstruction *result = ir_const(ira, source_instr, dest_type); 21534 copy_const_val(&result->value, val, true); 21535 result->value.type = dest_type; 21536 21537 // Keep the bigger alignment, it can only help- 21538 // unless the target is zero bits. 21539 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { 21540 result = ir_align_cast(ira, result, src_align_bytes, false); 21541 } 21542 21543 return result; 21544 } 21545 21546 if (dest_align_bytes > src_align_bytes) { 21547 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 21548 add_error_note(ira->codegen, msg, ptr->source_node, 21549 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); 21550 add_error_note(ira->codegen, msg, dest_type_src->source_node, 21551 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_type->name), dest_align_bytes)); 21552 return ira->codegen->invalid_instruction; 21553 } 21554 21555 IrInstruction *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); 21556 21557 if (type_has_bits(dest_type) && !type_has_bits(src_type)) { 21558 ErrorMsg *msg = ir_add_error(ira, source_instr, 21559 buf_sprintf("'%s' and '%s' do not have the same in-memory representation", 21560 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 21561 add_error_note(ira->codegen, msg, ptr->source_node, 21562 buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name))); 21563 add_error_note(ira->codegen, msg, dest_type_src->source_node, 21564 buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name))); 21565 return ira->codegen->invalid_instruction; 21566 } 21567 21568 // Keep the bigger alignment, it can only help- 21569 // unless the target is zero bits. 21570 IrInstruction *result; 21571 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { 21572 result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); 21573 if (type_is_invalid(result->value.type)) 21574 return ira->codegen->invalid_instruction; 21575 } else { 21576 result = casted_ptr; 21577 } 21578 return result; 21579 } 21580 21581 static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtrCastSrc *instruction) { 21582 IrInstruction *dest_type_value = instruction->dest_type->child; 21583 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 21584 if (type_is_invalid(dest_type)) 21585 return ira->codegen->invalid_instruction; 21586 21587 IrInstruction *ptr = instruction->ptr->child; 21588 ZigType *src_type = ptr->value.type; 21589 if (type_is_invalid(src_type)) 21590 return ira->codegen->invalid_instruction; 21591 21592 return ir_analyze_ptr_cast(ira, &instruction->base, ptr, dest_type, dest_type_value, 21593 instruction->safety_check_on); 21594 } 21595 21596 static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ConstExprValue *val, size_t len) { 21597 size_t buf_i = 0; 21598 // TODO optimize the buf case 21599 expand_undef_array(codegen, val); 21600 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) { 21601 ConstExprValue *elem = &val->data.x_array.data.s_none.elements[elem_i]; 21602 buf_write_value_bytes(codegen, &buf[buf_i], elem); 21603 buf_i += type_size(codegen, elem->type); 21604 } 21605 } 21606 21607 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) { 21608 if (val->special == ConstValSpecialUndef) 21609 val->special = ConstValSpecialStatic; 21610 assert(val->special == ConstValSpecialStatic); 21611 switch (val->type->id) { 21612 case ZigTypeIdInvalid: 21613 case ZigTypeIdMetaType: 21614 case ZigTypeIdOpaque: 21615 case ZigTypeIdBoundFn: 21616 case ZigTypeIdArgTuple: 21617 case ZigTypeIdUnreachable: 21618 case ZigTypeIdComptimeFloat: 21619 case ZigTypeIdComptimeInt: 21620 case ZigTypeIdEnumLiteral: 21621 case ZigTypeIdUndefined: 21622 case ZigTypeIdNull: 21623 case ZigTypeIdPromise: 21624 zig_unreachable(); 21625 case ZigTypeIdVoid: 21626 return; 21627 case ZigTypeIdBool: 21628 buf[0] = val->data.x_bool ? 1 : 0; 21629 return; 21630 case ZigTypeIdInt: 21631 bigint_write_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 21632 codegen->is_big_endian); 21633 return; 21634 case ZigTypeIdEnum: 21635 bigint_write_twos_complement(&val->data.x_enum_tag, buf, 21636 val->type->data.enumeration.tag_int_type->data.integral.bit_count, 21637 codegen->is_big_endian); 21638 return; 21639 case ZigTypeIdFloat: 21640 float_write_ieee597(val, buf, codegen->is_big_endian); 21641 return; 21642 case ZigTypeIdPointer: 21643 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 21644 BigInt bn; 21645 bigint_init_unsigned(&bn, val->data.x_ptr.data.hard_coded_addr.addr); 21646 bigint_write_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, codegen->is_big_endian); 21647 return; 21648 } else { 21649 zig_unreachable(); 21650 } 21651 case ZigTypeIdArray: 21652 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.array.len); 21653 case ZigTypeIdVector: 21654 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.vector.len); 21655 case ZigTypeIdStruct: 21656 switch (val->type->data.structure.layout) { 21657 case ContainerLayoutAuto: 21658 zig_unreachable(); 21659 case ContainerLayoutExtern: { 21660 size_t src_field_count = val->type->data.structure.src_field_count; 21661 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 21662 TypeStructField *struct_field = &val->type->data.structure.fields[field_i]; 21663 if (struct_field->gen_index == SIZE_MAX) 21664 continue; 21665 ConstExprValue *field_val = &val->data.x_struct.fields[field_i]; 21666 size_t offset = struct_field->offset; 21667 buf_write_value_bytes(codegen, buf + offset, field_val); 21668 } 21669 return; 21670 } 21671 case ContainerLayoutPacked: { 21672 size_t src_field_count = val->type->data.structure.src_field_count; 21673 size_t gen_field_count = val->type->data.structure.gen_field_count; 21674 size_t gen_i = 0; 21675 size_t src_i = 0; 21676 size_t offset = 0; 21677 bool is_big_endian = codegen->is_big_endian; 21678 uint8_t child_buf_prealloc[16]; 21679 size_t child_buf_len = 16; 21680 uint8_t *child_buf = child_buf_prealloc; 21681 while (gen_i < gen_field_count) { 21682 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 21683 if (big_int_byte_count > child_buf_len) { 21684 child_buf = allocate_nonzero<uint8_t>(big_int_byte_count); 21685 child_buf_len = big_int_byte_count; 21686 } 21687 BigInt big_int; 21688 bigint_init_unsigned(&big_int, 0); 21689 size_t used_bits = 0; 21690 while (src_i < src_field_count) { 21691 TypeStructField *field = &val->type->data.structure.fields[src_i]; 21692 assert(field->gen_index != SIZE_MAX); 21693 if (field->gen_index != gen_i) 21694 break; 21695 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 21696 buf_write_value_bytes(codegen, child_buf, &val->data.x_struct.fields[src_i]); 21697 BigInt child_val; 21698 bigint_read_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian, 21699 false); 21700 if (is_big_endian) { 21701 BigInt shift_amt; 21702 bigint_init_unsigned(&shift_amt, packed_bits_size); 21703 BigInt shifted; 21704 bigint_shl(&shifted, &big_int, &shift_amt); 21705 bigint_or(&big_int, &shifted, &child_val); 21706 } else { 21707 BigInt shift_amt; 21708 bigint_init_unsigned(&shift_amt, used_bits); 21709 BigInt child_val_shifted; 21710 bigint_shl(&child_val_shifted, &child_val, &shift_amt); 21711 BigInt tmp; 21712 bigint_or(&tmp, &big_int, &child_val_shifted); 21713 big_int = tmp; 21714 used_bits += packed_bits_size; 21715 } 21716 src_i += 1; 21717 } 21718 bigint_write_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian); 21719 offset += big_int_byte_count; 21720 gen_i += 1; 21721 } 21722 return; 21723 } 21724 } 21725 case ZigTypeIdOptional: 21726 zig_panic("TODO buf_write_value_bytes maybe type"); 21727 case ZigTypeIdErrorUnion: 21728 zig_panic("TODO buf_write_value_bytes error union"); 21729 case ZigTypeIdErrorSet: 21730 zig_panic("TODO buf_write_value_bytes pure error type"); 21731 case ZigTypeIdFn: 21732 zig_panic("TODO buf_write_value_bytes fn type"); 21733 case ZigTypeIdUnion: 21734 zig_panic("TODO buf_write_value_bytes union type"); 21735 } 21736 zig_unreachable(); 21737 } 21738 21739 static Error buf_read_value_bytes_array(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, 21740 ConstExprValue *val, ZigType *elem_type, size_t len) 21741 { 21742 Error err; 21743 uint64_t elem_size = type_size(codegen, elem_type); 21744 21745 switch (val->data.x_array.special) { 21746 case ConstArraySpecialNone: 21747 val->data.x_array.data.s_none.elements = create_const_vals(len); 21748 for (size_t i = 0; i < len; i++) { 21749 ConstExprValue *elem = &val->data.x_array.data.s_none.elements[i]; 21750 elem->special = ConstValSpecialStatic; 21751 elem->type = elem_type; 21752 if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem))) 21753 return err; 21754 } 21755 return ErrorNone; 21756 case ConstArraySpecialUndef: 21757 zig_panic("TODO buf_read_value_bytes ConstArraySpecialUndef array type"); 21758 case ConstArraySpecialBuf: 21759 zig_panic("TODO buf_read_value_bytes ConstArraySpecialBuf array type"); 21760 } 21761 zig_unreachable(); 21762 } 21763 21764 static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val) { 21765 Error err; 21766 src_assert(val->special == ConstValSpecialStatic, source_node); 21767 switch (val->type->id) { 21768 case ZigTypeIdInvalid: 21769 case ZigTypeIdMetaType: 21770 case ZigTypeIdOpaque: 21771 case ZigTypeIdBoundFn: 21772 case ZigTypeIdArgTuple: 21773 case ZigTypeIdUnreachable: 21774 case ZigTypeIdComptimeFloat: 21775 case ZigTypeIdComptimeInt: 21776 case ZigTypeIdEnumLiteral: 21777 case ZigTypeIdUndefined: 21778 case ZigTypeIdNull: 21779 case ZigTypeIdPromise: 21780 zig_unreachable(); 21781 case ZigTypeIdVoid: 21782 return ErrorNone; 21783 case ZigTypeIdBool: 21784 val->data.x_bool = (buf[0] != 0); 21785 return ErrorNone; 21786 case ZigTypeIdInt: 21787 bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 21788 codegen->is_big_endian, val->type->data.integral.is_signed); 21789 return ErrorNone; 21790 case ZigTypeIdFloat: 21791 float_read_ieee597(val, buf, codegen->is_big_endian); 21792 return ErrorNone; 21793 case ZigTypeIdPointer: 21794 { 21795 val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 21796 BigInt bn; 21797 bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, 21798 codegen->is_big_endian, false); 21799 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn); 21800 return ErrorNone; 21801 } 21802 case ZigTypeIdArray: 21803 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.array.child_type, 21804 val->type->data.array.len); 21805 case ZigTypeIdVector: 21806 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.vector.elem_type, 21807 val->type->data.vector.len); 21808 case ZigTypeIdEnum: 21809 switch (val->type->data.enumeration.layout) { 21810 case ContainerLayoutAuto: 21811 zig_panic("TODO buf_read_value_bytes enum auto"); 21812 case ContainerLayoutPacked: 21813 zig_panic("TODO buf_read_value_bytes enum packed"); 21814 case ContainerLayoutExtern: { 21815 ZigType *tag_int_type = val->type->data.enumeration.tag_int_type; 21816 src_assert(tag_int_type->id == ZigTypeIdInt, source_node); 21817 bigint_read_twos_complement(&val->data.x_enum_tag, buf, tag_int_type->data.integral.bit_count, 21818 codegen->is_big_endian, tag_int_type->data.integral.is_signed); 21819 return ErrorNone; 21820 } 21821 } 21822 zig_unreachable(); 21823 case ZigTypeIdStruct: 21824 switch (val->type->data.structure.layout) { 21825 case ContainerLayoutAuto: { 21826 ErrorMsg *msg = opt_ir_add_error_node(ira, codegen, source_node, 21827 buf_sprintf("non-extern, non-packed struct '%s' cannot have its bytes reinterpreted", 21828 buf_ptr(&val->type->name))); 21829 add_error_note(codegen, msg, val->type->data.structure.decl_node, 21830 buf_sprintf("declared here")); 21831 return ErrorSemanticAnalyzeFail; 21832 } 21833 case ContainerLayoutExtern: { 21834 size_t src_field_count = val->type->data.structure.src_field_count; 21835 val->data.x_struct.fields = create_const_vals(src_field_count); 21836 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 21837 ConstExprValue *field_val = &val->data.x_struct.fields[field_i]; 21838 field_val->special = ConstValSpecialStatic; 21839 TypeStructField *struct_field = &val->type->data.structure.fields[field_i]; 21840 field_val->type = struct_field->type_entry; 21841 if (struct_field->gen_index == SIZE_MAX) 21842 continue; 21843 size_t offset = struct_field->offset; 21844 uint8_t *new_buf = buf + offset; 21845 if ((err = buf_read_value_bytes(ira, codegen, source_node, new_buf, field_val))) 21846 return err; 21847 } 21848 return ErrorNone; 21849 } 21850 case ContainerLayoutPacked: { 21851 size_t src_field_count = val->type->data.structure.src_field_count; 21852 val->data.x_struct.fields = create_const_vals(src_field_count); 21853 size_t gen_field_count = val->type->data.structure.gen_field_count; 21854 size_t gen_i = 0; 21855 size_t src_i = 0; 21856 size_t offset = 0; 21857 bool is_big_endian = codegen->is_big_endian; 21858 uint8_t child_buf_prealloc[16]; 21859 size_t child_buf_len = 16; 21860 uint8_t *child_buf = child_buf_prealloc; 21861 while (gen_i < gen_field_count) { 21862 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 21863 if (big_int_byte_count > child_buf_len) { 21864 child_buf = allocate_nonzero<uint8_t>(big_int_byte_count); 21865 child_buf_len = big_int_byte_count; 21866 } 21867 BigInt big_int; 21868 bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false); 21869 while (src_i < src_field_count) { 21870 TypeStructField *field = &val->type->data.structure.fields[src_i]; 21871 src_assert(field->gen_index != SIZE_MAX, source_node); 21872 if (field->gen_index != gen_i) 21873 break; 21874 ConstExprValue *field_val = &val->data.x_struct.fields[src_i]; 21875 field_val->special = ConstValSpecialStatic; 21876 field_val->type = field->type_entry; 21877 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 21878 21879 BigInt child_val; 21880 if (is_big_endian) { 21881 zig_panic("TODO buf_read_value_bytes packed struct big endian"); 21882 } else { 21883 BigInt packed_bits_size_bi; 21884 bigint_init_unsigned(&packed_bits_size_bi, packed_bits_size); 21885 bigint_truncate(&child_val, &big_int, packed_bits_size, false); 21886 BigInt tmp; 21887 bigint_shr(&tmp, &big_int, &packed_bits_size_bi); 21888 big_int = tmp; 21889 } 21890 21891 bigint_write_twos_complement(&child_val, child_buf, big_int_byte_count * 8, is_big_endian); 21892 if ((err = buf_read_value_bytes(ira, codegen, source_node, child_buf, field_val))) { 21893 return err; 21894 } 21895 21896 src_i += 1; 21897 } 21898 offset += big_int_byte_count; 21899 gen_i += 1; 21900 } 21901 return ErrorNone; 21902 } 21903 } 21904 zig_unreachable(); 21905 case ZigTypeIdOptional: 21906 zig_panic("TODO buf_read_value_bytes maybe type"); 21907 case ZigTypeIdErrorUnion: 21908 zig_panic("TODO buf_read_value_bytes error union"); 21909 case ZigTypeIdErrorSet: 21910 zig_panic("TODO buf_read_value_bytes pure error type"); 21911 case ZigTypeIdFn: 21912 zig_panic("TODO buf_read_value_bytes fn type"); 21913 case ZigTypeIdUnion: 21914 zig_panic("TODO buf_read_value_bytes union type"); 21915 } 21916 zig_unreachable(); 21917 } 21918 21919 static bool type_can_bit_cast(ZigType *t) { 21920 switch (t->id) { 21921 case ZigTypeIdInvalid: 21922 zig_unreachable(); 21923 case ZigTypeIdMetaType: 21924 case ZigTypeIdOpaque: 21925 case ZigTypeIdBoundFn: 21926 case ZigTypeIdArgTuple: 21927 case ZigTypeIdUnreachable: 21928 case ZigTypeIdComptimeFloat: 21929 case ZigTypeIdComptimeInt: 21930 case ZigTypeIdEnumLiteral: 21931 case ZigTypeIdUndefined: 21932 case ZigTypeIdNull: 21933 case ZigTypeIdPointer: 21934 return false; 21935 default: 21936 // TODO list these types out explicitly, there are probably some other invalid ones here 21937 return true; 21938 } 21939 } 21940 21941 static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 21942 ZigType *dest_type) 21943 { 21944 Error err; 21945 21946 ZigType *src_type = value->value.type; 21947 ir_assert(get_codegen_ptr_type(src_type) == nullptr, source_instr); 21948 ir_assert(type_can_bit_cast(src_type), source_instr); 21949 ir_assert(get_codegen_ptr_type(dest_type) == nullptr, source_instr); 21950 ir_assert(type_can_bit_cast(dest_type), source_instr); 21951 21952 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown))) 21953 return ira->codegen->invalid_instruction; 21954 21955 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown))) 21956 return ira->codegen->invalid_instruction; 21957 21958 21959 uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); 21960 uint64_t src_size_bytes = type_size(ira->codegen, src_type); 21961 if (dest_size_bytes != src_size_bytes) { 21962 ir_add_error(ira, source_instr, 21963 buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64, 21964 buf_ptr(&dest_type->name), dest_size_bytes, 21965 buf_ptr(&src_type->name), src_size_bytes)); 21966 return ira->codegen->invalid_instruction; 21967 } 21968 21969 uint64_t dest_size_bits = type_size_bits(ira->codegen, dest_type); 21970 uint64_t src_size_bits = type_size_bits(ira->codegen, src_type); 21971 if (dest_size_bits != src_size_bits) { 21972 ir_add_error(ira, source_instr, 21973 buf_sprintf("destination type '%s' has %" ZIG_PRI_u64 " bits but source type '%s' has %" ZIG_PRI_u64 " bits", 21974 buf_ptr(&dest_type->name), dest_size_bits, 21975 buf_ptr(&src_type->name), src_size_bits)); 21976 return ira->codegen->invalid_instruction; 21977 } 21978 21979 if (instr_is_comptime(value)) { 21980 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 21981 if (!val) 21982 return ira->codegen->invalid_instruction; 21983 21984 IrInstruction *result = ir_const(ira, source_instr, dest_type); 21985 uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes); 21986 buf_write_value_bytes(ira->codegen, buf, val); 21987 if ((err = buf_read_value_bytes(ira, ira->codegen, source_instr->source_node, buf, &result->value))) 21988 return ira->codegen->invalid_instruction; 21989 return result; 21990 } 21991 21992 IrInstruction *result = ir_build_bit_cast_gen(ira, source_instr, value, dest_type); 21993 if (handle_is_ptr(dest_type) && !handle_is_ptr(src_type)) { 21994 ir_add_alloca(ira, result, dest_type); 21995 } 21996 return result; 21997 } 21998 21999 static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) { 22000 IrInstruction *dest_type_value = instruction->dest_type->child; 22001 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 22002 if (type_is_invalid(dest_type)) 22003 return ira->codegen->invalid_instruction; 22004 22005 IrInstruction *value = instruction->value->child; 22006 ZigType *src_type = value->value.type; 22007 if (type_is_invalid(src_type)) 22008 return ira->codegen->invalid_instruction; 22009 22010 if (get_codegen_ptr_type(src_type) != nullptr) { 22011 ir_add_error(ira, value, 22012 buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name))); 22013 return ira->codegen->invalid_instruction; 22014 } 22015 22016 if (!type_can_bit_cast(src_type)) { 22017 ir_add_error(ira, dest_type_value, 22018 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name))); 22019 return ira->codegen->invalid_instruction; 22020 } 22021 22022 if (get_codegen_ptr_type(dest_type) != nullptr) { 22023 ir_add_error(ira, dest_type_value, 22024 buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); 22025 return ira->codegen->invalid_instruction; 22026 } 22027 22028 if (!type_can_bit_cast(dest_type)) { 22029 ir_add_error(ira, dest_type_value, 22030 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); 22031 return ira->codegen->invalid_instruction; 22032 } 22033 22034 return ir_analyze_bit_cast(ira, &instruction->base, value, dest_type); 22035 } 22036 22037 static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 22038 ZigType *ptr_type) 22039 { 22040 ir_assert(get_src_ptr_type(ptr_type) != nullptr, source_instr); 22041 ir_assert(type_has_bits(ptr_type), source_instr); 22042 22043 IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); 22044 if (type_is_invalid(casted_int->value.type)) 22045 return ira->codegen->invalid_instruction; 22046 22047 if (instr_is_comptime(casted_int)) { 22048 ConstExprValue *val = ir_resolve_const(ira, casted_int, UndefBad); 22049 if (!val) 22050 return ira->codegen->invalid_instruction; 22051 22052 uint64_t addr = bigint_as_unsigned(&val->data.x_bigint); 22053 if (!ptr_allows_addr_zero(ptr_type) && addr == 0) { 22054 ir_add_error(ira, source_instr, 22055 buf_sprintf("pointer type '%s' does not allow address zero", buf_ptr(&ptr_type->name))); 22056 return ira->codegen->invalid_instruction; 22057 } 22058 22059 IrInstruction *result = ir_const(ira, source_instr, ptr_type); 22060 result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 22061 result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar; 22062 result->value.data.x_ptr.data.hard_coded_addr.addr = addr; 22063 return result; 22064 } 22065 22066 IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, source_instr->scope, 22067 source_instr->source_node, nullptr, casted_int); 22068 result->value.type = ptr_type; 22069 return result; 22070 } 22071 22072 static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) { 22073 Error err; 22074 IrInstruction *dest_type_value = instruction->dest_type->child; 22075 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 22076 if (type_is_invalid(dest_type)) 22077 return ira->codegen->invalid_instruction; 22078 22079 // We explicitly check for the size, so we can use get_src_ptr_type 22080 if (get_src_ptr_type(dest_type) == nullptr) { 22081 ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 22082 return ira->codegen->invalid_instruction; 22083 } 22084 22085 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 22086 return ira->codegen->invalid_instruction; 22087 if (!type_has_bits(dest_type)) { 22088 ir_add_error(ira, dest_type_value, 22089 buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name))); 22090 return ira->codegen->invalid_instruction; 22091 } 22092 22093 22094 IrInstruction *target = instruction->target->child; 22095 if (type_is_invalid(target->value.type)) 22096 return ira->codegen->invalid_instruction; 22097 22098 return ir_analyze_int_to_ptr(ira, &instruction->base, target, dest_type); 22099 } 22100 22101 static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, 22102 IrInstructionDeclRef *instruction) 22103 { 22104 Tld *tld = instruction->tld; 22105 LVal lval = instruction->lval; 22106 22107 resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node); 22108 if (tld->resolution == TldResolutionInvalid) 22109 return ira->codegen->invalid_instruction; 22110 22111 switch (tld->id) { 22112 case TldIdContainer: 22113 case TldIdCompTime: 22114 zig_unreachable(); 22115 case TldIdVar: { 22116 TldVar *tld_var = (TldVar *)tld; 22117 ZigVar *var = tld_var->var; 22118 22119 if (var == nullptr) { 22120 return ir_error_dependency_loop(ira, &instruction->base); 22121 } 22122 22123 IrInstruction *var_ptr = ir_get_var_ptr(ira, &instruction->base, var); 22124 if (type_is_invalid(var_ptr->value.type)) 22125 return ira->codegen->invalid_instruction; 22126 22127 if (tld_var->extern_lib_name != nullptr) { 22128 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, instruction->base.source_node); 22129 } 22130 22131 if (lval == LValPtr) { 22132 return var_ptr; 22133 } else { 22134 return ir_get_deref(ira, &instruction->base, var_ptr); 22135 } 22136 } 22137 case TldIdFn: { 22138 TldFn *tld_fn = (TldFn *)tld; 22139 ZigFn *fn_entry = tld_fn->fn_entry; 22140 ir_assert(fn_entry->type_entry, &instruction->base); 22141 22142 if (tld_fn->extern_lib_name != nullptr) { 22143 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, instruction->base.source_node); 22144 } 22145 22146 IrInstruction *ref_instruction = ir_create_const_fn(&ira->new_irb, instruction->base.scope, 22147 instruction->base.source_node, fn_entry); 22148 if (lval == LValPtr) { 22149 return ir_get_ref(ira, &instruction->base, ref_instruction, true, false); 22150 } else { 22151 return ref_instruction; 22152 } 22153 } 22154 } 22155 zig_unreachable(); 22156 } 22157 22158 static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { 22159 IrInstruction *target = instruction->target->child; 22160 if (type_is_invalid(target->value.type)) 22161 return ira->codegen->invalid_instruction; 22162 22163 ZigType *usize = ira->codegen->builtin_types.entry_usize; 22164 22165 // We check size explicitly so we can use get_src_ptr_type here. 22166 if (get_src_ptr_type(target->value.type) == nullptr) { 22167 ir_add_error(ira, target, 22168 buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value.type->name))); 22169 return ira->codegen->invalid_instruction; 22170 } 22171 22172 if (!type_has_bits(target->value.type)) { 22173 ir_add_error(ira, target, 22174 buf_sprintf("pointer to size 0 type has no address")); 22175 return ira->codegen->invalid_instruction; 22176 } 22177 22178 if (instr_is_comptime(target)) { 22179 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 22180 if (!val) 22181 return ira->codegen->invalid_instruction; 22182 if (val->type->id == ZigTypeIdPointer && val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 22183 IrInstruction *result = ir_const(ira, &instruction->base, usize); 22184 bigint_init_unsigned(&result->value.data.x_bigint, val->data.x_ptr.data.hard_coded_addr.addr); 22185 result->value.type = usize; 22186 return result; 22187 } 22188 } 22189 22190 IrInstruction *result = ir_build_ptr_to_int(&ira->new_irb, instruction->base.scope, 22191 instruction->base.source_node, target); 22192 result->value.type = usize; 22193 return result; 22194 } 22195 22196 static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) { 22197 Error err; 22198 ZigType *child_type = ir_resolve_type(ira, instruction->child_type->child); 22199 if (type_is_invalid(child_type)) 22200 return ira->codegen->invalid_instruction; 22201 22202 if (child_type->id == ZigTypeIdUnreachable) { 22203 ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed")); 22204 return ira->codegen->invalid_instruction; 22205 } else if (child_type->id == ZigTypeIdOpaque && instruction->ptr_len == PtrLenUnknown) { 22206 ir_add_error(ira, &instruction->base, buf_sprintf("unknown-length pointer to opaque")); 22207 return ira->codegen->invalid_instruction; 22208 } else if (instruction->ptr_len == PtrLenC) { 22209 if (!type_allowed_in_extern(ira->codegen, child_type)) { 22210 ir_add_error(ira, &instruction->base, 22211 buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", buf_ptr(&child_type->name))); 22212 return ira->codegen->invalid_instruction; 22213 } else if (child_type->id == ZigTypeIdOpaque) { 22214 ir_add_error(ira, &instruction->base, buf_sprintf("C pointers cannot point opaque types")); 22215 return ira->codegen->invalid_instruction; 22216 } else if (instruction->is_allow_zero) { 22217 ir_add_error(ira, &instruction->base, buf_sprintf("C pointers always allow address zero")); 22218 return ira->codegen->invalid_instruction; 22219 } 22220 } 22221 22222 uint32_t align_bytes; 22223 if (instruction->align_value != nullptr) { 22224 if (!ir_resolve_align(ira, instruction->align_value->child, &align_bytes)) 22225 return ira->codegen->invalid_instruction; 22226 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown))) 22227 return ira->codegen->invalid_instruction; 22228 if (!type_has_bits(child_type)) { 22229 align_bytes = 0; 22230 } 22231 } else { 22232 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) 22233 return ira->codegen->invalid_instruction; 22234 align_bytes = 0; 22235 } 22236 22237 bool allow_zero = instruction->is_allow_zero || instruction->ptr_len == PtrLenC; 22238 22239 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, 22240 instruction->is_const, instruction->is_volatile, 22241 instruction->ptr_len, align_bytes, 22242 instruction->bit_offset_start, instruction->host_int_bytes, allow_zero); 22243 return ir_const_type(ira, &instruction->base, result_type); 22244 } 22245 22246 static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstructionAlignCast *instruction) { 22247 uint32_t align_bytes; 22248 IrInstruction *align_bytes_inst = instruction->align_bytes->child; 22249 if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes)) 22250 return ira->codegen->invalid_instruction; 22251 22252 IrInstruction *target = instruction->target->child; 22253 if (type_is_invalid(target->value.type)) 22254 return ira->codegen->invalid_instruction; 22255 22256 IrInstruction *result = ir_align_cast(ira, target, align_bytes, true); 22257 if (type_is_invalid(result->value.type)) 22258 return ira->codegen->invalid_instruction; 22259 22260 return result; 22261 } 22262 22263 static IrInstruction *ir_analyze_instruction_opaque_type(IrAnalyze *ira, IrInstructionOpaqueType *instruction) { 22264 Buf *bare_name = buf_alloc(); 22265 Buf *full_name = get_anon_type_name(ira->codegen, ira->new_irb.exec, "opaque", 22266 instruction->base.scope, instruction->base.source_node, bare_name); 22267 ZigType *result_type = get_opaque_type(ira->codegen, instruction->base.scope, instruction->base.source_node, 22268 buf_ptr(full_name), bare_name); 22269 return ir_const_type(ira, &instruction->base, result_type); 22270 } 22271 22272 static IrInstruction *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstructionSetAlignStack *instruction) { 22273 uint32_t align_bytes; 22274 IrInstruction *align_bytes_inst = instruction->align_bytes->child; 22275 if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes)) 22276 return ira->codegen->invalid_instruction; 22277 22278 if (align_bytes > 256) { 22279 ir_add_error(ira, &instruction->base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes)); 22280 return ira->codegen->invalid_instruction; 22281 } 22282 22283 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 22284 if (fn_entry == nullptr) { 22285 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack outside function")); 22286 return ira->codegen->invalid_instruction; 22287 } 22288 if (fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionNaked) { 22289 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in naked function")); 22290 return ira->codegen->invalid_instruction; 22291 } 22292 22293 if (fn_entry->fn_inline == FnInlineAlways) { 22294 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in inline function")); 22295 return ira->codegen->invalid_instruction; 22296 } 22297 22298 if (fn_entry->set_alignstack_node != nullptr) { 22299 ErrorMsg *msg = ir_add_error_node(ira, instruction->base.source_node, 22300 buf_sprintf("alignstack set twice")); 22301 add_error_note(ira->codegen, msg, fn_entry->set_alignstack_node, buf_sprintf("first set here")); 22302 return ira->codegen->invalid_instruction; 22303 } 22304 22305 fn_entry->set_alignstack_node = instruction->base.source_node; 22306 fn_entry->alignstack_value = align_bytes; 22307 22308 return ir_const_void(ira, &instruction->base); 22309 } 22310 22311 static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstructionArgType *instruction) { 22312 IrInstruction *fn_type_inst = instruction->fn_type->child; 22313 ZigType *fn_type = ir_resolve_type(ira, fn_type_inst); 22314 if (type_is_invalid(fn_type)) 22315 return ira->codegen->invalid_instruction; 22316 22317 IrInstruction *arg_index_inst = instruction->arg_index->child; 22318 uint64_t arg_index; 22319 if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) 22320 return ira->codegen->invalid_instruction; 22321 22322 if (fn_type->id != ZigTypeIdFn) { 22323 ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); 22324 return ira->codegen->invalid_instruction; 22325 } 22326 22327 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 22328 if (arg_index >= fn_type_id->param_count) { 22329 ir_add_error(ira, arg_index_inst, 22330 buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", 22331 arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); 22332 return ira->codegen->invalid_instruction; 22333 } 22334 22335 ZigType *result_type = fn_type_id->param_info[arg_index].type; 22336 if (result_type == nullptr) { 22337 // Args are only unresolved if our function is generic. 22338 ir_assert(fn_type->data.fn.is_generic, &instruction->base); 22339 22340 ir_add_error(ira, arg_index_inst, 22341 buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", 22342 arg_index, buf_ptr(&fn_type->name))); 22343 return ira->codegen->invalid_instruction; 22344 } 22345 return ir_const_type(ira, &instruction->base, result_type); 22346 } 22347 22348 static IrInstruction *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstructionTagType *instruction) { 22349 Error err; 22350 IrInstruction *target_inst = instruction->target->child; 22351 ZigType *enum_type = ir_resolve_type(ira, target_inst); 22352 if (type_is_invalid(enum_type)) 22353 return ira->codegen->invalid_instruction; 22354 22355 if (enum_type->id == ZigTypeIdEnum) { 22356 if ((err = ensure_complete_type(ira->codegen, enum_type))) 22357 return ira->codegen->invalid_instruction; 22358 22359 return ir_const_type(ira, &instruction->base, enum_type->data.enumeration.tag_int_type); 22360 } else if (enum_type->id == ZigTypeIdUnion) { 22361 ZigType *tag_type = ir_resolve_union_tag_type(ira, instruction->target, enum_type); 22362 if (type_is_invalid(tag_type)) 22363 return ira->codegen->invalid_instruction; 22364 return ir_const_type(ira, &instruction->base, tag_type); 22365 } else { 22366 ir_add_error(ira, target_inst, buf_sprintf("expected enum or union, found '%s'", 22367 buf_ptr(&enum_type->name))); 22368 return ira->codegen->invalid_instruction; 22369 } 22370 } 22371 22372 static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) { 22373 IrInstruction *target_inst = instruction->target->child; 22374 if (type_is_invalid(target_inst->value.type)) 22375 return ira->codegen->invalid_instruction; 22376 IrInstruction *casted_target = ir_implicit_cast(ira, target_inst, ira->codegen->builtin_types.entry_promise); 22377 if (type_is_invalid(casted_target->value.type)) 22378 return ira->codegen->invalid_instruction; 22379 22380 IrInstruction *result = ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_target); 22381 result->value.type = ira->codegen->builtin_types.entry_void; 22382 result->value.special = ConstValSpecialStatic; 22383 return result; 22384 } 22385 22386 static IrInstruction *ir_analyze_instruction_coro_id(IrAnalyze *ira, IrInstructionCoroId *instruction) { 22387 IrInstruction *promise_ptr = instruction->promise_ptr->child; 22388 if (type_is_invalid(promise_ptr->value.type)) 22389 return ira->codegen->invalid_instruction; 22390 22391 IrInstruction *result = ir_build_coro_id(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 22392 promise_ptr); 22393 result->value.type = ira->codegen->builtin_types.entry_usize; 22394 return result; 22395 } 22396 22397 static IrInstruction *ir_analyze_instruction_coro_alloc(IrAnalyze *ira, IrInstructionCoroAlloc *instruction) { 22398 IrInstruction *coro_id = instruction->coro_id->child; 22399 if (type_is_invalid(coro_id->value.type)) 22400 return ira->codegen->invalid_instruction; 22401 22402 IrInstruction *result = ir_build_coro_alloc(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 22403 coro_id); 22404 result->value.type = ira->codegen->builtin_types.entry_bool; 22405 return result; 22406 } 22407 22408 static IrInstruction *ir_analyze_instruction_coro_size(IrAnalyze *ira, IrInstructionCoroSize *instruction) { 22409 IrInstruction *result = ir_build_coro_size(&ira->new_irb, instruction->base.scope, instruction->base.source_node); 22410 result->value.type = ira->codegen->builtin_types.entry_usize; 22411 return result; 22412 } 22413 22414 static IrInstruction *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstructionCoroBegin *instruction) { 22415 IrInstruction *coro_id = instruction->coro_id->child; 22416 if (type_is_invalid(coro_id->value.type)) 22417 return ira->codegen->invalid_instruction; 22418 22419 IrInstruction *coro_mem_ptr = instruction->coro_mem_ptr->child; 22420 if (type_is_invalid(coro_mem_ptr->value.type)) 22421 return ira->codegen->invalid_instruction; 22422 22423 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 22424 ir_assert(fn_entry != nullptr, &instruction->base); 22425 IrInstruction *result = ir_build_coro_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 22426 coro_id, coro_mem_ptr); 22427 result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type); 22428 return result; 22429 } 22430 22431 static IrInstruction *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) { 22432 return ir_get_implicit_allocator(ira, &instruction->base, instruction->id); 22433 } 22434 22435 static IrInstruction *ir_analyze_instruction_coro_alloc_fail(IrAnalyze *ira, IrInstructionCoroAllocFail *instruction) { 22436 IrInstruction *err_val = instruction->err_val->child; 22437 if (type_is_invalid(err_val->value.type)) 22438 return ir_unreach_error(ira); 22439 22440 IrInstruction *result = ir_build_coro_alloc_fail(&ira->new_irb, instruction->base.scope, instruction->base.source_node, err_val); 22441 result->value.type = ira->codegen->builtin_types.entry_unreachable; 22442 return ir_finish_anal(ira, result); 22443 } 22444 22445 static IrInstruction *ir_analyze_instruction_coro_suspend(IrAnalyze *ira, IrInstructionCoroSuspend *instruction) { 22446 IrInstruction *save_point = nullptr; 22447 if (instruction->save_point != nullptr) { 22448 save_point = instruction->save_point->child; 22449 if (type_is_invalid(save_point->value.type)) 22450 return ira->codegen->invalid_instruction; 22451 } 22452 22453 IrInstruction *is_final = instruction->is_final->child; 22454 if (type_is_invalid(is_final->value.type)) 22455 return ira->codegen->invalid_instruction; 22456 22457 IrInstruction *result = ir_build_coro_suspend(&ira->new_irb, instruction->base.scope, 22458 instruction->base.source_node, save_point, is_final); 22459 result->value.type = ira->codegen->builtin_types.entry_u8; 22460 return result; 22461 } 22462 22463 static IrInstruction *ir_analyze_instruction_coro_end(IrAnalyze *ira, IrInstructionCoroEnd *instruction) { 22464 IrInstruction *result = ir_build_coro_end(&ira->new_irb, instruction->base.scope, 22465 instruction->base.source_node); 22466 result->value.type = ira->codegen->builtin_types.entry_void; 22467 return result; 22468 } 22469 22470 static IrInstruction *ir_analyze_instruction_coro_free(IrAnalyze *ira, IrInstructionCoroFree *instruction) { 22471 IrInstruction *coro_id = instruction->coro_id->child; 22472 if (type_is_invalid(coro_id->value.type)) 22473 return ira->codegen->invalid_instruction; 22474 22475 IrInstruction *coro_handle = instruction->coro_handle->child; 22476 if (type_is_invalid(coro_handle->value.type)) 22477 return ira->codegen->invalid_instruction; 22478 22479 IrInstruction *result = ir_build_coro_free(&ira->new_irb, instruction->base.scope, 22480 instruction->base.source_node, coro_id, coro_handle); 22481 ZigType *ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false); 22482 result->value.type = get_optional_type(ira->codegen, ptr_type); 22483 return result; 22484 } 22485 22486 static IrInstruction *ir_analyze_instruction_coro_resume(IrAnalyze *ira, IrInstructionCoroResume *instruction) { 22487 IrInstruction *awaiter_handle = instruction->awaiter_handle->child; 22488 if (type_is_invalid(awaiter_handle->value.type)) 22489 return ira->codegen->invalid_instruction; 22490 22491 IrInstruction *casted_target = ir_implicit_cast(ira, awaiter_handle, ira->codegen->builtin_types.entry_promise); 22492 if (type_is_invalid(casted_target->value.type)) 22493 return ira->codegen->invalid_instruction; 22494 22495 IrInstruction *result = ir_build_coro_resume(&ira->new_irb, instruction->base.scope, 22496 instruction->base.source_node, casted_target); 22497 result->value.type = ira->codegen->builtin_types.entry_void; 22498 return result; 22499 } 22500 22501 static IrInstruction *ir_analyze_instruction_coro_save(IrAnalyze *ira, IrInstructionCoroSave *instruction) { 22502 IrInstruction *coro_handle = instruction->coro_handle->child; 22503 if (type_is_invalid(coro_handle->value.type)) 22504 return ira->codegen->invalid_instruction; 22505 22506 IrInstruction *result = ir_build_coro_save(&ira->new_irb, instruction->base.scope, 22507 instruction->base.source_node, coro_handle); 22508 result->value.type = ira->codegen->builtin_types.entry_usize; 22509 return result; 22510 } 22511 22512 static IrInstruction *ir_analyze_instruction_coro_promise(IrAnalyze *ira, IrInstructionCoroPromise *instruction) { 22513 IrInstruction *coro_handle = instruction->coro_handle->child; 22514 if (type_is_invalid(coro_handle->value.type)) 22515 return ira->codegen->invalid_instruction; 22516 22517 if (coro_handle->value.type->id != ZigTypeIdPromise || 22518 coro_handle->value.type->data.promise.result_type == nullptr) 22519 { 22520 ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'", 22521 buf_ptr(&coro_handle->value.type->name))); 22522 return ira->codegen->invalid_instruction; 22523 } 22524 22525 ZigType *coro_frame_type = get_promise_frame_type(ira->codegen, 22526 coro_handle->value.type->data.promise.result_type); 22527 22528 IrInstruction *result = ir_build_coro_promise(&ira->new_irb, instruction->base.scope, 22529 instruction->base.source_node, coro_handle); 22530 result->value.type = get_pointer_to_type(ira->codegen, coro_frame_type, false); 22531 return result; 22532 } 22533 22534 static IrInstruction *ir_analyze_instruction_coro_alloc_helper(IrAnalyze *ira, IrInstructionCoroAllocHelper *instruction) { 22535 IrInstruction *realloc_fn = instruction->realloc_fn->child; 22536 if (type_is_invalid(realloc_fn->value.type)) 22537 return ira->codegen->invalid_instruction; 22538 22539 IrInstruction *coro_size = instruction->coro_size->child; 22540 if (type_is_invalid(coro_size->value.type)) 22541 return ira->codegen->invalid_instruction; 22542 22543 IrInstruction *result = ir_build_coro_alloc_helper(&ira->new_irb, instruction->base.scope, 22544 instruction->base.source_node, realloc_fn, coro_size); 22545 ZigType *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false); 22546 result->value.type = get_optional_type(ira->codegen, u8_ptr_type); 22547 return result; 22548 } 22549 22550 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op) { 22551 ZigType *operand_type = ir_resolve_type(ira, op); 22552 if (type_is_invalid(operand_type)) 22553 return ira->codegen->builtin_types.entry_invalid; 22554 22555 if (operand_type->id == ZigTypeIdInt) { 22556 if (operand_type->data.integral.bit_count < 8) { 22557 ir_add_error(ira, op, 22558 buf_sprintf("expected integer type 8 bits or larger, found %" PRIu32 "-bit integer type", 22559 operand_type->data.integral.bit_count)); 22560 return ira->codegen->builtin_types.entry_invalid; 22561 } 22562 if (operand_type->data.integral.bit_count > ira->codegen->pointer_size_bytes * 8) { 22563 ir_add_error(ira, op, 22564 buf_sprintf("expected integer type pointer size or smaller, found %" PRIu32 "-bit integer type", 22565 operand_type->data.integral.bit_count)); 22566 return ira->codegen->builtin_types.entry_invalid; 22567 } 22568 if (!is_power_of_2(operand_type->data.integral.bit_count)) { 22569 ir_add_error(ira, op, 22570 buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count)); 22571 return ira->codegen->builtin_types.entry_invalid; 22572 } 22573 } else if (get_codegen_ptr_type(operand_type) == nullptr) { 22574 ir_add_error(ira, op, 22575 buf_sprintf("expected integer or pointer type, found '%s'", buf_ptr(&operand_type->name))); 22576 return ira->codegen->builtin_types.entry_invalid; 22577 } 22578 22579 return operand_type; 22580 } 22581 22582 static IrInstruction *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstructionAtomicRmw *instruction) { 22583 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 22584 if (type_is_invalid(operand_type)) 22585 return ira->codegen->invalid_instruction; 22586 22587 IrInstruction *ptr_inst = instruction->ptr->child; 22588 if (type_is_invalid(ptr_inst->value.type)) 22589 return ira->codegen->invalid_instruction; 22590 22591 // TODO let this be volatile 22592 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 22593 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 22594 if (type_is_invalid(casted_ptr->value.type)) 22595 return ira->codegen->invalid_instruction; 22596 22597 AtomicRmwOp op; 22598 if (instruction->op == nullptr) { 22599 op = instruction->resolved_op; 22600 } else { 22601 if (!ir_resolve_atomic_rmw_op(ira, instruction->op->child, &op)) { 22602 return ira->codegen->invalid_instruction; 22603 } 22604 } 22605 22606 IrInstruction *operand = instruction->operand->child; 22607 if (type_is_invalid(operand->value.type)) 22608 return ira->codegen->invalid_instruction; 22609 22610 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, operand_type); 22611 if (type_is_invalid(casted_operand->value.type)) 22612 return ira->codegen->invalid_instruction; 22613 22614 AtomicOrder ordering; 22615 if (instruction->ordering == nullptr) { 22616 ordering = instruction->resolved_ordering; 22617 } else { 22618 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 22619 return ira->codegen->invalid_instruction; 22620 if (ordering == AtomicOrderUnordered) { 22621 ir_add_error(ira, instruction->ordering, 22622 buf_sprintf("@atomicRmw atomic ordering must not be Unordered")); 22623 return ira->codegen->invalid_instruction; 22624 } 22625 } 22626 22627 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) 22628 { 22629 zig_panic("TODO compile-time execution of atomicRmw"); 22630 } 22631 22632 IrInstruction *result = ir_build_atomic_rmw(&ira->new_irb, instruction->base.scope, 22633 instruction->base.source_node, nullptr, casted_ptr, nullptr, casted_operand, nullptr, 22634 op, ordering); 22635 result->value.type = operand_type; 22636 return result; 22637 } 22638 22639 static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstructionAtomicLoad *instruction) { 22640 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 22641 if (type_is_invalid(operand_type)) 22642 return ira->codegen->invalid_instruction; 22643 22644 IrInstruction *ptr_inst = instruction->ptr->child; 22645 if (type_is_invalid(ptr_inst->value.type)) 22646 return ira->codegen->invalid_instruction; 22647 22648 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true); 22649 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 22650 if (type_is_invalid(casted_ptr->value.type)) 22651 return ira->codegen->invalid_instruction; 22652 22653 AtomicOrder ordering; 22654 if (instruction->ordering == nullptr) { 22655 ordering = instruction->resolved_ordering; 22656 } else { 22657 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 22658 return ira->codegen->invalid_instruction; 22659 } 22660 22661 if (ordering == AtomicOrderRelease || ordering == AtomicOrderAcqRel) { 22662 ir_assert(instruction->ordering != nullptr, &instruction->base); 22663 ir_add_error(ira, instruction->ordering, 22664 buf_sprintf("@atomicLoad atomic ordering must not be Release or AcqRel")); 22665 return ira->codegen->invalid_instruction; 22666 } 22667 22668 if (instr_is_comptime(casted_ptr)) { 22669 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr); 22670 ir_assert(result->value.type != nullptr, &instruction->base); 22671 return result; 22672 } 22673 22674 IrInstruction *result = ir_build_atomic_load(&ira->new_irb, instruction->base.scope, 22675 instruction->base.source_node, nullptr, casted_ptr, nullptr, ordering); 22676 result->value.type = operand_type; 22677 return result; 22678 } 22679 22680 static IrInstruction *ir_analyze_instruction_promise_result_type(IrAnalyze *ira, IrInstructionPromiseResultType *instruction) { 22681 ZigType *promise_type = ir_resolve_type(ira, instruction->promise_type->child); 22682 if (type_is_invalid(promise_type)) 22683 return ira->codegen->invalid_instruction; 22684 22685 if (promise_type->id != ZigTypeIdPromise || promise_type->data.promise.result_type == nullptr) { 22686 ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'", 22687 buf_ptr(&promise_type->name))); 22688 return ira->codegen->invalid_instruction; 22689 } 22690 22691 return ir_const_type(ira, &instruction->base, promise_type->data.promise.result_type); 22692 } 22693 22694 static IrInstruction *ir_analyze_instruction_await_bookkeeping(IrAnalyze *ira, IrInstructionAwaitBookkeeping *instruction) { 22695 ZigType *promise_result_type = ir_resolve_type(ira, instruction->promise_result_type->child); 22696 if (type_is_invalid(promise_result_type)) 22697 return ira->codegen->invalid_instruction; 22698 22699 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 22700 ir_assert(fn_entry != nullptr, &instruction->base); 22701 22702 if (type_can_fail(promise_result_type)) { 22703 fn_entry->calls_or_awaits_errorable_fn = true; 22704 } 22705 22706 return ir_const_void(ira, &instruction->base); 22707 } 22708 22709 static IrInstruction *ir_analyze_instruction_merge_err_ret_traces(IrAnalyze *ira, 22710 IrInstructionMergeErrRetTraces *instruction) 22711 { 22712 IrInstruction *coro_promise_ptr = instruction->coro_promise_ptr->child; 22713 if (type_is_invalid(coro_promise_ptr->value.type)) 22714 return ira->codegen->invalid_instruction; 22715 22716 ir_assert(coro_promise_ptr->value.type->id == ZigTypeIdPointer, &instruction->base); 22717 ZigType *promise_frame_type = coro_promise_ptr->value.type->data.pointer.child_type; 22718 ir_assert(promise_frame_type->id == ZigTypeIdStruct, &instruction->base); 22719 ZigType *promise_result_type = promise_frame_type->data.structure.fields[1].type_entry; 22720 22721 if (!type_can_fail(promise_result_type)) { 22722 return ir_const_void(ira, &instruction->base); 22723 } 22724 22725 IrInstruction *src_err_ret_trace_ptr = instruction->src_err_ret_trace_ptr->child; 22726 if (type_is_invalid(src_err_ret_trace_ptr->value.type)) 22727 return ira->codegen->invalid_instruction; 22728 22729 IrInstruction *dest_err_ret_trace_ptr = instruction->dest_err_ret_trace_ptr->child; 22730 if (type_is_invalid(dest_err_ret_trace_ptr->value.type)) 22731 return ira->codegen->invalid_instruction; 22732 22733 IrInstruction *result = ir_build_merge_err_ret_traces(&ira->new_irb, instruction->base.scope, 22734 instruction->base.source_node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); 22735 result->value.type = ira->codegen->builtin_types.entry_void; 22736 return result; 22737 } 22738 22739 static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) { 22740 IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope, 22741 instruction->base.source_node); 22742 result->value.type = ira->codegen->builtin_types.entry_void; 22743 return result; 22744 } 22745 22746 static IrInstruction *ir_analyze_instruction_mark_err_ret_trace_ptr(IrAnalyze *ira, IrInstructionMarkErrRetTracePtr *instruction) { 22747 IrInstruction *err_ret_trace_ptr = instruction->err_ret_trace_ptr->child; 22748 if (type_is_invalid(err_ret_trace_ptr->value.type)) 22749 return ira->codegen->invalid_instruction; 22750 22751 IrInstruction *result = ir_build_mark_err_ret_trace_ptr(&ira->new_irb, instruction->base.scope, 22752 instruction->base.source_node, err_ret_trace_ptr); 22753 result->value.type = ira->codegen->builtin_types.entry_void; 22754 return result; 22755 } 22756 22757 static IrInstruction *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionSqrt *instruction) { 22758 ZigType *float_type = ir_resolve_type(ira, instruction->type->child); 22759 if (type_is_invalid(float_type)) 22760 return ira->codegen->invalid_instruction; 22761 22762 IrInstruction *op = instruction->op->child; 22763 if (type_is_invalid(op->value.type)) 22764 return ira->codegen->invalid_instruction; 22765 22766 bool ok_type = float_type->id == ZigTypeIdComptimeFloat || float_type->id == ZigTypeIdFloat; 22767 if (!ok_type) { 22768 ir_add_error(ira, instruction->type, buf_sprintf("@sqrt does not support type '%s'", buf_ptr(&float_type->name))); 22769 return ira->codegen->invalid_instruction; 22770 } 22771 22772 IrInstruction *casted_op = ir_implicit_cast(ira, op, float_type); 22773 if (type_is_invalid(casted_op->value.type)) 22774 return ira->codegen->invalid_instruction; 22775 22776 if (instr_is_comptime(casted_op)) { 22777 ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad); 22778 if (!val) 22779 return ira->codegen->invalid_instruction; 22780 22781 IrInstruction *result = ir_const(ira, &instruction->base, float_type); 22782 ConstExprValue *out_val = &result->value; 22783 22784 if (float_type->id == ZigTypeIdComptimeFloat) { 22785 bigfloat_sqrt(&out_val->data.x_bigfloat, &val->data.x_bigfloat); 22786 } else if (float_type->id == ZigTypeIdFloat) { 22787 switch (float_type->data.floating.bit_count) { 22788 case 16: 22789 out_val->data.x_f16 = f16_sqrt(val->data.x_f16); 22790 break; 22791 case 32: 22792 out_val->data.x_f32 = sqrtf(val->data.x_f32); 22793 break; 22794 case 64: 22795 out_val->data.x_f64 = sqrt(val->data.x_f64); 22796 break; 22797 case 128: 22798 f128M_sqrt(&val->data.x_f128, &out_val->data.x_f128); 22799 break; 22800 default: 22801 zig_unreachable(); 22802 } 22803 } else { 22804 zig_unreachable(); 22805 } 22806 22807 return result; 22808 } 22809 22810 ir_assert(float_type->id == ZigTypeIdFloat, &instruction->base); 22811 if (float_type->data.floating.bit_count != 16 && 22812 float_type->data.floating.bit_count != 32 && 22813 float_type->data.floating.bit_count != 64) { 22814 ir_add_error(ira, instruction->type, buf_sprintf("compiler TODO: add implementation of sqrt for '%s'", buf_ptr(&float_type->name))); 22815 return ira->codegen->invalid_instruction; 22816 } 22817 22818 IrInstruction *result = ir_build_sqrt(&ira->new_irb, instruction->base.scope, 22819 instruction->base.source_node, nullptr, casted_op); 22820 result->value.type = float_type; 22821 return result; 22822 } 22823 22824 static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstructionBswap *instruction) { 22825 ZigType *int_type = ir_resolve_type(ira, instruction->type->child); 22826 if (type_is_invalid(int_type)) 22827 return ira->codegen->invalid_instruction; 22828 22829 IrInstruction *op = instruction->op->child; 22830 if (type_is_invalid(op->value.type)) 22831 return ira->codegen->invalid_instruction; 22832 22833 if (int_type->id != ZigTypeIdInt) { 22834 ir_add_error(ira, instruction->type, 22835 buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name))); 22836 return ira->codegen->invalid_instruction; 22837 } 22838 22839 if (int_type->data.integral.bit_count % 8 != 0) { 22840 ir_add_error(ira, instruction->type, 22841 buf_sprintf("@bswap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", 22842 buf_ptr(&int_type->name), int_type->data.integral.bit_count)); 22843 return ira->codegen->invalid_instruction; 22844 } 22845 22846 IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); 22847 if (type_is_invalid(casted_op->value.type)) 22848 return ira->codegen->invalid_instruction; 22849 22850 if (int_type->data.integral.bit_count == 0) { 22851 IrInstruction *result = ir_const(ira, &instruction->base, int_type); 22852 bigint_init_unsigned(&result->value.data.x_bigint, 0); 22853 return result; 22854 } 22855 22856 if (int_type->data.integral.bit_count == 8) { 22857 return casted_op; 22858 } 22859 22860 if (instr_is_comptime(casted_op)) { 22861 ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad); 22862 if (!val) 22863 return ira->codegen->invalid_instruction; 22864 22865 IrInstruction *result = ir_const(ira, &instruction->base, int_type); 22866 size_t buf_size = int_type->data.integral.bit_count / 8; 22867 uint8_t *buf = allocate_nonzero<uint8_t>(buf_size); 22868 bigint_write_twos_complement(&val->data.x_bigint, buf, int_type->data.integral.bit_count, true); 22869 bigint_read_twos_complement(&result->value.data.x_bigint, buf, int_type->data.integral.bit_count, false, 22870 int_type->data.integral.is_signed); 22871 return result; 22872 } 22873 22874 IrInstruction *result = ir_build_bswap(&ira->new_irb, instruction->base.scope, 22875 instruction->base.source_node, nullptr, casted_op); 22876 result->value.type = int_type; 22877 return result; 22878 } 22879 22880 static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstructionBitReverse *instruction) { 22881 ZigType *int_type = ir_resolve_type(ira, instruction->type->child); 22882 if (type_is_invalid(int_type)) 22883 return ira->codegen->invalid_instruction; 22884 22885 IrInstruction *op = instruction->op->child; 22886 if (type_is_invalid(op->value.type)) 22887 return ira->codegen->invalid_instruction; 22888 22889 if (int_type->id != ZigTypeIdInt) { 22890 ir_add_error(ira, instruction->type, 22891 buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name))); 22892 return ira->codegen->invalid_instruction; 22893 } 22894 22895 IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); 22896 if (type_is_invalid(casted_op->value.type)) 22897 return ira->codegen->invalid_instruction; 22898 22899 if (int_type->data.integral.bit_count == 0) { 22900 IrInstruction *result = ir_const(ira, &instruction->base, int_type); 22901 bigint_init_unsigned(&result->value.data.x_bigint, 0); 22902 return result; 22903 } 22904 22905 if (instr_is_comptime(casted_op)) { 22906 ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad); 22907 if (!val) 22908 return ira->codegen->invalid_instruction; 22909 22910 IrInstruction *result = ir_const(ira, &instruction->base, int_type); 22911 size_t num_bits = int_type->data.integral.bit_count; 22912 size_t buf_size = (num_bits + 7) / 8; 22913 uint8_t *comptime_buf = allocate_nonzero<uint8_t>(buf_size); 22914 uint8_t *result_buf = allocate_nonzero<uint8_t>(buf_size); 22915 memset(comptime_buf,0,buf_size); 22916 memset(result_buf,0,buf_size); 22917 22918 bigint_write_twos_complement(&val->data.x_bigint,comptime_buf,num_bits,ira->codegen->is_big_endian); 22919 22920 size_t bit_i = 0; 22921 size_t bit_rev_i = num_bits - 1; 22922 for (; bit_i < num_bits; bit_i++, bit_rev_i--) { 22923 if (comptime_buf[bit_i / 8] & (1 << (bit_i % 8))) { 22924 result_buf[bit_rev_i / 8] |= (1 << (bit_rev_i % 8)); 22925 } 22926 } 22927 22928 bigint_read_twos_complement(&result->value.data.x_bigint, 22929 result_buf, 22930 int_type->data.integral.bit_count, 22931 ira->codegen->is_big_endian, 22932 int_type->data.integral.is_signed); 22933 22934 return result; 22935 } 22936 22937 IrInstruction *result = ir_build_bit_reverse(&ira->new_irb, instruction->base.scope, 22938 instruction->base.source_node, nullptr, casted_op); 22939 result->value.type = int_type; 22940 return result; 22941 } 22942 22943 22944 static IrInstruction *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstructionEnumToInt *instruction) { 22945 IrInstruction *target = instruction->target->child; 22946 if (type_is_invalid(target->value.type)) 22947 return ira->codegen->invalid_instruction; 22948 22949 return ir_analyze_enum_to_int(ira, &instruction->base, target); 22950 } 22951 22952 static IrInstruction *ir_analyze_instruction_int_to_enum(IrAnalyze *ira, IrInstructionIntToEnum *instruction) { 22953 Error err; 22954 IrInstruction *dest_type_value = instruction->dest_type->child; 22955 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 22956 if (type_is_invalid(dest_type)) 22957 return ira->codegen->invalid_instruction; 22958 22959 if (dest_type->id != ZigTypeIdEnum) { 22960 ir_add_error(ira, instruction->dest_type, 22961 buf_sprintf("expected enum, found type '%s'", buf_ptr(&dest_type->name))); 22962 return ira->codegen->invalid_instruction; 22963 } 22964 22965 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 22966 return ira->codegen->invalid_instruction; 22967 22968 ZigType *tag_type = dest_type->data.enumeration.tag_int_type; 22969 22970 IrInstruction *target = instruction->target->child; 22971 if (type_is_invalid(target->value.type)) 22972 return ira->codegen->invalid_instruction; 22973 22974 IrInstruction *casted_target = ir_implicit_cast(ira, target, tag_type); 22975 if (type_is_invalid(casted_target->value.type)) 22976 return ira->codegen->invalid_instruction; 22977 22978 return ir_analyze_int_to_enum(ira, &instruction->base, casted_target, dest_type); 22979 } 22980 22981 static IrInstruction *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, IrInstructionCheckRuntimeScope *instruction) { 22982 IrInstruction *block_comptime_inst = instruction->scope_is_comptime->child; 22983 bool scope_is_comptime; 22984 if (!ir_resolve_bool(ira, block_comptime_inst, &scope_is_comptime)) 22985 return ira->codegen->invalid_instruction; 22986 22987 IrInstruction *is_comptime_inst = instruction->is_comptime->child; 22988 bool is_comptime; 22989 if (!ir_resolve_bool(ira, is_comptime_inst, &is_comptime)) 22990 return ira->codegen->invalid_instruction; 22991 22992 if (!scope_is_comptime && is_comptime) { 22993 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 22994 buf_sprintf("comptime control flow inside runtime block")); 22995 add_error_note(ira->codegen, msg, block_comptime_inst->source_node, 22996 buf_sprintf("runtime block created here")); 22997 return ira->codegen->invalid_instruction; 22998 } 22999 23000 return ir_const_void(ira, &instruction->base); 23001 } 23002 23003 static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { 23004 switch (instruction->id) { 23005 case IrInstructionIdInvalid: 23006 case IrInstructionIdWidenOrShorten: 23007 case IrInstructionIdStructInit: 23008 case IrInstructionIdUnionInit: 23009 case IrInstructionIdStructFieldPtr: 23010 case IrInstructionIdUnionFieldPtr: 23011 case IrInstructionIdOptionalWrap: 23012 case IrInstructionIdErrWrapCode: 23013 case IrInstructionIdErrWrapPayload: 23014 case IrInstructionIdCast: 23015 case IrInstructionIdDeclVarGen: 23016 case IrInstructionIdPtrCastGen: 23017 case IrInstructionIdCmpxchgGen: 23018 case IrInstructionIdArrayToVector: 23019 case IrInstructionIdVectorToArray: 23020 case IrInstructionIdAssertZero: 23021 case IrInstructionIdAssertNonNull: 23022 case IrInstructionIdResizeSlice: 23023 case IrInstructionIdLoadPtrGen: 23024 case IrInstructionIdBitCastGen: 23025 zig_unreachable(); 23026 23027 case IrInstructionIdReturn: 23028 return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction); 23029 case IrInstructionIdConst: 23030 return ir_analyze_instruction_const(ira, (IrInstructionConst *)instruction); 23031 case IrInstructionIdUnOp: 23032 return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction); 23033 case IrInstructionIdBinOp: 23034 return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction); 23035 case IrInstructionIdDeclVarSrc: 23036 return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVarSrc *)instruction); 23037 case IrInstructionIdLoadPtr: 23038 return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction); 23039 case IrInstructionIdStorePtr: 23040 return ir_analyze_instruction_store_ptr(ira, (IrInstructionStorePtr *)instruction); 23041 case IrInstructionIdElemPtr: 23042 return ir_analyze_instruction_elem_ptr(ira, (IrInstructionElemPtr *)instruction); 23043 case IrInstructionIdVarPtr: 23044 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); 23045 case IrInstructionIdFieldPtr: 23046 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); 23047 case IrInstructionIdCall: 23048 return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); 23049 case IrInstructionIdBr: 23050 return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); 23051 case IrInstructionIdCondBr: 23052 return ir_analyze_instruction_cond_br(ira, (IrInstructionCondBr *)instruction); 23053 case IrInstructionIdUnreachable: 23054 return ir_analyze_instruction_unreachable(ira, (IrInstructionUnreachable *)instruction); 23055 case IrInstructionIdPhi: 23056 return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); 23057 case IrInstructionIdTypeOf: 23058 return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); 23059 case IrInstructionIdToPtrType: 23060 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); 23061 case IrInstructionIdPtrTypeChild: 23062 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); 23063 case IrInstructionIdSetCold: 23064 return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); 23065 case IrInstructionIdSetRuntimeSafety: 23066 return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction); 23067 case IrInstructionIdSetFloatMode: 23068 return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction); 23069 case IrInstructionIdSliceType: 23070 return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction); 23071 case IrInstructionIdGlobalAsm: 23072 return ir_analyze_instruction_global_asm(ira, (IrInstructionGlobalAsm *)instruction); 23073 case IrInstructionIdAsm: 23074 return ir_analyze_instruction_asm(ira, (IrInstructionAsm *)instruction); 23075 case IrInstructionIdArrayType: 23076 return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction); 23077 case IrInstructionIdPromiseType: 23078 return ir_analyze_instruction_promise_type(ira, (IrInstructionPromiseType *)instruction); 23079 case IrInstructionIdSizeOf: 23080 return ir_analyze_instruction_size_of(ira, (IrInstructionSizeOf *)instruction); 23081 case IrInstructionIdTestNonNull: 23082 return ir_analyze_instruction_test_non_null(ira, (IrInstructionTestNonNull *)instruction); 23083 case IrInstructionIdOptionalUnwrapPtr: 23084 return ir_analyze_instruction_optional_unwrap_ptr(ira, (IrInstructionOptionalUnwrapPtr *)instruction); 23085 case IrInstructionIdClz: 23086 return ir_analyze_instruction_clz(ira, (IrInstructionClz *)instruction); 23087 case IrInstructionIdCtz: 23088 return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction); 23089 case IrInstructionIdPopCount: 23090 return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction); 23091 case IrInstructionIdSwitchBr: 23092 return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction); 23093 case IrInstructionIdSwitchTarget: 23094 return ir_analyze_instruction_switch_target(ira, (IrInstructionSwitchTarget *)instruction); 23095 case IrInstructionIdSwitchVar: 23096 return ir_analyze_instruction_switch_var(ira, (IrInstructionSwitchVar *)instruction); 23097 case IrInstructionIdUnionTag: 23098 return ir_analyze_instruction_union_tag(ira, (IrInstructionUnionTag *)instruction); 23099 case IrInstructionIdImport: 23100 return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction); 23101 case IrInstructionIdRef: 23102 return ir_analyze_instruction_ref(ira, (IrInstructionRef *)instruction); 23103 case IrInstructionIdContainerInitList: 23104 return ir_analyze_instruction_container_init_list(ira, (IrInstructionContainerInitList *)instruction); 23105 case IrInstructionIdContainerInitFields: 23106 return ir_analyze_instruction_container_init_fields(ira, (IrInstructionContainerInitFields *)instruction); 23107 case IrInstructionIdCompileErr: 23108 return ir_analyze_instruction_compile_err(ira, (IrInstructionCompileErr *)instruction); 23109 case IrInstructionIdCompileLog: 23110 return ir_analyze_instruction_compile_log(ira, (IrInstructionCompileLog *)instruction); 23111 case IrInstructionIdErrName: 23112 return ir_analyze_instruction_err_name(ira, (IrInstructionErrName *)instruction); 23113 case IrInstructionIdTypeName: 23114 return ir_analyze_instruction_type_name(ira, (IrInstructionTypeName *)instruction); 23115 case IrInstructionIdCImport: 23116 return ir_analyze_instruction_c_import(ira, (IrInstructionCImport *)instruction); 23117 case IrInstructionIdCInclude: 23118 return ir_analyze_instruction_c_include(ira, (IrInstructionCInclude *)instruction); 23119 case IrInstructionIdCDefine: 23120 return ir_analyze_instruction_c_define(ira, (IrInstructionCDefine *)instruction); 23121 case IrInstructionIdCUndef: 23122 return ir_analyze_instruction_c_undef(ira, (IrInstructionCUndef *)instruction); 23123 case IrInstructionIdEmbedFile: 23124 return ir_analyze_instruction_embed_file(ira, (IrInstructionEmbedFile *)instruction); 23125 case IrInstructionIdCmpxchgSrc: 23126 return ir_analyze_instruction_cmpxchg(ira, (IrInstructionCmpxchgSrc *)instruction); 23127 case IrInstructionIdFence: 23128 return ir_analyze_instruction_fence(ira, (IrInstructionFence *)instruction); 23129 case IrInstructionIdTruncate: 23130 return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction); 23131 case IrInstructionIdIntCast: 23132 return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction); 23133 case IrInstructionIdFloatCast: 23134 return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction); 23135 case IrInstructionIdErrSetCast: 23136 return ir_analyze_instruction_err_set_cast(ira, (IrInstructionErrSetCast *)instruction); 23137 case IrInstructionIdFromBytes: 23138 return ir_analyze_instruction_from_bytes(ira, (IrInstructionFromBytes *)instruction); 23139 case IrInstructionIdToBytes: 23140 return ir_analyze_instruction_to_bytes(ira, (IrInstructionToBytes *)instruction); 23141 case IrInstructionIdIntToFloat: 23142 return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); 23143 case IrInstructionIdFloatToInt: 23144 return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction); 23145 case IrInstructionIdBoolToInt: 23146 return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction); 23147 case IrInstructionIdIntType: 23148 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); 23149 case IrInstructionIdVectorType: 23150 return ir_analyze_instruction_vector_type(ira, (IrInstructionVectorType *)instruction); 23151 case IrInstructionIdBoolNot: 23152 return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); 23153 case IrInstructionIdMemset: 23154 return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); 23155 case IrInstructionIdMemcpy: 23156 return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); 23157 case IrInstructionIdSlice: 23158 return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction); 23159 case IrInstructionIdMemberCount: 23160 return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); 23161 case IrInstructionIdMemberType: 23162 return ir_analyze_instruction_member_type(ira, (IrInstructionMemberType *)instruction); 23163 case IrInstructionIdMemberName: 23164 return ir_analyze_instruction_member_name(ira, (IrInstructionMemberName *)instruction); 23165 case IrInstructionIdBreakpoint: 23166 return ir_analyze_instruction_breakpoint(ira, (IrInstructionBreakpoint *)instruction); 23167 case IrInstructionIdReturnAddress: 23168 return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction); 23169 case IrInstructionIdFrameAddress: 23170 return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction); 23171 case IrInstructionIdHandle: 23172 return ir_analyze_instruction_handle(ira, (IrInstructionHandle *)instruction); 23173 case IrInstructionIdAlignOf: 23174 return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); 23175 case IrInstructionIdOverflowOp: 23176 return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); 23177 case IrInstructionIdTestErr: 23178 return ir_analyze_instruction_test_err(ira, (IrInstructionTestErr *)instruction); 23179 case IrInstructionIdUnwrapErrCode: 23180 return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); 23181 case IrInstructionIdUnwrapErrPayload: 23182 return ir_analyze_instruction_unwrap_err_payload(ira, (IrInstructionUnwrapErrPayload *)instruction); 23183 case IrInstructionIdFnProto: 23184 return ir_analyze_instruction_fn_proto(ira, (IrInstructionFnProto *)instruction); 23185 case IrInstructionIdTestComptime: 23186 return ir_analyze_instruction_test_comptime(ira, (IrInstructionTestComptime *)instruction); 23187 case IrInstructionIdCheckSwitchProngs: 23188 return ir_analyze_instruction_check_switch_prongs(ira, (IrInstructionCheckSwitchProngs *)instruction); 23189 case IrInstructionIdCheckStatementIsVoid: 23190 return ir_analyze_instruction_check_statement_is_void(ira, (IrInstructionCheckStatementIsVoid *)instruction); 23191 case IrInstructionIdDeclRef: 23192 return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction); 23193 case IrInstructionIdPanic: 23194 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); 23195 case IrInstructionIdPtrCastSrc: 23196 return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction); 23197 case IrInstructionIdBitCast: 23198 return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction); 23199 case IrInstructionIdIntToPtr: 23200 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); 23201 case IrInstructionIdPtrToInt: 23202 return ir_analyze_instruction_ptr_to_int(ira, (IrInstructionPtrToInt *)instruction); 23203 case IrInstructionIdTagName: 23204 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionTagName *)instruction); 23205 case IrInstructionIdFieldParentPtr: 23206 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); 23207 case IrInstructionIdByteOffsetOf: 23208 return ir_analyze_instruction_byte_offset_of(ira, (IrInstructionByteOffsetOf *)instruction); 23209 case IrInstructionIdBitOffsetOf: 23210 return ir_analyze_instruction_bit_offset_of(ira, (IrInstructionBitOffsetOf *)instruction); 23211 case IrInstructionIdTypeInfo: 23212 return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); 23213 case IrInstructionIdTypeId: 23214 return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); 23215 case IrInstructionIdSetEvalBranchQuota: 23216 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstructionSetEvalBranchQuota *)instruction); 23217 case IrInstructionIdPtrType: 23218 return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); 23219 case IrInstructionIdAlignCast: 23220 return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); 23221 case IrInstructionIdOpaqueType: 23222 return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); 23223 case IrInstructionIdSetAlignStack: 23224 return ir_analyze_instruction_set_align_stack(ira, (IrInstructionSetAlignStack *)instruction); 23225 case IrInstructionIdArgType: 23226 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction); 23227 case IrInstructionIdTagType: 23228 return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction); 23229 case IrInstructionIdExport: 23230 return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction); 23231 case IrInstructionIdErrorReturnTrace: 23232 return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction); 23233 case IrInstructionIdErrorUnion: 23234 return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction); 23235 case IrInstructionIdCancel: 23236 return ir_analyze_instruction_cancel(ira, (IrInstructionCancel *)instruction); 23237 case IrInstructionIdCoroId: 23238 return ir_analyze_instruction_coro_id(ira, (IrInstructionCoroId *)instruction); 23239 case IrInstructionIdCoroAlloc: 23240 return ir_analyze_instruction_coro_alloc(ira, (IrInstructionCoroAlloc *)instruction); 23241 case IrInstructionIdCoroSize: 23242 return ir_analyze_instruction_coro_size(ira, (IrInstructionCoroSize *)instruction); 23243 case IrInstructionIdCoroBegin: 23244 return ir_analyze_instruction_coro_begin(ira, (IrInstructionCoroBegin *)instruction); 23245 case IrInstructionIdGetImplicitAllocator: 23246 return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction); 23247 case IrInstructionIdCoroAllocFail: 23248 return ir_analyze_instruction_coro_alloc_fail(ira, (IrInstructionCoroAllocFail *)instruction); 23249 case IrInstructionIdCoroSuspend: 23250 return ir_analyze_instruction_coro_suspend(ira, (IrInstructionCoroSuspend *)instruction); 23251 case IrInstructionIdCoroEnd: 23252 return ir_analyze_instruction_coro_end(ira, (IrInstructionCoroEnd *)instruction); 23253 case IrInstructionIdCoroFree: 23254 return ir_analyze_instruction_coro_free(ira, (IrInstructionCoroFree *)instruction); 23255 case IrInstructionIdCoroResume: 23256 return ir_analyze_instruction_coro_resume(ira, (IrInstructionCoroResume *)instruction); 23257 case IrInstructionIdCoroSave: 23258 return ir_analyze_instruction_coro_save(ira, (IrInstructionCoroSave *)instruction); 23259 case IrInstructionIdCoroPromise: 23260 return ir_analyze_instruction_coro_promise(ira, (IrInstructionCoroPromise *)instruction); 23261 case IrInstructionIdCoroAllocHelper: 23262 return ir_analyze_instruction_coro_alloc_helper(ira, (IrInstructionCoroAllocHelper *)instruction); 23263 case IrInstructionIdAtomicRmw: 23264 return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction); 23265 case IrInstructionIdAtomicLoad: 23266 return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction); 23267 case IrInstructionIdPromiseResultType: 23268 return ir_analyze_instruction_promise_result_type(ira, (IrInstructionPromiseResultType *)instruction); 23269 case IrInstructionIdAwaitBookkeeping: 23270 return ir_analyze_instruction_await_bookkeeping(ira, (IrInstructionAwaitBookkeeping *)instruction); 23271 case IrInstructionIdSaveErrRetAddr: 23272 return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction); 23273 case IrInstructionIdAddImplicitReturnType: 23274 return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction); 23275 case IrInstructionIdMergeErrRetTraces: 23276 return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction); 23277 case IrInstructionIdMarkErrRetTracePtr: 23278 return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); 23279 case IrInstructionIdSqrt: 23280 return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction); 23281 case IrInstructionIdBswap: 23282 return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction); 23283 case IrInstructionIdBitReverse: 23284 return ir_analyze_instruction_bit_reverse(ira, (IrInstructionBitReverse *)instruction); 23285 case IrInstructionIdIntToErr: 23286 return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); 23287 case IrInstructionIdErrToInt: 23288 return ir_analyze_instruction_err_to_int(ira, (IrInstructionErrToInt *)instruction); 23289 case IrInstructionIdIntToEnum: 23290 return ir_analyze_instruction_int_to_enum(ira, (IrInstructionIntToEnum *)instruction); 23291 case IrInstructionIdEnumToInt: 23292 return ir_analyze_instruction_enum_to_int(ira, (IrInstructionEnumToInt *)instruction); 23293 case IrInstructionIdCheckRuntimeScope: 23294 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction); 23295 } 23296 zig_unreachable(); 23297 } 23298 23299 static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) { 23300 IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction); 23301 ir_assert(new_instruction->value.type != nullptr, old_instruction); 23302 old_instruction->child = new_instruction; 23303 return new_instruction; 23304 } 23305 23306 // This function attempts to evaluate IR code while doing type checking and other analysis. 23307 // It emits a new IrExecutable which is partially evaluated IR code. 23308 ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, 23309 ZigType *expected_type, AstNode *expected_type_source_node) 23310 { 23311 assert(!old_exec->invalid); 23312 assert(expected_type == nullptr || !type_is_invalid(expected_type)); 23313 23314 IrAnalyze *ira = allocate<IrAnalyze>(1); 23315 old_exec->analysis = ira; 23316 ira->codegen = codegen; 23317 23318 ZigFn *fn_entry = exec_fn_entry(old_exec); 23319 bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; 23320 ira->explicit_return_type = is_async ? get_promise_type(codegen, expected_type) : expected_type; 23321 ira->explicit_return_type_source_node = expected_type_source_node; 23322 23323 ira->old_irb.codegen = codegen; 23324 ira->old_irb.exec = old_exec; 23325 23326 ira->new_irb.codegen = codegen; 23327 ira->new_irb.exec = new_exec; 23328 23329 ConstExprValue *vals = create_const_vals(ira->old_irb.exec->mem_slot_count); 23330 ira->exec_context.mem_slot_list.resize(ira->old_irb.exec->mem_slot_count); 23331 for (size_t i = 0; i < ira->exec_context.mem_slot_list.length; i += 1) { 23332 ira->exec_context.mem_slot_list.items[i] = &vals[i]; 23333 } 23334 23335 IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); 23336 IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); 23337 ir_ref_bb(new_entry_bb); 23338 ira->new_irb.current_basic_block = new_entry_bb; 23339 ira->old_bb_index = 0; 23340 23341 ir_start_bb(ira, old_entry_bb, nullptr); 23342 23343 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 23344 IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 23345 23346 if (old_instruction->ref_count == 0 && !ir_has_side_effects(old_instruction)) { 23347 ira->instruction_index += 1; 23348 continue; 23349 } 23350 23351 IrInstruction *new_instruction = ir_analyze_instruction(ira, old_instruction); 23352 if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) { 23353 return ira->codegen->builtin_types.entry_invalid; 23354 } 23355 23356 // unreachable instructions do their own control flow. 23357 if (new_instruction->value.type->id == ZigTypeIdUnreachable) 23358 continue; 23359 23360 ira->instruction_index += 1; 23361 } 23362 23363 if (new_exec->invalid) { 23364 return ira->codegen->builtin_types.entry_invalid; 23365 } else if (ira->src_implicit_return_type_list.length == 0) { 23366 return codegen->builtin_types.entry_unreachable; 23367 } else { 23368 return ir_resolve_peer_types(ira, expected_type_source_node, expected_type, ira->src_implicit_return_type_list.items, 23369 ira->src_implicit_return_type_list.length); 23370 } 23371 } 23372 23373 bool ir_has_side_effects(IrInstruction *instruction) { 23374 switch (instruction->id) { 23375 case IrInstructionIdInvalid: 23376 zig_unreachable(); 23377 case IrInstructionIdBr: 23378 case IrInstructionIdCondBr: 23379 case IrInstructionIdSwitchBr: 23380 case IrInstructionIdDeclVarSrc: 23381 case IrInstructionIdDeclVarGen: 23382 case IrInstructionIdStorePtr: 23383 case IrInstructionIdCall: 23384 case IrInstructionIdReturn: 23385 case IrInstructionIdUnreachable: 23386 case IrInstructionIdSetCold: 23387 case IrInstructionIdSetRuntimeSafety: 23388 case IrInstructionIdSetFloatMode: 23389 case IrInstructionIdImport: 23390 case IrInstructionIdCompileErr: 23391 case IrInstructionIdCompileLog: 23392 case IrInstructionIdCImport: 23393 case IrInstructionIdCInclude: 23394 case IrInstructionIdCDefine: 23395 case IrInstructionIdCUndef: 23396 case IrInstructionIdFence: 23397 case IrInstructionIdMemset: 23398 case IrInstructionIdMemcpy: 23399 case IrInstructionIdBreakpoint: 23400 case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free 23401 case IrInstructionIdCheckSwitchProngs: 23402 case IrInstructionIdCheckStatementIsVoid: 23403 case IrInstructionIdCheckRuntimeScope: 23404 case IrInstructionIdPanic: 23405 case IrInstructionIdSetEvalBranchQuota: 23406 case IrInstructionIdPtrType: 23407 case IrInstructionIdSetAlignStack: 23408 case IrInstructionIdExport: 23409 case IrInstructionIdCancel: 23410 case IrInstructionIdCoroId: 23411 case IrInstructionIdCoroBegin: 23412 case IrInstructionIdCoroAllocFail: 23413 case IrInstructionIdCoroEnd: 23414 case IrInstructionIdCoroResume: 23415 case IrInstructionIdCoroSave: 23416 case IrInstructionIdCoroAllocHelper: 23417 case IrInstructionIdAwaitBookkeeping: 23418 case IrInstructionIdSaveErrRetAddr: 23419 case IrInstructionIdAddImplicitReturnType: 23420 case IrInstructionIdMergeErrRetTraces: 23421 case IrInstructionIdMarkErrRetTracePtr: 23422 case IrInstructionIdAtomicRmw: 23423 case IrInstructionIdCmpxchgGen: 23424 case IrInstructionIdCmpxchgSrc: 23425 case IrInstructionIdAssertZero: 23426 case IrInstructionIdAssertNonNull: 23427 case IrInstructionIdResizeSlice: 23428 case IrInstructionIdGlobalAsm: 23429 return true; 23430 23431 case IrInstructionIdPhi: 23432 case IrInstructionIdUnOp: 23433 case IrInstructionIdBinOp: 23434 case IrInstructionIdLoadPtr: 23435 case IrInstructionIdLoadPtrGen: 23436 case IrInstructionIdConst: 23437 case IrInstructionIdCast: 23438 case IrInstructionIdContainerInitList: 23439 case IrInstructionIdContainerInitFields: 23440 case IrInstructionIdStructInit: 23441 case IrInstructionIdUnionInit: 23442 case IrInstructionIdFieldPtr: 23443 case IrInstructionIdElemPtr: 23444 case IrInstructionIdVarPtr: 23445 case IrInstructionIdTypeOf: 23446 case IrInstructionIdToPtrType: 23447 case IrInstructionIdPtrTypeChild: 23448 case IrInstructionIdStructFieldPtr: 23449 case IrInstructionIdUnionFieldPtr: 23450 case IrInstructionIdArrayType: 23451 case IrInstructionIdPromiseType: 23452 case IrInstructionIdSliceType: 23453 case IrInstructionIdSizeOf: 23454 case IrInstructionIdTestNonNull: 23455 case IrInstructionIdOptionalUnwrapPtr: 23456 case IrInstructionIdClz: 23457 case IrInstructionIdCtz: 23458 case IrInstructionIdPopCount: 23459 case IrInstructionIdSwitchVar: 23460 case IrInstructionIdSwitchTarget: 23461 case IrInstructionIdUnionTag: 23462 case IrInstructionIdRef: 23463 case IrInstructionIdEmbedFile: 23464 case IrInstructionIdTruncate: 23465 case IrInstructionIdIntType: 23466 case IrInstructionIdVectorType: 23467 case IrInstructionIdBoolNot: 23468 case IrInstructionIdSlice: 23469 case IrInstructionIdMemberCount: 23470 case IrInstructionIdMemberType: 23471 case IrInstructionIdMemberName: 23472 case IrInstructionIdAlignOf: 23473 case IrInstructionIdReturnAddress: 23474 case IrInstructionIdFrameAddress: 23475 case IrInstructionIdHandle: 23476 case IrInstructionIdTestErr: 23477 case IrInstructionIdUnwrapErrCode: 23478 case IrInstructionIdOptionalWrap: 23479 case IrInstructionIdErrWrapCode: 23480 case IrInstructionIdErrWrapPayload: 23481 case IrInstructionIdFnProto: 23482 case IrInstructionIdTestComptime: 23483 case IrInstructionIdPtrCastSrc: 23484 case IrInstructionIdPtrCastGen: 23485 case IrInstructionIdBitCast: 23486 case IrInstructionIdBitCastGen: 23487 case IrInstructionIdWidenOrShorten: 23488 case IrInstructionIdPtrToInt: 23489 case IrInstructionIdIntToPtr: 23490 case IrInstructionIdIntToEnum: 23491 case IrInstructionIdIntToErr: 23492 case IrInstructionIdErrToInt: 23493 case IrInstructionIdDeclRef: 23494 case IrInstructionIdErrName: 23495 case IrInstructionIdTypeName: 23496 case IrInstructionIdTagName: 23497 case IrInstructionIdFieldParentPtr: 23498 case IrInstructionIdByteOffsetOf: 23499 case IrInstructionIdBitOffsetOf: 23500 case IrInstructionIdTypeInfo: 23501 case IrInstructionIdTypeId: 23502 case IrInstructionIdAlignCast: 23503 case IrInstructionIdOpaqueType: 23504 case IrInstructionIdArgType: 23505 case IrInstructionIdTagType: 23506 case IrInstructionIdErrorReturnTrace: 23507 case IrInstructionIdErrorUnion: 23508 case IrInstructionIdGetImplicitAllocator: 23509 case IrInstructionIdCoroAlloc: 23510 case IrInstructionIdCoroSize: 23511 case IrInstructionIdCoroSuspend: 23512 case IrInstructionIdCoroFree: 23513 case IrInstructionIdCoroPromise: 23514 case IrInstructionIdPromiseResultType: 23515 case IrInstructionIdSqrt: 23516 case IrInstructionIdBswap: 23517 case IrInstructionIdBitReverse: 23518 case IrInstructionIdAtomicLoad: 23519 case IrInstructionIdIntCast: 23520 case IrInstructionIdFloatCast: 23521 case IrInstructionIdErrSetCast: 23522 case IrInstructionIdIntToFloat: 23523 case IrInstructionIdFloatToInt: 23524 case IrInstructionIdBoolToInt: 23525 case IrInstructionIdFromBytes: 23526 case IrInstructionIdToBytes: 23527 case IrInstructionIdEnumToInt: 23528 case IrInstructionIdVectorToArray: 23529 case IrInstructionIdArrayToVector: 23530 return false; 23531 23532 case IrInstructionIdAsm: 23533 { 23534 IrInstructionAsm *asm_instruction = (IrInstructionAsm *)instruction; 23535 return asm_instruction->has_side_effects; 23536 } 23537 case IrInstructionIdUnwrapErrPayload: 23538 { 23539 IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = 23540 (IrInstructionUnwrapErrPayload *)instruction; 23541 return unwrap_err_payload_instruction->safety_check_on; 23542 } 23543 } 23544 zig_unreachable(); 23545 }