blob 3e80fad2 (1145677B) - 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 AstNode *main_block_node; 30 }; 31 32 struct IrAnalyze { 33 CodeGen *codegen; 34 IrBuilder old_irb; 35 IrBuilder new_irb; 36 IrExecContext exec_context; 37 size_t old_bb_index; 38 size_t instruction_index; 39 ZigType *explicit_return_type; 40 AstNode *explicit_return_type_source_node; 41 ZigList<IrInstruction *> src_implicit_return_type_list; 42 ZigList<IrSuspendPosition> resume_stack; 43 IrBasicBlock *const_predecessor_bb; 44 }; 45 46 enum ConstCastResultId { 47 ConstCastResultIdOk, 48 ConstCastResultIdInvalid, 49 ConstCastResultIdErrSet, 50 ConstCastResultIdErrSetGlobal, 51 ConstCastResultIdPointerChild, 52 ConstCastResultIdSliceChild, 53 ConstCastResultIdOptionalChild, 54 ConstCastResultIdErrorUnionPayload, 55 ConstCastResultIdErrorUnionErrorSet, 56 ConstCastResultIdFnAlign, 57 ConstCastResultIdFnCC, 58 ConstCastResultIdFnVarArgs, 59 ConstCastResultIdFnIsGeneric, 60 ConstCastResultIdFnReturnType, 61 ConstCastResultIdFnArgCount, 62 ConstCastResultIdFnGenericArgCount, 63 ConstCastResultIdFnArg, 64 ConstCastResultIdFnArgNoAlias, 65 ConstCastResultIdType, 66 ConstCastResultIdUnresolvedInferredErrSet, 67 ConstCastResultIdAsyncAllocatorType, 68 ConstCastResultIdBadAllowsZero, 69 }; 70 71 struct ConstCastOnly; 72 struct ConstCastArg { 73 size_t arg_index; 74 ZigType *actual_param_type; 75 ZigType *expected_param_type; 76 ConstCastOnly *child; 77 }; 78 79 struct ConstCastArgNoAlias { 80 size_t arg_index; 81 }; 82 83 struct ConstCastOptionalMismatch; 84 struct ConstCastPointerMismatch; 85 struct ConstCastSliceMismatch; 86 struct ConstCastErrUnionErrSetMismatch; 87 struct ConstCastErrUnionPayloadMismatch; 88 struct ConstCastErrSetMismatch; 89 struct ConstCastTypeMismatch; 90 struct ConstCastBadAllowsZero; 91 92 struct ConstCastOnly { 93 ConstCastResultId id; 94 union { 95 ConstCastErrSetMismatch *error_set_mismatch; 96 ConstCastPointerMismatch *pointer_mismatch; 97 ConstCastSliceMismatch *slice_mismatch; 98 ConstCastOptionalMismatch *optional; 99 ConstCastErrUnionPayloadMismatch *error_union_payload; 100 ConstCastErrUnionErrSetMismatch *error_union_error_set; 101 ConstCastTypeMismatch *type_mismatch; 102 ConstCastOnly *return_type; 103 ConstCastOnly *null_wrap_ptr_child; 104 ConstCastArg fn_arg; 105 ConstCastArgNoAlias arg_no_alias; 106 ConstCastBadAllowsZero *bad_allows_zero; 107 } data; 108 }; 109 110 struct ConstCastTypeMismatch { 111 ZigType *wanted_type; 112 ZigType *actual_type; 113 }; 114 115 struct ConstCastOptionalMismatch { 116 ConstCastOnly child; 117 ZigType *wanted_child; 118 ZigType *actual_child; 119 }; 120 121 struct ConstCastPointerMismatch { 122 ConstCastOnly child; 123 ZigType *wanted_child; 124 ZigType *actual_child; 125 }; 126 127 struct ConstCastSliceMismatch { 128 ConstCastOnly child; 129 ZigType *wanted_child; 130 ZigType *actual_child; 131 }; 132 133 struct ConstCastErrUnionErrSetMismatch { 134 ConstCastOnly child; 135 ZigType *wanted_err_set; 136 ZigType *actual_err_set; 137 }; 138 139 struct ConstCastErrUnionPayloadMismatch { 140 ConstCastOnly child; 141 ZigType *wanted_payload; 142 ZigType *actual_payload; 143 }; 144 145 struct ConstCastErrSetMismatch { 146 ZigList<ErrorTableEntry *> missing_errors; 147 }; 148 149 struct ConstCastBadAllowsZero { 150 ZigType *wanted_type; 151 ZigType *actual_type; 152 }; 153 154 155 enum UndefAllowed { 156 UndefOk, 157 UndefBad, 158 }; 159 160 static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); 161 static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, 162 ResultLoc *result_loc); 163 static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type); 164 static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, 165 ResultLoc *result_loc); 166 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg); 167 static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 168 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing); 169 static void ir_assert(bool ok, IrInstruction *source_instruction); 170 static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var); 171 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); 172 static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval, ResultLoc *result_loc); 173 static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc); 174 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); 175 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); 176 static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val); 177 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); 178 static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 179 ConstExprValue *out_val, ConstExprValue *ptr_val); 180 static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, 181 ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on); 182 static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); 183 static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs); 184 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); 185 static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 186 ZigType *ptr_type); 187 static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 188 ZigType *dest_type); 189 static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, 190 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime); 191 static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, 192 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, 193 bool non_null_comptime, bool allow_discard); 194 static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, 195 IrInstruction *base_ptr, bool safety_check_on, bool initializing); 196 static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, 197 IrInstruction *base_ptr, bool safety_check_on, bool initializing); 198 static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, 199 IrInstruction *base_ptr, bool initializing); 200 static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, 201 IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const); 202 static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, 203 IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, 204 LVal lval, ResultLoc *parent_result_loc); 205 206 static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { 207 assert(get_src_ptr_type(const_val->type) != nullptr); 208 assert(const_val->special == ConstValSpecialStatic); 209 ConstExprValue *result; 210 211 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { 212 case OnePossibleValueInvalid: 213 zig_unreachable(); 214 case OnePossibleValueYes: 215 result = create_const_vals(1); 216 result->type = const_val->type->data.pointer.child_type; 217 result->special = ConstValSpecialStatic; 218 return result; 219 case OnePossibleValueNo: 220 break; 221 } 222 223 switch (const_val->data.x_ptr.special) { 224 case ConstPtrSpecialInvalid: 225 zig_unreachable(); 226 case ConstPtrSpecialRef: 227 result = const_val->data.x_ptr.data.ref.pointee; 228 break; 229 case ConstPtrSpecialBaseArray: { 230 ConstExprValue *array_val = const_val->data.x_ptr.data.base_array.array_val; 231 expand_undef_array(g, array_val); 232 result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index]; 233 break; 234 } 235 case ConstPtrSpecialBaseStruct: { 236 ConstExprValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val; 237 result = &struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; 238 break; 239 } 240 case ConstPtrSpecialBaseErrorUnionCode: 241 result = const_val->data.x_ptr.data.base_err_union_code.err_union_val->data.x_err_union.error_set; 242 break; 243 case ConstPtrSpecialBaseErrorUnionPayload: 244 result = const_val->data.x_ptr.data.base_err_union_payload.err_union_val->data.x_err_union.payload; 245 break; 246 case ConstPtrSpecialBaseOptionalPayload: 247 result = const_val->data.x_ptr.data.base_optional_payload.optional_val->data.x_optional; 248 break; 249 case ConstPtrSpecialNull: 250 result = const_val; 251 break; 252 case ConstPtrSpecialHardCodedAddr: 253 zig_unreachable(); 254 case ConstPtrSpecialDiscard: 255 zig_unreachable(); 256 case ConstPtrSpecialFunction: 257 zig_unreachable(); 258 } 259 assert(result != nullptr); 260 return result; 261 } 262 263 static bool is_opt_err_set(ZigType *ty) { 264 return ty->id == ZigTypeIdErrorSet || 265 (ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet); 266 } 267 268 static bool is_slice(ZigType *type) { 269 return type->id == ZigTypeIdStruct && type->data.structure.is_slice; 270 } 271 272 static bool slice_is_const(ZigType *type) { 273 assert(is_slice(type)); 274 return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; 275 } 276 277 // This function returns true when you can change the type of a ConstExprValue and the 278 // value remains meaningful. 279 static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { 280 if (a == b) 281 return true; 282 283 if (get_codegen_ptr_type(a) != nullptr && get_codegen_ptr_type(b) != nullptr) 284 return true; 285 286 if (is_opt_err_set(a) && is_opt_err_set(b)) 287 return true; 288 289 if (a->id != b->id) 290 return false; 291 292 switch (a->id) { 293 case ZigTypeIdInvalid: 294 case ZigTypeIdUnreachable: 295 zig_unreachable(); 296 case ZigTypeIdMetaType: 297 case ZigTypeIdVoid: 298 case ZigTypeIdBool: 299 case ZigTypeIdComptimeFloat: 300 case ZigTypeIdComptimeInt: 301 case ZigTypeIdEnumLiteral: 302 case ZigTypeIdPointer: 303 case ZigTypeIdUndefined: 304 case ZigTypeIdNull: 305 case ZigTypeIdBoundFn: 306 case ZigTypeIdErrorSet: 307 case ZigTypeIdOpaque: 308 case ZigTypeIdAnyFrame: 309 return true; 310 case ZigTypeIdFloat: 311 return a->data.floating.bit_count == b->data.floating.bit_count; 312 case ZigTypeIdInt: 313 return a->data.integral.is_signed == b->data.integral.is_signed; 314 case ZigTypeIdStruct: 315 return is_slice(a) && is_slice(b); 316 case ZigTypeIdArray: 317 case ZigTypeIdOptional: 318 case ZigTypeIdErrorUnion: 319 case ZigTypeIdEnum: 320 case ZigTypeIdUnion: 321 case ZigTypeIdFn: 322 case ZigTypeIdArgTuple: 323 case ZigTypeIdVector: 324 case ZigTypeIdFnFrame: 325 return false; 326 } 327 zig_unreachable(); 328 } 329 330 static bool ir_should_inline(IrExecutable *exec, Scope *scope) { 331 if (exec->is_inline) 332 return true; 333 334 while (scope != nullptr) { 335 if (scope->id == ScopeIdCompTime) 336 return true; 337 if (scope->id == ScopeIdFnDef) 338 break; 339 scope = scope->parent; 340 } 341 return false; 342 } 343 344 static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) { 345 assert(basic_block); 346 assert(instruction); 347 basic_block->instruction_list.append(instruction); 348 } 349 350 static size_t exec_next_debug_id(IrExecutable *exec) { 351 size_t result = exec->next_debug_id; 352 exec->next_debug_id += 1; 353 return result; 354 } 355 356 static size_t exec_next_mem_slot(IrExecutable *exec) { 357 size_t result = exec->mem_slot_count; 358 exec->mem_slot_count += 1; 359 return result; 360 } 361 362 static ZigFn *exec_fn_entry(IrExecutable *exec) { 363 return exec->fn_entry; 364 } 365 366 static Buf *exec_c_import_buf(IrExecutable *exec) { 367 return exec->c_import_buf; 368 } 369 370 static bool value_is_comptime(ConstExprValue *const_val) { 371 return const_val->special != ConstValSpecialRuntime; 372 } 373 374 static bool instr_is_comptime(IrInstruction *instruction) { 375 return value_is_comptime(&instruction->value); 376 } 377 378 static bool instr_is_unreachable(IrInstruction *instruction) { 379 return instruction->value.type && instruction->value.type->id == ZigTypeIdUnreachable; 380 } 381 382 static void ir_link_new_bb(IrBasicBlock *new_bb, IrBasicBlock *old_bb) { 383 new_bb->other = old_bb; 384 old_bb->other = new_bb; 385 } 386 387 static void ir_ref_bb(IrBasicBlock *bb) { 388 bb->ref_count += 1; 389 } 390 391 static void ir_ref_instruction(IrInstruction *instruction, IrBasicBlock *cur_bb) { 392 assert(instruction->id != IrInstructionIdInvalid); 393 instruction->ref_count += 1; 394 if (instruction->owner_bb != cur_bb && !instr_is_comptime(instruction)) 395 ir_ref_bb(instruction->owner_bb); 396 } 397 398 static void ir_ref_var(ZigVar *var) { 399 var->ref_count += 1; 400 } 401 402 ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { 403 ConstExprValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type, 404 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr, 405 node, nullptr, ira->new_irb.exec, nullptr); 406 407 if (type_is_invalid(result->type)) 408 return ira->codegen->builtin_types.entry_invalid; 409 410 assert(result->special != ConstValSpecialRuntime); 411 return result->data.x_type; 412 } 413 414 static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const char *name_hint) { 415 IrBasicBlock *result = allocate<IrBasicBlock>(1); 416 result->scope = scope; 417 result->name_hint = name_hint; 418 result->debug_id = exec_next_debug_id(irb->exec); 419 result->index = SIZE_MAX; // set later 420 return result; 421 } 422 423 static IrBasicBlock *ir_build_bb_from(IrBuilder *irb, IrBasicBlock *other_bb) { 424 IrBasicBlock *new_bb = ir_create_basic_block(irb, other_bb->scope, other_bb->name_hint); 425 ir_link_new_bb(new_bb, other_bb); 426 return new_bb; 427 } 428 429 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVarSrc *) { 430 return IrInstructionIdDeclVarSrc; 431 } 432 433 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVarGen *) { 434 return IrInstructionIdDeclVarGen; 435 } 436 437 static constexpr IrInstructionId ir_instruction_id(IrInstructionCondBr *) { 438 return IrInstructionIdCondBr; 439 } 440 441 static constexpr IrInstructionId ir_instruction_id(IrInstructionBr *) { 442 return IrInstructionIdBr; 443 } 444 445 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchBr *) { 446 return IrInstructionIdSwitchBr; 447 } 448 449 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchVar *) { 450 return IrInstructionIdSwitchVar; 451 } 452 453 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchElseVar *) { 454 return IrInstructionIdSwitchElseVar; 455 } 456 457 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchTarget *) { 458 return IrInstructionIdSwitchTarget; 459 } 460 461 static constexpr IrInstructionId ir_instruction_id(IrInstructionPhi *) { 462 return IrInstructionIdPhi; 463 } 464 465 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnOp *) { 466 return IrInstructionIdUnOp; 467 } 468 469 static constexpr IrInstructionId ir_instruction_id(IrInstructionBinOp *) { 470 return IrInstructionIdBinOp; 471 } 472 473 static constexpr IrInstructionId ir_instruction_id(IrInstructionExport *) { 474 return IrInstructionIdExport; 475 } 476 477 static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) { 478 return IrInstructionIdLoadPtr; 479 } 480 481 static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtrGen *) { 482 return IrInstructionIdLoadPtrGen; 483 } 484 485 static constexpr IrInstructionId ir_instruction_id(IrInstructionStorePtr *) { 486 return IrInstructionIdStorePtr; 487 } 488 489 static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldPtr *) { 490 return IrInstructionIdFieldPtr; 491 } 492 493 static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *) { 494 return IrInstructionIdStructFieldPtr; 495 } 496 497 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionFieldPtr *) { 498 return IrInstructionIdUnionFieldPtr; 499 } 500 501 static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) { 502 return IrInstructionIdElemPtr; 503 } 504 505 static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) { 506 return IrInstructionIdVarPtr; 507 } 508 509 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnPtr *) { 510 return IrInstructionIdReturnPtr; 511 } 512 513 static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrc *) { 514 return IrInstructionIdCallSrc; 515 } 516 517 static constexpr IrInstructionId ir_instruction_id(IrInstructionCallGen *) { 518 return IrInstructionIdCallGen; 519 } 520 521 static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) { 522 return IrInstructionIdConst; 523 } 524 525 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturn *) { 526 return IrInstructionIdReturn; 527 } 528 529 static constexpr IrInstructionId ir_instruction_id(IrInstructionCast *) { 530 return IrInstructionIdCast; 531 } 532 533 static constexpr IrInstructionId ir_instruction_id(IrInstructionResizeSlice *) { 534 return IrInstructionIdResizeSlice; 535 } 536 537 static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitList *) { 538 return IrInstructionIdContainerInitList; 539 } 540 541 static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitFields *) { 542 return IrInstructionIdContainerInitFields; 543 } 544 545 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnreachable *) { 546 return IrInstructionIdUnreachable; 547 } 548 549 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) { 550 return IrInstructionIdTypeOf; 551 } 552 553 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) { 554 return IrInstructionIdSetCold; 555 } 556 557 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetRuntimeSafety *) { 558 return IrInstructionIdSetRuntimeSafety; 559 } 560 561 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFloatMode *) { 562 return IrInstructionIdSetFloatMode; 563 } 564 565 static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) { 566 return IrInstructionIdArrayType; 567 } 568 569 static constexpr IrInstructionId ir_instruction_id(IrInstructionAnyFrameType *) { 570 return IrInstructionIdAnyFrameType; 571 } 572 573 static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { 574 return IrInstructionIdSliceType; 575 } 576 577 static constexpr IrInstructionId ir_instruction_id(IrInstructionGlobalAsm *) { 578 return IrInstructionIdGlobalAsm; 579 } 580 581 static constexpr IrInstructionId ir_instruction_id(IrInstructionAsm *) { 582 return IrInstructionIdAsm; 583 } 584 585 static constexpr IrInstructionId ir_instruction_id(IrInstructionSizeOf *) { 586 return IrInstructionIdSizeOf; 587 } 588 589 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestNonNull *) { 590 return IrInstructionIdTestNonNull; 591 } 592 593 static constexpr IrInstructionId ir_instruction_id(IrInstructionOptionalUnwrapPtr *) { 594 return IrInstructionIdOptionalUnwrapPtr; 595 } 596 597 static constexpr IrInstructionId ir_instruction_id(IrInstructionClz *) { 598 return IrInstructionIdClz; 599 } 600 601 static constexpr IrInstructionId ir_instruction_id(IrInstructionCtz *) { 602 return IrInstructionIdCtz; 603 } 604 605 static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) { 606 return IrInstructionIdPopCount; 607 } 608 609 static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) { 610 return IrInstructionIdBswap; 611 } 612 613 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) { 614 return IrInstructionIdBitReverse; 615 } 616 617 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) { 618 return IrInstructionIdUnionTag; 619 } 620 621 static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) { 622 return IrInstructionIdImport; 623 } 624 625 static constexpr IrInstructionId ir_instruction_id(IrInstructionCImport *) { 626 return IrInstructionIdCImport; 627 } 628 629 static constexpr IrInstructionId ir_instruction_id(IrInstructionCInclude *) { 630 return IrInstructionIdCInclude; 631 } 632 633 static constexpr IrInstructionId ir_instruction_id(IrInstructionCDefine *) { 634 return IrInstructionIdCDefine; 635 } 636 637 static constexpr IrInstructionId ir_instruction_id(IrInstructionCUndef *) { 638 return IrInstructionIdCUndef; 639 } 640 641 static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) { 642 return IrInstructionIdRef; 643 } 644 645 static constexpr IrInstructionId ir_instruction_id(IrInstructionRefGen *) { 646 return IrInstructionIdRefGen; 647 } 648 649 static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { 650 return IrInstructionIdCompileErr; 651 } 652 653 static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileLog *) { 654 return IrInstructionIdCompileLog; 655 } 656 657 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrName *) { 658 return IrInstructionIdErrName; 659 } 660 661 static constexpr IrInstructionId ir_instruction_id(IrInstructionEmbedFile *) { 662 return IrInstructionIdEmbedFile; 663 } 664 665 static constexpr IrInstructionId ir_instruction_id(IrInstructionCmpxchgSrc *) { 666 return IrInstructionIdCmpxchgSrc; 667 } 668 669 static constexpr IrInstructionId ir_instruction_id(IrInstructionCmpxchgGen *) { 670 return IrInstructionIdCmpxchgGen; 671 } 672 673 static constexpr IrInstructionId ir_instruction_id(IrInstructionFence *) { 674 return IrInstructionIdFence; 675 } 676 677 static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) { 678 return IrInstructionIdTruncate; 679 } 680 681 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntCast *) { 682 return IrInstructionIdIntCast; 683 } 684 685 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) { 686 return IrInstructionIdFloatCast; 687 } 688 689 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrSetCast *) { 690 return IrInstructionIdErrSetCast; 691 } 692 693 static constexpr IrInstructionId ir_instruction_id(IrInstructionToBytes *) { 694 return IrInstructionIdToBytes; 695 } 696 697 static constexpr IrInstructionId ir_instruction_id(IrInstructionFromBytes *) { 698 return IrInstructionIdFromBytes; 699 } 700 701 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) { 702 return IrInstructionIdIntToFloat; 703 } 704 705 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) { 706 return IrInstructionIdFloatToInt; 707 } 708 709 static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) { 710 return IrInstructionIdBoolToInt; 711 } 712 713 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { 714 return IrInstructionIdIntType; 715 } 716 717 static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorType *) { 718 return IrInstructionIdVectorType; 719 } 720 721 static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { 722 return IrInstructionIdBoolNot; 723 } 724 725 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemset *) { 726 return IrInstructionIdMemset; 727 } 728 729 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) { 730 return IrInstructionIdMemcpy; 731 } 732 733 static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceSrc *) { 734 return IrInstructionIdSliceSrc; 735 } 736 737 static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceGen *) { 738 return IrInstructionIdSliceGen; 739 } 740 741 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) { 742 return IrInstructionIdMemberCount; 743 } 744 745 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberType *) { 746 return IrInstructionIdMemberType; 747 } 748 749 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberName *) { 750 return IrInstructionIdMemberName; 751 } 752 753 static constexpr IrInstructionId ir_instruction_id(IrInstructionBreakpoint *) { 754 return IrInstructionIdBreakpoint; 755 } 756 757 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnAddress *) { 758 return IrInstructionIdReturnAddress; 759 } 760 761 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *) { 762 return IrInstructionIdFrameAddress; 763 } 764 765 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameHandle *) { 766 return IrInstructionIdFrameHandle; 767 } 768 769 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameType *) { 770 return IrInstructionIdFrameType; 771 } 772 773 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameSizeSrc *) { 774 return IrInstructionIdFrameSizeSrc; 775 } 776 777 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameSizeGen *) { 778 return IrInstructionIdFrameSizeGen; 779 } 780 781 static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignOf *) { 782 return IrInstructionIdAlignOf; 783 } 784 785 static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { 786 return IrInstructionIdOverflowOp; 787 } 788 789 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrSrc *) { 790 return IrInstructionIdTestErrSrc; 791 } 792 793 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrGen *) { 794 return IrInstructionIdTestErrGen; 795 } 796 797 static constexpr IrInstructionId ir_instruction_id(IrInstructionMulAdd *) { 798 return IrInstructionIdMulAdd; 799 } 800 801 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrCode *) { 802 return IrInstructionIdUnwrapErrCode; 803 } 804 805 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrPayload *) { 806 return IrInstructionIdUnwrapErrPayload; 807 } 808 809 static constexpr IrInstructionId ir_instruction_id(IrInstructionOptionalWrap *) { 810 return IrInstructionIdOptionalWrap; 811 } 812 813 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapPayload *) { 814 return IrInstructionIdErrWrapPayload; 815 } 816 817 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapCode *) { 818 return IrInstructionIdErrWrapCode; 819 } 820 821 static constexpr IrInstructionId ir_instruction_id(IrInstructionFnProto *) { 822 return IrInstructionIdFnProto; 823 } 824 825 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestComptime *) { 826 return IrInstructionIdTestComptime; 827 } 828 829 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastSrc *) { 830 return IrInstructionIdPtrCastSrc; 831 } 832 833 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) { 834 return IrInstructionIdPtrCastGen; 835 } 836 837 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastSrc *) { 838 return IrInstructionIdBitCastSrc; 839 } 840 841 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) { 842 return IrInstructionIdBitCastGen; 843 } 844 845 static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) { 846 return IrInstructionIdWidenOrShorten; 847 } 848 849 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrToInt *) { 850 return IrInstructionIdPtrToInt; 851 } 852 853 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToPtr *) { 854 return IrInstructionIdIntToPtr; 855 } 856 857 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToEnum *) { 858 return IrInstructionIdIntToEnum; 859 } 860 861 static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumToInt *) { 862 return IrInstructionIdEnumToInt; 863 } 864 865 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToErr *) { 866 return IrInstructionIdIntToErr; 867 } 868 869 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrToInt *) { 870 return IrInstructionIdErrToInt; 871 } 872 873 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckSwitchProngs *) { 874 return IrInstructionIdCheckSwitchProngs; 875 } 876 877 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckStatementIsVoid *) { 878 return IrInstructionIdCheckStatementIsVoid; 879 } 880 881 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeName *) { 882 return IrInstructionIdTypeName; 883 } 884 885 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) { 886 return IrInstructionIdDeclRef; 887 } 888 889 static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) { 890 return IrInstructionIdPanic; 891 } 892 893 static constexpr IrInstructionId ir_instruction_id(IrInstructionTagName *) { 894 return IrInstructionIdTagName; 895 } 896 897 static constexpr IrInstructionId ir_instruction_id(IrInstructionTagType *) { 898 return IrInstructionIdTagType; 899 } 900 901 static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) { 902 return IrInstructionIdFieldParentPtr; 903 } 904 905 static constexpr IrInstructionId ir_instruction_id(IrInstructionByteOffsetOf *) { 906 return IrInstructionIdByteOffsetOf; 907 } 908 909 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitOffsetOf *) { 910 return IrInstructionIdBitOffsetOf; 911 } 912 913 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { 914 return IrInstructionIdTypeInfo; 915 } 916 917 static constexpr IrInstructionId ir_instruction_id(IrInstructionHasField *) { 918 return IrInstructionIdHasField; 919 } 920 921 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { 922 return IrInstructionIdTypeId; 923 } 924 925 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetEvalBranchQuota *) { 926 return IrInstructionIdSetEvalBranchQuota; 927 } 928 929 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrType *) { 930 return IrInstructionIdPtrType; 931 } 932 933 static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { 934 return IrInstructionIdAlignCast; 935 } 936 937 static constexpr IrInstructionId ir_instruction_id(IrInstructionImplicitCast *) { 938 return IrInstructionIdImplicitCast; 939 } 940 941 static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *) { 942 return IrInstructionIdResolveResult; 943 } 944 945 static constexpr IrInstructionId ir_instruction_id(IrInstructionResetResult *) { 946 return IrInstructionIdResetResult; 947 } 948 949 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrOfArrayToSlice *) { 950 return IrInstructionIdPtrOfArrayToSlice; 951 } 952 953 static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { 954 return IrInstructionIdOpaqueType; 955 } 956 957 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetAlignStack *) { 958 return IrInstructionIdSetAlignStack; 959 } 960 961 static constexpr IrInstructionId ir_instruction_id(IrInstructionArgType *) { 962 return IrInstructionIdArgType; 963 } 964 965 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorReturnTrace *) { 966 return IrInstructionIdErrorReturnTrace; 967 } 968 969 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorUnion *) { 970 return IrInstructionIdErrorUnion; 971 } 972 973 static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicRmw *) { 974 return IrInstructionIdAtomicRmw; 975 } 976 977 static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) { 978 return IrInstructionIdAtomicLoad; 979 } 980 981 static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) { 982 return IrInstructionIdSaveErrRetAddr; 983 } 984 985 static constexpr IrInstructionId ir_instruction_id(IrInstructionAddImplicitReturnType *) { 986 return IrInstructionIdAddImplicitReturnType; 987 } 988 989 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatOp *) { 990 return IrInstructionIdFloatOp; 991 } 992 993 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { 994 return IrInstructionIdCheckRuntimeScope; 995 } 996 997 static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorToArray *) { 998 return IrInstructionIdVectorToArray; 999 } 1000 1001 static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayToVector *) { 1002 return IrInstructionIdArrayToVector; 1003 } 1004 1005 static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertZero *) { 1006 return IrInstructionIdAssertZero; 1007 } 1008 1009 static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) { 1010 return IrInstructionIdAssertNonNull; 1011 } 1012 1013 static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) { 1014 return IrInstructionIdHasDecl; 1015 } 1016 1017 static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent *) { 1018 return IrInstructionIdUndeclaredIdent; 1019 } 1020 1021 static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaSrc *) { 1022 return IrInstructionIdAllocaSrc; 1023 } 1024 1025 static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaGen *) { 1026 return IrInstructionIdAllocaGen; 1027 } 1028 1029 static constexpr IrInstructionId ir_instruction_id(IrInstructionEndExpr *) { 1030 return IrInstructionIdEndExpr; 1031 } 1032 1033 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInitNamedField *) { 1034 return IrInstructionIdUnionInitNamedField; 1035 } 1036 1037 static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBegin *) { 1038 return IrInstructionIdSuspendBegin; 1039 } 1040 1041 static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendFinish *) { 1042 return IrInstructionIdSuspendFinish; 1043 } 1044 1045 static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitSrc *) { 1046 return IrInstructionIdAwaitSrc; 1047 } 1048 1049 static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitGen *) { 1050 return IrInstructionIdAwaitGen; 1051 } 1052 1053 static constexpr IrInstructionId ir_instruction_id(IrInstructionResume *) { 1054 return IrInstructionIdResume; 1055 } 1056 1057 static constexpr IrInstructionId ir_instruction_id(IrInstructionSpillBegin *) { 1058 return IrInstructionIdSpillBegin; 1059 } 1060 1061 static constexpr IrInstructionId ir_instruction_id(IrInstructionSpillEnd *) { 1062 return IrInstructionIdSpillEnd; 1063 } 1064 1065 template<typename T> 1066 static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1067 T *special_instruction = allocate<T>(1); 1068 special_instruction->base.id = ir_instruction_id(special_instruction); 1069 special_instruction->base.scope = scope; 1070 special_instruction->base.source_node = source_node; 1071 special_instruction->base.debug_id = exec_next_debug_id(irb->exec); 1072 special_instruction->base.owner_bb = irb->current_basic_block; 1073 special_instruction->base.value.global_refs = allocate<ConstGlobalRefs>(1); 1074 return special_instruction; 1075 } 1076 1077 template<typename T> 1078 static T *ir_build_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1079 T *special_instruction = ir_create_instruction<T>(irb, scope, source_node); 1080 ir_instruction_append(irb->current_basic_block, &special_instruction->base); 1081 return special_instruction; 1082 } 1083 1084 static IrInstruction *ir_build_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *dest_type, 1085 IrInstruction *value, CastOp cast_op) 1086 { 1087 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, scope, source_node); 1088 cast_instruction->dest_type = dest_type; 1089 cast_instruction->value = value; 1090 cast_instruction->cast_op = cast_op; 1091 1092 ir_ref_instruction(value, irb->current_basic_block); 1093 1094 return &cast_instruction->base; 1095 } 1096 1097 static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *condition, 1098 IrBasicBlock *then_block, IrBasicBlock *else_block, IrInstruction *is_comptime) 1099 { 1100 IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, scope, source_node); 1101 cond_br_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1102 cond_br_instruction->base.value.special = ConstValSpecialStatic; 1103 cond_br_instruction->condition = condition; 1104 cond_br_instruction->then_block = then_block; 1105 cond_br_instruction->else_block = else_block; 1106 cond_br_instruction->is_comptime = is_comptime; 1107 1108 ir_ref_instruction(condition, irb->current_basic_block); 1109 ir_ref_bb(then_block); 1110 ir_ref_bb(else_block); 1111 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); 1112 1113 return &cond_br_instruction->base; 1114 } 1115 1116 static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, 1117 IrInstruction *operand) 1118 { 1119 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); 1120 return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1121 return_instruction->base.value.special = ConstValSpecialStatic; 1122 return_instruction->operand = operand; 1123 1124 if (operand != nullptr) ir_ref_instruction(operand, irb->current_basic_block); 1125 1126 return &return_instruction->base; 1127 } 1128 1129 static IrInstruction *ir_build_const_void(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1130 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1131 const_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1132 const_instruction->base.value.special = ConstValSpecialStatic; 1133 return &const_instruction->base; 1134 } 1135 1136 static IrInstruction *ir_build_const_undefined(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1137 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1138 const_instruction->base.value.special = ConstValSpecialUndef; 1139 const_instruction->base.value.type = irb->codegen->builtin_types.entry_undef; 1140 return &const_instruction->base; 1141 } 1142 1143 static IrInstruction *ir_build_const_uint(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { 1144 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1145 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_int; 1146 const_instruction->base.value.special = ConstValSpecialStatic; 1147 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); 1148 return &const_instruction->base; 1149 } 1150 1151 static IrInstruction *ir_build_const_bigint(IrBuilder *irb, Scope *scope, AstNode *source_node, BigInt *bigint) { 1152 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1153 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_int; 1154 const_instruction->base.value.special = ConstValSpecialStatic; 1155 bigint_init_bigint(&const_instruction->base.value.data.x_bigint, bigint); 1156 return &const_instruction->base; 1157 } 1158 1159 static IrInstruction *ir_build_const_bigfloat(IrBuilder *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) { 1160 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1161 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_float; 1162 const_instruction->base.value.special = ConstValSpecialStatic; 1163 bigfloat_init_bigfloat(&const_instruction->base.value.data.x_bigfloat, bigfloat); 1164 return &const_instruction->base; 1165 } 1166 1167 static IrInstruction *ir_build_const_null(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1168 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1169 const_instruction->base.value.type = irb->codegen->builtin_types.entry_null; 1170 const_instruction->base.value.special = ConstValSpecialStatic; 1171 return &const_instruction->base; 1172 } 1173 1174 static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { 1175 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1176 const_instruction->base.value.type = irb->codegen->builtin_types.entry_usize; 1177 const_instruction->base.value.special = ConstValSpecialStatic; 1178 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); 1179 return &const_instruction->base; 1180 } 1181 1182 static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1183 ZigType *type_entry) 1184 { 1185 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1186 const_instruction->base.value.type = irb->codegen->builtin_types.entry_type; 1187 const_instruction->base.value.special = ConstValSpecialStatic; 1188 const_instruction->base.value.data.x_type = type_entry; 1189 return &const_instruction->base; 1190 } 1191 1192 static IrInstruction *ir_build_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1193 ZigType *type_entry) 1194 { 1195 IrInstruction *instruction = ir_create_const_type(irb, scope, source_node, type_entry); 1196 ir_instruction_append(irb->current_basic_block, instruction); 1197 return instruction; 1198 } 1199 1200 static IrInstruction *ir_create_const_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigFn *fn_entry) { 1201 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1202 const_instruction->base.value.type = fn_entry->type_entry; 1203 const_instruction->base.value.special = ConstValSpecialStatic; 1204 const_instruction->base.value.data.x_ptr.data.fn.fn_entry = fn_entry; 1205 const_instruction->base.value.data.x_ptr.mut = ConstPtrMutComptimeConst; 1206 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialFunction; 1207 return &const_instruction->base; 1208 } 1209 1210 static IrInstruction *ir_build_const_import(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *import) { 1211 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1212 const_instruction->base.value.type = irb->codegen->builtin_types.entry_type; 1213 const_instruction->base.value.special = ConstValSpecialStatic; 1214 const_instruction->base.value.data.x_type = import; 1215 return &const_instruction->base; 1216 } 1217 1218 static IrInstruction *ir_build_const_bool(IrBuilder *irb, Scope *scope, AstNode *source_node, bool value) { 1219 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1220 const_instruction->base.value.type = irb->codegen->builtin_types.entry_bool; 1221 const_instruction->base.value.special = ConstValSpecialStatic; 1222 const_instruction->base.value.data.x_bool = value; 1223 return &const_instruction->base; 1224 } 1225 1226 static IrInstruction *ir_build_const_enum_literal(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *name) { 1227 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1228 const_instruction->base.value.type = irb->codegen->builtin_types.entry_enum_literal; 1229 const_instruction->base.value.special = ConstValSpecialStatic; 1230 const_instruction->base.value.data.x_enum_literal = name; 1231 return &const_instruction->base; 1232 } 1233 1234 static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, 1235 ZigFn *fn_entry, IrInstruction *first_arg) 1236 { 1237 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1238 const_instruction->base.value.type = get_bound_fn_type(irb->codegen, fn_entry); 1239 const_instruction->base.value.special = ConstValSpecialStatic; 1240 const_instruction->base.value.data.x_bound_fn.fn = fn_entry; 1241 const_instruction->base.value.data.x_bound_fn.first_arg = first_arg; 1242 return &const_instruction->base; 1243 } 1244 1245 static IrInstruction *ir_create_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1246 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1247 init_const_str_lit(irb->codegen, &const_instruction->base.value, str); 1248 1249 return &const_instruction->base; 1250 } 1251 static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1252 IrInstruction *instruction = ir_create_const_str_lit(irb, scope, source_node, str); 1253 ir_instruction_append(irb->current_basic_block, instruction); 1254 return instruction; 1255 } 1256 1257 static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1258 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1259 init_const_c_str_lit(irb->codegen, &const_instruction->base.value, str); 1260 return &const_instruction->base; 1261 } 1262 1263 static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, 1264 IrInstruction *op1, IrInstruction *op2, bool safety_check_on) 1265 { 1266 IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irb, scope, source_node); 1267 bin_op_instruction->op_id = op_id; 1268 bin_op_instruction->op1 = op1; 1269 bin_op_instruction->op2 = op2; 1270 bin_op_instruction->safety_check_on = safety_check_on; 1271 1272 ir_ref_instruction(op1, irb->current_basic_block); 1273 ir_ref_instruction(op2, irb->current_basic_block); 1274 1275 return &bin_op_instruction->base; 1276 } 1277 1278 static IrInstruction *ir_build_var_ptr_x(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, 1279 ScopeFnDef *crossed_fndef_scope) 1280 { 1281 IrInstructionVarPtr *instruction = ir_build_instruction<IrInstructionVarPtr>(irb, scope, source_node); 1282 instruction->var = var; 1283 instruction->crossed_fndef_scope = crossed_fndef_scope; 1284 1285 ir_ref_var(var); 1286 1287 return &instruction->base; 1288 } 1289 1290 static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var) { 1291 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); 1292 } 1293 1294 static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { 1295 IrInstructionReturnPtr *instruction = ir_build_instruction<IrInstructionReturnPtr>(&ira->new_irb, 1296 source_instruction->scope, source_instruction->source_node); 1297 instruction->base.value.type = ty; 1298 return &instruction->base; 1299 } 1300 1301 static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1302 IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len, 1303 IrInstruction *init_array_type) 1304 { 1305 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); 1306 instruction->array_ptr = array_ptr; 1307 instruction->elem_index = elem_index; 1308 instruction->safety_check_on = safety_check_on; 1309 instruction->ptr_len = ptr_len; 1310 instruction->init_array_type = init_array_type; 1311 1312 ir_ref_instruction(array_ptr, irb->current_basic_block); 1313 ir_ref_instruction(elem_index, irb->current_basic_block); 1314 if (init_array_type != nullptr) ir_ref_instruction(init_array_type, irb->current_basic_block); 1315 1316 return &instruction->base; 1317 } 1318 1319 static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node, 1320 IrInstruction *container_ptr, IrInstruction *field_name_expr, bool initializing) 1321 { 1322 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); 1323 instruction->container_ptr = container_ptr; 1324 instruction->field_name_buffer = nullptr; 1325 instruction->field_name_expr = field_name_expr; 1326 instruction->initializing = initializing; 1327 1328 ir_ref_instruction(container_ptr, irb->current_basic_block); 1329 ir_ref_instruction(field_name_expr, irb->current_basic_block); 1330 1331 return &instruction->base; 1332 } 1333 1334 static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1335 IrInstruction *container_ptr, Buf *field_name, bool initializing) 1336 { 1337 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); 1338 instruction->container_ptr = container_ptr; 1339 instruction->field_name_buffer = field_name; 1340 instruction->field_name_expr = nullptr; 1341 instruction->initializing = initializing; 1342 1343 ir_ref_instruction(container_ptr, irb->current_basic_block); 1344 1345 return &instruction->base; 1346 } 1347 1348 static IrInstruction *ir_build_has_field(IrBuilder *irb, Scope *scope, AstNode *source_node, 1349 IrInstruction *container_type, IrInstruction *field_name) 1350 { 1351 IrInstructionHasField *instruction = ir_build_instruction<IrInstructionHasField>(irb, scope, source_node); 1352 instruction->container_type = container_type; 1353 instruction->field_name = field_name; 1354 1355 ir_ref_instruction(container_type, irb->current_basic_block); 1356 ir_ref_instruction(field_name, irb->current_basic_block); 1357 1358 return &instruction->base; 1359 } 1360 1361 static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1362 IrInstruction *struct_ptr, TypeStructField *field) 1363 { 1364 IrInstructionStructFieldPtr *instruction = ir_build_instruction<IrInstructionStructFieldPtr>(irb, scope, source_node); 1365 instruction->struct_ptr = struct_ptr; 1366 instruction->field = field; 1367 1368 ir_ref_instruction(struct_ptr, irb->current_basic_block); 1369 1370 return &instruction->base; 1371 } 1372 1373 static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1374 IrInstruction *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing) 1375 { 1376 IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node); 1377 instruction->initializing = initializing; 1378 instruction->safety_check_on = safety_check_on; 1379 instruction->union_ptr = union_ptr; 1380 instruction->field = field; 1381 1382 ir_ref_instruction(union_ptr, irb->current_basic_block); 1383 1384 return &instruction->base; 1385 } 1386 1387 static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 1388 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, 1389 bool is_comptime, FnInline fn_inline, bool is_async, 1390 IrInstruction *new_stack, ResultLoc *result_loc) 1391 { 1392 IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node); 1393 call_instruction->fn_entry = fn_entry; 1394 call_instruction->fn_ref = fn_ref; 1395 call_instruction->is_comptime = is_comptime; 1396 call_instruction->fn_inline = fn_inline; 1397 call_instruction->args = args; 1398 call_instruction->arg_count = arg_count; 1399 call_instruction->is_async = is_async; 1400 call_instruction->new_stack = new_stack; 1401 call_instruction->result_loc = result_loc; 1402 1403 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); 1404 for (size_t i = 0; i < arg_count; i += 1) 1405 ir_ref_instruction(args[i], irb->current_basic_block); 1406 if (is_async && new_stack != nullptr) { 1407 // in this case the arg at the end is the return pointer 1408 ir_ref_instruction(args[arg_count], irb->current_basic_block); 1409 } 1410 if (new_stack != nullptr) ir_ref_instruction(new_stack, irb->current_basic_block); 1411 1412 return &call_instruction->base; 1413 } 1414 1415 static IrInstructionCallGen *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, 1416 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, 1417 FnInline fn_inline, bool is_async, IrInstruction *new_stack, 1418 IrInstruction *result_loc, ZigType *return_type) 1419 { 1420 IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, 1421 source_instruction->scope, source_instruction->source_node); 1422 call_instruction->base.value.type = return_type; 1423 call_instruction->fn_entry = fn_entry; 1424 call_instruction->fn_ref = fn_ref; 1425 call_instruction->fn_inline = fn_inline; 1426 call_instruction->args = args; 1427 call_instruction->arg_count = arg_count; 1428 call_instruction->is_async = is_async; 1429 call_instruction->new_stack = new_stack; 1430 call_instruction->result_loc = result_loc; 1431 1432 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block); 1433 for (size_t i = 0; i < arg_count; i += 1) 1434 ir_ref_instruction(args[i], ira->new_irb.current_basic_block); 1435 if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block); 1436 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 1437 1438 return call_instruction; 1439 } 1440 1441 static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, 1442 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values, 1443 ResultLocPeerParent *peer_parent) 1444 { 1445 assert(incoming_count != 0); 1446 assert(incoming_count != SIZE_MAX); 1447 1448 IrInstructionPhi *phi_instruction = ir_build_instruction<IrInstructionPhi>(irb, scope, source_node); 1449 phi_instruction->incoming_count = incoming_count; 1450 phi_instruction->incoming_blocks = incoming_blocks; 1451 phi_instruction->incoming_values = incoming_values; 1452 phi_instruction->peer_parent = peer_parent; 1453 1454 for (size_t i = 0; i < incoming_count; i += 1) { 1455 ir_ref_bb(incoming_blocks[i]); 1456 ir_ref_instruction(incoming_values[i], irb->current_basic_block); 1457 } 1458 1459 return &phi_instruction->base; 1460 } 1461 1462 static IrInstruction *ir_create_br(IrBuilder *irb, Scope *scope, AstNode *source_node, 1463 IrBasicBlock *dest_block, IrInstruction *is_comptime) 1464 { 1465 IrInstructionBr *br_instruction = ir_create_instruction<IrInstructionBr>(irb, scope, source_node); 1466 br_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1467 br_instruction->base.value.special = ConstValSpecialStatic; 1468 br_instruction->dest_block = dest_block; 1469 br_instruction->is_comptime = is_comptime; 1470 1471 ir_ref_bb(dest_block); 1472 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 1473 1474 return &br_instruction->base; 1475 } 1476 1477 static IrInstruction *ir_build_br(IrBuilder *irb, Scope *scope, AstNode *source_node, 1478 IrBasicBlock *dest_block, IrInstruction *is_comptime) 1479 { 1480 IrInstruction *instruction = ir_create_br(irb, scope, source_node, dest_block, is_comptime); 1481 ir_instruction_append(irb->current_basic_block, instruction); 1482 return instruction; 1483 } 1484 1485 static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1486 IrInstruction *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, 1487 IrInstruction *align_value, uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero) 1488 { 1489 IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node); 1490 ptr_type_of_instruction->align_value = align_value; 1491 ptr_type_of_instruction->child_type = child_type; 1492 ptr_type_of_instruction->is_const = is_const; 1493 ptr_type_of_instruction->is_volatile = is_volatile; 1494 ptr_type_of_instruction->ptr_len = ptr_len; 1495 ptr_type_of_instruction->bit_offset_start = bit_offset_start; 1496 ptr_type_of_instruction->host_int_bytes = host_int_bytes; 1497 ptr_type_of_instruction->is_allow_zero = is_allow_zero; 1498 1499 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 1500 ir_ref_instruction(child_type, irb->current_basic_block); 1501 1502 return &ptr_type_of_instruction->base; 1503 } 1504 1505 static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 1506 IrInstruction *value, LVal lval, ResultLoc *result_loc) 1507 { 1508 IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); 1509 instruction->op_id = op_id; 1510 instruction->value = value; 1511 instruction->lval = lval; 1512 instruction->result_loc = result_loc; 1513 1514 ir_ref_instruction(value, irb->current_basic_block); 1515 1516 return &instruction->base; 1517 } 1518 1519 static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 1520 IrInstruction *value) 1521 { 1522 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr); 1523 } 1524 1525 static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node, 1526 IrInstruction *container_type, size_t item_count, IrInstruction **elem_result_loc_list, 1527 IrInstruction *result_loc) 1528 { 1529 IrInstructionContainerInitList *container_init_list_instruction = 1530 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); 1531 container_init_list_instruction->container_type = container_type; 1532 container_init_list_instruction->item_count = item_count; 1533 container_init_list_instruction->elem_result_loc_list = elem_result_loc_list; 1534 container_init_list_instruction->result_loc = result_loc; 1535 1536 ir_ref_instruction(container_type, irb->current_basic_block); 1537 for (size_t i = 0; i < item_count; i += 1) { 1538 ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block); 1539 } 1540 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 1541 1542 return &container_init_list_instruction->base; 1543 } 1544 1545 static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node, 1546 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields, 1547 IrInstruction *result_loc) 1548 { 1549 IrInstructionContainerInitFields *container_init_fields_instruction = 1550 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); 1551 container_init_fields_instruction->container_type = container_type; 1552 container_init_fields_instruction->field_count = field_count; 1553 container_init_fields_instruction->fields = fields; 1554 container_init_fields_instruction->result_loc = result_loc; 1555 1556 ir_ref_instruction(container_type, irb->current_basic_block); 1557 for (size_t i = 0; i < field_count; i += 1) { 1558 ir_ref_instruction(fields[i].result_loc, irb->current_basic_block); 1559 } 1560 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 1561 1562 return &container_init_fields_instruction->base; 1563 } 1564 1565 static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1566 IrInstructionUnreachable *unreachable_instruction = 1567 ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); 1568 unreachable_instruction->base.value.special = ConstValSpecialStatic; 1569 unreachable_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1570 return &unreachable_instruction->base; 1571 } 1572 1573 static IrInstructionStorePtr *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1574 IrInstruction *ptr, IrInstruction *value) 1575 { 1576 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node); 1577 instruction->base.value.special = ConstValSpecialStatic; 1578 instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1579 instruction->ptr = ptr; 1580 instruction->value = value; 1581 1582 ir_ref_instruction(ptr, irb->current_basic_block); 1583 ir_ref_instruction(value, irb->current_basic_block); 1584 1585 return instruction; 1586 } 1587 1588 static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 1589 ZigVar *var, IrInstruction *align_value, IrInstruction *ptr) 1590 { 1591 IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node); 1592 decl_var_instruction->base.value.special = ConstValSpecialStatic; 1593 decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1594 decl_var_instruction->var = var; 1595 decl_var_instruction->align_value = align_value; 1596 decl_var_instruction->ptr = ptr; 1597 1598 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 1599 ir_ref_instruction(ptr, irb->current_basic_block); 1600 1601 return &decl_var_instruction->base; 1602 } 1603 1604 static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction, 1605 ZigVar *var, IrInstruction *var_ptr) 1606 { 1607 IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb, 1608 source_instruction->scope, source_instruction->source_node); 1609 decl_var_instruction->base.value.special = ConstValSpecialStatic; 1610 decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void; 1611 decl_var_instruction->var = var; 1612 decl_var_instruction->var_ptr = var_ptr; 1613 1614 ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block); 1615 1616 return &decl_var_instruction->base; 1617 } 1618 1619 static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction, 1620 IrInstruction *operand, ZigType *ty, IrInstruction *result_loc) 1621 { 1622 IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb, 1623 source_instruction->scope, source_instruction->source_node); 1624 instruction->base.value.type = ty; 1625 instruction->operand = operand; 1626 instruction->result_loc = result_loc; 1627 1628 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 1629 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 1630 1631 return &instruction->base; 1632 } 1633 1634 static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node, 1635 IrInstruction *name, IrInstruction *target, IrInstruction *linkage) 1636 { 1637 IrInstructionExport *export_instruction = ir_build_instruction<IrInstructionExport>( 1638 irb, scope, source_node); 1639 export_instruction->base.value.special = ConstValSpecialStatic; 1640 export_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1641 export_instruction->name = name; 1642 export_instruction->target = target; 1643 export_instruction->linkage = linkage; 1644 1645 ir_ref_instruction(name, irb->current_basic_block); 1646 ir_ref_instruction(target, irb->current_basic_block); 1647 if (linkage) ir_ref_instruction(linkage, irb->current_basic_block); 1648 1649 return &export_instruction->base; 1650 } 1651 1652 static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { 1653 IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node); 1654 instruction->ptr = ptr; 1655 1656 ir_ref_instruction(ptr, irb->current_basic_block); 1657 1658 return &instruction->base; 1659 } 1660 1661 static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1662 IrInstructionTypeOf *instruction = ir_build_instruction<IrInstructionTypeOf>(irb, scope, source_node); 1663 instruction->value = value; 1664 1665 ir_ref_instruction(value, irb->current_basic_block); 1666 1667 return &instruction->base; 1668 } 1669 1670 static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) { 1671 IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); 1672 instruction->is_cold = is_cold; 1673 1674 ir_ref_instruction(is_cold, irb->current_basic_block); 1675 1676 return &instruction->base; 1677 } 1678 1679 static IrInstruction *ir_build_set_runtime_safety(IrBuilder *irb, Scope *scope, AstNode *source_node, 1680 IrInstruction *safety_on) 1681 { 1682 IrInstructionSetRuntimeSafety *instruction = ir_build_instruction<IrInstructionSetRuntimeSafety>(irb, scope, source_node); 1683 instruction->safety_on = safety_on; 1684 1685 ir_ref_instruction(safety_on, irb->current_basic_block); 1686 1687 return &instruction->base; 1688 } 1689 1690 static IrInstruction *ir_build_set_float_mode(IrBuilder *irb, Scope *scope, AstNode *source_node, 1691 IrInstruction *mode_value) 1692 { 1693 IrInstructionSetFloatMode *instruction = ir_build_instruction<IrInstructionSetFloatMode>(irb, scope, source_node); 1694 instruction->mode_value = mode_value; 1695 1696 ir_ref_instruction(mode_value, irb->current_basic_block); 1697 1698 return &instruction->base; 1699 } 1700 1701 static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *size, 1702 IrInstruction *child_type) 1703 { 1704 IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, scope, source_node); 1705 instruction->size = size; 1706 instruction->child_type = child_type; 1707 1708 ir_ref_instruction(size, irb->current_basic_block); 1709 ir_ref_instruction(child_type, irb->current_basic_block); 1710 1711 return &instruction->base; 1712 } 1713 1714 static IrInstruction *ir_build_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1715 IrInstruction *payload_type) 1716 { 1717 IrInstructionAnyFrameType *instruction = ir_build_instruction<IrInstructionAnyFrameType>(irb, scope, source_node); 1718 instruction->payload_type = payload_type; 1719 1720 if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); 1721 1722 return &instruction->base; 1723 } 1724 static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1725 IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value, bool is_allow_zero) 1726 { 1727 IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, scope, source_node); 1728 instruction->is_const = is_const; 1729 instruction->is_volatile = is_volatile; 1730 instruction->child_type = child_type; 1731 instruction->align_value = align_value; 1732 instruction->is_allow_zero = is_allow_zero; 1733 1734 ir_ref_instruction(child_type, irb->current_basic_block); 1735 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 1736 1737 return &instruction->base; 1738 } 1739 1740 static IrInstruction *ir_build_global_asm(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *asm_code) { 1741 IrInstructionGlobalAsm *instruction = ir_build_instruction<IrInstructionGlobalAsm>(irb, scope, source_node); 1742 instruction->asm_code = asm_code; 1743 return &instruction->base; 1744 } 1745 1746 static IrInstruction *ir_build_asm(IrBuilder *irb, Scope *scope, AstNode *source_node, 1747 Buf *asm_template, AsmToken *token_list, size_t token_list_len, 1748 IrInstruction **input_list, IrInstruction **output_types, ZigVar **output_vars, size_t return_count, 1749 bool has_side_effects) 1750 { 1751 IrInstructionAsm *instruction = ir_build_instruction<IrInstructionAsm>(irb, scope, source_node); 1752 instruction->asm_template = asm_template; 1753 instruction->token_list = token_list; 1754 instruction->token_list_len = token_list_len; 1755 instruction->input_list = input_list; 1756 instruction->output_types = output_types; 1757 instruction->output_vars = output_vars; 1758 instruction->return_count = return_count; 1759 instruction->has_side_effects = has_side_effects; 1760 1761 assert(source_node->type == NodeTypeAsmExpr); 1762 for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) { 1763 IrInstruction *output_type = output_types[i]; 1764 if (output_type) ir_ref_instruction(output_type, irb->current_basic_block); 1765 } 1766 1767 for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) { 1768 IrInstruction *input_value = input_list[i]; 1769 ir_ref_instruction(input_value, irb->current_basic_block); 1770 } 1771 1772 return &instruction->base; 1773 } 1774 1775 static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { 1776 IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, scope, source_node); 1777 instruction->type_value = type_value; 1778 1779 ir_ref_instruction(type_value, irb->current_basic_block); 1780 1781 return &instruction->base; 1782 } 1783 1784 static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1785 IrInstructionTestNonNull *instruction = ir_build_instruction<IrInstructionTestNonNull>(irb, scope, source_node); 1786 instruction->value = value; 1787 1788 ir_ref_instruction(value, irb->current_basic_block); 1789 1790 return &instruction->base; 1791 } 1792 1793 static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1794 IrInstruction *base_ptr, bool safety_check_on, bool initializing) 1795 { 1796 IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node); 1797 instruction->base_ptr = base_ptr; 1798 instruction->safety_check_on = safety_check_on; 1799 instruction->initializing = initializing; 1800 1801 ir_ref_instruction(base_ptr, irb->current_basic_block); 1802 1803 return &instruction->base; 1804 } 1805 1806 static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_ty, 1807 IrInstruction *operand, IrInstruction *result_loc) 1808 { 1809 IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>( 1810 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 1811 instruction->base.value.type = result_ty; 1812 instruction->operand = operand; 1813 instruction->result_loc = result_loc; 1814 1815 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 1816 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 1817 1818 return &instruction->base; 1819 } 1820 1821 static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instruction, 1822 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) 1823 { 1824 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>( 1825 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 1826 instruction->base.value.type = result_type; 1827 instruction->operand = operand; 1828 instruction->result_loc = result_loc; 1829 1830 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 1831 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 1832 1833 return &instruction->base; 1834 } 1835 1836 static IrInstruction *ir_build_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instruction, 1837 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) 1838 { 1839 IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>( 1840 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 1841 instruction->base.value.type = result_type; 1842 instruction->operand = operand; 1843 instruction->result_loc = result_loc; 1844 1845 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 1846 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 1847 1848 return &instruction->base; 1849 } 1850 1851 static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 1852 IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node); 1853 instruction->type = type; 1854 instruction->op = op; 1855 1856 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 1857 ir_ref_instruction(op, irb->current_basic_block); 1858 1859 return &instruction->base; 1860 } 1861 1862 static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 1863 IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node); 1864 instruction->type = type; 1865 instruction->op = op; 1866 1867 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 1868 ir_ref_instruction(op, irb->current_basic_block); 1869 1870 return &instruction->base; 1871 } 1872 1873 static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 1874 IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node); 1875 instruction->type = type; 1876 instruction->op = op; 1877 1878 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 1879 ir_ref_instruction(op, irb->current_basic_block); 1880 1881 return &instruction->base; 1882 } 1883 1884 static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 1885 IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node); 1886 instruction->type = type; 1887 instruction->op = op; 1888 1889 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 1890 ir_ref_instruction(op, irb->current_basic_block); 1891 1892 return &instruction->base; 1893 } 1894 1895 static IrInstruction *ir_build_bit_reverse(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 1896 IrInstructionBitReverse *instruction = ir_build_instruction<IrInstructionBitReverse>(irb, scope, source_node); 1897 instruction->type = type; 1898 instruction->op = op; 1899 1900 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 1901 ir_ref_instruction(op, irb->current_basic_block); 1902 1903 return &instruction->base; 1904 } 1905 1906 static IrInstructionSwitchBr *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value, 1907 IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, 1908 IrInstruction *switch_prongs_void) 1909 { 1910 IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node); 1911 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1912 instruction->base.value.special = ConstValSpecialStatic; 1913 instruction->target_value = target_value; 1914 instruction->else_block = else_block; 1915 instruction->case_count = case_count; 1916 instruction->cases = cases; 1917 instruction->is_comptime = is_comptime; 1918 instruction->switch_prongs_void = switch_prongs_void; 1919 1920 ir_ref_instruction(target_value, irb->current_basic_block); 1921 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 1922 ir_ref_bb(else_block); 1923 if (switch_prongs_void) ir_ref_instruction(switch_prongs_void, irb->current_basic_block); 1924 1925 for (size_t i = 0; i < case_count; i += 1) { 1926 ir_ref_instruction(cases[i].value, irb->current_basic_block); 1927 ir_ref_bb(cases[i].block); 1928 } 1929 1930 return instruction; 1931 } 1932 1933 static IrInstruction *ir_build_switch_target(IrBuilder *irb, Scope *scope, AstNode *source_node, 1934 IrInstruction *target_value_ptr) 1935 { 1936 IrInstructionSwitchTarget *instruction = ir_build_instruction<IrInstructionSwitchTarget>(irb, scope, source_node); 1937 instruction->target_value_ptr = target_value_ptr; 1938 1939 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 1940 1941 return &instruction->base; 1942 } 1943 1944 static IrInstruction *ir_build_switch_var(IrBuilder *irb, Scope *scope, AstNode *source_node, 1945 IrInstruction *target_value_ptr, IrInstruction **prongs_ptr, size_t prongs_len) 1946 { 1947 IrInstructionSwitchVar *instruction = ir_build_instruction<IrInstructionSwitchVar>(irb, scope, source_node); 1948 instruction->target_value_ptr = target_value_ptr; 1949 instruction->prongs_ptr = prongs_ptr; 1950 instruction->prongs_len = prongs_len; 1951 1952 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 1953 for (size_t i = 0; i < prongs_len; i += 1) { 1954 ir_ref_instruction(prongs_ptr[i], irb->current_basic_block); 1955 } 1956 1957 return &instruction->base; 1958 } 1959 1960 // For this instruction the switch_br must be set later. 1961 static IrInstructionSwitchElseVar *ir_build_switch_else_var(IrBuilder *irb, Scope *scope, AstNode *source_node, 1962 IrInstruction *target_value_ptr) 1963 { 1964 IrInstructionSwitchElseVar *instruction = ir_build_instruction<IrInstructionSwitchElseVar>(irb, scope, source_node); 1965 instruction->target_value_ptr = target_value_ptr; 1966 1967 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 1968 1969 return instruction; 1970 } 1971 1972 static IrInstruction *ir_build_union_tag(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1973 IrInstructionUnionTag *instruction = ir_build_instruction<IrInstructionUnionTag>(irb, scope, source_node); 1974 instruction->value = value; 1975 1976 ir_ref_instruction(value, irb->current_basic_block); 1977 1978 return &instruction->base; 1979 } 1980 1981 static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1982 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, scope, source_node); 1983 instruction->name = name; 1984 1985 ir_ref_instruction(name, irb->current_basic_block); 1986 1987 return &instruction->base; 1988 } 1989 1990 static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value, 1991 bool is_const, bool is_volatile) 1992 { 1993 IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, scope, source_node); 1994 instruction->value = value; 1995 instruction->is_const = is_const; 1996 instruction->is_volatile = is_volatile; 1997 1998 ir_ref_instruction(value, irb->current_basic_block); 1999 2000 return &instruction->base; 2001 } 2002 2003 static IrInstruction *ir_build_ref_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, 2004 IrInstruction *operand, IrInstruction *result_loc) 2005 { 2006 IrInstructionRefGen *instruction = ir_build_instruction<IrInstructionRefGen>(&ira->new_irb, 2007 source_instruction->scope, source_instruction->source_node); 2008 instruction->base.value.type = result_type; 2009 instruction->operand = operand; 2010 instruction->result_loc = result_loc; 2011 2012 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 2013 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 2014 2015 return &instruction->base; 2016 } 2017 2018 static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { 2019 IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); 2020 instruction->msg = msg; 2021 2022 ir_ref_instruction(msg, irb->current_basic_block); 2023 2024 return &instruction->base; 2025 } 2026 2027 static IrInstruction *ir_build_compile_log(IrBuilder *irb, Scope *scope, AstNode *source_node, 2028 size_t msg_count, IrInstruction **msg_list) 2029 { 2030 IrInstructionCompileLog *instruction = ir_build_instruction<IrInstructionCompileLog>(irb, scope, source_node); 2031 instruction->msg_count = msg_count; 2032 instruction->msg_list = msg_list; 2033 2034 for (size_t i = 0; i < msg_count; i += 1) { 2035 ir_ref_instruction(msg_list[i], irb->current_basic_block); 2036 } 2037 2038 return &instruction->base; 2039 } 2040 2041 static IrInstruction *ir_build_err_name(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2042 IrInstructionErrName *instruction = ir_build_instruction<IrInstructionErrName>(irb, scope, source_node); 2043 instruction->value = value; 2044 2045 ir_ref_instruction(value, irb->current_basic_block); 2046 2047 return &instruction->base; 2048 } 2049 2050 static IrInstruction *ir_build_c_import(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2051 IrInstructionCImport *instruction = ir_build_instruction<IrInstructionCImport>(irb, scope, source_node); 2052 return &instruction->base; 2053 } 2054 2055 static IrInstruction *ir_build_c_include(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 2056 IrInstructionCInclude *instruction = ir_build_instruction<IrInstructionCInclude>(irb, scope, source_node); 2057 instruction->name = name; 2058 2059 ir_ref_instruction(name, irb->current_basic_block); 2060 2061 return &instruction->base; 2062 } 2063 2064 static IrInstruction *ir_build_c_define(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name, IrInstruction *value) { 2065 IrInstructionCDefine *instruction = ir_build_instruction<IrInstructionCDefine>(irb, scope, source_node); 2066 instruction->name = name; 2067 instruction->value = value; 2068 2069 ir_ref_instruction(name, irb->current_basic_block); 2070 ir_ref_instruction(value, irb->current_basic_block); 2071 2072 return &instruction->base; 2073 } 2074 2075 static IrInstruction *ir_build_c_undef(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 2076 IrInstructionCUndef *instruction = ir_build_instruction<IrInstructionCUndef>(irb, scope, source_node); 2077 instruction->name = name; 2078 2079 ir_ref_instruction(name, irb->current_basic_block); 2080 2081 return &instruction->base; 2082 } 2083 2084 static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 2085 IrInstructionEmbedFile *instruction = ir_build_instruction<IrInstructionEmbedFile>(irb, scope, source_node); 2086 instruction->name = name; 2087 2088 ir_ref_instruction(name, irb->current_basic_block); 2089 2090 return &instruction->base; 2091 } 2092 2093 static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2094 IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, 2095 IrInstruction *success_order_value, IrInstruction *failure_order_value, bool is_weak, ResultLoc *result_loc) 2096 { 2097 IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node); 2098 instruction->type_value = type_value; 2099 instruction->ptr = ptr; 2100 instruction->cmp_value = cmp_value; 2101 instruction->new_value = new_value; 2102 instruction->success_order_value = success_order_value; 2103 instruction->failure_order_value = failure_order_value; 2104 instruction->is_weak = is_weak; 2105 instruction->result_loc = result_loc; 2106 2107 ir_ref_instruction(type_value, irb->current_basic_block); 2108 ir_ref_instruction(ptr, irb->current_basic_block); 2109 ir_ref_instruction(cmp_value, irb->current_basic_block); 2110 ir_ref_instruction(new_value, irb->current_basic_block); 2111 ir_ref_instruction(success_order_value, irb->current_basic_block); 2112 ir_ref_instruction(failure_order_value, irb->current_basic_block); 2113 2114 return &instruction->base; 2115 } 2116 2117 static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, 2118 IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, 2119 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstruction *result_loc) 2120 { 2121 IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb, 2122 source_instruction->scope, source_instruction->source_node); 2123 instruction->base.value.type = result_type; 2124 instruction->ptr = ptr; 2125 instruction->cmp_value = cmp_value; 2126 instruction->new_value = new_value; 2127 instruction->success_order = success_order; 2128 instruction->failure_order = failure_order; 2129 instruction->is_weak = is_weak; 2130 instruction->result_loc = result_loc; 2131 2132 ir_ref_instruction(ptr, ira->new_irb.current_basic_block); 2133 ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block); 2134 ir_ref_instruction(new_value, ira->new_irb.current_basic_block); 2135 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 2136 2137 return &instruction->base; 2138 } 2139 2140 static IrInstruction *ir_build_fence(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *order_value, AtomicOrder order) { 2141 IrInstructionFence *instruction = ir_build_instruction<IrInstructionFence>(irb, scope, source_node); 2142 instruction->order_value = order_value; 2143 instruction->order = order; 2144 2145 ir_ref_instruction(order_value, irb->current_basic_block); 2146 2147 return &instruction->base; 2148 } 2149 2150 static IrInstruction *ir_build_truncate(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2151 IrInstructionTruncate *instruction = ir_build_instruction<IrInstructionTruncate>(irb, scope, source_node); 2152 instruction->dest_type = dest_type; 2153 instruction->target = target; 2154 2155 ir_ref_instruction(dest_type, irb->current_basic_block); 2156 ir_ref_instruction(target, irb->current_basic_block); 2157 2158 return &instruction->base; 2159 } 2160 2161 static IrInstruction *ir_build_int_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2162 IrInstructionIntCast *instruction = ir_build_instruction<IrInstructionIntCast>(irb, scope, source_node); 2163 instruction->dest_type = dest_type; 2164 instruction->target = target; 2165 2166 ir_ref_instruction(dest_type, irb->current_basic_block); 2167 ir_ref_instruction(target, irb->current_basic_block); 2168 2169 return &instruction->base; 2170 } 2171 2172 static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2173 IrInstructionFloatCast *instruction = ir_build_instruction<IrInstructionFloatCast>(irb, scope, source_node); 2174 instruction->dest_type = dest_type; 2175 instruction->target = target; 2176 2177 ir_ref_instruction(dest_type, irb->current_basic_block); 2178 ir_ref_instruction(target, irb->current_basic_block); 2179 2180 return &instruction->base; 2181 } 2182 2183 static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2184 IrInstructionErrSetCast *instruction = ir_build_instruction<IrInstructionErrSetCast>(irb, scope, source_node); 2185 instruction->dest_type = dest_type; 2186 instruction->target = target; 2187 2188 ir_ref_instruction(dest_type, irb->current_basic_block); 2189 ir_ref_instruction(target, irb->current_basic_block); 2190 2191 return &instruction->base; 2192 } 2193 2194 static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target, 2195 ResultLoc *result_loc) 2196 { 2197 IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); 2198 instruction->target = target; 2199 instruction->result_loc = result_loc; 2200 2201 ir_ref_instruction(target, irb->current_basic_block); 2202 2203 return &instruction->base; 2204 } 2205 2206 static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, 2207 IrInstruction *dest_child_type, IrInstruction *target, ResultLoc *result_loc) 2208 { 2209 IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); 2210 instruction->dest_child_type = dest_child_type; 2211 instruction->target = target; 2212 instruction->result_loc = result_loc; 2213 2214 ir_ref_instruction(dest_child_type, irb->current_basic_block); 2215 ir_ref_instruction(target, irb->current_basic_block); 2216 2217 return &instruction->base; 2218 } 2219 2220 static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2221 IrInstructionIntToFloat *instruction = ir_build_instruction<IrInstructionIntToFloat>(irb, scope, source_node); 2222 instruction->dest_type = dest_type; 2223 instruction->target = target; 2224 2225 ir_ref_instruction(dest_type, irb->current_basic_block); 2226 ir_ref_instruction(target, irb->current_basic_block); 2227 2228 return &instruction->base; 2229 } 2230 2231 static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2232 IrInstructionFloatToInt *instruction = ir_build_instruction<IrInstructionFloatToInt>(irb, scope, source_node); 2233 instruction->dest_type = dest_type; 2234 instruction->target = target; 2235 2236 ir_ref_instruction(dest_type, irb->current_basic_block); 2237 ir_ref_instruction(target, irb->current_basic_block); 2238 2239 return &instruction->base; 2240 } 2241 2242 static IrInstruction *ir_build_bool_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { 2243 IrInstructionBoolToInt *instruction = ir_build_instruction<IrInstructionBoolToInt>(irb, scope, source_node); 2244 instruction->target = target; 2245 2246 ir_ref_instruction(target, irb->current_basic_block); 2247 2248 return &instruction->base; 2249 } 2250 2251 static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) { 2252 IrInstructionIntType *instruction = ir_build_instruction<IrInstructionIntType>(irb, scope, source_node); 2253 instruction->is_signed = is_signed; 2254 instruction->bit_count = bit_count; 2255 2256 ir_ref_instruction(is_signed, irb->current_basic_block); 2257 ir_ref_instruction(bit_count, irb->current_basic_block); 2258 2259 return &instruction->base; 2260 } 2261 2262 static IrInstruction *ir_build_vector_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *len, 2263 IrInstruction *elem_type) 2264 { 2265 IrInstructionVectorType *instruction = ir_build_instruction<IrInstructionVectorType>(irb, scope, source_node); 2266 instruction->len = len; 2267 instruction->elem_type = elem_type; 2268 2269 ir_ref_instruction(len, irb->current_basic_block); 2270 ir_ref_instruction(elem_type, irb->current_basic_block); 2271 2272 return &instruction->base; 2273 } 2274 2275 static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2276 IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node); 2277 instruction->value = value; 2278 2279 ir_ref_instruction(value, irb->current_basic_block); 2280 2281 return &instruction->base; 2282 } 2283 2284 static IrInstruction *ir_build_memset(IrBuilder *irb, Scope *scope, AstNode *source_node, 2285 IrInstruction *dest_ptr, IrInstruction *byte, IrInstruction *count) 2286 { 2287 IrInstructionMemset *instruction = ir_build_instruction<IrInstructionMemset>(irb, scope, source_node); 2288 instruction->dest_ptr = dest_ptr; 2289 instruction->byte = byte; 2290 instruction->count = count; 2291 2292 ir_ref_instruction(dest_ptr, irb->current_basic_block); 2293 ir_ref_instruction(byte, irb->current_basic_block); 2294 ir_ref_instruction(count, irb->current_basic_block); 2295 2296 return &instruction->base; 2297 } 2298 2299 static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *source_node, 2300 IrInstruction *dest_ptr, IrInstruction *src_ptr, IrInstruction *count) 2301 { 2302 IrInstructionMemcpy *instruction = ir_build_instruction<IrInstructionMemcpy>(irb, scope, source_node); 2303 instruction->dest_ptr = dest_ptr; 2304 instruction->src_ptr = src_ptr; 2305 instruction->count = count; 2306 2307 ir_ref_instruction(dest_ptr, irb->current_basic_block); 2308 ir_ref_instruction(src_ptr, irb->current_basic_block); 2309 ir_ref_instruction(count, irb->current_basic_block); 2310 2311 return &instruction->base; 2312 } 2313 2314 static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2315 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, ResultLoc *result_loc) 2316 { 2317 IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node); 2318 instruction->ptr = ptr; 2319 instruction->start = start; 2320 instruction->end = end; 2321 instruction->safety_check_on = safety_check_on; 2322 instruction->result_loc = result_loc; 2323 2324 ir_ref_instruction(ptr, irb->current_basic_block); 2325 ir_ref_instruction(start, irb->current_basic_block); 2326 if (end) ir_ref_instruction(end, irb->current_basic_block); 2327 2328 return &instruction->base; 2329 } 2330 2331 static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *slice_type, 2332 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, IrInstruction *result_loc) 2333 { 2334 IrInstructionSliceGen *instruction = ir_build_instruction<IrInstructionSliceGen>( 2335 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2336 instruction->base.value.type = slice_type; 2337 instruction->ptr = ptr; 2338 instruction->start = start; 2339 instruction->end = end; 2340 instruction->safety_check_on = safety_check_on; 2341 instruction->result_loc = result_loc; 2342 2343 ir_ref_instruction(ptr, ira->new_irb.current_basic_block); 2344 ir_ref_instruction(start, ira->new_irb.current_basic_block); 2345 if (end) ir_ref_instruction(end, ira->new_irb.current_basic_block); 2346 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 2347 2348 return &instruction->base; 2349 } 2350 2351 static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) { 2352 IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); 2353 instruction->container = container; 2354 2355 ir_ref_instruction(container, irb->current_basic_block); 2356 2357 return &instruction->base; 2358 } 2359 2360 static IrInstruction *ir_build_member_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2361 IrInstruction *container_type, IrInstruction *member_index) 2362 { 2363 IrInstructionMemberType *instruction = ir_build_instruction<IrInstructionMemberType>(irb, scope, source_node); 2364 instruction->container_type = container_type; 2365 instruction->member_index = member_index; 2366 2367 ir_ref_instruction(container_type, irb->current_basic_block); 2368 ir_ref_instruction(member_index, irb->current_basic_block); 2369 2370 return &instruction->base; 2371 } 2372 2373 static IrInstruction *ir_build_member_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2374 IrInstruction *container_type, IrInstruction *member_index) 2375 { 2376 IrInstructionMemberName *instruction = ir_build_instruction<IrInstructionMemberName>(irb, scope, source_node); 2377 instruction->container_type = container_type; 2378 instruction->member_index = member_index; 2379 2380 ir_ref_instruction(container_type, irb->current_basic_block); 2381 ir_ref_instruction(member_index, irb->current_basic_block); 2382 2383 return &instruction->base; 2384 } 2385 2386 static IrInstruction *ir_build_breakpoint(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2387 IrInstructionBreakpoint *instruction = ir_build_instruction<IrInstructionBreakpoint>(irb, scope, source_node); 2388 return &instruction->base; 2389 } 2390 2391 static IrInstruction *ir_build_return_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2392 IrInstructionReturnAddress *instruction = ir_build_instruction<IrInstructionReturnAddress>(irb, scope, source_node); 2393 return &instruction->base; 2394 } 2395 2396 static IrInstruction *ir_build_frame_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2397 IrInstructionFrameAddress *instruction = ir_build_instruction<IrInstructionFrameAddress>(irb, scope, source_node); 2398 return &instruction->base; 2399 } 2400 2401 static IrInstruction *ir_build_handle(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2402 IrInstructionFrameHandle *instruction = ir_build_instruction<IrInstructionFrameHandle>(irb, scope, source_node); 2403 return &instruction->base; 2404 } 2405 2406 static IrInstruction *ir_build_frame_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn) { 2407 IrInstructionFrameType *instruction = ir_build_instruction<IrInstructionFrameType>(irb, scope, source_node); 2408 instruction->fn = fn; 2409 2410 ir_ref_instruction(fn, irb->current_basic_block); 2411 2412 return &instruction->base; 2413 } 2414 2415 static IrInstruction *ir_build_frame_size_src(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn) { 2416 IrInstructionFrameSizeSrc *instruction = ir_build_instruction<IrInstructionFrameSizeSrc>(irb, scope, source_node); 2417 instruction->fn = fn; 2418 2419 ir_ref_instruction(fn, irb->current_basic_block); 2420 2421 return &instruction->base; 2422 } 2423 2424 static IrInstruction *ir_build_frame_size_gen(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn) 2425 { 2426 IrInstructionFrameSizeGen *instruction = ir_build_instruction<IrInstructionFrameSizeGen>(irb, scope, source_node); 2427 instruction->fn = fn; 2428 2429 ir_ref_instruction(fn, irb->current_basic_block); 2430 2431 return &instruction->base; 2432 } 2433 2434 static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode *source_node, 2435 IrOverflowOp op, IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, 2436 IrInstruction *result_ptr, ZigType *result_ptr_type) 2437 { 2438 IrInstructionOverflowOp *instruction = ir_build_instruction<IrInstructionOverflowOp>(irb, scope, source_node); 2439 instruction->op = op; 2440 instruction->type_value = type_value; 2441 instruction->op1 = op1; 2442 instruction->op2 = op2; 2443 instruction->result_ptr = result_ptr; 2444 instruction->result_ptr_type = result_ptr_type; 2445 2446 ir_ref_instruction(type_value, irb->current_basic_block); 2447 ir_ref_instruction(op1, irb->current_basic_block); 2448 ir_ref_instruction(op2, irb->current_basic_block); 2449 ir_ref_instruction(result_ptr, irb->current_basic_block); 2450 2451 return &instruction->base; 2452 } 2453 2454 2455 //TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign, 2456 // lround, llround, lrint, llrint 2457 // So far this is only non-complicated type functions. 2458 const char *float_op_to_name(BuiltinFnId op, bool llvm_name) { 2459 const bool b = llvm_name; 2460 2461 switch (op) { 2462 case BuiltinFnIdSqrt: 2463 return "sqrt"; 2464 case BuiltinFnIdSin: 2465 return "sin"; 2466 case BuiltinFnIdCos: 2467 return "cos"; 2468 case BuiltinFnIdExp: 2469 return "exp"; 2470 case BuiltinFnIdExp2: 2471 return "exp2"; 2472 case BuiltinFnIdLn: 2473 return b ? "log" : "ln"; 2474 case BuiltinFnIdLog10: 2475 return "log10"; 2476 case BuiltinFnIdLog2: 2477 return "log2"; 2478 case BuiltinFnIdFabs: 2479 return "fabs"; 2480 case BuiltinFnIdFloor: 2481 return "floor"; 2482 case BuiltinFnIdCeil: 2483 return "ceil"; 2484 case BuiltinFnIdTrunc: 2485 return "trunc"; 2486 case BuiltinFnIdNearbyInt: 2487 return b ? "nearbyint" : "nearbyInt"; 2488 case BuiltinFnIdRound: 2489 return "round"; 2490 default: 2491 zig_unreachable(); 2492 } 2493 } 2494 2495 static IrInstruction *ir_build_float_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op1, BuiltinFnId op) { 2496 IrInstructionFloatOp *instruction = ir_build_instruction<IrInstructionFloatOp>(irb, scope, source_node); 2497 instruction->type = type; 2498 instruction->op1 = op1; 2499 instruction->op = op; 2500 2501 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 2502 ir_ref_instruction(op1, irb->current_basic_block); 2503 2504 return &instruction->base; 2505 } 2506 2507 static IrInstruction *ir_build_mul_add(IrBuilder *irb, Scope *scope, AstNode *source_node, 2508 IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, IrInstruction *op3) { 2509 IrInstructionMulAdd *instruction = ir_build_instruction<IrInstructionMulAdd>(irb, scope, source_node); 2510 instruction->type_value = type_value; 2511 instruction->op1 = op1; 2512 instruction->op2 = op2; 2513 instruction->op3 = op3; 2514 2515 ir_ref_instruction(type_value, irb->current_basic_block); 2516 ir_ref_instruction(op1, irb->current_basic_block); 2517 ir_ref_instruction(op2, irb->current_basic_block); 2518 ir_ref_instruction(op3, irb->current_basic_block); 2519 2520 return &instruction->base; 2521 } 2522 2523 static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { 2524 IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node); 2525 instruction->type_value = type_value; 2526 2527 ir_ref_instruction(type_value, irb->current_basic_block); 2528 2529 return &instruction->base; 2530 } 2531 2532 static IrInstruction *ir_build_test_err_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2533 IrInstruction *base_ptr, bool resolve_err_set, bool base_ptr_is_payload) 2534 { 2535 IrInstructionTestErrSrc *instruction = ir_build_instruction<IrInstructionTestErrSrc>(irb, scope, source_node); 2536 instruction->base_ptr = base_ptr; 2537 instruction->resolve_err_set = resolve_err_set; 2538 instruction->base_ptr_is_payload = base_ptr_is_payload; 2539 2540 ir_ref_instruction(base_ptr, irb->current_basic_block); 2541 2542 return &instruction->base; 2543 } 2544 2545 static IrInstruction *ir_build_test_err_gen(IrAnalyze *ira, IrInstruction *source_instruction, 2546 IrInstruction *err_union) 2547 { 2548 IrInstructionTestErrGen *instruction = ir_build_instruction<IrInstructionTestErrGen>( 2549 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2550 instruction->base.value.type = ira->codegen->builtin_types.entry_bool; 2551 instruction->err_union = err_union; 2552 2553 ir_ref_instruction(err_union, ira->new_irb.current_basic_block); 2554 2555 return &instruction->base; 2556 } 2557 2558 static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, 2559 IrInstruction *err_union_ptr) 2560 { 2561 IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); 2562 instruction->err_union_ptr = err_union_ptr; 2563 2564 ir_ref_instruction(err_union_ptr, irb->current_basic_block); 2565 2566 return &instruction->base; 2567 } 2568 2569 static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, 2570 IrInstruction *value, bool safety_check_on, bool initializing) 2571 { 2572 IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); 2573 instruction->value = value; 2574 instruction->safety_check_on = safety_check_on; 2575 instruction->initializing = initializing; 2576 2577 ir_ref_instruction(value, irb->current_basic_block); 2578 2579 return &instruction->base; 2580 } 2581 2582 static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node, 2583 IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type, 2584 bool is_var_args) 2585 { 2586 IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node); 2587 instruction->param_types = param_types; 2588 instruction->align_value = align_value; 2589 instruction->return_type = return_type; 2590 instruction->is_var_args = is_var_args; 2591 2592 assert(source_node->type == NodeTypeFnProto); 2593 size_t param_count = source_node->data.fn_proto.params.length; 2594 if (is_var_args) param_count -= 1; 2595 for (size_t i = 0; i < param_count; i += 1) { 2596 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); 2597 } 2598 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 2599 ir_ref_instruction(return_type, irb->current_basic_block); 2600 2601 return &instruction->base; 2602 } 2603 2604 static IrInstruction *ir_build_test_comptime(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2605 IrInstructionTestComptime *instruction = ir_build_instruction<IrInstructionTestComptime>(irb, scope, source_node); 2606 instruction->value = value; 2607 2608 ir_ref_instruction(value, irb->current_basic_block); 2609 2610 return &instruction->base; 2611 } 2612 2613 static IrInstruction *ir_build_ptr_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2614 IrInstruction *dest_type, IrInstruction *ptr, bool safety_check_on) 2615 { 2616 IrInstructionPtrCastSrc *instruction = ir_build_instruction<IrInstructionPtrCastSrc>( 2617 irb, scope, source_node); 2618 instruction->dest_type = dest_type; 2619 instruction->ptr = ptr; 2620 instruction->safety_check_on = safety_check_on; 2621 2622 ir_ref_instruction(dest_type, irb->current_basic_block); 2623 ir_ref_instruction(ptr, irb->current_basic_block); 2624 2625 return &instruction->base; 2626 } 2627 2628 static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *source_instruction, 2629 ZigType *ptr_type, IrInstruction *ptr, bool safety_check_on) 2630 { 2631 IrInstructionPtrCastGen *instruction = ir_build_instruction<IrInstructionPtrCastGen>( 2632 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2633 instruction->base.value.type = ptr_type; 2634 instruction->ptr = ptr; 2635 instruction->safety_check_on = safety_check_on; 2636 2637 ir_ref_instruction(ptr, ira->new_irb.current_basic_block); 2638 2639 return &instruction->base; 2640 } 2641 2642 static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction, 2643 IrInstruction *ptr, ZigType *ty, IrInstruction *result_loc) 2644 { 2645 IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>( 2646 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2647 instruction->base.value.type = ty; 2648 instruction->ptr = ptr; 2649 instruction->result_loc = result_loc; 2650 2651 ir_ref_instruction(ptr, ira->new_irb.current_basic_block); 2652 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 2653 2654 return &instruction->base; 2655 } 2656 2657 static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2658 IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast) 2659 { 2660 IrInstructionBitCastSrc *instruction = ir_build_instruction<IrInstructionBitCastSrc>(irb, scope, source_node); 2661 instruction->operand = operand; 2662 instruction->result_loc_bit_cast = result_loc_bit_cast; 2663 2664 ir_ref_instruction(operand, irb->current_basic_block); 2665 2666 return &instruction->base; 2667 } 2668 2669 static IrInstruction *ir_build_bit_cast_gen(IrAnalyze *ira, IrInstruction *source_instruction, 2670 IrInstruction *operand, ZigType *ty) 2671 { 2672 IrInstructionBitCastGen *instruction = ir_build_instruction<IrInstructionBitCastGen>( 2673 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2674 instruction->base.value.type = ty; 2675 instruction->operand = operand; 2676 2677 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 2678 2679 return &instruction->base; 2680 } 2681 2682 static IrInstruction *ir_build_widen_or_shorten(IrBuilder *irb, Scope *scope, AstNode *source_node, 2683 IrInstruction *target) 2684 { 2685 IrInstructionWidenOrShorten *instruction = ir_build_instruction<IrInstructionWidenOrShorten>( 2686 irb, scope, source_node); 2687 instruction->target = target; 2688 2689 ir_ref_instruction(target, irb->current_basic_block); 2690 2691 return &instruction->base; 2692 } 2693 2694 static IrInstruction *ir_build_int_to_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 2695 IrInstruction *dest_type, IrInstruction *target) 2696 { 2697 IrInstructionIntToPtr *instruction = ir_build_instruction<IrInstructionIntToPtr>( 2698 irb, scope, source_node); 2699 instruction->dest_type = dest_type; 2700 instruction->target = target; 2701 2702 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2703 ir_ref_instruction(target, irb->current_basic_block); 2704 2705 return &instruction->base; 2706 } 2707 2708 static IrInstruction *ir_build_ptr_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2709 IrInstruction *target) 2710 { 2711 IrInstructionPtrToInt *instruction = ir_build_instruction<IrInstructionPtrToInt>( 2712 irb, scope, source_node); 2713 instruction->target = target; 2714 2715 ir_ref_instruction(target, irb->current_basic_block); 2716 2717 return &instruction->base; 2718 } 2719 2720 static IrInstruction *ir_build_int_to_enum(IrBuilder *irb, Scope *scope, AstNode *source_node, 2721 IrInstruction *dest_type, IrInstruction *target) 2722 { 2723 IrInstructionIntToEnum *instruction = ir_build_instruction<IrInstructionIntToEnum>( 2724 irb, scope, source_node); 2725 instruction->dest_type = dest_type; 2726 instruction->target = target; 2727 2728 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2729 ir_ref_instruction(target, irb->current_basic_block); 2730 2731 return &instruction->base; 2732 } 2733 2734 2735 2736 static IrInstruction *ir_build_enum_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2737 IrInstruction *target) 2738 { 2739 IrInstructionEnumToInt *instruction = ir_build_instruction<IrInstructionEnumToInt>( 2740 irb, scope, source_node); 2741 instruction->target = target; 2742 2743 ir_ref_instruction(target, irb->current_basic_block); 2744 2745 return &instruction->base; 2746 } 2747 2748 static IrInstruction *ir_build_int_to_err(IrBuilder *irb, Scope *scope, AstNode *source_node, 2749 IrInstruction *target) 2750 { 2751 IrInstructionIntToErr *instruction = ir_build_instruction<IrInstructionIntToErr>( 2752 irb, scope, source_node); 2753 instruction->target = target; 2754 2755 ir_ref_instruction(target, irb->current_basic_block); 2756 2757 return &instruction->base; 2758 } 2759 2760 static IrInstruction *ir_build_err_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2761 IrInstruction *target) 2762 { 2763 IrInstructionErrToInt *instruction = ir_build_instruction<IrInstructionErrToInt>( 2764 irb, scope, source_node); 2765 instruction->target = target; 2766 2767 ir_ref_instruction(target, irb->current_basic_block); 2768 2769 return &instruction->base; 2770 } 2771 2772 static IrInstruction *ir_build_check_switch_prongs(IrBuilder *irb, Scope *scope, AstNode *source_node, 2773 IrInstruction *target_value, IrInstructionCheckSwitchProngsRange *ranges, size_t range_count, 2774 bool have_else_prong) 2775 { 2776 IrInstructionCheckSwitchProngs *instruction = ir_build_instruction<IrInstructionCheckSwitchProngs>( 2777 irb, scope, source_node); 2778 instruction->target_value = target_value; 2779 instruction->ranges = ranges; 2780 instruction->range_count = range_count; 2781 instruction->have_else_prong = have_else_prong; 2782 2783 ir_ref_instruction(target_value, irb->current_basic_block); 2784 for (size_t i = 0; i < range_count; i += 1) { 2785 ir_ref_instruction(ranges[i].start, irb->current_basic_block); 2786 ir_ref_instruction(ranges[i].end, irb->current_basic_block); 2787 } 2788 2789 return &instruction->base; 2790 } 2791 2792 static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *scope, AstNode *source_node, 2793 IrInstruction* statement_value) 2794 { 2795 IrInstructionCheckStatementIsVoid *instruction = ir_build_instruction<IrInstructionCheckStatementIsVoid>( 2796 irb, scope, source_node); 2797 instruction->statement_value = statement_value; 2798 2799 ir_ref_instruction(statement_value, irb->current_basic_block); 2800 2801 return &instruction->base; 2802 } 2803 2804 static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2805 IrInstruction *type_value) 2806 { 2807 IrInstructionTypeName *instruction = ir_build_instruction<IrInstructionTypeName>( 2808 irb, scope, source_node); 2809 instruction->type_value = type_value; 2810 2811 ir_ref_instruction(type_value, irb->current_basic_block); 2812 2813 return &instruction->base; 2814 } 2815 2816 static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) { 2817 IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>(irb, scope, source_node); 2818 instruction->tld = tld; 2819 instruction->lval = lval; 2820 2821 return &instruction->base; 2822 } 2823 2824 static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { 2825 IrInstructionPanic *instruction = ir_build_instruction<IrInstructionPanic>(irb, scope, source_node); 2826 instruction->base.value.special = ConstValSpecialStatic; 2827 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 2828 instruction->msg = msg; 2829 2830 ir_ref_instruction(msg, irb->current_basic_block); 2831 2832 return &instruction->base; 2833 } 2834 2835 static IrInstruction *ir_build_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2836 IrInstruction *target) 2837 { 2838 IrInstructionTagName *instruction = ir_build_instruction<IrInstructionTagName>(irb, scope, source_node); 2839 instruction->target = target; 2840 2841 ir_ref_instruction(target, irb->current_basic_block); 2842 2843 return &instruction->base; 2844 } 2845 2846 static IrInstruction *ir_build_tag_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2847 IrInstruction *target) 2848 { 2849 IrInstructionTagType *instruction = ir_build_instruction<IrInstructionTagType>(irb, scope, source_node); 2850 instruction->target = target; 2851 2852 ir_ref_instruction(target, irb->current_basic_block); 2853 2854 return &instruction->base; 2855 } 2856 2857 static IrInstruction *ir_build_field_parent_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 2858 IrInstruction *type_value, IrInstruction *field_name, IrInstruction *field_ptr, TypeStructField *field) 2859 { 2860 IrInstructionFieldParentPtr *instruction = ir_build_instruction<IrInstructionFieldParentPtr>( 2861 irb, scope, source_node); 2862 instruction->type_value = type_value; 2863 instruction->field_name = field_name; 2864 instruction->field_ptr = field_ptr; 2865 instruction->field = field; 2866 2867 ir_ref_instruction(type_value, irb->current_basic_block); 2868 ir_ref_instruction(field_name, irb->current_basic_block); 2869 ir_ref_instruction(field_ptr, irb->current_basic_block); 2870 2871 return &instruction->base; 2872 } 2873 2874 static IrInstruction *ir_build_byte_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node, 2875 IrInstruction *type_value, IrInstruction *field_name) 2876 { 2877 IrInstructionByteOffsetOf *instruction = ir_build_instruction<IrInstructionByteOffsetOf>(irb, scope, source_node); 2878 instruction->type_value = type_value; 2879 instruction->field_name = field_name; 2880 2881 ir_ref_instruction(type_value, irb->current_basic_block); 2882 ir_ref_instruction(field_name, irb->current_basic_block); 2883 2884 return &instruction->base; 2885 } 2886 2887 static IrInstruction *ir_build_bit_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node, 2888 IrInstruction *type_value, IrInstruction *field_name) 2889 { 2890 IrInstructionBitOffsetOf *instruction = ir_build_instruction<IrInstructionBitOffsetOf>(irb, scope, source_node); 2891 instruction->type_value = type_value; 2892 instruction->field_name = field_name; 2893 2894 ir_ref_instruction(type_value, irb->current_basic_block); 2895 ir_ref_instruction(field_name, irb->current_basic_block); 2896 2897 return &instruction->base; 2898 } 2899 2900 static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *source_node, 2901 IrInstruction *type_value) { 2902 IrInstructionTypeInfo *instruction = ir_build_instruction<IrInstructionTypeInfo>(irb, scope, source_node); 2903 instruction->type_value = type_value; 2904 2905 ir_ref_instruction(type_value, irb->current_basic_block); 2906 2907 return &instruction->base; 2908 } 2909 2910 static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node, 2911 IrInstruction *type_value) 2912 { 2913 IrInstructionTypeId *instruction = ir_build_instruction<IrInstructionTypeId>(irb, scope, source_node); 2914 instruction->type_value = type_value; 2915 2916 ir_ref_instruction(type_value, irb->current_basic_block); 2917 2918 return &instruction->base; 2919 } 2920 2921 static IrInstruction *ir_build_set_eval_branch_quota(IrBuilder *irb, Scope *scope, AstNode *source_node, 2922 IrInstruction *new_quota) 2923 { 2924 IrInstructionSetEvalBranchQuota *instruction = ir_build_instruction<IrInstructionSetEvalBranchQuota>(irb, scope, source_node); 2925 instruction->new_quota = new_quota; 2926 2927 ir_ref_instruction(new_quota, irb->current_basic_block); 2928 2929 return &instruction->base; 2930 } 2931 2932 static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 2933 IrInstruction *align_bytes, IrInstruction *target) 2934 { 2935 IrInstructionAlignCast *instruction = ir_build_instruction<IrInstructionAlignCast>(irb, scope, source_node); 2936 instruction->align_bytes = align_bytes; 2937 instruction->target = target; 2938 2939 if (align_bytes) ir_ref_instruction(align_bytes, irb->current_basic_block); 2940 ir_ref_instruction(target, irb->current_basic_block); 2941 2942 return &instruction->base; 2943 } 2944 2945 static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 2946 IrInstruction *dest_type, IrInstruction *target, ResultLoc *result_loc) 2947 { 2948 IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node); 2949 instruction->dest_type = dest_type; 2950 instruction->target = target; 2951 instruction->result_loc = result_loc; 2952 2953 ir_ref_instruction(dest_type, irb->current_basic_block); 2954 ir_ref_instruction(target, irb->current_basic_block); 2955 2956 return &instruction->base; 2957 } 2958 2959 static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node, 2960 ResultLoc *result_loc, IrInstruction *ty) 2961 { 2962 IrInstructionResolveResult *instruction = ir_build_instruction<IrInstructionResolveResult>(irb, scope, source_node); 2963 instruction->result_loc = result_loc; 2964 instruction->ty = ty; 2965 2966 ir_ref_instruction(ty, irb->current_basic_block); 2967 2968 return &instruction->base; 2969 } 2970 2971 static IrInstruction *ir_build_reset_result(IrBuilder *irb, Scope *scope, AstNode *source_node, 2972 ResultLoc *result_loc) 2973 { 2974 IrInstructionResetResult *instruction = ir_build_instruction<IrInstructionResetResult>(irb, scope, source_node); 2975 instruction->result_loc = result_loc; 2976 2977 return &instruction->base; 2978 } 2979 2980 static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2981 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); 2982 2983 return &instruction->base; 2984 } 2985 2986 static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, AstNode *source_node, 2987 IrInstruction *align_bytes) 2988 { 2989 IrInstructionSetAlignStack *instruction = ir_build_instruction<IrInstructionSetAlignStack>(irb, scope, source_node); 2990 instruction->align_bytes = align_bytes; 2991 2992 ir_ref_instruction(align_bytes, irb->current_basic_block); 2993 2994 return &instruction->base; 2995 } 2996 2997 static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2998 IrInstruction *fn_type, IrInstruction *arg_index) 2999 { 3000 IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node); 3001 instruction->fn_type = fn_type; 3002 instruction->arg_index = arg_index; 3003 3004 ir_ref_instruction(fn_type, irb->current_basic_block); 3005 ir_ref_instruction(arg_index, irb->current_basic_block); 3006 3007 return &instruction->base; 3008 } 3009 3010 static IrInstruction *ir_build_error_return_trace(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstructionErrorReturnTrace::Optional optional) { 3011 IrInstructionErrorReturnTrace *instruction = ir_build_instruction<IrInstructionErrorReturnTrace>(irb, scope, source_node); 3012 instruction->optional = optional; 3013 3014 return &instruction->base; 3015 } 3016 3017 static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode *source_node, 3018 IrInstruction *err_set, IrInstruction *payload) 3019 { 3020 IrInstructionErrorUnion *instruction = ir_build_instruction<IrInstructionErrorUnion>(irb, scope, source_node); 3021 instruction->err_set = err_set; 3022 instruction->payload = payload; 3023 3024 ir_ref_instruction(err_set, irb->current_basic_block); 3025 ir_ref_instruction(payload, irb->current_basic_block); 3026 3027 return &instruction->base; 3028 } 3029 3030 static IrInstruction *ir_build_atomic_rmw(IrBuilder *irb, Scope *scope, AstNode *source_node, 3031 IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *op, IrInstruction *operand, 3032 IrInstruction *ordering, AtomicRmwOp resolved_op, AtomicOrder resolved_ordering) 3033 { 3034 IrInstructionAtomicRmw *instruction = ir_build_instruction<IrInstructionAtomicRmw>(irb, scope, source_node); 3035 instruction->operand_type = operand_type; 3036 instruction->ptr = ptr; 3037 instruction->op = op; 3038 instruction->operand = operand; 3039 instruction->ordering = ordering; 3040 instruction->resolved_op = resolved_op; 3041 instruction->resolved_ordering = resolved_ordering; 3042 3043 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); 3044 ir_ref_instruction(ptr, irb->current_basic_block); 3045 if (op != nullptr) ir_ref_instruction(op, irb->current_basic_block); 3046 ir_ref_instruction(operand, irb->current_basic_block); 3047 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); 3048 3049 return &instruction->base; 3050 } 3051 3052 static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode *source_node, 3053 IrInstruction *operand_type, IrInstruction *ptr, 3054 IrInstruction *ordering, AtomicOrder resolved_ordering) 3055 { 3056 IrInstructionAtomicLoad *instruction = ir_build_instruction<IrInstructionAtomicLoad>(irb, scope, source_node); 3057 instruction->operand_type = operand_type; 3058 instruction->ptr = ptr; 3059 instruction->ordering = ordering; 3060 instruction->resolved_ordering = resolved_ordering; 3061 3062 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); 3063 ir_ref_instruction(ptr, irb->current_basic_block); 3064 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); 3065 3066 return &instruction->base; 3067 } 3068 3069 static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) { 3070 IrInstructionSaveErrRetAddr *instruction = ir_build_instruction<IrInstructionSaveErrRetAddr>(irb, scope, source_node); 3071 return &instruction->base; 3072 } 3073 3074 static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 3075 IrInstruction *value) 3076 { 3077 IrInstructionAddImplicitReturnType *instruction = ir_build_instruction<IrInstructionAddImplicitReturnType>(irb, scope, source_node); 3078 instruction->value = value; 3079 3080 ir_ref_instruction(value, irb->current_basic_block); 3081 3082 return &instruction->base; 3083 } 3084 3085 static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *source_node, 3086 IrInstruction *container, IrInstruction *name) 3087 { 3088 IrInstructionHasDecl *instruction = ir_build_instruction<IrInstructionHasDecl>(irb, scope, source_node); 3089 instruction->container = container; 3090 instruction->name = name; 3091 3092 ir_ref_instruction(container, irb->current_basic_block); 3093 ir_ref_instruction(name, irb->current_basic_block); 3094 3095 return &instruction->base; 3096 } 3097 3098 static IrInstruction *ir_build_undeclared_identifier(IrBuilder *irb, Scope *scope, AstNode *source_node, 3099 Buf *name) 3100 { 3101 IrInstructionUndeclaredIdent *instruction = ir_build_instruction<IrInstructionUndeclaredIdent>(irb, scope, source_node); 3102 instruction->name = name; 3103 3104 return &instruction->base; 3105 } 3106 3107 static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { 3108 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node); 3109 instruction->scope_is_comptime = scope_is_comptime; 3110 instruction->is_comptime = is_comptime; 3111 3112 ir_ref_instruction(scope_is_comptime, irb->current_basic_block); 3113 ir_ref_instruction(is_comptime, irb->current_basic_block); 3114 3115 return &instruction->base; 3116 } 3117 3118 static IrInstruction *ir_build_union_init_named_field(IrBuilder *irb, Scope *scope, AstNode *source_node, 3119 IrInstruction *union_type, IrInstruction *field_name, IrInstruction *field_result_loc, IrInstruction *result_loc) 3120 { 3121 IrInstructionUnionInitNamedField *instruction = ir_build_instruction<IrInstructionUnionInitNamedField>(irb, scope, source_node); 3122 instruction->union_type = union_type; 3123 instruction->field_name = field_name; 3124 instruction->field_result_loc = field_result_loc; 3125 instruction->result_loc = result_loc; 3126 3127 ir_ref_instruction(union_type, irb->current_basic_block); 3128 ir_ref_instruction(field_name, irb->current_basic_block); 3129 ir_ref_instruction(field_result_loc, irb->current_basic_block); 3130 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 3131 3132 return &instruction->base; 3133 } 3134 3135 3136 static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction, 3137 ZigType *result_type, IrInstruction *vector, IrInstruction *result_loc) 3138 { 3139 IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb, 3140 source_instruction->scope, source_instruction->source_node); 3141 instruction->base.value.type = result_type; 3142 instruction->vector = vector; 3143 instruction->result_loc = result_loc; 3144 3145 ir_ref_instruction(vector, ira->new_irb.current_basic_block); 3146 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 3147 3148 return &instruction->base; 3149 } 3150 3151 static IrInstruction *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instruction, 3152 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) 3153 { 3154 IrInstructionPtrOfArrayToSlice *instruction = ir_build_instruction<IrInstructionPtrOfArrayToSlice>(&ira->new_irb, 3155 source_instruction->scope, source_instruction->source_node); 3156 instruction->base.value.type = result_type; 3157 instruction->operand = operand; 3158 instruction->result_loc = result_loc; 3159 3160 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 3161 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 3162 3163 return &instruction->base; 3164 } 3165 3166 static IrInstruction *ir_build_array_to_vector(IrAnalyze *ira, IrInstruction *source_instruction, 3167 IrInstruction *array, ZigType *result_type) 3168 { 3169 IrInstructionArrayToVector *instruction = ir_build_instruction<IrInstructionArrayToVector>(&ira->new_irb, 3170 source_instruction->scope, source_instruction->source_node); 3171 instruction->base.value.type = result_type; 3172 instruction->array = array; 3173 3174 ir_ref_instruction(array, ira->new_irb.current_basic_block); 3175 3176 return &instruction->base; 3177 } 3178 3179 static IrInstruction *ir_build_assert_zero(IrAnalyze *ira, IrInstruction *source_instruction, 3180 IrInstruction *target) 3181 { 3182 IrInstructionAssertZero *instruction = ir_build_instruction<IrInstructionAssertZero>(&ira->new_irb, 3183 source_instruction->scope, source_instruction->source_node); 3184 instruction->base.value.type = ira->codegen->builtin_types.entry_void; 3185 instruction->target = target; 3186 3187 ir_ref_instruction(target, ira->new_irb.current_basic_block); 3188 3189 return &instruction->base; 3190 } 3191 3192 static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *source_instruction, 3193 IrInstruction *target) 3194 { 3195 IrInstructionAssertNonNull *instruction = ir_build_instruction<IrInstructionAssertNonNull>(&ira->new_irb, 3196 source_instruction->scope, source_instruction->source_node); 3197 instruction->base.value.type = ira->codegen->builtin_types.entry_void; 3198 instruction->target = target; 3199 3200 ir_ref_instruction(target, ira->new_irb.current_basic_block); 3201 3202 return &instruction->base; 3203 } 3204 3205 static IrInstruction *ir_build_alloca_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 3206 IrInstruction *align, const char *name_hint, IrInstruction *is_comptime) 3207 { 3208 IrInstructionAllocaSrc *instruction = ir_build_instruction<IrInstructionAllocaSrc>(irb, scope, source_node); 3209 instruction->base.is_gen = true; 3210 instruction->align = align; 3211 instruction->name_hint = name_hint; 3212 instruction->is_comptime = is_comptime; 3213 3214 if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block); 3215 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); 3216 3217 return &instruction->base; 3218 } 3219 3220 static IrInstructionAllocaGen *ir_build_alloca_gen(IrAnalyze *ira, IrInstruction *source_instruction, 3221 uint32_t align, const char *name_hint) 3222 { 3223 IrInstructionAllocaGen *instruction = ir_create_instruction<IrInstructionAllocaGen>(&ira->new_irb, 3224 source_instruction->scope, source_instruction->source_node); 3225 instruction->align = align; 3226 instruction->name_hint = name_hint; 3227 3228 return instruction; 3229 } 3230 3231 static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, 3232 IrInstruction *value, ResultLoc *result_loc) 3233 { 3234 IrInstructionEndExpr *instruction = ir_build_instruction<IrInstructionEndExpr>(irb, scope, source_node); 3235 instruction->base.is_gen = true; 3236 instruction->value = value; 3237 instruction->result_loc = result_loc; 3238 3239 ir_ref_instruction(value, irb->current_basic_block); 3240 3241 return &instruction->base; 3242 } 3243 3244 static IrInstructionSuspendBegin *ir_build_suspend_begin(IrBuilder *irb, Scope *scope, AstNode *source_node) { 3245 IrInstructionSuspendBegin *instruction = ir_build_instruction<IrInstructionSuspendBegin>(irb, scope, source_node); 3246 instruction->base.value.type = irb->codegen->builtin_types.entry_void; 3247 3248 return instruction; 3249 } 3250 3251 static IrInstruction *ir_build_suspend_finish(IrBuilder *irb, Scope *scope, AstNode *source_node, 3252 IrInstructionSuspendBegin *begin) 3253 { 3254 IrInstructionSuspendFinish *instruction = ir_build_instruction<IrInstructionSuspendFinish>(irb, scope, source_node); 3255 instruction->base.value.type = irb->codegen->builtin_types.entry_void; 3256 instruction->begin = begin; 3257 3258 ir_ref_instruction(&begin->base, irb->current_basic_block); 3259 3260 return &instruction->base; 3261 } 3262 3263 static IrInstruction *ir_build_await_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 3264 IrInstruction *frame, ResultLoc *result_loc) 3265 { 3266 IrInstructionAwaitSrc *instruction = ir_build_instruction<IrInstructionAwaitSrc>(irb, scope, source_node); 3267 instruction->frame = frame; 3268 instruction->result_loc = result_loc; 3269 3270 ir_ref_instruction(frame, irb->current_basic_block); 3271 3272 return &instruction->base; 3273 } 3274 3275 static IrInstruction *ir_build_await_gen(IrAnalyze *ira, IrInstruction *source_instruction, 3276 IrInstruction *frame, ZigType *result_type, IrInstruction *result_loc) 3277 { 3278 IrInstructionAwaitGen *instruction = ir_build_instruction<IrInstructionAwaitGen>(&ira->new_irb, 3279 source_instruction->scope, source_instruction->source_node); 3280 instruction->base.value.type = result_type; 3281 instruction->frame = frame; 3282 instruction->result_loc = result_loc; 3283 3284 ir_ref_instruction(frame, ira->new_irb.current_basic_block); 3285 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 3286 3287 return &instruction->base; 3288 } 3289 3290 static IrInstruction *ir_build_resume(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *frame) { 3291 IrInstructionResume *instruction = ir_build_instruction<IrInstructionResume>(irb, scope, source_node); 3292 instruction->base.value.type = irb->codegen->builtin_types.entry_void; 3293 instruction->frame = frame; 3294 3295 ir_ref_instruction(frame, irb->current_basic_block); 3296 3297 return &instruction->base; 3298 } 3299 3300 static IrInstructionSpillBegin *ir_build_spill_begin(IrBuilder *irb, Scope *scope, AstNode *source_node, 3301 IrInstruction *operand, SpillId spill_id) 3302 { 3303 IrInstructionSpillBegin *instruction = ir_build_instruction<IrInstructionSpillBegin>(irb, scope, source_node); 3304 instruction->base.value.special = ConstValSpecialStatic; 3305 instruction->base.value.type = irb->codegen->builtin_types.entry_void; 3306 instruction->operand = operand; 3307 instruction->spill_id = spill_id; 3308 3309 ir_ref_instruction(operand, irb->current_basic_block); 3310 3311 return instruction; 3312 } 3313 3314 static IrInstruction *ir_build_spill_end(IrBuilder *irb, Scope *scope, AstNode *source_node, 3315 IrInstructionSpillBegin *begin) 3316 { 3317 IrInstructionSpillEnd *instruction = ir_build_instruction<IrInstructionSpillEnd>(irb, scope, source_node); 3318 instruction->begin = begin; 3319 3320 ir_ref_instruction(&begin->base, irb->current_basic_block); 3321 3322 return &instruction->base; 3323 } 3324 3325 static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { 3326 results[ReturnKindUnconditional] = 0; 3327 results[ReturnKindError] = 0; 3328 3329 Scope *scope = inner_scope; 3330 3331 while (scope != outer_scope) { 3332 assert(scope); 3333 switch (scope->id) { 3334 case ScopeIdDefer: { 3335 AstNode *defer_node = scope->source_node; 3336 assert(defer_node->type == NodeTypeDefer); 3337 ReturnKind defer_kind = defer_node->data.defer.kind; 3338 results[defer_kind] += 1; 3339 scope = scope->parent; 3340 continue; 3341 } 3342 case ScopeIdDecls: 3343 case ScopeIdFnDef: 3344 return; 3345 case ScopeIdBlock: 3346 case ScopeIdVarDecl: 3347 case ScopeIdLoop: 3348 case ScopeIdSuspend: 3349 case ScopeIdCompTime: 3350 case ScopeIdRuntime: 3351 scope = scope->parent; 3352 continue; 3353 case ScopeIdDeferExpr: 3354 case ScopeIdCImport: 3355 zig_unreachable(); 3356 } 3357 } 3358 } 3359 3360 static IrInstruction *ir_mark_gen(IrInstruction *instruction) { 3361 instruction->is_gen = true; 3362 return instruction; 3363 } 3364 3365 static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers) { 3366 Scope *scope = inner_scope; 3367 bool is_noreturn = false; 3368 while (scope != outer_scope) { 3369 if (!scope) 3370 return is_noreturn; 3371 3372 switch (scope->id) { 3373 case ScopeIdDefer: { 3374 AstNode *defer_node = scope->source_node; 3375 assert(defer_node->type == NodeTypeDefer); 3376 ReturnKind defer_kind = defer_node->data.defer.kind; 3377 if (defer_kind == ReturnKindUnconditional || 3378 (gen_error_defers && defer_kind == ReturnKindError)) 3379 { 3380 AstNode *defer_expr_node = defer_node->data.defer.expr; 3381 Scope *defer_expr_scope = defer_node->data.defer.expr_scope; 3382 IrInstruction *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); 3383 if (defer_expr_value != irb->codegen->invalid_instruction) { 3384 if (defer_expr_value->value.type != nullptr && 3385 defer_expr_value->value.type->id == ZigTypeIdUnreachable) 3386 { 3387 is_noreturn = true; 3388 } else { 3389 ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, 3390 defer_expr_value)); 3391 } 3392 } 3393 } 3394 scope = scope->parent; 3395 continue; 3396 } 3397 case ScopeIdDecls: 3398 case ScopeIdFnDef: 3399 return is_noreturn; 3400 case ScopeIdBlock: 3401 case ScopeIdVarDecl: 3402 case ScopeIdLoop: 3403 case ScopeIdSuspend: 3404 case ScopeIdCompTime: 3405 case ScopeIdRuntime: 3406 scope = scope->parent; 3407 continue; 3408 case ScopeIdDeferExpr: 3409 case ScopeIdCImport: 3410 zig_unreachable(); 3411 } 3412 } 3413 return is_noreturn; 3414 } 3415 3416 static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { 3417 assert(basic_block); 3418 3419 irb->current_basic_block = basic_block; 3420 } 3421 3422 static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) { 3423 basic_block->index = irb->exec->basic_block_list.length; 3424 irb->exec->basic_block_list.append(basic_block); 3425 ir_set_cursor_at_end(irb, basic_block); 3426 } 3427 3428 static ScopeSuspend *get_scope_suspend(Scope *scope) { 3429 while (scope) { 3430 if (scope->id == ScopeIdSuspend) 3431 return (ScopeSuspend *)scope; 3432 if (scope->id == ScopeIdFnDef) 3433 return nullptr; 3434 3435 scope = scope->parent; 3436 } 3437 return nullptr; 3438 } 3439 3440 static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { 3441 while (scope) { 3442 if (scope->id == ScopeIdDeferExpr) 3443 return (ScopeDeferExpr *)scope; 3444 if (scope->id == ScopeIdFnDef) 3445 return nullptr; 3446 3447 scope = scope->parent; 3448 } 3449 return nullptr; 3450 } 3451 3452 static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 3453 assert(node->type == NodeTypeReturnExpr); 3454 3455 ZigFn *fn_entry = exec_fn_entry(irb->exec); 3456 if (!fn_entry) { 3457 add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition")); 3458 return irb->codegen->invalid_instruction; 3459 } 3460 3461 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); 3462 if (scope_defer_expr) { 3463 if (!scope_defer_expr->reported_err) { 3464 add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression")); 3465 scope_defer_expr->reported_err = true; 3466 } 3467 return irb->codegen->invalid_instruction; 3468 } 3469 3470 Scope *outer_scope = irb->exec->begin_scope; 3471 3472 AstNode *expr_node = node->data.return_expr.expr; 3473 switch (node->data.return_expr.kind) { 3474 case ReturnKindUnconditional: 3475 { 3476 ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); 3477 result_loc_ret->base.id = ResultLocIdReturn; 3478 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 3479 3480 IrInstruction *return_value; 3481 if (expr_node) { 3482 // Temporarily set this so that if we return a type it gets the name of the function 3483 ZigFn *prev_name_fn = irb->exec->name_fn; 3484 irb->exec->name_fn = exec_fn_entry(irb->exec); 3485 return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base); 3486 irb->exec->name_fn = prev_name_fn; 3487 if (return_value == irb->codegen->invalid_instruction) 3488 return irb->codegen->invalid_instruction; 3489 } else { 3490 return_value = ir_build_const_void(irb, scope, node); 3491 } 3492 3493 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value)); 3494 3495 size_t defer_counts[2]; 3496 ir_count_defers(irb, scope, outer_scope, defer_counts); 3497 bool have_err_defers = defer_counts[ReturnKindError] > 0; 3498 if (!have_err_defers && !irb->codegen->have_err_ret_tracing) { 3499 // only generate unconditional defers 3500 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3501 IrInstruction *result = ir_build_return(irb, scope, node, return_value); 3502 result_loc_ret->base.source_instruction = result; 3503 return result; 3504 } 3505 bool should_inline = ir_should_inline(irb->exec, scope); 3506 3507 IrBasicBlock *err_block = ir_create_basic_block(irb, scope, "ErrRetErr"); 3508 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk"); 3509 3510 if (!have_err_defers) { 3511 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3512 } 3513 3514 IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, return_value, false, true); 3515 3516 IrInstruction *is_comptime; 3517 if (should_inline) { 3518 is_comptime = ir_build_const_bool(irb, scope, node, should_inline); 3519 } else { 3520 is_comptime = ir_build_test_comptime(irb, scope, node, is_err); 3521 } 3522 3523 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); 3524 IrBasicBlock *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt"); 3525 3526 ir_set_cursor_at_end_and_append_block(irb, err_block); 3527 if (have_err_defers) { 3528 ir_gen_defers_for_block(irb, scope, outer_scope, true); 3529 } 3530 if (irb->codegen->have_err_ret_tracing && !should_inline) { 3531 ir_build_save_err_ret_addr(irb, scope, node); 3532 } 3533 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 3534 3535 ir_set_cursor_at_end_and_append_block(irb, ok_block); 3536 if (have_err_defers) { 3537 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3538 } 3539 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 3540 3541 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); 3542 IrInstruction *result = ir_build_return(irb, scope, node, return_value); 3543 result_loc_ret->base.source_instruction = result; 3544 return result; 3545 } 3546 case ReturnKindError: 3547 { 3548 assert(expr_node); 3549 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 3550 if (err_union_ptr == irb->codegen->invalid_instruction) 3551 return irb->codegen->invalid_instruction; 3552 IrInstruction *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true, false); 3553 3554 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); 3555 IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); 3556 IrInstruction *is_comptime; 3557 bool should_inline = ir_should_inline(irb->exec, scope); 3558 if (should_inline) { 3559 is_comptime = ir_build_const_bool(irb, scope, node, true); 3560 } else { 3561 is_comptime = ir_build_test_comptime(irb, scope, node, is_err_val); 3562 } 3563 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime)); 3564 3565 ir_set_cursor_at_end_and_append_block(irb, return_block); 3566 IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); 3567 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 3568 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val)); 3569 IrInstructionSpillBegin *spill_begin = ir_build_spill_begin(irb, scope, node, err_val, 3570 SpillIdRetErrCode); 3571 ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); 3572 result_loc_ret->base.id = ResultLocIdReturn; 3573 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 3574 ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base); 3575 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { 3576 if (irb->codegen->have_err_ret_tracing && !should_inline) { 3577 ir_build_save_err_ret_addr(irb, scope, node); 3578 } 3579 err_val = ir_build_spill_end(irb, scope, node, spill_begin); 3580 IrInstruction *ret_inst = ir_build_return(irb, scope, node, err_val); 3581 result_loc_ret->base.source_instruction = ret_inst; 3582 } 3583 3584 ir_set_cursor_at_end_and_append_block(irb, continue_block); 3585 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false, false); 3586 if (lval == LValPtr) 3587 return unwrapped_ptr; 3588 else 3589 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, unwrapped_ptr), result_loc); 3590 } 3591 } 3592 zig_unreachable(); 3593 } 3594 3595 static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope, 3596 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime, 3597 bool skip_name_check) 3598 { 3599 ZigVar *variable_entry = allocate<ZigVar>(1); 3600 variable_entry->parent_scope = parent_scope; 3601 variable_entry->shadowable = is_shadowable; 3602 variable_entry->mem_slot_index = SIZE_MAX; 3603 variable_entry->is_comptime = is_comptime; 3604 variable_entry->src_arg_index = SIZE_MAX; 3605 variable_entry->const_value = create_const_vals(1); 3606 3607 if (is_comptime != nullptr) { 3608 is_comptime->ref_count += 1; 3609 } 3610 3611 if (name) { 3612 buf_init_from_buf(&variable_entry->name, name); 3613 3614 if (!skip_name_check) { 3615 ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr); 3616 if (existing_var && !existing_var->shadowable) { 3617 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) { 3618 ErrorMsg *msg = add_node_error(codegen, node, 3619 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); 3620 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); 3621 } 3622 variable_entry->var_type = codegen->builtin_types.entry_invalid; 3623 } else { 3624 ZigType *type; 3625 if (get_primitive_type(codegen, name, &type) != ErrorPrimitiveTypeNotFound) { 3626 add_node_error(codegen, node, 3627 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name))); 3628 variable_entry->var_type = codegen->builtin_types.entry_invalid; 3629 } else { 3630 Tld *tld = find_decl(codegen, parent_scope, name); 3631 if (tld != nullptr) { 3632 ErrorMsg *msg = add_node_error(codegen, node, 3633 buf_sprintf("redefinition of '%s'", buf_ptr(name))); 3634 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); 3635 variable_entry->var_type = codegen->builtin_types.entry_invalid; 3636 } 3637 } 3638 } 3639 } 3640 } else { 3641 assert(is_shadowable); 3642 // TODO make this name not actually be in scope. user should be able to make a variable called "_anon" 3643 // might already be solved, let's just make sure it has test coverage 3644 // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables 3645 buf_init_from_str(&variable_entry->name, "_anon"); 3646 } 3647 3648 variable_entry->src_is_const = src_is_const; 3649 variable_entry->gen_is_const = gen_is_const; 3650 variable_entry->decl_node = node; 3651 variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry); 3652 3653 return variable_entry; 3654 } 3655 3656 // Set name to nullptr to make the variable anonymous (not visible to programmer). 3657 // After you call this function var->child_scope has the variable in scope 3658 static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name, 3659 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime) 3660 { 3661 bool is_underscored = name ? buf_eql_str(name, "_") : false; 3662 ZigVar *var = create_local_var(irb->codegen, node, scope, 3663 (is_underscored ? nullptr : name), src_is_const, gen_is_const, 3664 (is_underscored ? true : is_shadowable), is_comptime, false); 3665 if (is_comptime != nullptr || gen_is_const) { 3666 var->mem_slot_index = exec_next_mem_slot(irb->exec); 3667 var->owner_exec = irb->exec; 3668 } 3669 assert(var->child_scope); 3670 return var; 3671 } 3672 3673 static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { 3674 ResultLocPeer *result = allocate<ResultLocPeer>(1); 3675 result->base.id = ResultLocIdPeer; 3676 result->base.source_instruction = peer_parent->base.source_instruction; 3677 result->parent = peer_parent; 3678 return result; 3679 } 3680 3681 static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node, LVal lval, 3682 ResultLoc *result_loc) 3683 { 3684 assert(block_node->type == NodeTypeBlock); 3685 3686 ZigList<IrInstruction *> incoming_values = {0}; 3687 ZigList<IrBasicBlock *> incoming_blocks = {0}; 3688 3689 ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope); 3690 3691 Scope *outer_block_scope = &scope_block->base; 3692 Scope *child_scope = outer_block_scope; 3693 3694 ZigFn *fn_entry = scope_fn_entry(parent_scope); 3695 if (fn_entry && fn_entry->child_scope == parent_scope) { 3696 fn_entry->def_scope = scope_block; 3697 } 3698 3699 if (block_node->data.block.statements.length == 0) { 3700 // {} 3701 return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc); 3702 } 3703 3704 if (block_node->data.block.name != nullptr) { 3705 scope_block->lval = lval; 3706 scope_block->incoming_blocks = &incoming_blocks; 3707 scope_block->incoming_values = &incoming_values; 3708 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); 3709 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, 3710 ir_should_inline(irb->exec, parent_scope)); 3711 3712 scope_block->peer_parent = allocate<ResultLocPeerParent>(1); 3713 scope_block->peer_parent->base.id = ResultLocIdPeerParent; 3714 scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; 3715 scope_block->peer_parent->end_bb = scope_block->end_block; 3716 scope_block->peer_parent->is_comptime = scope_block->is_comptime; 3717 scope_block->peer_parent->parent = result_loc; 3718 ir_build_reset_result(irb, parent_scope, block_node, &scope_block->peer_parent->base); 3719 } 3720 3721 bool is_continuation_unreachable = false; 3722 IrInstruction *noreturn_return_value = nullptr; 3723 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { 3724 AstNode *statement_node = block_node->data.block.statements.at(i); 3725 3726 IrInstruction *statement_value = ir_gen_node(irb, statement_node, child_scope); 3727 is_continuation_unreachable = instr_is_unreachable(statement_value); 3728 if (is_continuation_unreachable) { 3729 // keep the last noreturn statement value around in case we need to return it 3730 noreturn_return_value = statement_value; 3731 } 3732 // This logic must be kept in sync with 3733 // [STMT_EXPR_TEST_THING] <--- (search this token) 3734 if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { 3735 // defer starts a new scope 3736 child_scope = statement_node->data.defer.child_scope; 3737 assert(child_scope); 3738 } else if (statement_value->id == IrInstructionIdDeclVarSrc) { 3739 // variable declarations start a new scope 3740 IrInstructionDeclVarSrc *decl_var_instruction = (IrInstructionDeclVarSrc *)statement_value; 3741 child_scope = decl_var_instruction->var->child_scope; 3742 } else if (statement_value != irb->codegen->invalid_instruction && !is_continuation_unreachable) { 3743 // this statement's value must be void 3744 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); 3745 } 3746 } 3747 3748 if (is_continuation_unreachable) { 3749 assert(noreturn_return_value != nullptr); 3750 if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) { 3751 return noreturn_return_value; 3752 } 3753 3754 if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) { 3755 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; 3756 } 3757 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 3758 IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, 3759 incoming_blocks.items, incoming_values.items, scope_block->peer_parent); 3760 return ir_expr_wrap(irb, parent_scope, phi, result_loc); 3761 } else { 3762 incoming_blocks.append(irb->current_basic_block); 3763 IrInstruction *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)); 3764 3765 if (scope_block->peer_parent != nullptr) { 3766 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent); 3767 scope_block->peer_parent->peers.append(peer_result); 3768 ir_build_end_expr(irb, parent_scope, block_node, else_expr_result, &peer_result->base); 3769 3770 if (scope_block->peer_parent->peers.length != 0) { 3771 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; 3772 } 3773 } 3774 3775 incoming_values.append(else_expr_result); 3776 } 3777 3778 bool is_return_from_fn = block_node == irb->main_block_node; 3779 if (!is_return_from_fn) { 3780 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 3781 } 3782 3783 IrInstruction *result; 3784 if (block_node->data.block.name != nullptr) { 3785 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); 3786 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 3787 IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, 3788 incoming_blocks.items, incoming_values.items, scope_block->peer_parent); 3789 result = ir_expr_wrap(irb, parent_scope, phi, result_loc); 3790 } else { 3791 IrInstruction *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); 3792 result = ir_lval_wrap(irb, parent_scope, void_inst, lval, result_loc); 3793 } 3794 if (!is_return_from_fn) 3795 return result; 3796 3797 // no need for save_err_ret_addr because this cannot return error 3798 // only generate unconditional defers 3799 3800 ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result)); 3801 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 3802 return ir_mark_gen(ir_build_return(irb, child_scope, result->source_node, result)); 3803 } 3804 3805 static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 3806 Scope *inner_scope = scope; 3807 if (op_id == IrBinOpArrayCat || op_id == IrBinOpArrayMult) { 3808 inner_scope = create_comptime_scope(irb->codegen, node, scope); 3809 } 3810 3811 IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, inner_scope); 3812 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, inner_scope); 3813 3814 if (op1 == irb->codegen->invalid_instruction || op2 == irb->codegen->invalid_instruction) 3815 return irb->codegen->invalid_instruction; 3816 3817 return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 3818 } 3819 3820 static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { 3821 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); 3822 if (lvalue == irb->codegen->invalid_instruction) 3823 return irb->codegen->invalid_instruction; 3824 3825 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); 3826 result_loc_inst->base.id = ResultLocIdInstruction; 3827 result_loc_inst->base.source_instruction = lvalue; 3828 ir_ref_instruction(lvalue, irb->current_basic_block); 3829 ir_build_reset_result(irb, scope, node, &result_loc_inst->base); 3830 3831 IrInstruction *rvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op2, scope, LValNone, 3832 &result_loc_inst->base); 3833 if (rvalue == irb->codegen->invalid_instruction) 3834 return irb->codegen->invalid_instruction; 3835 3836 return ir_build_const_void(irb, scope, node); 3837 } 3838 3839 static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 3840 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); 3841 if (lvalue == irb->codegen->invalid_instruction) 3842 return lvalue; 3843 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 3844 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3845 if (op2 == irb->codegen->invalid_instruction) 3846 return op2; 3847 IrInstruction *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 3848 ir_build_store_ptr(irb, scope, node, lvalue, result); 3849 return ir_build_const_void(irb, scope, node); 3850 } 3851 3852 static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node) { 3853 assert(node->type == NodeTypeBinOpExpr); 3854 3855 IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 3856 if (val1 == irb->codegen->invalid_instruction) 3857 return irb->codegen->invalid_instruction; 3858 IrBasicBlock *post_val1_block = irb->current_basic_block; 3859 3860 IrInstruction *is_comptime; 3861 if (ir_should_inline(irb->exec, scope)) { 3862 is_comptime = ir_build_const_bool(irb, scope, node, true); 3863 } else { 3864 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 3865 } 3866 3867 // block for when val1 == false 3868 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse"); 3869 // block for when val1 == true (don't even evaluate the second part) 3870 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue"); 3871 3872 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 3873 3874 ir_set_cursor_at_end_and_append_block(irb, false_block); 3875 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3876 if (val2 == irb->codegen->invalid_instruction) 3877 return irb->codegen->invalid_instruction; 3878 IrBasicBlock *post_val2_block = irb->current_basic_block; 3879 3880 ir_build_br(irb, scope, node, true_block, is_comptime); 3881 3882 ir_set_cursor_at_end_and_append_block(irb, true_block); 3883 3884 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 3885 incoming_values[0] = val1; 3886 incoming_values[1] = val2; 3887 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 3888 incoming_blocks[0] = post_val1_block; 3889 incoming_blocks[1] = post_val2_block; 3890 3891 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); 3892 } 3893 3894 static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { 3895 assert(node->type == NodeTypeBinOpExpr); 3896 3897 IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 3898 if (val1 == irb->codegen->invalid_instruction) 3899 return irb->codegen->invalid_instruction; 3900 IrBasicBlock *post_val1_block = irb->current_basic_block; 3901 3902 IrInstruction *is_comptime; 3903 if (ir_should_inline(irb->exec, scope)) { 3904 is_comptime = ir_build_const_bool(irb, scope, node, true); 3905 } else { 3906 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 3907 } 3908 3909 // block for when val1 == true 3910 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue"); 3911 // block for when val1 == false (don't even evaluate the second part) 3912 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse"); 3913 3914 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 3915 3916 ir_set_cursor_at_end_and_append_block(irb, true_block); 3917 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3918 if (val2 == irb->codegen->invalid_instruction) 3919 return irb->codegen->invalid_instruction; 3920 IrBasicBlock *post_val2_block = irb->current_basic_block; 3921 3922 ir_build_br(irb, scope, node, false_block, is_comptime); 3923 3924 ir_set_cursor_at_end_and_append_block(irb, false_block); 3925 3926 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 3927 incoming_values[0] = val1; 3928 incoming_values[1] = val2; 3929 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 3930 incoming_blocks[0] = post_val1_block; 3931 incoming_blocks[1] = post_val2_block; 3932 3933 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); 3934 } 3935 3936 static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, 3937 IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) 3938 { 3939 ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); 3940 peer_parent->base.id = ResultLocIdPeerParent; 3941 peer_parent->base.source_instruction = cond_br_inst; 3942 peer_parent->end_bb = end_block; 3943 peer_parent->is_comptime = is_comptime; 3944 peer_parent->parent = parent; 3945 3946 IrInstruction *popped_inst = irb->current_basic_block->instruction_list.pop(); 3947 ir_assert(popped_inst == cond_br_inst, cond_br_inst); 3948 3949 ir_build_reset_result(irb, cond_br_inst->scope, cond_br_inst->source_node, &peer_parent->base); 3950 irb->current_basic_block->instruction_list.append(popped_inst); 3951 3952 return peer_parent; 3953 } 3954 3955 static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, 3956 IrBasicBlock *else_block, IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) 3957 { 3958 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime); 3959 3960 peer_parent->peers.append(create_peer_result(peer_parent)); 3961 peer_parent->peers.last()->next_bb = else_block; 3962 3963 peer_parent->peers.append(create_peer_result(peer_parent)); 3964 peer_parent->peers.last()->next_bb = end_block; 3965 3966 return peer_parent; 3967 } 3968 3969 static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, 3970 ResultLoc *result_loc) 3971 { 3972 assert(node->type == NodeTypeBinOpExpr); 3973 3974 AstNode *op1_node = node->data.bin_op_expr.op1; 3975 AstNode *op2_node = node->data.bin_op_expr.op2; 3976 3977 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); 3978 if (maybe_ptr == irb->codegen->invalid_instruction) 3979 return irb->codegen->invalid_instruction; 3980 3981 IrInstruction *maybe_val = ir_build_load_ptr(irb, parent_scope, node, maybe_ptr); 3982 IrInstruction *is_non_null = ir_build_test_nonnull(irb, parent_scope, node, maybe_val); 3983 3984 IrInstruction *is_comptime; 3985 if (ir_should_inline(irb->exec, parent_scope)) { 3986 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 3987 } else { 3988 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_non_null); 3989 } 3990 3991 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); 3992 IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); 3993 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); 3994 IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); 3995 3996 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, 3997 result_loc, is_comptime); 3998 3999 ir_set_cursor_at_end_and_append_block(irb, null_block); 4000 IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone, 4001 &peer_parent->peers.at(0)->base); 4002 if (null_result == irb->codegen->invalid_instruction) 4003 return irb->codegen->invalid_instruction; 4004 IrBasicBlock *after_null_block = irb->current_basic_block; 4005 if (!instr_is_unreachable(null_result)) 4006 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 4007 4008 ir_set_cursor_at_end_and_append_block(irb, ok_block); 4009 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false); 4010 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 4011 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); 4012 IrBasicBlock *after_ok_block = irb->current_basic_block; 4013 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 4014 4015 ir_set_cursor_at_end_and_append_block(irb, end_block); 4016 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 4017 incoming_values[0] = null_result; 4018 incoming_values[1] = unwrapped_payload; 4019 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 4020 incoming_blocks[0] = after_null_block; 4021 incoming_blocks[1] = after_ok_block; 4022 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); 4023 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 4024 } 4025 4026 static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 4027 assert(node->type == NodeTypeBinOpExpr); 4028 4029 AstNode *op1_node = node->data.bin_op_expr.op1; 4030 AstNode *op2_node = node->data.bin_op_expr.op2; 4031 4032 IrInstruction *err_set = ir_gen_node(irb, op1_node, parent_scope); 4033 if (err_set == irb->codegen->invalid_instruction) 4034 return irb->codegen->invalid_instruction; 4035 4036 IrInstruction *payload = ir_gen_node(irb, op2_node, parent_scope); 4037 if (payload == irb->codegen->invalid_instruction) 4038 return irb->codegen->invalid_instruction; 4039 4040 return ir_build_error_union(irb, parent_scope, node, err_set, payload); 4041 } 4042 4043 static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 4044 assert(node->type == NodeTypeBinOpExpr); 4045 4046 BinOpType bin_op_type = node->data.bin_op_expr.bin_op; 4047 switch (bin_op_type) { 4048 case BinOpTypeInvalid: 4049 zig_unreachable(); 4050 case BinOpTypeAssign: 4051 return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc); 4052 case BinOpTypeAssignTimes: 4053 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc); 4054 case BinOpTypeAssignTimesWrap: 4055 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc); 4056 case BinOpTypeAssignDiv: 4057 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); 4058 case BinOpTypeAssignMod: 4059 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); 4060 case BinOpTypeAssignPlus: 4061 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc); 4062 case BinOpTypeAssignPlusWrap: 4063 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc); 4064 case BinOpTypeAssignMinus: 4065 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc); 4066 case BinOpTypeAssignMinusWrap: 4067 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc); 4068 case BinOpTypeAssignBitShiftLeft: 4069 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); 4070 case BinOpTypeAssignBitShiftRight: 4071 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); 4072 case BinOpTypeAssignBitAnd: 4073 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc); 4074 case BinOpTypeAssignBitXor: 4075 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc); 4076 case BinOpTypeAssignBitOr: 4077 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc); 4078 case BinOpTypeAssignMergeErrorSets: 4079 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); 4080 case BinOpTypeBoolOr: 4081 return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc); 4082 case BinOpTypeBoolAnd: 4083 return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc); 4084 case BinOpTypeCmpEq: 4085 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc); 4086 case BinOpTypeCmpNotEq: 4087 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc); 4088 case BinOpTypeCmpLessThan: 4089 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc); 4090 case BinOpTypeCmpGreaterThan: 4091 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc); 4092 case BinOpTypeCmpLessOrEq: 4093 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc); 4094 case BinOpTypeCmpGreaterOrEq: 4095 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc); 4096 case BinOpTypeBinOr: 4097 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc); 4098 case BinOpTypeBinXor: 4099 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc); 4100 case BinOpTypeBinAnd: 4101 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc); 4102 case BinOpTypeBitShiftLeft: 4103 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); 4104 case BinOpTypeBitShiftRight: 4105 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); 4106 case BinOpTypeAdd: 4107 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc); 4108 case BinOpTypeAddWrap: 4109 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc); 4110 case BinOpTypeSub: 4111 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc); 4112 case BinOpTypeSubWrap: 4113 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc); 4114 case BinOpTypeMult: 4115 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc); 4116 case BinOpTypeMultWrap: 4117 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc); 4118 case BinOpTypeDiv: 4119 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); 4120 case BinOpTypeMod: 4121 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); 4122 case BinOpTypeArrayCat: 4123 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc); 4124 case BinOpTypeArrayMult: 4125 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc); 4126 case BinOpTypeMergeErrorSets: 4127 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); 4128 case BinOpTypeUnwrapOptional: 4129 return ir_gen_orelse(irb, scope, node, lval, result_loc); 4130 case BinOpTypeErrorUnion: 4131 return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc); 4132 } 4133 zig_unreachable(); 4134 } 4135 4136 static IrInstruction *ir_gen_int_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 4137 assert(node->type == NodeTypeIntLiteral); 4138 4139 return ir_build_const_bigint(irb, scope, node, node->data.int_literal.bigint); 4140 } 4141 4142 static IrInstruction *ir_gen_float_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 4143 assert(node->type == NodeTypeFloatLiteral); 4144 4145 if (node->data.float_literal.overflow) { 4146 add_node_error(irb->codegen, node, buf_sprintf("float literal out of range of any type")); 4147 return irb->codegen->invalid_instruction; 4148 } 4149 4150 return ir_build_const_bigfloat(irb, scope, node, node->data.float_literal.bigfloat); 4151 } 4152 4153 static IrInstruction *ir_gen_char_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 4154 assert(node->type == NodeTypeCharLiteral); 4155 4156 return ir_build_const_uint(irb, scope, node, node->data.char_literal.value); 4157 } 4158 4159 static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 4160 assert(node->type == NodeTypeNullLiteral); 4161 4162 return ir_build_const_null(irb, scope, node); 4163 } 4164 4165 static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode *node, Buf *var_name) { 4166 ScopeDecls *scope_decls = nullptr; 4167 while (scope != nullptr) { 4168 if (scope->id == ScopeIdDecls) { 4169 scope_decls = reinterpret_cast<ScopeDecls *>(scope); 4170 } 4171 scope = scope->parent; 4172 } 4173 TldVar *tld_var = allocate<TldVar>(1); 4174 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); 4175 tld_var->base.resolution = TldResolutionInvalid; 4176 tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, 4177 &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid); 4178 scope_decls->decl_table.put(var_name, &tld_var->base); 4179 } 4180 4181 static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 4182 Error err; 4183 assert(node->type == NodeTypeSymbol); 4184 4185 Buf *variable_name = node->data.symbol_expr.symbol; 4186 4187 if (buf_eql_str(variable_name, "_")) { 4188 if (lval == LValPtr) { 4189 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node); 4190 const_instruction->base.value.type = get_pointer_to_type(irb->codegen, 4191 irb->codegen->builtin_types.entry_void, false); 4192 const_instruction->base.value.special = ConstValSpecialStatic; 4193 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard; 4194 return &const_instruction->base; 4195 } else { 4196 add_node_error(irb->codegen, node, buf_sprintf("`_` may only be used to assign things to")); 4197 return irb->codegen->invalid_instruction; 4198 } 4199 } 4200 4201 ZigType *primitive_type; 4202 if ((err = get_primitive_type(irb->codegen, variable_name, &primitive_type))) { 4203 if (err == ErrorOverflow) { 4204 add_node_error(irb->codegen, node, 4205 buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535", 4206 buf_ptr(variable_name))); 4207 return irb->codegen->invalid_instruction; 4208 } 4209 assert(err == ErrorPrimitiveTypeNotFound); 4210 } else { 4211 IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_type); 4212 if (lval == LValPtr) { 4213 return ir_build_ref(irb, scope, node, value, false, false); 4214 } else { 4215 return ir_expr_wrap(irb, scope, value, result_loc); 4216 } 4217 } 4218 4219 ScopeFnDef *crossed_fndef_scope; 4220 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); 4221 if (var) { 4222 IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); 4223 if (lval == LValPtr) { 4224 return var_ptr; 4225 } else { 4226 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, var_ptr), result_loc); 4227 } 4228 } 4229 4230 Tld *tld = find_decl(irb->codegen, scope, variable_name); 4231 if (tld) { 4232 IrInstruction *decl_ref = ir_build_decl_ref(irb, scope, node, tld, lval); 4233 if (lval == LValPtr) { 4234 return decl_ref; 4235 } else { 4236 return ir_expr_wrap(irb, scope, decl_ref, result_loc); 4237 } 4238 } 4239 4240 if (get_container_scope(node->owner)->any_imports_failed) { 4241 // skip the error message since we had a failing import in this file 4242 // if an import breaks we don't need redundant undeclared identifier errors 4243 return irb->codegen->invalid_instruction; 4244 } 4245 4246 return ir_build_undeclared_identifier(irb, scope, node, variable_name); 4247 } 4248 4249 static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 4250 ResultLoc *result_loc) 4251 { 4252 assert(node->type == NodeTypeArrayAccessExpr); 4253 4254 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; 4255 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr); 4256 if (array_ref_instruction == irb->codegen->invalid_instruction) 4257 return array_ref_instruction; 4258 4259 AstNode *subscript_node = node->data.array_access_expr.subscript; 4260 IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, scope); 4261 if (subscript_instruction == irb->codegen->invalid_instruction) 4262 return subscript_instruction; 4263 4264 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, 4265 subscript_instruction, true, PtrLenSingle, nullptr); 4266 if (lval == LValPtr) 4267 return ptr_instruction; 4268 4269 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 4270 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 4271 } 4272 4273 static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) { 4274 assert(node->type == NodeTypeFieldAccessExpr); 4275 4276 AstNode *container_ref_node = node->data.field_access_expr.struct_expr; 4277 Buf *field_name = node->data.field_access_expr.field_name; 4278 4279 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr); 4280 if (container_ref_instruction == irb->codegen->invalid_instruction) 4281 return container_ref_instruction; 4282 4283 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name, false); 4284 } 4285 4286 static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) { 4287 assert(node->type == NodeTypeFnCallExpr); 4288 4289 AstNode *type_node = node->data.fn_call_expr.params.at(0); 4290 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 4291 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 4292 AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3); 4293 4294 4295 IrInstruction *type_value = ir_gen_node(irb, type_node, scope); 4296 if (type_value == irb->codegen->invalid_instruction) 4297 return irb->codegen->invalid_instruction; 4298 4299 IrInstruction *op1 = ir_gen_node(irb, op1_node, scope); 4300 if (op1 == irb->codegen->invalid_instruction) 4301 return irb->codegen->invalid_instruction; 4302 4303 IrInstruction *op2 = ir_gen_node(irb, op2_node, scope); 4304 if (op2 == irb->codegen->invalid_instruction) 4305 return irb->codegen->invalid_instruction; 4306 4307 IrInstruction *result_ptr = ir_gen_node(irb, result_ptr_node, scope); 4308 if (result_ptr == irb->codegen->invalid_instruction) 4309 return irb->codegen->invalid_instruction; 4310 4311 return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr); 4312 } 4313 4314 static IrInstruction *ir_gen_mul_add(IrBuilder *irb, Scope *scope, AstNode *node) { 4315 assert(node->type == NodeTypeFnCallExpr); 4316 4317 AstNode *type_node = node->data.fn_call_expr.params.at(0); 4318 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 4319 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 4320 AstNode *op3_node = node->data.fn_call_expr.params.at(3); 4321 4322 IrInstruction *type_value = ir_gen_node(irb, type_node, scope); 4323 if (type_value == irb->codegen->invalid_instruction) 4324 return irb->codegen->invalid_instruction; 4325 4326 IrInstruction *op1 = ir_gen_node(irb, op1_node, scope); 4327 if (op1 == irb->codegen->invalid_instruction) 4328 return irb->codegen->invalid_instruction; 4329 4330 IrInstruction *op2 = ir_gen_node(irb, op2_node, scope); 4331 if (op2 == irb->codegen->invalid_instruction) 4332 return irb->codegen->invalid_instruction; 4333 4334 IrInstruction *op3 = ir_gen_node(irb, op3_node, scope); 4335 if (op3 == irb->codegen->invalid_instruction) 4336 return irb->codegen->invalid_instruction; 4337 4338 return ir_build_mul_add(irb, scope, node, type_value, op1, op2, op3); 4339 } 4340 4341 static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *node) { 4342 for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) { 4343 if (it_scope->id == ScopeIdDecls) { 4344 ScopeDecls *decls_scope = (ScopeDecls *)it_scope; 4345 ZigType *container_type = decls_scope->container_type; 4346 if (container_type != nullptr) { 4347 return ir_build_const_type(irb, orig_scope, node, container_type); 4348 } else { 4349 return ir_build_const_import(irb, orig_scope, node, decls_scope->import); 4350 } 4351 } 4352 } 4353 zig_unreachable(); 4354 } 4355 4356 static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 4357 ResultLoc *result_loc) 4358 { 4359 assert(node->type == NodeTypeFnCallExpr); 4360 4361 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; 4362 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 4363 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 4364 4365 if (!entry) { // new built in not found 4366 add_node_error(irb->codegen, node, 4367 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name))); 4368 return irb->codegen->invalid_instruction; 4369 } 4370 4371 BuiltinFnEntry *builtin_fn = entry->value; 4372 size_t actual_param_count = node->data.fn_call_expr.params.length; 4373 4374 if (builtin_fn->param_count != SIZE_MAX && builtin_fn->param_count != actual_param_count) { 4375 add_node_error(irb->codegen, node, 4376 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 4377 builtin_fn->param_count, actual_param_count)); 4378 return irb->codegen->invalid_instruction; 4379 } 4380 4381 switch (builtin_fn->id) { 4382 case BuiltinFnIdInvalid: 4383 zig_unreachable(); 4384 case BuiltinFnIdTypeof: 4385 { 4386 AstNode *arg_node = node->data.fn_call_expr.params.at(0); 4387 IrInstruction *arg = ir_gen_node(irb, arg_node, scope); 4388 if (arg == irb->codegen->invalid_instruction) 4389 return arg; 4390 4391 IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); 4392 return ir_lval_wrap(irb, scope, type_of, lval, result_loc); 4393 } 4394 case BuiltinFnIdSetCold: 4395 { 4396 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4397 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4398 if (arg0_value == irb->codegen->invalid_instruction) 4399 return arg0_value; 4400 4401 IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); 4402 return ir_lval_wrap(irb, scope, set_cold, lval, result_loc); 4403 } 4404 case BuiltinFnIdSetRuntimeSafety: 4405 { 4406 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4407 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4408 if (arg0_value == irb->codegen->invalid_instruction) 4409 return arg0_value; 4410 4411 IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); 4412 return ir_lval_wrap(irb, scope, set_safety, lval, result_loc); 4413 } 4414 case BuiltinFnIdSetFloatMode: 4415 { 4416 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4417 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4418 if (arg0_value == irb->codegen->invalid_instruction) 4419 return arg0_value; 4420 4421 IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); 4422 return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc); 4423 } 4424 case BuiltinFnIdSizeof: 4425 { 4426 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4427 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4428 if (arg0_value == irb->codegen->invalid_instruction) 4429 return arg0_value; 4430 4431 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); 4432 return ir_lval_wrap(irb, scope, size_of, lval, result_loc); 4433 } 4434 case BuiltinFnIdImport: 4435 { 4436 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4437 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4438 if (arg0_value == irb->codegen->invalid_instruction) 4439 return arg0_value; 4440 4441 IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); 4442 return ir_lval_wrap(irb, scope, import, lval, result_loc); 4443 } 4444 case BuiltinFnIdCImport: 4445 { 4446 IrInstruction *c_import = ir_build_c_import(irb, scope, node); 4447 return ir_lval_wrap(irb, scope, c_import, lval, result_loc); 4448 } 4449 case BuiltinFnIdCInclude: 4450 { 4451 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4452 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4453 if (arg0_value == irb->codegen->invalid_instruction) 4454 return arg0_value; 4455 4456 if (!exec_c_import_buf(irb->exec)) { 4457 add_node_error(irb->codegen, node, buf_sprintf("C include valid only inside C import block")); 4458 return irb->codegen->invalid_instruction; 4459 } 4460 4461 IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value); 4462 return ir_lval_wrap(irb, scope, c_include, lval, result_loc); 4463 } 4464 case BuiltinFnIdCDefine: 4465 { 4466 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4467 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4468 if (arg0_value == irb->codegen->invalid_instruction) 4469 return arg0_value; 4470 4471 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4472 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4473 if (arg1_value == irb->codegen->invalid_instruction) 4474 return arg1_value; 4475 4476 if (!exec_c_import_buf(irb->exec)) { 4477 add_node_error(irb->codegen, node, buf_sprintf("C define valid only inside C import block")); 4478 return irb->codegen->invalid_instruction; 4479 } 4480 4481 IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); 4482 return ir_lval_wrap(irb, scope, c_define, lval, result_loc); 4483 } 4484 case BuiltinFnIdCUndef: 4485 { 4486 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4487 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4488 if (arg0_value == irb->codegen->invalid_instruction) 4489 return arg0_value; 4490 4491 if (!exec_c_import_buf(irb->exec)) { 4492 add_node_error(irb->codegen, node, buf_sprintf("C undef valid only inside C import block")); 4493 return irb->codegen->invalid_instruction; 4494 } 4495 4496 IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); 4497 return ir_lval_wrap(irb, scope, c_undef, lval, result_loc); 4498 } 4499 case BuiltinFnIdCompileErr: 4500 { 4501 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4502 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4503 if (arg0_value == irb->codegen->invalid_instruction) 4504 return arg0_value; 4505 4506 IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); 4507 return ir_lval_wrap(irb, scope, compile_err, lval, result_loc); 4508 } 4509 case BuiltinFnIdCompileLog: 4510 { 4511 IrInstruction **args = allocate<IrInstruction*>(actual_param_count); 4512 4513 for (size_t i = 0; i < actual_param_count; i += 1) { 4514 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 4515 args[i] = ir_gen_node(irb, arg_node, scope); 4516 if (args[i] == irb->codegen->invalid_instruction) 4517 return irb->codegen->invalid_instruction; 4518 } 4519 4520 IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); 4521 return ir_lval_wrap(irb, scope, compile_log, lval, result_loc); 4522 } 4523 case BuiltinFnIdErrName: 4524 { 4525 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4526 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4527 if (arg0_value == irb->codegen->invalid_instruction) 4528 return arg0_value; 4529 4530 IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value); 4531 return ir_lval_wrap(irb, scope, err_name, lval, result_loc); 4532 } 4533 case BuiltinFnIdEmbedFile: 4534 { 4535 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4536 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4537 if (arg0_value == irb->codegen->invalid_instruction) 4538 return arg0_value; 4539 4540 IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); 4541 return ir_lval_wrap(irb, scope, embed_file, lval, result_loc); 4542 } 4543 case BuiltinFnIdCmpxchgWeak: 4544 case BuiltinFnIdCmpxchgStrong: 4545 { 4546 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4547 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4548 if (arg0_value == irb->codegen->invalid_instruction) 4549 return arg0_value; 4550 4551 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4552 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4553 if (arg1_value == irb->codegen->invalid_instruction) 4554 return arg1_value; 4555 4556 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4557 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4558 if (arg2_value == irb->codegen->invalid_instruction) 4559 return arg2_value; 4560 4561 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 4562 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 4563 if (arg3_value == irb->codegen->invalid_instruction) 4564 return arg3_value; 4565 4566 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 4567 IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); 4568 if (arg4_value == irb->codegen->invalid_instruction) 4569 return arg4_value; 4570 4571 AstNode *arg5_node = node->data.fn_call_expr.params.at(5); 4572 IrInstruction *arg5_value = ir_gen_node(irb, arg5_node, scope); 4573 if (arg5_value == irb->codegen->invalid_instruction) 4574 return arg5_value; 4575 4576 IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, 4577 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak), 4578 result_loc); 4579 return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc); 4580 } 4581 case BuiltinFnIdFence: 4582 { 4583 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4584 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4585 if (arg0_value == irb->codegen->invalid_instruction) 4586 return arg0_value; 4587 4588 IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); 4589 return ir_lval_wrap(irb, scope, fence, lval, result_loc); 4590 } 4591 case BuiltinFnIdDivExact: 4592 { 4593 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4594 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4595 if (arg0_value == irb->codegen->invalid_instruction) 4596 return arg0_value; 4597 4598 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4599 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4600 if (arg1_value == irb->codegen->invalid_instruction) 4601 return arg1_value; 4602 4603 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); 4604 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 4605 } 4606 case BuiltinFnIdDivTrunc: 4607 { 4608 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4609 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4610 if (arg0_value == irb->codegen->invalid_instruction) 4611 return arg0_value; 4612 4613 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4614 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4615 if (arg1_value == irb->codegen->invalid_instruction) 4616 return arg1_value; 4617 4618 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); 4619 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 4620 } 4621 case BuiltinFnIdDivFloor: 4622 { 4623 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4624 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4625 if (arg0_value == irb->codegen->invalid_instruction) 4626 return arg0_value; 4627 4628 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4629 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4630 if (arg1_value == irb->codegen->invalid_instruction) 4631 return arg1_value; 4632 4633 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); 4634 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 4635 } 4636 case BuiltinFnIdRem: 4637 { 4638 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4639 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4640 if (arg0_value == irb->codegen->invalid_instruction) 4641 return arg0_value; 4642 4643 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4644 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4645 if (arg1_value == irb->codegen->invalid_instruction) 4646 return arg1_value; 4647 4648 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); 4649 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 4650 } 4651 case BuiltinFnIdMod: 4652 { 4653 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4654 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4655 if (arg0_value == irb->codegen->invalid_instruction) 4656 return arg0_value; 4657 4658 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4659 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4660 if (arg1_value == irb->codegen->invalid_instruction) 4661 return arg1_value; 4662 4663 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); 4664 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 4665 } 4666 case BuiltinFnIdSqrt: 4667 case BuiltinFnIdSin: 4668 case BuiltinFnIdCos: 4669 case BuiltinFnIdExp: 4670 case BuiltinFnIdExp2: 4671 case BuiltinFnIdLn: 4672 case BuiltinFnIdLog2: 4673 case BuiltinFnIdLog10: 4674 case BuiltinFnIdFabs: 4675 case BuiltinFnIdFloor: 4676 case BuiltinFnIdCeil: 4677 case BuiltinFnIdTrunc: 4678 case BuiltinFnIdNearbyInt: 4679 case BuiltinFnIdRound: 4680 { 4681 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4682 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4683 if (arg0_value == irb->codegen->invalid_instruction) 4684 return arg0_value; 4685 4686 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4687 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4688 if (arg1_value == irb->codegen->invalid_instruction) 4689 return arg1_value; 4690 4691 IrInstruction *ir_sqrt = ir_build_float_op(irb, scope, node, arg0_value, arg1_value, builtin_fn->id); 4692 return ir_lval_wrap(irb, scope, ir_sqrt, lval, result_loc); 4693 } 4694 case BuiltinFnIdTruncate: 4695 { 4696 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4697 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4698 if (arg0_value == irb->codegen->invalid_instruction) 4699 return arg0_value; 4700 4701 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4702 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4703 if (arg1_value == irb->codegen->invalid_instruction) 4704 return arg1_value; 4705 4706 IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); 4707 return ir_lval_wrap(irb, scope, truncate, lval, result_loc); 4708 } 4709 case BuiltinFnIdIntCast: 4710 { 4711 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4712 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4713 if (arg0_value == irb->codegen->invalid_instruction) 4714 return arg0_value; 4715 4716 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4717 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4718 if (arg1_value == irb->codegen->invalid_instruction) 4719 return arg1_value; 4720 4721 IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); 4722 return ir_lval_wrap(irb, scope, result, lval, result_loc); 4723 } 4724 case BuiltinFnIdFloatCast: 4725 { 4726 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4727 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4728 if (arg0_value == irb->codegen->invalid_instruction) 4729 return arg0_value; 4730 4731 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4732 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4733 if (arg1_value == irb->codegen->invalid_instruction) 4734 return arg1_value; 4735 4736 IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); 4737 return ir_lval_wrap(irb, scope, result, lval, result_loc); 4738 } 4739 case BuiltinFnIdErrSetCast: 4740 { 4741 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4742 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4743 if (arg0_value == irb->codegen->invalid_instruction) 4744 return arg0_value; 4745 4746 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4747 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4748 if (arg1_value == irb->codegen->invalid_instruction) 4749 return arg1_value; 4750 4751 IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); 4752 return ir_lval_wrap(irb, scope, result, lval, result_loc); 4753 } 4754 case BuiltinFnIdFromBytes: 4755 { 4756 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4757 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4758 if (arg0_value == irb->codegen->invalid_instruction) 4759 return arg0_value; 4760 4761 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4762 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4763 if (arg1_value == irb->codegen->invalid_instruction) 4764 return arg1_value; 4765 4766 IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc); 4767 return ir_lval_wrap(irb, scope, result, lval, result_loc); 4768 } 4769 case BuiltinFnIdToBytes: 4770 { 4771 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4772 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4773 if (arg0_value == irb->codegen->invalid_instruction) 4774 return arg0_value; 4775 4776 IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc); 4777 return ir_lval_wrap(irb, scope, result, lval, result_loc); 4778 } 4779 case BuiltinFnIdIntToFloat: 4780 { 4781 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4782 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4783 if (arg0_value == irb->codegen->invalid_instruction) 4784 return arg0_value; 4785 4786 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4787 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4788 if (arg1_value == irb->codegen->invalid_instruction) 4789 return arg1_value; 4790 4791 IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); 4792 return ir_lval_wrap(irb, scope, result, lval, result_loc); 4793 } 4794 case BuiltinFnIdFloatToInt: 4795 { 4796 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4797 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4798 if (arg0_value == irb->codegen->invalid_instruction) 4799 return arg0_value; 4800 4801 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4802 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4803 if (arg1_value == irb->codegen->invalid_instruction) 4804 return arg1_value; 4805 4806 IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); 4807 return ir_lval_wrap(irb, scope, result, lval, result_loc); 4808 } 4809 case BuiltinFnIdErrToInt: 4810 { 4811 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4812 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4813 if (arg0_value == irb->codegen->invalid_instruction) 4814 return arg0_value; 4815 4816 IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value); 4817 return ir_lval_wrap(irb, scope, result, lval, result_loc); 4818 } 4819 case BuiltinFnIdIntToErr: 4820 { 4821 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4822 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4823 if (arg0_value == irb->codegen->invalid_instruction) 4824 return arg0_value; 4825 4826 IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value); 4827 return ir_lval_wrap(irb, scope, result, lval, result_loc); 4828 } 4829 case BuiltinFnIdBoolToInt: 4830 { 4831 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4832 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4833 if (arg0_value == irb->codegen->invalid_instruction) 4834 return arg0_value; 4835 4836 IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value); 4837 return ir_lval_wrap(irb, scope, result, lval, result_loc); 4838 } 4839 case BuiltinFnIdIntType: 4840 { 4841 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4842 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4843 if (arg0_value == irb->codegen->invalid_instruction) 4844 return arg0_value; 4845 4846 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4847 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4848 if (arg1_value == irb->codegen->invalid_instruction) 4849 return arg1_value; 4850 4851 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); 4852 return ir_lval_wrap(irb, scope, int_type, lval, result_loc); 4853 } 4854 case BuiltinFnIdVectorType: 4855 { 4856 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4857 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4858 if (arg0_value == irb->codegen->invalid_instruction) 4859 return arg0_value; 4860 4861 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4862 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4863 if (arg1_value == irb->codegen->invalid_instruction) 4864 return arg1_value; 4865 4866 IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); 4867 return ir_lval_wrap(irb, scope, vector_type, lval, result_loc); 4868 } 4869 case BuiltinFnIdMemcpy: 4870 { 4871 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4872 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4873 if (arg0_value == irb->codegen->invalid_instruction) 4874 return arg0_value; 4875 4876 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4877 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4878 if (arg1_value == irb->codegen->invalid_instruction) 4879 return arg1_value; 4880 4881 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4882 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4883 if (arg2_value == irb->codegen->invalid_instruction) 4884 return arg2_value; 4885 4886 IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value); 4887 return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc); 4888 } 4889 case BuiltinFnIdMemset: 4890 { 4891 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4892 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4893 if (arg0_value == irb->codegen->invalid_instruction) 4894 return arg0_value; 4895 4896 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4897 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4898 if (arg1_value == irb->codegen->invalid_instruction) 4899 return arg1_value; 4900 4901 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4902 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4903 if (arg2_value == irb->codegen->invalid_instruction) 4904 return arg2_value; 4905 4906 IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value); 4907 return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc); 4908 } 4909 case BuiltinFnIdMemberCount: 4910 { 4911 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4912 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4913 if (arg0_value == irb->codegen->invalid_instruction) 4914 return arg0_value; 4915 4916 IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value); 4917 return ir_lval_wrap(irb, scope, member_count, lval, result_loc); 4918 } 4919 case BuiltinFnIdMemberType: 4920 { 4921 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4922 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4923 if (arg0_value == irb->codegen->invalid_instruction) 4924 return arg0_value; 4925 4926 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4927 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4928 if (arg1_value == irb->codegen->invalid_instruction) 4929 return arg1_value; 4930 4931 4932 IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value); 4933 return ir_lval_wrap(irb, scope, member_type, lval, result_loc); 4934 } 4935 case BuiltinFnIdMemberName: 4936 { 4937 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4938 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4939 if (arg0_value == irb->codegen->invalid_instruction) 4940 return arg0_value; 4941 4942 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4943 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4944 if (arg1_value == irb->codegen->invalid_instruction) 4945 return arg1_value; 4946 4947 4948 IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value); 4949 return ir_lval_wrap(irb, scope, member_name, lval, result_loc); 4950 } 4951 case BuiltinFnIdField: 4952 { 4953 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4954 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr); 4955 if (arg0_value == irb->codegen->invalid_instruction) 4956 return arg0_value; 4957 4958 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4959 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4960 if (arg1_value == irb->codegen->invalid_instruction) 4961 return arg1_value; 4962 4963 IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, 4964 arg0_value, arg1_value, false); 4965 4966 if (lval == LValPtr) 4967 return ptr_instruction; 4968 4969 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 4970 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 4971 } 4972 case BuiltinFnIdHasField: 4973 { 4974 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4975 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4976 if (arg0_value == irb->codegen->invalid_instruction) 4977 return arg0_value; 4978 4979 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4980 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4981 if (arg1_value == irb->codegen->invalid_instruction) 4982 return arg1_value; 4983 4984 IrInstruction *type_info = ir_build_has_field(irb, scope, node, arg0_value, arg1_value); 4985 return ir_lval_wrap(irb, scope, type_info, lval, result_loc); 4986 } 4987 case BuiltinFnIdTypeInfo: 4988 { 4989 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4990 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4991 if (arg0_value == irb->codegen->invalid_instruction) 4992 return arg0_value; 4993 4994 IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); 4995 return ir_lval_wrap(irb, scope, type_info, lval, result_loc); 4996 } 4997 case BuiltinFnIdBreakpoint: 4998 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc); 4999 case BuiltinFnIdReturnAddress: 5000 return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval, result_loc); 5001 case BuiltinFnIdFrameAddress: 5002 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval, result_loc); 5003 case BuiltinFnIdFrameHandle: 5004 if (!irb->exec->fn_entry) { 5005 add_node_error(irb->codegen, node, buf_sprintf("@frame() called outside of function definition")); 5006 return irb->codegen->invalid_instruction; 5007 } 5008 return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval, result_loc); 5009 case BuiltinFnIdFrameType: { 5010 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5011 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5012 if (arg0_value == irb->codegen->invalid_instruction) 5013 return arg0_value; 5014 5015 IrInstruction *frame_type = ir_build_frame_type(irb, scope, node, arg0_value); 5016 return ir_lval_wrap(irb, scope, frame_type, lval, result_loc); 5017 } 5018 case BuiltinFnIdFrameSize: { 5019 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5020 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5021 if (arg0_value == irb->codegen->invalid_instruction) 5022 return arg0_value; 5023 5024 IrInstruction *frame_size = ir_build_frame_size_src(irb, scope, node, arg0_value); 5025 return ir_lval_wrap(irb, scope, frame_size, lval, result_loc); 5026 } 5027 case BuiltinFnIdAlignOf: 5028 { 5029 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5030 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5031 if (arg0_value == irb->codegen->invalid_instruction) 5032 return arg0_value; 5033 5034 IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value); 5035 return ir_lval_wrap(irb, scope, align_of, lval, result_loc); 5036 } 5037 case BuiltinFnIdAddWithOverflow: 5038 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval, result_loc); 5039 case BuiltinFnIdSubWithOverflow: 5040 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval, result_loc); 5041 case BuiltinFnIdMulWithOverflow: 5042 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval, result_loc); 5043 case BuiltinFnIdShlWithOverflow: 5044 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval, result_loc); 5045 case BuiltinFnIdMulAdd: 5046 return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc); 5047 case BuiltinFnIdTypeName: 5048 { 5049 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5050 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5051 if (arg0_value == irb->codegen->invalid_instruction) 5052 return arg0_value; 5053 5054 IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value); 5055 return ir_lval_wrap(irb, scope, type_name, lval, result_loc); 5056 } 5057 case BuiltinFnIdPanic: 5058 { 5059 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5060 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5061 if (arg0_value == irb->codegen->invalid_instruction) 5062 return arg0_value; 5063 5064 IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); 5065 return ir_lval_wrap(irb, scope, panic, lval, result_loc); 5066 } 5067 case BuiltinFnIdPtrCast: 5068 { 5069 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5070 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5071 if (arg0_value == irb->codegen->invalid_instruction) 5072 return arg0_value; 5073 5074 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5075 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5076 if (arg1_value == irb->codegen->invalid_instruction) 5077 return arg1_value; 5078 5079 IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); 5080 return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc); 5081 } 5082 case BuiltinFnIdBitCast: 5083 { 5084 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); 5085 IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope); 5086 if (dest_type == irb->codegen->invalid_instruction) 5087 return dest_type; 5088 5089 ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1); 5090 result_loc_bit_cast->base.id = ResultLocIdBitCast; 5091 result_loc_bit_cast->base.source_instruction = dest_type; 5092 ir_ref_instruction(dest_type, irb->current_basic_block); 5093 result_loc_bit_cast->parent = result_loc; 5094 5095 ir_build_reset_result(irb, scope, node, &result_loc_bit_cast->base); 5096 5097 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5098 IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, 5099 &result_loc_bit_cast->base); 5100 if (arg1_value == irb->codegen->invalid_instruction) 5101 return arg1_value; 5102 5103 IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast); 5104 return ir_lval_wrap(irb, scope, bitcast, lval, result_loc); 5105 } 5106 case BuiltinFnIdIntToPtr: 5107 { 5108 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5109 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5110 if (arg0_value == irb->codegen->invalid_instruction) 5111 return arg0_value; 5112 5113 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5114 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5115 if (arg1_value == irb->codegen->invalid_instruction) 5116 return arg1_value; 5117 5118 IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value); 5119 return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc); 5120 } 5121 case BuiltinFnIdPtrToInt: 5122 { 5123 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5124 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5125 if (arg0_value == irb->codegen->invalid_instruction) 5126 return arg0_value; 5127 5128 IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value); 5129 return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc); 5130 } 5131 case BuiltinFnIdTagName: 5132 { 5133 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5134 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5135 if (arg0_value == irb->codegen->invalid_instruction) 5136 return arg0_value; 5137 5138 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value); 5139 IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag); 5140 return ir_lval_wrap(irb, scope, tag_name, lval, result_loc); 5141 } 5142 case BuiltinFnIdTagType: 5143 { 5144 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5145 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5146 if (arg0_value == irb->codegen->invalid_instruction) 5147 return arg0_value; 5148 5149 IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); 5150 return ir_lval_wrap(irb, scope, tag_type, lval, result_loc); 5151 } 5152 case BuiltinFnIdFieldParentPtr: 5153 { 5154 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5155 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5156 if (arg0_value == irb->codegen->invalid_instruction) 5157 return arg0_value; 5158 5159 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5160 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5161 if (arg1_value == irb->codegen->invalid_instruction) 5162 return arg1_value; 5163 5164 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5165 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5166 if (arg2_value == irb->codegen->invalid_instruction) 5167 return arg2_value; 5168 5169 IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr); 5170 return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc); 5171 } 5172 case BuiltinFnIdByteOffsetOf: 5173 { 5174 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5175 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5176 if (arg0_value == irb->codegen->invalid_instruction) 5177 return arg0_value; 5178 5179 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5180 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5181 if (arg1_value == irb->codegen->invalid_instruction) 5182 return arg1_value; 5183 5184 IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); 5185 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); 5186 } 5187 case BuiltinFnIdBitOffsetOf: 5188 { 5189 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5190 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5191 if (arg0_value == irb->codegen->invalid_instruction) 5192 return arg0_value; 5193 5194 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5195 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5196 if (arg1_value == irb->codegen->invalid_instruction) 5197 return arg1_value; 5198 5199 IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); 5200 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); 5201 } 5202 case BuiltinFnIdInlineCall: 5203 case BuiltinFnIdNoInlineCall: 5204 { 5205 if (node->data.fn_call_expr.params.length == 0) { 5206 add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0")); 5207 return irb->codegen->invalid_instruction; 5208 } 5209 5210 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(0); 5211 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 5212 if (fn_ref == irb->codegen->invalid_instruction) 5213 return fn_ref; 5214 5215 size_t arg_count = node->data.fn_call_expr.params.length - 1; 5216 5217 IrInstruction **args = allocate<IrInstruction*>(arg_count); 5218 for (size_t i = 0; i < arg_count; i += 1) { 5219 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 1); 5220 args[i] = ir_gen_node(irb, arg_node, scope); 5221 if (args[i] == irb->codegen->invalid_instruction) 5222 return args[i]; 5223 } 5224 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; 5225 5226 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, 5227 fn_inline, false, nullptr, result_loc); 5228 return ir_lval_wrap(irb, scope, call, lval, result_loc); 5229 } 5230 case BuiltinFnIdNewStackCall: 5231 { 5232 if (node->data.fn_call_expr.params.length < 2) { 5233 add_node_error(irb->codegen, node, 5234 buf_sprintf("expected at least 2 arguments, found %" ZIG_PRI_usize, 5235 node->data.fn_call_expr.params.length)); 5236 return irb->codegen->invalid_instruction; 5237 } 5238 5239 AstNode *new_stack_node = node->data.fn_call_expr.params.at(0); 5240 IrInstruction *new_stack = ir_gen_node(irb, new_stack_node, scope); 5241 if (new_stack == irb->codegen->invalid_instruction) 5242 return new_stack; 5243 5244 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); 5245 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 5246 if (fn_ref == irb->codegen->invalid_instruction) 5247 return fn_ref; 5248 5249 size_t arg_count = node->data.fn_call_expr.params.length - 2; 5250 5251 IrInstruction **args = allocate<IrInstruction*>(arg_count); 5252 for (size_t i = 0; i < arg_count; i += 1) { 5253 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 2); 5254 args[i] = ir_gen_node(irb, arg_node, scope); 5255 if (args[i] == irb->codegen->invalid_instruction) 5256 return args[i]; 5257 } 5258 5259 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, 5260 FnInlineAuto, false, new_stack, result_loc); 5261 return ir_lval_wrap(irb, scope, call, lval, result_loc); 5262 } 5263 case BuiltinFnIdAsyncCall: 5264 { 5265 size_t arg_offset = 3; 5266 if (node->data.fn_call_expr.params.length < arg_offset) { 5267 add_node_error(irb->codegen, node, 5268 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 5269 arg_offset, node->data.fn_call_expr.params.length)); 5270 return irb->codegen->invalid_instruction; 5271 } 5272 5273 AstNode *bytes_node = node->data.fn_call_expr.params.at(0); 5274 IrInstruction *bytes = ir_gen_node(irb, bytes_node, scope); 5275 if (bytes == irb->codegen->invalid_instruction) 5276 return bytes; 5277 5278 AstNode *ret_ptr_node = node->data.fn_call_expr.params.at(1); 5279 IrInstruction *ret_ptr = ir_gen_node(irb, ret_ptr_node, scope); 5280 if (ret_ptr == irb->codegen->invalid_instruction) 5281 return ret_ptr; 5282 5283 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(2); 5284 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 5285 if (fn_ref == irb->codegen->invalid_instruction) 5286 return fn_ref; 5287 5288 size_t arg_count = node->data.fn_call_expr.params.length - arg_offset; 5289 5290 // last "arg" is return pointer 5291 IrInstruction **args = allocate<IrInstruction*>(arg_count + 1); 5292 5293 for (size_t i = 0; i < arg_count; i += 1) { 5294 AstNode *arg_node = node->data.fn_call_expr.params.at(i + arg_offset); 5295 IrInstruction *arg = ir_gen_node(irb, arg_node, scope); 5296 if (arg == irb->codegen->invalid_instruction) 5297 return arg; 5298 args[i] = arg; 5299 } 5300 5301 args[arg_count] = ret_ptr; 5302 5303 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, 5304 FnInlineAuto, true, bytes, result_loc); 5305 return ir_lval_wrap(irb, scope, call, lval, result_loc); 5306 } 5307 case BuiltinFnIdTypeId: 5308 { 5309 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5310 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5311 if (arg0_value == irb->codegen->invalid_instruction) 5312 return arg0_value; 5313 5314 IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value); 5315 return ir_lval_wrap(irb, scope, type_id, lval, result_loc); 5316 } 5317 case BuiltinFnIdShlExact: 5318 { 5319 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5320 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5321 if (arg0_value == irb->codegen->invalid_instruction) 5322 return arg0_value; 5323 5324 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5325 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5326 if (arg1_value == irb->codegen->invalid_instruction) 5327 return arg1_value; 5328 5329 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); 5330 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 5331 } 5332 case BuiltinFnIdShrExact: 5333 { 5334 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5335 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5336 if (arg0_value == irb->codegen->invalid_instruction) 5337 return arg0_value; 5338 5339 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5340 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5341 if (arg1_value == irb->codegen->invalid_instruction) 5342 return arg1_value; 5343 5344 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); 5345 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 5346 } 5347 case BuiltinFnIdSetEvalBranchQuota: 5348 { 5349 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5350 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5351 if (arg0_value == irb->codegen->invalid_instruction) 5352 return arg0_value; 5353 5354 IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); 5355 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval, result_loc); 5356 } 5357 case BuiltinFnIdAlignCast: 5358 { 5359 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5360 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5361 if (arg0_value == irb->codegen->invalid_instruction) 5362 return arg0_value; 5363 5364 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5365 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5366 if (arg1_value == irb->codegen->invalid_instruction) 5367 return arg1_value; 5368 5369 IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value); 5370 return ir_lval_wrap(irb, scope, align_cast, lval, result_loc); 5371 } 5372 case BuiltinFnIdOpaqueType: 5373 { 5374 IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); 5375 return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc); 5376 } 5377 case BuiltinFnIdThis: 5378 { 5379 IrInstruction *this_inst = ir_gen_this(irb, scope, node); 5380 return ir_lval_wrap(irb, scope, this_inst, lval, result_loc); 5381 } 5382 case BuiltinFnIdSetAlignStack: 5383 { 5384 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5385 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5386 if (arg0_value == irb->codegen->invalid_instruction) 5387 return arg0_value; 5388 5389 IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); 5390 return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc); 5391 } 5392 case BuiltinFnIdArgType: 5393 { 5394 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5395 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5396 if (arg0_value == irb->codegen->invalid_instruction) 5397 return arg0_value; 5398 5399 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5400 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5401 if (arg1_value == irb->codegen->invalid_instruction) 5402 return arg1_value; 5403 5404 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); 5405 return ir_lval_wrap(irb, scope, arg_type, lval, result_loc); 5406 } 5407 case BuiltinFnIdExport: 5408 { 5409 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5410 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5411 if (arg0_value == irb->codegen->invalid_instruction) 5412 return arg0_value; 5413 5414 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5415 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5416 if (arg1_value == irb->codegen->invalid_instruction) 5417 return arg1_value; 5418 5419 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5420 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5421 if (arg2_value == irb->codegen->invalid_instruction) 5422 return arg2_value; 5423 5424 IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); 5425 return ir_lval_wrap(irb, scope, ir_export, lval, result_loc); 5426 } 5427 case BuiltinFnIdErrorReturnTrace: 5428 { 5429 IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null); 5430 return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc); 5431 } 5432 case BuiltinFnIdAtomicRmw: 5433 { 5434 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5435 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5436 if (arg0_value == irb->codegen->invalid_instruction) 5437 return arg0_value; 5438 5439 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5440 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5441 if (arg1_value == irb->codegen->invalid_instruction) 5442 return arg1_value; 5443 5444 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5445 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5446 if (arg2_value == irb->codegen->invalid_instruction) 5447 return arg2_value; 5448 5449 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 5450 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 5451 if (arg3_value == irb->codegen->invalid_instruction) 5452 return arg3_value; 5453 5454 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 5455 IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); 5456 if (arg4_value == irb->codegen->invalid_instruction) 5457 return arg4_value; 5458 5459 IrInstruction *inst = ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, 5460 arg4_value, 5461 // these 2 values don't mean anything since we passed non-null values for other args 5462 AtomicRmwOp_xchg, AtomicOrderMonotonic); 5463 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 5464 } 5465 case BuiltinFnIdAtomicLoad: 5466 { 5467 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5468 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5469 if (arg0_value == irb->codegen->invalid_instruction) 5470 return arg0_value; 5471 5472 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5473 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5474 if (arg1_value == irb->codegen->invalid_instruction) 5475 return arg1_value; 5476 5477 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5478 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5479 if (arg2_value == irb->codegen->invalid_instruction) 5480 return arg2_value; 5481 5482 IrInstruction *inst = ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, 5483 // this value does not mean anything since we passed non-null values for other arg 5484 AtomicOrderMonotonic); 5485 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 5486 } 5487 case BuiltinFnIdIntToEnum: 5488 { 5489 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5490 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5491 if (arg0_value == irb->codegen->invalid_instruction) 5492 return arg0_value; 5493 5494 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5495 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5496 if (arg1_value == irb->codegen->invalid_instruction) 5497 return arg1_value; 5498 5499 IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value); 5500 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5501 } 5502 case BuiltinFnIdEnumToInt: 5503 { 5504 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5505 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5506 if (arg0_value == irb->codegen->invalid_instruction) 5507 return arg0_value; 5508 5509 IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); 5510 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5511 } 5512 case BuiltinFnIdCtz: 5513 case BuiltinFnIdPopCount: 5514 case BuiltinFnIdClz: 5515 case BuiltinFnIdBswap: 5516 case BuiltinFnIdBitReverse: 5517 { 5518 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5519 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5520 if (arg0_value == irb->codegen->invalid_instruction) 5521 return arg0_value; 5522 5523 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5524 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5525 if (arg1_value == irb->codegen->invalid_instruction) 5526 return arg1_value; 5527 5528 IrInstruction *result; 5529 switch (builtin_fn->id) { 5530 case BuiltinFnIdCtz: 5531 result = ir_build_ctz(irb, scope, node, arg0_value, arg1_value); 5532 break; 5533 case BuiltinFnIdPopCount: 5534 result = ir_build_pop_count(irb, scope, node, arg0_value, arg1_value); 5535 break; 5536 case BuiltinFnIdClz: 5537 result = ir_build_clz(irb, scope, node, arg0_value, arg1_value); 5538 break; 5539 case BuiltinFnIdBswap: 5540 result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value); 5541 break; 5542 case BuiltinFnIdBitReverse: 5543 result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value); 5544 break; 5545 default: 5546 zig_unreachable(); 5547 } 5548 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5549 } 5550 case BuiltinFnIdHasDecl: 5551 { 5552 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5553 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5554 if (arg0_value == irb->codegen->invalid_instruction) 5555 return arg0_value; 5556 5557 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5558 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5559 if (arg1_value == irb->codegen->invalid_instruction) 5560 return arg1_value; 5561 5562 IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value); 5563 return ir_lval_wrap(irb, scope, has_decl, lval, result_loc); 5564 } 5565 case BuiltinFnIdUnionInit: 5566 { 5567 AstNode *union_type_node = node->data.fn_call_expr.params.at(0); 5568 IrInstruction *union_type_inst = ir_gen_node(irb, union_type_node, scope); 5569 if (union_type_inst == irb->codegen->invalid_instruction) 5570 return union_type_inst; 5571 5572 AstNode *name_node = node->data.fn_call_expr.params.at(1); 5573 IrInstruction *name_inst = ir_gen_node(irb, name_node, scope); 5574 if (name_inst == irb->codegen->invalid_instruction) 5575 return name_inst; 5576 5577 AstNode *init_node = node->data.fn_call_expr.params.at(2); 5578 5579 return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node, 5580 lval, result_loc); 5581 } 5582 } 5583 zig_unreachable(); 5584 } 5585 5586 static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 5587 ResultLoc *result_loc) 5588 { 5589 assert(node->type == NodeTypeFnCallExpr); 5590 5591 if (node->data.fn_call_expr.is_builtin) 5592 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); 5593 5594 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; 5595 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 5596 if (fn_ref == irb->codegen->invalid_instruction) 5597 return fn_ref; 5598 5599 size_t arg_count = node->data.fn_call_expr.params.length; 5600 IrInstruction **args = allocate<IrInstruction*>(arg_count); 5601 for (size_t i = 0; i < arg_count; i += 1) { 5602 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 5603 args[i] = ir_gen_node(irb, arg_node, scope); 5604 if (args[i] == irb->codegen->invalid_instruction) 5605 return args[i]; 5606 } 5607 5608 bool is_async = node->data.fn_call_expr.is_async; 5609 IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, 5610 FnInlineAuto, is_async, nullptr, result_loc); 5611 return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); 5612 } 5613 5614 static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 5615 ResultLoc *result_loc) 5616 { 5617 assert(node->type == NodeTypeIfBoolExpr); 5618 5619 IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); 5620 if (condition == irb->codegen->invalid_instruction) 5621 return irb->codegen->invalid_instruction; 5622 5623 IrInstruction *is_comptime; 5624 if (ir_should_inline(irb->exec, scope)) { 5625 is_comptime = ir_build_const_bool(irb, scope, node, true); 5626 } else { 5627 is_comptime = ir_build_test_comptime(irb, scope, node, condition); 5628 } 5629 5630 AstNode *then_node = node->data.if_bool_expr.then_block; 5631 AstNode *else_node = node->data.if_bool_expr.else_node; 5632 5633 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "Then"); 5634 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); 5635 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); 5636 5637 IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, condition, 5638 then_block, else_block, is_comptime); 5639 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 5640 result_loc, is_comptime); 5641 5642 ir_set_cursor_at_end_and_append_block(irb, then_block); 5643 5644 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 5645 IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, 5646 &peer_parent->peers.at(0)->base); 5647 if (then_expr_result == irb->codegen->invalid_instruction) 5648 return irb->codegen->invalid_instruction; 5649 IrBasicBlock *after_then_block = irb->current_basic_block; 5650 if (!instr_is_unreachable(then_expr_result)) 5651 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5652 5653 ir_set_cursor_at_end_and_append_block(irb, else_block); 5654 IrInstruction *else_expr_result; 5655 if (else_node) { 5656 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); 5657 if (else_expr_result == irb->codegen->invalid_instruction) 5658 return irb->codegen->invalid_instruction; 5659 } else { 5660 else_expr_result = ir_build_const_void(irb, scope, node); 5661 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 5662 } 5663 IrBasicBlock *after_else_block = irb->current_basic_block; 5664 if (!instr_is_unreachable(else_expr_result)) 5665 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5666 5667 ir_set_cursor_at_end_and_append_block(irb, endif_block); 5668 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 5669 incoming_values[0] = then_expr_result; 5670 incoming_values[1] = else_expr_result; 5671 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 5672 incoming_blocks[0] = after_then_block; 5673 incoming_blocks[1] = after_else_block; 5674 5675 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 5676 return ir_expr_wrap(irb, scope, phi, result_loc); 5677 } 5678 5679 static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { 5680 assert(node->type == NodeTypePrefixOpExpr); 5681 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 5682 5683 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); 5684 if (value == irb->codegen->invalid_instruction) 5685 return value; 5686 5687 return ir_build_un_op(irb, scope, node, op_id, value); 5688 } 5689 5690 static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id) { 5691 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); 5692 } 5693 5694 static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc) { 5695 ir_build_end_expr(irb, scope, inst->source_node, inst, result_loc); 5696 return inst; 5697 } 5698 5699 static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval, 5700 ResultLoc *result_loc) 5701 { 5702 // This logic must be kept in sync with 5703 // [STMT_EXPR_TEST_THING] <--- (search this token) 5704 if (value == irb->codegen->invalid_instruction || 5705 instr_is_unreachable(value) || 5706 value->source_node->type == NodeTypeDefer || 5707 value->id == IrInstructionIdDeclVarSrc) 5708 { 5709 return value; 5710 } 5711 5712 if (lval == LValPtr) { 5713 // We needed a pointer to a value, but we got a value. So we create 5714 // an instruction which just makes a pointer of it. 5715 return ir_build_ref(irb, scope, value->source_node, value, false, false); 5716 } else if (result_loc != nullptr) { 5717 return ir_expr_wrap(irb, scope, value, result_loc); 5718 } else { 5719 return value; 5720 } 5721 5722 } 5723 5724 static PtrLen star_token_to_ptr_len(TokenId token_id) { 5725 switch (token_id) { 5726 case TokenIdStar: 5727 case TokenIdStarStar: 5728 return PtrLenSingle; 5729 case TokenIdBracketStarBracket: 5730 return PtrLenUnknown; 5731 case TokenIdBracketStarCBracket: 5732 return PtrLenC; 5733 default: 5734 zig_unreachable(); 5735 } 5736 } 5737 5738 static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) { 5739 assert(node->type == NodeTypePointerType); 5740 PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id); 5741 bool is_const = node->data.pointer_type.is_const; 5742 bool is_volatile = node->data.pointer_type.is_volatile; 5743 bool is_allow_zero = node->data.pointer_type.allow_zero_token != nullptr; 5744 AstNode *expr_node = node->data.pointer_type.op_expr; 5745 AstNode *align_expr = node->data.pointer_type.align_expr; 5746 5747 IrInstruction *align_value; 5748 if (align_expr != nullptr) { 5749 align_value = ir_gen_node(irb, align_expr, scope); 5750 if (align_value == irb->codegen->invalid_instruction) 5751 return align_value; 5752 } else { 5753 align_value = nullptr; 5754 } 5755 5756 IrInstruction *child_type = ir_gen_node(irb, expr_node, scope); 5757 if (child_type == irb->codegen->invalid_instruction) 5758 return child_type; 5759 5760 uint32_t bit_offset_start = 0; 5761 if (node->data.pointer_type.bit_offset_start != nullptr) { 5762 if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_start, 32, false)) { 5763 Buf *val_buf = buf_alloc(); 5764 bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10); 5765 exec_add_error_node(irb->codegen, irb->exec, node, 5766 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); 5767 return irb->codegen->invalid_instruction; 5768 } 5769 bit_offset_start = bigint_as_unsigned(node->data.pointer_type.bit_offset_start); 5770 } 5771 5772 uint32_t host_int_bytes = 0; 5773 if (node->data.pointer_type.host_int_bytes != nullptr) { 5774 if (!bigint_fits_in_bits(node->data.pointer_type.host_int_bytes, 32, false)) { 5775 Buf *val_buf = buf_alloc(); 5776 bigint_append_buf(val_buf, node->data.pointer_type.host_int_bytes, 10); 5777 exec_add_error_node(irb->codegen, irb->exec, node, 5778 buf_sprintf("value %s too large for u32 byte count", buf_ptr(val_buf))); 5779 return irb->codegen->invalid_instruction; 5780 } 5781 host_int_bytes = bigint_as_unsigned(node->data.pointer_type.host_int_bytes); 5782 } 5783 5784 if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) { 5785 exec_add_error_node(irb->codegen, irb->exec, node, 5786 buf_sprintf("bit offset starts after end of host integer")); 5787 return irb->codegen->invalid_instruction; 5788 } 5789 5790 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, 5791 ptr_len, align_value, bit_offset_start, host_int_bytes, is_allow_zero); 5792 } 5793 5794 static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, 5795 AstNode *expr_node, LVal lval, ResultLoc *result_loc) 5796 { 5797 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 5798 if (err_union_ptr == irb->codegen->invalid_instruction) 5799 return irb->codegen->invalid_instruction; 5800 5801 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true, false); 5802 if (payload_ptr == irb->codegen->invalid_instruction) 5803 return irb->codegen->invalid_instruction; 5804 5805 if (lval == LValPtr) 5806 return payload_ptr; 5807 5808 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr); 5809 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 5810 } 5811 5812 static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) { 5813 assert(node->type == NodeTypePrefixOpExpr); 5814 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 5815 5816 IrInstruction *value = ir_gen_node(irb, expr_node, scope); 5817 if (value == irb->codegen->invalid_instruction) 5818 return irb->codegen->invalid_instruction; 5819 5820 return ir_build_bool_not(irb, scope, node, value); 5821 } 5822 5823 static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 5824 ResultLoc *result_loc) 5825 { 5826 assert(node->type == NodeTypePrefixOpExpr); 5827 5828 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; 5829 5830 switch (prefix_op) { 5831 case PrefixOpInvalid: 5832 zig_unreachable(); 5833 case PrefixOpBoolNot: 5834 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval, result_loc); 5835 case PrefixOpBinNot: 5836 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval, result_loc); 5837 case PrefixOpNegation: 5838 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval, result_loc); 5839 case PrefixOpNegationWrap: 5840 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval, result_loc); 5841 case PrefixOpOptional: 5842 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval, result_loc); 5843 case PrefixOpAddrOf: { 5844 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 5845 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval, result_loc); 5846 } 5847 } 5848 zig_unreachable(); 5849 } 5850 5851 static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, 5852 IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, 5853 LVal lval, ResultLoc *parent_result_loc) 5854 { 5855 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type); 5856 IrInstruction *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr, 5857 field_name, true); 5858 5859 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); 5860 result_loc_inst->base.id = ResultLocIdInstruction; 5861 result_loc_inst->base.source_instruction = field_ptr; 5862 ir_ref_instruction(field_ptr, irb->current_basic_block); 5863 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 5864 5865 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 5866 &result_loc_inst->base); 5867 if (expr_value == irb->codegen->invalid_instruction) 5868 return expr_value; 5869 5870 IrInstruction *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type, 5871 field_name, field_ptr, container_ptr); 5872 5873 return ir_lval_wrap(irb, scope, init_union, lval, parent_result_loc); 5874 } 5875 5876 static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 5877 ResultLoc *parent_result_loc) 5878 { 5879 assert(node->type == NodeTypeContainerInitExpr); 5880 5881 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; 5882 ContainerInitKind kind = container_init_expr->kind; 5883 5884 IrInstruction *container_type = nullptr; 5885 IrInstruction *elem_type = nullptr; 5886 if (container_init_expr->type->type == NodeTypeInferredArrayType) { 5887 elem_type = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.child_type, scope); 5888 if (elem_type == irb->codegen->invalid_instruction) 5889 return elem_type; 5890 } else { 5891 container_type = ir_gen_node(irb, container_init_expr->type, scope); 5892 if (container_type == irb->codegen->invalid_instruction) 5893 return container_type; 5894 } 5895 5896 switch (kind) { 5897 case ContainerInitKindStruct: { 5898 if (elem_type != nullptr) { 5899 add_node_error(irb->codegen, container_init_expr->type, 5900 buf_sprintf("initializing array with struct syntax")); 5901 return irb->codegen->invalid_instruction; 5902 } 5903 5904 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc, 5905 container_type); 5906 5907 size_t field_count = container_init_expr->entries.length; 5908 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); 5909 for (size_t i = 0; i < field_count; i += 1) { 5910 AstNode *entry_node = container_init_expr->entries.at(i); 5911 assert(entry_node->type == NodeTypeStructValueField); 5912 5913 Buf *name = entry_node->data.struct_val_field.name; 5914 AstNode *expr_node = entry_node->data.struct_val_field.expr; 5915 5916 IrInstruction *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true); 5917 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); 5918 result_loc_inst->base.id = ResultLocIdInstruction; 5919 result_loc_inst->base.source_instruction = field_ptr; 5920 result_loc_inst->base.allow_write_through_const = true; 5921 ir_ref_instruction(field_ptr, irb->current_basic_block); 5922 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 5923 5924 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 5925 &result_loc_inst->base); 5926 if (expr_value == irb->codegen->invalid_instruction) 5927 return expr_value; 5928 5929 fields[i].name = name; 5930 fields[i].source_node = entry_node; 5931 fields[i].result_loc = field_ptr; 5932 } 5933 IrInstruction *init_fields = ir_build_container_init_fields(irb, scope, node, container_type, 5934 field_count, fields, container_ptr); 5935 5936 return ir_lval_wrap(irb, scope, init_fields, lval, parent_result_loc); 5937 } 5938 case ContainerInitKindArray: { 5939 size_t item_count = container_init_expr->entries.length; 5940 5941 if (container_type == nullptr) { 5942 IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); 5943 container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type); 5944 } 5945 5946 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc, 5947 container_type); 5948 5949 IrInstruction **result_locs = allocate<IrInstruction *>(item_count); 5950 for (size_t i = 0; i < item_count; i += 1) { 5951 AstNode *expr_node = container_init_expr->entries.at(i); 5952 5953 IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i); 5954 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, elem_index, 5955 false, PtrLenSingle, container_type); 5956 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); 5957 result_loc_inst->base.id = ResultLocIdInstruction; 5958 result_loc_inst->base.source_instruction = elem_ptr; 5959 result_loc_inst->base.allow_write_through_const = true; 5960 ir_ref_instruction(elem_ptr, irb->current_basic_block); 5961 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 5962 5963 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 5964 &result_loc_inst->base); 5965 if (expr_value == irb->codegen->invalid_instruction) 5966 return expr_value; 5967 5968 result_locs[i] = elem_ptr; 5969 } 5970 IrInstruction *init_list = ir_build_container_init_list(irb, scope, node, container_type, 5971 item_count, result_locs, container_ptr); 5972 return ir_lval_wrap(irb, scope, init_list, lval, parent_result_loc); 5973 } 5974 } 5975 zig_unreachable(); 5976 } 5977 5978 static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *alloca, ZigVar *var) { 5979 ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); 5980 result_loc_var->base.id = ResultLocIdVar; 5981 result_loc_var->base.source_instruction = alloca; 5982 result_loc_var->var = var; 5983 5984 ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base); 5985 5986 return result_loc_var; 5987 } 5988 5989 static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, 5990 IrInstruction *init, const char *name_hint, IrInstruction *is_comptime) 5991 { 5992 IrInstruction *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime); 5993 ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var); 5994 ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base); 5995 ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca); 5996 } 5997 5998 static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) { 5999 assert(node->type == NodeTypeVariableDeclaration); 6000 6001 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; 6002 6003 if (buf_eql_str(variable_declaration->symbol, "_")) { 6004 add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol")); 6005 return irb->codegen->invalid_instruction; 6006 } 6007 6008 // Used for the type expr and the align expr 6009 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 6010 6011 IrInstruction *type_instruction; 6012 if (variable_declaration->type != nullptr) { 6013 type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope); 6014 if (type_instruction == irb->codegen->invalid_instruction) 6015 return type_instruction; 6016 } else { 6017 type_instruction = nullptr; 6018 } 6019 6020 bool is_shadowable = false; 6021 bool is_const = variable_declaration->is_const; 6022 bool is_extern = variable_declaration->is_extern; 6023 6024 bool is_comptime_scalar = ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime; 6025 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar); 6026 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, 6027 is_const, is_const, is_shadowable, is_comptime); 6028 // we detect IrInstructionIdDeclVarSrc in gen_block to make sure the next node 6029 // is inside var->child_scope 6030 6031 if (!is_extern && !variable_declaration->expr) { 6032 var->var_type = irb->codegen->builtin_types.entry_invalid; 6033 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); 6034 return irb->codegen->invalid_instruction; 6035 } 6036 6037 IrInstruction *align_value = nullptr; 6038 if (variable_declaration->align_expr != nullptr) { 6039 align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope); 6040 if (align_value == irb->codegen->invalid_instruction) 6041 return align_value; 6042 } 6043 6044 if (variable_declaration->section_expr != nullptr) { 6045 add_node_error(irb->codegen, variable_declaration->section_expr, 6046 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol))); 6047 } 6048 6049 // Parser should ensure that this never happens 6050 assert(variable_declaration->threadlocal_tok == nullptr); 6051 6052 IrInstruction *alloca = ir_build_alloca_src(irb, scope, node, align_value, 6053 buf_ptr(variable_declaration->symbol), is_comptime); 6054 6055 // Create a result location for the initialization expression. 6056 ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var); 6057 ResultLoc *init_result_loc = (type_instruction == nullptr) ? &result_loc_var->base : nullptr; 6058 6059 Scope *init_scope = is_comptime_scalar ? 6060 create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope; 6061 6062 // Temporarily set the name of the IrExecutable to the VariableDeclaration 6063 // so that the struct or enum from the init expression inherits the name. 6064 Buf *old_exec_name = irb->exec->name; 6065 irb->exec->name = variable_declaration->symbol; 6066 IrInstruction *init_value = ir_gen_node_extra(irb, variable_declaration->expr, init_scope, 6067 LValNone, init_result_loc); 6068 irb->exec->name = old_exec_name; 6069 6070 if (init_value == irb->codegen->invalid_instruction) 6071 return irb->codegen->invalid_instruction; 6072 6073 if (type_instruction != nullptr) { 6074 IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value, 6075 &result_loc_var->base); 6076 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); 6077 } 6078 6079 return ir_build_var_decl_src(irb, scope, node, var, align_value, alloca); 6080 } 6081 6082 static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 6083 ResultLoc *result_loc) 6084 { 6085 assert(node->type == NodeTypeWhileExpr); 6086 6087 AstNode *continue_expr_node = node->data.while_expr.continue_expr; 6088 AstNode *else_node = node->data.while_expr.else_node; 6089 6090 IrBasicBlock *cond_block = ir_create_basic_block(irb, scope, "WhileCond"); 6091 IrBasicBlock *body_block = ir_create_basic_block(irb, scope, "WhileBody"); 6092 IrBasicBlock *continue_block = continue_expr_node ? 6093 ir_create_basic_block(irb, scope, "WhileContinue") : cond_block; 6094 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "WhileEnd"); 6095 IrBasicBlock *else_block = else_node ? 6096 ir_create_basic_block(irb, scope, "WhileElse") : end_block; 6097 6098 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, 6099 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline); 6100 ir_build_br(irb, scope, node, cond_block, is_comptime); 6101 6102 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6103 Buf *var_symbol = node->data.while_expr.var_symbol; 6104 Buf *err_symbol = node->data.while_expr.err_symbol; 6105 if (err_symbol != nullptr) { 6106 ir_set_cursor_at_end_and_append_block(irb, cond_block); 6107 6108 Scope *payload_scope; 6109 AstNode *symbol_node = node; // TODO make more accurate 6110 ZigVar *payload_var; 6111 if (var_symbol) { 6112 // TODO make it an error to write to payload variable 6113 payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 6114 true, false, false, is_comptime); 6115 payload_scope = payload_var->child_scope; 6116 } else { 6117 payload_scope = subexpr_scope; 6118 } 6119 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, 6120 LValPtr, nullptr); 6121 if (err_val_ptr == irb->codegen->invalid_instruction) 6122 return err_val_ptr; 6123 IrInstruction *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, 6124 true, false); 6125 IrBasicBlock *after_cond_block = irb->current_basic_block; 6126 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 6127 IrInstruction *cond_br_inst; 6128 if (!instr_is_unreachable(is_err)) { 6129 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, 6130 else_block, body_block, is_comptime); 6131 cond_br_inst->is_gen = true; 6132 } else { 6133 // for the purposes of the source instruction to ir_build_result_peers 6134 cond_br_inst = irb->current_basic_block->instruction_list.last(); 6135 } 6136 6137 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 6138 is_comptime); 6139 6140 ir_set_cursor_at_end_and_append_block(irb, body_block); 6141 if (var_symbol) { 6142 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, 6143 err_val_ptr, false, false); 6144 IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? 6145 ir_build_ref(irb, payload_scope, symbol_node, payload_ptr, true, false) : payload_ptr; 6146 ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, var_ptr); 6147 } 6148 6149 ZigList<IrInstruction *> incoming_values = {0}; 6150 ZigList<IrBasicBlock *> incoming_blocks = {0}; 6151 6152 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope); 6153 loop_scope->break_block = end_block; 6154 loop_scope->continue_block = continue_block; 6155 loop_scope->is_comptime = is_comptime; 6156 loop_scope->incoming_blocks = &incoming_blocks; 6157 loop_scope->incoming_values = &incoming_values; 6158 loop_scope->lval = lval; 6159 loop_scope->peer_parent = peer_parent; 6160 6161 // Note the body block of the loop is not the place that lval and result_loc are used - 6162 // it's actually in break statements, handled similarly to return statements. 6163 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 6164 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 6165 if (body_result == irb->codegen->invalid_instruction) 6166 return body_result; 6167 6168 if (!instr_is_unreachable(body_result)) { 6169 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result)); 6170 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime)); 6171 } 6172 6173 if (continue_expr_node) { 6174 ir_set_cursor_at_end_and_append_block(irb, continue_block); 6175 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope); 6176 if (expr_result == irb->codegen->invalid_instruction) 6177 return expr_result; 6178 if (!instr_is_unreachable(expr_result)) { 6179 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, continue_expr_node, expr_result)); 6180 ir_mark_gen(ir_build_br(irb, payload_scope, node, cond_block, is_comptime)); 6181 } 6182 } 6183 6184 ir_set_cursor_at_end_and_append_block(irb, else_block); 6185 assert(else_node != nullptr); 6186 6187 // TODO make it an error to write to error variable 6188 AstNode *err_symbol_node = else_node; // TODO make more accurate 6189 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, 6190 true, false, false, is_comptime); 6191 Scope *err_scope = err_var->child_scope; 6192 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); 6193 ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, err_ptr); 6194 6195 if (peer_parent->peers.length != 0) { 6196 peer_parent->peers.last()->next_bb = else_block; 6197 } 6198 ResultLocPeer *peer_result = create_peer_result(peer_parent); 6199 peer_parent->peers.append(peer_result); 6200 IrInstruction *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base); 6201 if (else_result == irb->codegen->invalid_instruction) 6202 return else_result; 6203 if (!instr_is_unreachable(else_result)) 6204 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 6205 IrBasicBlock *after_else_block = irb->current_basic_block; 6206 ir_set_cursor_at_end_and_append_block(irb, end_block); 6207 if (else_result) { 6208 incoming_blocks.append(after_else_block); 6209 incoming_values.append(else_result); 6210 } else { 6211 incoming_blocks.append(after_cond_block); 6212 incoming_values.append(void_else_result); 6213 } 6214 if (peer_parent->peers.length != 0) { 6215 peer_parent->peers.last()->next_bb = end_block; 6216 } 6217 6218 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 6219 incoming_blocks.items, incoming_values.items, peer_parent); 6220 return ir_expr_wrap(irb, scope, phi, result_loc); 6221 } else if (var_symbol != nullptr) { 6222 ir_set_cursor_at_end_and_append_block(irb, cond_block); 6223 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6224 // TODO make it an error to write to payload variable 6225 AstNode *symbol_node = node; // TODO make more accurate 6226 6227 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 6228 true, false, false, is_comptime); 6229 Scope *child_scope = payload_var->child_scope; 6230 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, 6231 LValPtr, nullptr); 6232 if (maybe_val_ptr == irb->codegen->invalid_instruction) 6233 return maybe_val_ptr; 6234 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); 6235 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); 6236 IrBasicBlock *after_cond_block = irb->current_basic_block; 6237 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 6238 IrInstruction *cond_br_inst; 6239 if (!instr_is_unreachable(is_non_null)) { 6240 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, 6241 body_block, else_block, is_comptime); 6242 cond_br_inst->is_gen = true; 6243 } else { 6244 // for the purposes of the source instruction to ir_build_result_peers 6245 cond_br_inst = irb->current_basic_block->instruction_list.last(); 6246 } 6247 6248 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 6249 is_comptime); 6250 6251 ir_set_cursor_at_end_and_append_block(irb, body_block); 6252 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false, false); 6253 IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? 6254 ir_build_ref(irb, child_scope, symbol_node, payload_ptr, true, false) : payload_ptr; 6255 ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, var_ptr); 6256 6257 ZigList<IrInstruction *> incoming_values = {0}; 6258 ZigList<IrBasicBlock *> incoming_blocks = {0}; 6259 6260 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 6261 loop_scope->break_block = end_block; 6262 loop_scope->continue_block = continue_block; 6263 loop_scope->is_comptime = is_comptime; 6264 loop_scope->incoming_blocks = &incoming_blocks; 6265 loop_scope->incoming_values = &incoming_values; 6266 loop_scope->lval = lval; 6267 loop_scope->peer_parent = peer_parent; 6268 6269 // Note the body block of the loop is not the place that lval and result_loc are used - 6270 // it's actually in break statements, handled similarly to return statements. 6271 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 6272 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 6273 if (body_result == irb->codegen->invalid_instruction) 6274 return body_result; 6275 6276 if (!instr_is_unreachable(body_result)) { 6277 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result)); 6278 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 6279 } 6280 6281 if (continue_expr_node) { 6282 ir_set_cursor_at_end_and_append_block(irb, continue_block); 6283 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, child_scope); 6284 if (expr_result == irb->codegen->invalid_instruction) 6285 return expr_result; 6286 if (!instr_is_unreachable(expr_result)) { 6287 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, continue_expr_node, expr_result)); 6288 ir_mark_gen(ir_build_br(irb, child_scope, node, cond_block, is_comptime)); 6289 } 6290 } 6291 6292 IrInstruction *else_result = nullptr; 6293 if (else_node) { 6294 ir_set_cursor_at_end_and_append_block(irb, else_block); 6295 6296 if (peer_parent->peers.length != 0) { 6297 peer_parent->peers.last()->next_bb = else_block; 6298 } 6299 ResultLocPeer *peer_result = create_peer_result(peer_parent); 6300 peer_parent->peers.append(peer_result); 6301 else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base); 6302 if (else_result == irb->codegen->invalid_instruction) 6303 return else_result; 6304 if (!instr_is_unreachable(else_result)) 6305 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 6306 } 6307 IrBasicBlock *after_else_block = irb->current_basic_block; 6308 ir_set_cursor_at_end_and_append_block(irb, end_block); 6309 if (else_result) { 6310 incoming_blocks.append(after_else_block); 6311 incoming_values.append(else_result); 6312 } else { 6313 incoming_blocks.append(after_cond_block); 6314 incoming_values.append(void_else_result); 6315 } 6316 if (peer_parent->peers.length != 0) { 6317 peer_parent->peers.last()->next_bb = end_block; 6318 } 6319 6320 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 6321 incoming_blocks.items, incoming_values.items, peer_parent); 6322 return ir_expr_wrap(irb, scope, phi, result_loc); 6323 } else { 6324 ir_set_cursor_at_end_and_append_block(irb, cond_block); 6325 IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); 6326 if (cond_val == irb->codegen->invalid_instruction) 6327 return cond_val; 6328 IrBasicBlock *after_cond_block = irb->current_basic_block; 6329 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 6330 IrInstruction *cond_br_inst; 6331 if (!instr_is_unreachable(cond_val)) { 6332 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, 6333 body_block, else_block, is_comptime); 6334 cond_br_inst->is_gen = true; 6335 } else { 6336 // for the purposes of the source instruction to ir_build_result_peers 6337 cond_br_inst = irb->current_basic_block->instruction_list.last(); 6338 } 6339 6340 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 6341 is_comptime); 6342 ir_set_cursor_at_end_and_append_block(irb, body_block); 6343 6344 ZigList<IrInstruction *> incoming_values = {0}; 6345 ZigList<IrBasicBlock *> incoming_blocks = {0}; 6346 6347 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6348 6349 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope); 6350 loop_scope->break_block = end_block; 6351 loop_scope->continue_block = continue_block; 6352 loop_scope->is_comptime = is_comptime; 6353 loop_scope->incoming_blocks = &incoming_blocks; 6354 loop_scope->incoming_values = &incoming_values; 6355 loop_scope->lval = lval; 6356 loop_scope->peer_parent = peer_parent; 6357 6358 // Note the body block of the loop is not the place that lval and result_loc are used - 6359 // it's actually in break statements, handled similarly to return statements. 6360 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 6361 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 6362 if (body_result == irb->codegen->invalid_instruction) 6363 return body_result; 6364 6365 if (!instr_is_unreachable(body_result)) { 6366 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result)); 6367 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime)); 6368 } 6369 6370 if (continue_expr_node) { 6371 ir_set_cursor_at_end_and_append_block(irb, continue_block); 6372 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, subexpr_scope); 6373 if (expr_result == irb->codegen->invalid_instruction) 6374 return expr_result; 6375 if (!instr_is_unreachable(expr_result)) { 6376 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, continue_expr_node, expr_result)); 6377 ir_mark_gen(ir_build_br(irb, scope, node, cond_block, is_comptime)); 6378 } 6379 } 6380 6381 IrInstruction *else_result = nullptr; 6382 if (else_node) { 6383 ir_set_cursor_at_end_and_append_block(irb, else_block); 6384 6385 if (peer_parent->peers.length != 0) { 6386 peer_parent->peers.last()->next_bb = else_block; 6387 } 6388 ResultLocPeer *peer_result = create_peer_result(peer_parent); 6389 peer_parent->peers.append(peer_result); 6390 6391 else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base); 6392 if (else_result == irb->codegen->invalid_instruction) 6393 return else_result; 6394 if (!instr_is_unreachable(else_result)) 6395 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 6396 } 6397 IrBasicBlock *after_else_block = irb->current_basic_block; 6398 ir_set_cursor_at_end_and_append_block(irb, end_block); 6399 if (else_result) { 6400 incoming_blocks.append(after_else_block); 6401 incoming_values.append(else_result); 6402 } else { 6403 incoming_blocks.append(after_cond_block); 6404 incoming_values.append(void_else_result); 6405 } 6406 if (peer_parent->peers.length != 0) { 6407 peer_parent->peers.last()->next_bb = end_block; 6408 } 6409 6410 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 6411 incoming_blocks.items, incoming_values.items, peer_parent); 6412 return ir_expr_wrap(irb, scope, phi, result_loc); 6413 } 6414 } 6415 6416 static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, 6417 ResultLoc *result_loc) 6418 { 6419 assert(node->type == NodeTypeForExpr); 6420 6421 AstNode *array_node = node->data.for_expr.array_expr; 6422 AstNode *elem_node = node->data.for_expr.elem_node; 6423 AstNode *index_node = node->data.for_expr.index_node; 6424 AstNode *body_node = node->data.for_expr.body; 6425 AstNode *else_node = node->data.for_expr.else_node; 6426 6427 if (!elem_node) { 6428 add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter")); 6429 return irb->codegen->invalid_instruction; 6430 } 6431 assert(elem_node->type == NodeTypeSymbol); 6432 6433 IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr, nullptr); 6434 if (array_val_ptr == irb->codegen->invalid_instruction) 6435 return array_val_ptr; 6436 6437 IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, 6438 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); 6439 6440 AstNode *index_var_source_node; 6441 ZigVar *index_var; 6442 const char *index_var_name; 6443 if (index_node) { 6444 index_var_source_node = index_node; 6445 Buf *index_var_name_buf = index_node->data.symbol_expr.symbol; 6446 index_var = ir_create_var(irb, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime); 6447 index_var_name = buf_ptr(index_var_name_buf); 6448 } else { 6449 index_var_source_node = node; 6450 index_var = ir_create_var(irb, node, parent_scope, nullptr, true, false, true, is_comptime); 6451 index_var_name = "i"; 6452 } 6453 6454 IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0); 6455 build_decl_var_and_init(irb, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime); 6456 parent_scope = index_var->child_scope; 6457 6458 IrInstruction *one = ir_build_const_usize(irb, parent_scope, node, 1); 6459 IrInstruction *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var); 6460 6461 6462 IrBasicBlock *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond"); 6463 IrBasicBlock *body_block = ir_create_basic_block(irb, parent_scope, "ForBody"); 6464 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd"); 6465 IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block; 6466 IrBasicBlock *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue"); 6467 6468 Buf *len_field_name = buf_create_from_str("len"); 6469 IrInstruction *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false); 6470 IrInstruction *len_val = ir_build_load_ptr(irb, parent_scope, node, len_ref); 6471 ir_build_br(irb, parent_scope, node, cond_block, is_comptime); 6472 6473 ir_set_cursor_at_end_and_append_block(irb, cond_block); 6474 IrInstruction *index_val = ir_build_load_ptr(irb, parent_scope, node, index_ptr); 6475 IrInstruction *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); 6476 IrBasicBlock *after_cond_block = irb->current_basic_block; 6477 IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); 6478 IrInstruction *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, 6479 body_block, else_block, is_comptime)); 6480 6481 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime); 6482 6483 ir_set_cursor_at_end_and_append_block(irb, body_block); 6484 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, parent_scope, node, array_val_ptr, index_val, false, 6485 PtrLenSingle, nullptr); 6486 // TODO make it an error to write to element variable or i variable. 6487 Buf *elem_var_name = elem_node->data.symbol_expr.symbol; 6488 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); 6489 Scope *child_scope = elem_var->child_scope; 6490 6491 IrInstruction *var_ptr = node->data.for_expr.elem_is_ptr ? 6492 ir_build_ref(irb, parent_scope, elem_node, elem_ptr, true, false) : elem_ptr; 6493 ir_build_var_decl_src(irb, parent_scope, elem_node, elem_var, nullptr, var_ptr); 6494 6495 ZigList<IrInstruction *> incoming_values = {0}; 6496 ZigList<IrBasicBlock *> incoming_blocks = {0}; 6497 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 6498 loop_scope->break_block = end_block; 6499 loop_scope->continue_block = continue_block; 6500 loop_scope->is_comptime = is_comptime; 6501 loop_scope->incoming_blocks = &incoming_blocks; 6502 loop_scope->incoming_values = &incoming_values; 6503 loop_scope->lval = LValNone; 6504 loop_scope->peer_parent = peer_parent; 6505 6506 // Note the body block of the loop is not the place that lval and result_loc are used - 6507 // it's actually in break statements, handled similarly to return statements. 6508 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 6509 IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base); 6510 6511 if (!instr_is_unreachable(body_result)) { 6512 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result)); 6513 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 6514 } 6515 6516 ir_set_cursor_at_end_and_append_block(irb, continue_block); 6517 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); 6518 ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true; 6519 ir_build_br(irb, child_scope, node, cond_block, is_comptime); 6520 6521 IrInstruction *else_result = nullptr; 6522 if (else_node) { 6523 ir_set_cursor_at_end_and_append_block(irb, else_block); 6524 6525 if (peer_parent->peers.length != 0) { 6526 peer_parent->peers.last()->next_bb = else_block; 6527 } 6528 ResultLocPeer *peer_result = create_peer_result(peer_parent); 6529 peer_parent->peers.append(peer_result); 6530 else_result = ir_gen_node_extra(irb, else_node, parent_scope, LValNone, &peer_result->base); 6531 if (else_result == irb->codegen->invalid_instruction) 6532 return else_result; 6533 if (!instr_is_unreachable(else_result)) 6534 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 6535 } 6536 IrBasicBlock *after_else_block = irb->current_basic_block; 6537 ir_set_cursor_at_end_and_append_block(irb, end_block); 6538 6539 if (else_result) { 6540 incoming_blocks.append(after_else_block); 6541 incoming_values.append(else_result); 6542 } else { 6543 incoming_blocks.append(after_cond_block); 6544 incoming_values.append(void_else_value); 6545 } 6546 if (peer_parent->peers.length != 0) { 6547 peer_parent->peers.last()->next_bb = end_block; 6548 } 6549 6550 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, 6551 incoming_blocks.items, incoming_values.items, peer_parent); 6552 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 6553 } 6554 6555 static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 6556 assert(node->type == NodeTypeBoolLiteral); 6557 return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value); 6558 } 6559 6560 static IrInstruction *ir_gen_enum_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 6561 assert(node->type == NodeTypeEnumLiteral); 6562 Buf *name = &node->data.enum_literal.identifier->data.str_lit.str; 6563 return ir_build_const_enum_literal(irb, scope, node, name); 6564 } 6565 6566 static IrInstruction *ir_gen_string_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 6567 assert(node->type == NodeTypeStringLiteral); 6568 6569 if (node->data.string_literal.c) { 6570 return ir_build_const_c_str_lit(irb, scope, node, node->data.string_literal.buf); 6571 } else { 6572 return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf); 6573 } 6574 } 6575 6576 static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *node) { 6577 assert(node->type == NodeTypeArrayType); 6578 6579 AstNode *size_node = node->data.array_type.size; 6580 AstNode *child_type_node = node->data.array_type.child_type; 6581 bool is_const = node->data.array_type.is_const; 6582 bool is_volatile = node->data.array_type.is_volatile; 6583 bool is_allow_zero = node->data.array_type.allow_zero_token != nullptr; 6584 AstNode *align_expr = node->data.array_type.align_expr; 6585 6586 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 6587 if (size_node) { 6588 if (is_const) { 6589 add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); 6590 return irb->codegen->invalid_instruction; 6591 } 6592 if (is_volatile) { 6593 add_node_error(irb->codegen, node, buf_create_from_str("volatile qualifier invalid on array type")); 6594 return irb->codegen->invalid_instruction; 6595 } 6596 if (is_allow_zero) { 6597 add_node_error(irb->codegen, node, buf_create_from_str("allowzero qualifier invalid on array type")); 6598 return irb->codegen->invalid_instruction; 6599 } 6600 if (align_expr != nullptr) { 6601 add_node_error(irb->codegen, node, buf_create_from_str("align qualifier invalid on array type")); 6602 return irb->codegen->invalid_instruction; 6603 } 6604 6605 IrInstruction *size_value = ir_gen_node(irb, size_node, comptime_scope); 6606 if (size_value == irb->codegen->invalid_instruction) 6607 return size_value; 6608 6609 IrInstruction *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 6610 if (child_type == irb->codegen->invalid_instruction) 6611 return child_type; 6612 6613 return ir_build_array_type(irb, scope, node, size_value, child_type); 6614 } else { 6615 IrInstruction *align_value; 6616 if (align_expr != nullptr) { 6617 align_value = ir_gen_node(irb, align_expr, comptime_scope); 6618 if (align_value == irb->codegen->invalid_instruction) 6619 return align_value; 6620 } else { 6621 align_value = nullptr; 6622 } 6623 6624 IrInstruction *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 6625 if (child_type == irb->codegen->invalid_instruction) 6626 return child_type; 6627 6628 return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, align_value, is_allow_zero); 6629 } 6630 } 6631 6632 static IrInstruction *ir_gen_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *node) { 6633 assert(node->type == NodeTypeAnyFrameType); 6634 6635 AstNode *payload_type_node = node->data.anyframe_type.payload_type; 6636 IrInstruction *payload_type_value = nullptr; 6637 6638 if (payload_type_node != nullptr) { 6639 payload_type_value = ir_gen_node(irb, payload_type_node, scope); 6640 if (payload_type_value == irb->codegen->invalid_instruction) 6641 return payload_type_value; 6642 6643 } 6644 6645 return ir_build_anyframe_type(irb, scope, node, payload_type_value); 6646 } 6647 6648 static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 6649 assert(node->type == NodeTypeUndefinedLiteral); 6650 return ir_build_const_undefined(irb, scope, node); 6651 } 6652 6653 static Error parse_asm_template(IrBuilder *irb, AstNode *source_node, Buf *asm_template, 6654 ZigList<AsmToken> *tok_list) 6655 { 6656 // TODO Connect the errors in this function back up to the actual source location 6657 // rather than just the token. https://github.com/ziglang/zig/issues/2080 6658 enum State { 6659 StateStart, 6660 StatePercent, 6661 StateTemplate, 6662 StateVar, 6663 }; 6664 6665 assert(tok_list->length == 0); 6666 6667 AsmToken *cur_tok = nullptr; 6668 6669 enum State state = StateStart; 6670 6671 for (size_t i = 0; i < buf_len(asm_template); i += 1) { 6672 uint8_t c = *((uint8_t*)buf_ptr(asm_template) + i); 6673 switch (state) { 6674 case StateStart: 6675 if (c == '%') { 6676 tok_list->add_one(); 6677 cur_tok = &tok_list->last(); 6678 cur_tok->id = AsmTokenIdPercent; 6679 cur_tok->start = i; 6680 state = StatePercent; 6681 } else { 6682 tok_list->add_one(); 6683 cur_tok = &tok_list->last(); 6684 cur_tok->id = AsmTokenIdTemplate; 6685 cur_tok->start = i; 6686 state = StateTemplate; 6687 } 6688 break; 6689 case StatePercent: 6690 if (c == '%') { 6691 cur_tok->end = i; 6692 state = StateStart; 6693 } else if (c == '[') { 6694 cur_tok->id = AsmTokenIdVar; 6695 state = StateVar; 6696 } else if (c == '=') { 6697 cur_tok->id = AsmTokenIdUniqueId; 6698 cur_tok->end = i; 6699 state = StateStart; 6700 } else { 6701 add_node_error(irb->codegen, source_node, 6702 buf_create_from_str("expected a '%' or '['")); 6703 return ErrorSemanticAnalyzeFail; 6704 } 6705 break; 6706 case StateTemplate: 6707 if (c == '%') { 6708 cur_tok->end = i; 6709 i -= 1; 6710 cur_tok = nullptr; 6711 state = StateStart; 6712 } 6713 break; 6714 case StateVar: 6715 if (c == ']') { 6716 cur_tok->end = i; 6717 state = StateStart; 6718 } else if ((c >= 'a' && c <= 'z') || 6719 (c >= '0' && c <= '9') || 6720 (c == '_')) 6721 { 6722 // do nothing 6723 } else { 6724 add_node_error(irb->codegen, source_node, 6725 buf_sprintf("invalid substitution character: '%c'", c)); 6726 return ErrorSemanticAnalyzeFail; 6727 } 6728 break; 6729 } 6730 } 6731 6732 switch (state) { 6733 case StateStart: 6734 break; 6735 case StatePercent: 6736 case StateVar: 6737 add_node_error(irb->codegen, source_node, buf_sprintf("unexpected end of assembly template")); 6738 return ErrorSemanticAnalyzeFail; 6739 case StateTemplate: 6740 cur_tok->end = buf_len(asm_template); 6741 break; 6742 } 6743 return ErrorNone; 6744 } 6745 6746 static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 6747 Error err; 6748 assert(node->type == NodeTypeAsmExpr); 6749 AstNodeAsmExpr *asm_expr = &node->data.asm_expr; 6750 bool is_volatile = asm_expr->volatile_token != nullptr; 6751 bool in_fn_scope = (scope_fn_entry(scope) != nullptr); 6752 6753 Buf *template_buf = &asm_expr->asm_template->data.str_lit.str; 6754 6755 if (!in_fn_scope) { 6756 if (is_volatile) { 6757 add_token_error(irb->codegen, node->owner, asm_expr->volatile_token, 6758 buf_sprintf("volatile is meaningless on global assembly")); 6759 return irb->codegen->invalid_instruction; 6760 } 6761 6762 if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 || 6763 asm_expr->clobber_list.length != 0) 6764 { 6765 add_node_error(irb->codegen, node, 6766 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers")); 6767 return irb->codegen->invalid_instruction; 6768 } 6769 6770 return ir_build_global_asm(irb, scope, node, template_buf); 6771 } 6772 6773 ZigList<AsmToken> tok_list = {}; 6774 if ((err = parse_asm_template(irb, node, template_buf, &tok_list))) { 6775 return irb->codegen->invalid_instruction; 6776 } 6777 6778 IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length); 6779 IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length); 6780 ZigVar **output_vars = allocate<ZigVar *>(asm_expr->output_list.length); 6781 size_t return_count = 0; 6782 if (!is_volatile && asm_expr->output_list.length == 0) { 6783 add_node_error(irb->codegen, node, 6784 buf_sprintf("assembly expression with no output must be marked volatile")); 6785 return irb->codegen->invalid_instruction; 6786 } 6787 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 6788 AsmOutput *asm_output = asm_expr->output_list.at(i); 6789 if (asm_output->return_type) { 6790 return_count += 1; 6791 6792 IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, scope); 6793 if (return_type == irb->codegen->invalid_instruction) 6794 return irb->codegen->invalid_instruction; 6795 if (return_count > 1) { 6796 add_node_error(irb->codegen, node, 6797 buf_sprintf("inline assembly allows up to one output value")); 6798 return irb->codegen->invalid_instruction; 6799 } 6800 output_types[i] = return_type; 6801 } else { 6802 Buf *variable_name = asm_output->variable_name; 6803 // TODO there is some duplication here with ir_gen_symbol. I need to do a full audit of how 6804 // inline assembly works. https://github.com/ziglang/zig/issues/215 6805 ZigVar *var = find_variable(irb->codegen, scope, variable_name, nullptr); 6806 if (var) { 6807 output_vars[i] = var; 6808 } else { 6809 add_node_error(irb->codegen, node, 6810 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); 6811 return irb->codegen->invalid_instruction; 6812 } 6813 } 6814 6815 const char modifier = *buf_ptr(asm_output->constraint); 6816 if (modifier != '=') { 6817 add_node_error(irb->codegen, node, 6818 buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported." 6819 " Compiler TODO: see https://github.com/ziglang/zig/issues/215", 6820 buf_ptr(asm_output->asm_symbolic_name), modifier)); 6821 return irb->codegen->invalid_instruction; 6822 } 6823 } 6824 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 6825 AsmInput *asm_input = asm_expr->input_list.at(i); 6826 IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, scope); 6827 if (input_value == irb->codegen->invalid_instruction) 6828 return irb->codegen->invalid_instruction; 6829 6830 input_list[i] = input_value; 6831 } 6832 6833 return ir_build_asm(irb, scope, node, template_buf, tok_list.items, tok_list.length, 6834 input_list, output_types, output_vars, return_count, is_volatile); 6835 } 6836 6837 static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 6838 ResultLoc *result_loc) 6839 { 6840 assert(node->type == NodeTypeIfOptional); 6841 6842 Buf *var_symbol = node->data.test_expr.var_symbol; 6843 AstNode *expr_node = node->data.test_expr.target_node; 6844 AstNode *then_node = node->data.test_expr.then_node; 6845 AstNode *else_node = node->data.test_expr.else_node; 6846 bool var_is_ptr = node->data.test_expr.var_is_ptr; 6847 6848 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 6849 if (maybe_val_ptr == irb->codegen->invalid_instruction) 6850 return maybe_val_ptr; 6851 6852 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); 6853 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_val); 6854 6855 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "OptionalThen"); 6856 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "OptionalElse"); 6857 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "OptionalEndIf"); 6858 6859 IrInstruction *is_comptime; 6860 if (ir_should_inline(irb->exec, scope)) { 6861 is_comptime = ir_build_const_bool(irb, scope, node, true); 6862 } else { 6863 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); 6864 } 6865 IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null, 6866 then_block, else_block, is_comptime); 6867 6868 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 6869 result_loc, is_comptime); 6870 6871 ir_set_cursor_at_end_and_append_block(irb, then_block); 6872 6873 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6874 Scope *var_scope; 6875 if (var_symbol) { 6876 bool is_shadowable = false; 6877 bool is_const = true; 6878 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 6879 var_symbol, is_const, is_const, is_shadowable, is_comptime); 6880 6881 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false); 6882 IrInstruction *var_ptr = var_is_ptr ? ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; 6883 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); 6884 var_scope = var->child_scope; 6885 } else { 6886 var_scope = subexpr_scope; 6887 } 6888 IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, 6889 &peer_parent->peers.at(0)->base); 6890 if (then_expr_result == irb->codegen->invalid_instruction) 6891 return then_expr_result; 6892 IrBasicBlock *after_then_block = irb->current_basic_block; 6893 if (!instr_is_unreachable(then_expr_result)) 6894 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 6895 6896 ir_set_cursor_at_end_and_append_block(irb, else_block); 6897 IrInstruction *else_expr_result; 6898 if (else_node) { 6899 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); 6900 if (else_expr_result == irb->codegen->invalid_instruction) 6901 return else_expr_result; 6902 } else { 6903 else_expr_result = ir_build_const_void(irb, scope, node); 6904 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 6905 } 6906 IrBasicBlock *after_else_block = irb->current_basic_block; 6907 if (!instr_is_unreachable(else_expr_result)) 6908 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 6909 6910 ir_set_cursor_at_end_and_append_block(irb, endif_block); 6911 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 6912 incoming_values[0] = then_expr_result; 6913 incoming_values[1] = else_expr_result; 6914 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 6915 incoming_blocks[0] = after_then_block; 6916 incoming_blocks[1] = after_else_block; 6917 6918 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 6919 return ir_expr_wrap(irb, scope, phi, result_loc); 6920 } 6921 6922 static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 6923 ResultLoc *result_loc) 6924 { 6925 assert(node->type == NodeTypeIfErrorExpr); 6926 6927 AstNode *target_node = node->data.if_err_expr.target_node; 6928 AstNode *then_node = node->data.if_err_expr.then_node; 6929 AstNode *else_node = node->data.if_err_expr.else_node; 6930 bool var_is_ptr = node->data.if_err_expr.var_is_ptr; 6931 bool var_is_const = true; 6932 Buf *var_symbol = node->data.if_err_expr.var_symbol; 6933 Buf *err_symbol = node->data.if_err_expr.err_symbol; 6934 6935 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); 6936 if (err_val_ptr == irb->codegen->invalid_instruction) 6937 return err_val_ptr; 6938 6939 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 6940 IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true, false); 6941 6942 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); 6943 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); 6944 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "TryEnd"); 6945 6946 bool force_comptime = ir_should_inline(irb->exec, scope); 6947 IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); 6948 IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); 6949 6950 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 6951 result_loc, is_comptime); 6952 6953 ir_set_cursor_at_end_and_append_block(irb, ok_block); 6954 6955 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6956 Scope *var_scope; 6957 if (var_symbol) { 6958 bool is_shadowable = false; 6959 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); 6960 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 6961 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); 6962 6963 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false, false); 6964 IrInstruction *var_ptr = var_is_ptr ? 6965 ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; 6966 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); 6967 var_scope = var->child_scope; 6968 } else { 6969 var_scope = subexpr_scope; 6970 } 6971 IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, 6972 &peer_parent->peers.at(0)->base); 6973 if (then_expr_result == irb->codegen->invalid_instruction) 6974 return then_expr_result; 6975 IrBasicBlock *after_then_block = irb->current_basic_block; 6976 if (!instr_is_unreachable(then_expr_result)) 6977 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 6978 6979 ir_set_cursor_at_end_and_append_block(irb, else_block); 6980 6981 IrInstruction *else_expr_result; 6982 if (else_node) { 6983 Scope *err_var_scope; 6984 if (err_symbol) { 6985 bool is_shadowable = false; 6986 bool is_const = true; 6987 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 6988 err_symbol, is_const, is_const, is_shadowable, is_comptime); 6989 6990 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr); 6991 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, err_ptr); 6992 err_var_scope = var->child_scope; 6993 } else { 6994 err_var_scope = subexpr_scope; 6995 } 6996 else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base); 6997 if (else_expr_result == irb->codegen->invalid_instruction) 6998 return else_expr_result; 6999 } else { 7000 else_expr_result = ir_build_const_void(irb, scope, node); 7001 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 7002 } 7003 IrBasicBlock *after_else_block = irb->current_basic_block; 7004 if (!instr_is_unreachable(else_expr_result)) 7005 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 7006 7007 ir_set_cursor_at_end_and_append_block(irb, endif_block); 7008 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 7009 incoming_values[0] = then_expr_result; 7010 incoming_values[1] = else_expr_result; 7011 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 7012 incoming_blocks[0] = after_then_block; 7013 incoming_blocks[1] = after_else_block; 7014 7015 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 7016 return ir_expr_wrap(irb, scope, phi, result_loc); 7017 } 7018 7019 static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, 7020 IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, 7021 IrInstruction *target_value_ptr, IrInstruction **prong_values, size_t prong_values_len, 7022 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values, 7023 IrInstructionSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc) 7024 { 7025 assert(switch_node->type == NodeTypeSwitchExpr); 7026 assert(prong_node->type == NodeTypeSwitchProng); 7027 7028 AstNode *expr_node = prong_node->data.switch_prong.expr; 7029 AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol; 7030 Scope *child_scope; 7031 if (var_symbol_node) { 7032 assert(var_symbol_node->type == NodeTypeSymbol); 7033 Buf *var_name = var_symbol_node->data.symbol_expr.symbol; 7034 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr; 7035 7036 bool is_shadowable = false; 7037 bool is_const = true; 7038 ZigVar *var = ir_create_var(irb, var_symbol_node, scope, 7039 var_name, is_const, is_const, is_shadowable, var_is_comptime); 7040 child_scope = var->child_scope; 7041 IrInstruction *var_ptr; 7042 if (out_switch_else_var != nullptr) { 7043 IrInstructionSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, 7044 target_value_ptr); 7045 *out_switch_else_var = switch_else_var; 7046 IrInstruction *payload_ptr = &switch_else_var->base; 7047 var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; 7048 } else if (prong_values != nullptr) { 7049 IrInstruction *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, 7050 prong_values, prong_values_len); 7051 var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; 7052 } else { 7053 var_ptr = var_is_ptr ? 7054 ir_build_ref(irb, scope, var_symbol_node, target_value_ptr, true, false) : target_value_ptr; 7055 } 7056 ir_build_var_decl_src(irb, scope, var_symbol_node, var, nullptr, var_ptr); 7057 } else { 7058 child_scope = scope; 7059 } 7060 7061 IrInstruction *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc); 7062 if (expr_result == irb->codegen->invalid_instruction) 7063 return false; 7064 if (!instr_is_unreachable(expr_result)) 7065 ir_mark_gen(ir_build_br(irb, scope, switch_node, end_block, is_comptime)); 7066 incoming_blocks->append(irb->current_basic_block); 7067 incoming_values->append(expr_result); 7068 return true; 7069 } 7070 7071 static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 7072 ResultLoc *result_loc) 7073 { 7074 assert(node->type == NodeTypeSwitchExpr); 7075 7076 AstNode *target_node = node->data.switch_expr.expr; 7077 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); 7078 if (target_value_ptr == irb->codegen->invalid_instruction) 7079 return target_value_ptr; 7080 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); 7081 7082 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "SwitchElse"); 7083 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "SwitchEnd"); 7084 7085 size_t prong_count = node->data.switch_expr.prongs.length; 7086 ZigList<IrInstructionSwitchBrCase> cases = {0}; 7087 7088 IrInstruction *is_comptime; 7089 IrInstruction *var_is_comptime; 7090 if (ir_should_inline(irb->exec, scope)) { 7091 is_comptime = ir_build_const_bool(irb, scope, node, true); 7092 var_is_comptime = is_comptime; 7093 } else { 7094 is_comptime = ir_build_test_comptime(irb, scope, node, target_value); 7095 var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr); 7096 } 7097 7098 ZigList<IrInstruction *> incoming_values = {0}; 7099 ZigList<IrBasicBlock *> incoming_blocks = {0}; 7100 ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0}; 7101 7102 IrInstructionSwitchElseVar *switch_else_var = nullptr; 7103 7104 ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); 7105 peer_parent->base.id = ResultLocIdPeerParent; 7106 peer_parent->end_bb = end_block; 7107 peer_parent->is_comptime = is_comptime; 7108 peer_parent->parent = result_loc; 7109 7110 ir_build_reset_result(irb, scope, node, &peer_parent->base); 7111 7112 // First do the else and the ranges 7113 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 7114 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 7115 AstNode *else_prong = nullptr; 7116 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 7117 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 7118 size_t prong_item_count = prong_node->data.switch_prong.items.length; 7119 if (prong_item_count == 0) { 7120 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 7121 if (else_prong) { 7122 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 7123 buf_sprintf("multiple else prongs in switch expression")); 7124 add_error_note(irb->codegen, msg, else_prong, 7125 buf_sprintf("previous else prong is here")); 7126 return irb->codegen->invalid_instruction; 7127 } 7128 else_prong = prong_node; 7129 7130 IrBasicBlock *prev_block = irb->current_basic_block; 7131 if (peer_parent->peers.length > 0) { 7132 peer_parent->peers.last()->next_bb = else_block; 7133 } 7134 peer_parent->peers.append(this_peer_result_loc); 7135 ir_set_cursor_at_end_and_append_block(irb, else_block); 7136 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 7137 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, 7138 &switch_else_var, LValNone, &this_peer_result_loc->base)) 7139 { 7140 return irb->codegen->invalid_instruction; 7141 } 7142 ir_set_cursor_at_end(irb, prev_block); 7143 } else if (prong_node->data.switch_prong.any_items_are_range) { 7144 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 7145 7146 IrInstruction *ok_bit = nullptr; 7147 AstNode *last_item_node = nullptr; 7148 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 7149 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 7150 last_item_node = item_node; 7151 if (item_node->type == NodeTypeSwitchRange) { 7152 AstNode *start_node = item_node->data.switch_range.start; 7153 AstNode *end_node = item_node->data.switch_range.end; 7154 7155 IrInstruction *start_value = ir_gen_node(irb, start_node, comptime_scope); 7156 if (start_value == irb->codegen->invalid_instruction) 7157 return irb->codegen->invalid_instruction; 7158 7159 IrInstruction *end_value = ir_gen_node(irb, end_node, comptime_scope); 7160 if (end_value == irb->codegen->invalid_instruction) 7161 return irb->codegen->invalid_instruction; 7162 7163 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 7164 check_range->start = start_value; 7165 check_range->end = end_value; 7166 7167 IrInstruction *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq, 7168 target_value, start_value, false); 7169 IrInstruction *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq, 7170 target_value, end_value, false); 7171 IrInstruction *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd, 7172 lower_range_ok, upper_range_ok, false); 7173 if (ok_bit) { 7174 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false); 7175 } else { 7176 ok_bit = both_ok; 7177 } 7178 } else { 7179 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); 7180 if (item_value == irb->codegen->invalid_instruction) 7181 return irb->codegen->invalid_instruction; 7182 7183 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 7184 check_range->start = item_value; 7185 check_range->end = item_value; 7186 7187 IrInstruction *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq, 7188 item_value, target_value, false); 7189 if (ok_bit) { 7190 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false); 7191 } else { 7192 ok_bit = cmp_ok; 7193 } 7194 } 7195 } 7196 7197 IrBasicBlock *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes"); 7198 IrBasicBlock *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo"); 7199 7200 assert(ok_bit); 7201 assert(last_item_node); 7202 IrInstruction *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, 7203 range_block_yes, range_block_no, is_comptime)); 7204 if (peer_parent->base.source_instruction == nullptr) { 7205 peer_parent->base.source_instruction = br_inst; 7206 } 7207 7208 if (peer_parent->peers.length > 0) { 7209 peer_parent->peers.last()->next_bb = range_block_yes; 7210 } 7211 peer_parent->peers.append(this_peer_result_loc); 7212 ir_set_cursor_at_end_and_append_block(irb, range_block_yes); 7213 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 7214 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, 7215 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) 7216 { 7217 return irb->codegen->invalid_instruction; 7218 } 7219 7220 ir_set_cursor_at_end_and_append_block(irb, range_block_no); 7221 } 7222 } 7223 7224 // next do the non-else non-ranges 7225 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 7226 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 7227 size_t prong_item_count = prong_node->data.switch_prong.items.length; 7228 if (prong_item_count == 0) 7229 continue; 7230 if (prong_node->data.switch_prong.any_items_are_range) 7231 continue; 7232 7233 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 7234 7235 IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); 7236 IrInstruction **items = allocate<IrInstruction *>(prong_item_count); 7237 7238 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 7239 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 7240 assert(item_node->type != NodeTypeSwitchRange); 7241 7242 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); 7243 if (item_value == irb->codegen->invalid_instruction) 7244 return irb->codegen->invalid_instruction; 7245 7246 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 7247 check_range->start = item_value; 7248 check_range->end = item_value; 7249 7250 IrInstructionSwitchBrCase *this_case = cases.add_one(); 7251 this_case->value = item_value; 7252 this_case->block = prong_block; 7253 7254 items[item_i] = item_value; 7255 } 7256 7257 IrBasicBlock *prev_block = irb->current_basic_block; 7258 if (peer_parent->peers.length > 0) { 7259 peer_parent->peers.last()->next_bb = prong_block; 7260 } 7261 peer_parent->peers.append(this_peer_result_loc); 7262 ir_set_cursor_at_end_and_append_block(irb, prong_block); 7263 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 7264 is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, 7265 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) 7266 { 7267 return irb->codegen->invalid_instruction; 7268 } 7269 7270 ir_set_cursor_at_end(irb, prev_block); 7271 7272 } 7273 7274 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, 7275 check_ranges.items, check_ranges.length, else_prong != nullptr); 7276 7277 IrInstruction *br_instruction; 7278 if (cases.length == 0) { 7279 br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); 7280 } else { 7281 IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, scope, node, target_value, else_block, 7282 cases.length, cases.items, is_comptime, switch_prongs_void); 7283 if (switch_else_var != nullptr) { 7284 switch_else_var->switch_br = switch_br; 7285 } 7286 br_instruction = &switch_br->base; 7287 } 7288 if (peer_parent->base.source_instruction == nullptr) { 7289 peer_parent->base.source_instruction = br_instruction; 7290 } 7291 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 7292 peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction; 7293 } 7294 7295 if (!else_prong) { 7296 if (peer_parent->peers.length != 0) { 7297 peer_parent->peers.last()->next_bb = else_block; 7298 } 7299 ir_set_cursor_at_end_and_append_block(irb, else_block); 7300 ir_build_unreachable(irb, scope, node); 7301 } else { 7302 if (peer_parent->peers.length != 0) { 7303 peer_parent->peers.last()->next_bb = end_block; 7304 } 7305 } 7306 7307 ir_set_cursor_at_end_and_append_block(irb, end_block); 7308 assert(incoming_blocks.length == incoming_values.length); 7309 IrInstruction *result_instruction; 7310 if (incoming_blocks.length == 0) { 7311 result_instruction = ir_build_const_void(irb, scope, node); 7312 } else { 7313 result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, 7314 incoming_blocks.items, incoming_values.items, peer_parent); 7315 } 7316 return ir_lval_wrap(irb, scope, result_instruction, lval, result_loc); 7317 } 7318 7319 static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { 7320 assert(node->type == NodeTypeCompTime); 7321 7322 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); 7323 // purposefully pass null for result_loc and let EndExpr handle it 7324 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); 7325 } 7326 7327 static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { 7328 IrInstruction *is_comptime; 7329 if (ir_should_inline(irb->exec, break_scope)) { 7330 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 7331 } else { 7332 is_comptime = block_scope->is_comptime; 7333 } 7334 7335 IrInstruction *result_value; 7336 if (node->data.break_expr.expr) { 7337 ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent); 7338 block_scope->peer_parent->peers.append(peer_result); 7339 7340 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, block_scope->lval, 7341 &peer_result->base); 7342 if (result_value == irb->codegen->invalid_instruction) 7343 return irb->codegen->invalid_instruction; 7344 } else { 7345 result_value = ir_build_const_void(irb, break_scope, node); 7346 } 7347 7348 IrBasicBlock *dest_block = block_scope->end_block; 7349 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 7350 7351 block_scope->incoming_blocks->append(irb->current_basic_block); 7352 block_scope->incoming_values->append(result_value); 7353 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 7354 } 7355 7356 static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *node) { 7357 assert(node->type == NodeTypeBreak); 7358 7359 // Search up the scope. We'll find one of these things first: 7360 // * function definition scope or global scope => error, break outside loop 7361 // * defer expression scope => error, cannot break out of defer expression 7362 // * loop scope => OK 7363 // * (if it's a labeled break) labeled block => OK 7364 7365 Scope *search_scope = break_scope; 7366 ScopeLoop *loop_scope; 7367 for (;;) { 7368 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 7369 if (node->data.break_expr.name != nullptr) { 7370 add_node_error(irb->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name))); 7371 return irb->codegen->invalid_instruction; 7372 } else { 7373 add_node_error(irb->codegen, node, buf_sprintf("break expression outside loop")); 7374 return irb->codegen->invalid_instruction; 7375 } 7376 } else if (search_scope->id == ScopeIdDeferExpr) { 7377 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of defer expression")); 7378 return irb->codegen->invalid_instruction; 7379 } else if (search_scope->id == ScopeIdLoop) { 7380 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 7381 if (node->data.break_expr.name == nullptr || 7382 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name))) 7383 { 7384 loop_scope = this_loop_scope; 7385 break; 7386 } 7387 } else if (search_scope->id == ScopeIdBlock) { 7388 ScopeBlock *this_block_scope = (ScopeBlock *)search_scope; 7389 if (node->data.break_expr.name != nullptr && 7390 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name))) 7391 { 7392 assert(this_block_scope->end_block != nullptr); 7393 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope); 7394 } 7395 } else if (search_scope->id == ScopeIdSuspend) { 7396 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of suspend block")); 7397 return irb->codegen->invalid_instruction; 7398 } 7399 search_scope = search_scope->parent; 7400 } 7401 7402 IrInstruction *is_comptime; 7403 if (ir_should_inline(irb->exec, break_scope)) { 7404 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 7405 } else { 7406 is_comptime = loop_scope->is_comptime; 7407 } 7408 7409 IrInstruction *result_value; 7410 if (node->data.break_expr.expr) { 7411 ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent); 7412 loop_scope->peer_parent->peers.append(peer_result); 7413 7414 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, 7415 loop_scope->lval, &peer_result->base); 7416 if (result_value == irb->codegen->invalid_instruction) 7417 return irb->codegen->invalid_instruction; 7418 } else { 7419 result_value = ir_build_const_void(irb, break_scope, node); 7420 } 7421 7422 IrBasicBlock *dest_block = loop_scope->break_block; 7423 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 7424 7425 loop_scope->incoming_blocks->append(irb->current_basic_block); 7426 loop_scope->incoming_values->append(result_value); 7427 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 7428 } 7429 7430 static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, AstNode *node) { 7431 assert(node->type == NodeTypeContinue); 7432 7433 // Search up the scope. We'll find one of these things first: 7434 // * function definition scope or global scope => error, break outside loop 7435 // * defer expression scope => error, cannot break out of defer expression 7436 // * loop scope => OK 7437 7438 ZigList<ScopeRuntime *> runtime_scopes = {}; 7439 7440 Scope *search_scope = continue_scope; 7441 ScopeLoop *loop_scope; 7442 for (;;) { 7443 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 7444 if (node->data.continue_expr.name != nullptr) { 7445 add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name))); 7446 return irb->codegen->invalid_instruction; 7447 } else { 7448 add_node_error(irb->codegen, node, buf_sprintf("continue expression outside loop")); 7449 return irb->codegen->invalid_instruction; 7450 } 7451 } else if (search_scope->id == ScopeIdDeferExpr) { 7452 add_node_error(irb->codegen, node, buf_sprintf("cannot continue out of defer expression")); 7453 return irb->codegen->invalid_instruction; 7454 } else if (search_scope->id == ScopeIdLoop) { 7455 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 7456 if (node->data.continue_expr.name == nullptr || 7457 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name))) 7458 { 7459 loop_scope = this_loop_scope; 7460 break; 7461 } 7462 } else if (search_scope->id == ScopeIdRuntime) { 7463 ScopeRuntime *scope_runtime = (ScopeRuntime *)search_scope; 7464 runtime_scopes.append(scope_runtime); 7465 } 7466 search_scope = search_scope->parent; 7467 } 7468 7469 IrInstruction *is_comptime; 7470 if (ir_should_inline(irb->exec, continue_scope)) { 7471 is_comptime = ir_build_const_bool(irb, continue_scope, node, true); 7472 } else { 7473 is_comptime = loop_scope->is_comptime; 7474 } 7475 7476 for (size_t i = 0; i < runtime_scopes.length; i += 1) { 7477 ScopeRuntime *scope_runtime = runtime_scopes.at(i); 7478 ir_mark_gen(ir_build_check_runtime_scope(irb, continue_scope, node, scope_runtime->is_comptime, is_comptime)); 7479 } 7480 7481 IrBasicBlock *dest_block = loop_scope->continue_block; 7482 ir_gen_defers_for_block(irb, continue_scope, dest_block->scope, false); 7483 return ir_mark_gen(ir_build_br(irb, continue_scope, node, dest_block, is_comptime)); 7484 } 7485 7486 static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) { 7487 assert(node->type == NodeTypeErrorType); 7488 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set); 7489 } 7490 7491 static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 7492 assert(node->type == NodeTypeDefer); 7493 7494 ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope); 7495 node->data.defer.child_scope = &defer_child_scope->base; 7496 7497 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope); 7498 node->data.defer.expr_scope = &defer_expr_scope->base; 7499 7500 return ir_build_const_void(irb, parent_scope, node); 7501 } 7502 7503 static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 7504 assert(node->type == NodeTypeSliceExpr); 7505 7506 AstNodeSliceExpr *slice_expr = &node->data.slice_expr; 7507 AstNode *array_node = slice_expr->array_ref_expr; 7508 AstNode *start_node = slice_expr->start; 7509 AstNode *end_node = slice_expr->end; 7510 7511 IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr); 7512 if (ptr_value == irb->codegen->invalid_instruction) 7513 return irb->codegen->invalid_instruction; 7514 7515 IrInstruction *start_value = ir_gen_node(irb, start_node, scope); 7516 if (start_value == irb->codegen->invalid_instruction) 7517 return irb->codegen->invalid_instruction; 7518 7519 IrInstruction *end_value; 7520 if (end_node) { 7521 end_value = ir_gen_node(irb, end_node, scope); 7522 if (end_value == irb->codegen->invalid_instruction) 7523 return irb->codegen->invalid_instruction; 7524 } else { 7525 end_value = nullptr; 7526 } 7527 7528 IrInstruction *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, true, result_loc); 7529 return ir_lval_wrap(irb, scope, slice, lval, result_loc); 7530 } 7531 7532 static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, 7533 ResultLoc *result_loc) 7534 { 7535 assert(node->type == NodeTypeCatchExpr); 7536 7537 AstNode *op1_node = node->data.unwrap_err_expr.op1; 7538 AstNode *op2_node = node->data.unwrap_err_expr.op2; 7539 AstNode *var_node = node->data.unwrap_err_expr.symbol; 7540 7541 if (op2_node->type == NodeTypeUnreachable) { 7542 if (var_node != nullptr) { 7543 assert(var_node->type == NodeTypeSymbol); 7544 Buf *var_name = var_node->data.symbol_expr.symbol; 7545 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); 7546 return irb->codegen->invalid_instruction; 7547 } 7548 return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc); 7549 } 7550 7551 7552 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); 7553 if (err_union_ptr == irb->codegen->invalid_instruction) 7554 return irb->codegen->invalid_instruction; 7555 7556 IrInstruction *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true, false); 7557 7558 IrInstruction *is_comptime; 7559 if (ir_should_inline(irb->exec, parent_scope)) { 7560 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 7561 } else { 7562 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_err); 7563 } 7564 7565 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); 7566 IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); 7567 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); 7568 IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); 7569 7570 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc, 7571 is_comptime); 7572 7573 ir_set_cursor_at_end_and_append_block(irb, err_block); 7574 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, parent_scope, is_comptime); 7575 Scope *err_scope; 7576 if (var_node) { 7577 assert(var_node->type == NodeTypeSymbol); 7578 Buf *var_name = var_node->data.symbol_expr.symbol; 7579 bool is_const = true; 7580 bool is_shadowable = false; 7581 ZigVar *var = ir_create_var(irb, node, subexpr_scope, var_name, 7582 is_const, is_const, is_shadowable, is_comptime); 7583 err_scope = var->child_scope; 7584 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); 7585 ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, err_ptr); 7586 } else { 7587 err_scope = subexpr_scope; 7588 } 7589 IrInstruction *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base); 7590 if (err_result == irb->codegen->invalid_instruction) 7591 return irb->codegen->invalid_instruction; 7592 IrBasicBlock *after_err_block = irb->current_basic_block; 7593 if (!instr_is_unreachable(err_result)) 7594 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 7595 7596 ir_set_cursor_at_end_and_append_block(irb, ok_block); 7597 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false, false); 7598 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 7599 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); 7600 IrBasicBlock *after_ok_block = irb->current_basic_block; 7601 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 7602 7603 ir_set_cursor_at_end_and_append_block(irb, end_block); 7604 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 7605 incoming_values[0] = err_result; 7606 incoming_values[1] = unwrapped_payload; 7607 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 7608 incoming_blocks[0] = after_err_block; 7609 incoming_blocks[1] = after_ok_block; 7610 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); 7611 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 7612 } 7613 7614 static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { 7615 if (inner_scope == nullptr || inner_scope == outer_scope) return false; 7616 bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent); 7617 if (inner_scope->id != ScopeIdVarDecl) 7618 return need_comma; 7619 7620 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; 7621 if (need_comma) 7622 buf_append_char(name, ','); 7623 // TODO: const ptr reinterpret here to make the var type agree with the value? 7624 render_const_value(codegen, name, var_scope->var->const_value); 7625 return true; 7626 } 7627 7628 static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, 7629 Scope *scope, AstNode *source_node, Buf *out_bare_name) 7630 { 7631 if (exec->name) { 7632 ZigType *import = get_scope_import(scope); 7633 Buf *namespace_name = buf_create_from_buf(&import->name); 7634 if (buf_len(namespace_name) != 0) buf_append_char(namespace_name, NAMESPACE_SEP_CHAR); 7635 buf_append_buf(namespace_name, exec->name); 7636 buf_init_from_buf(out_bare_name, exec->name); 7637 return namespace_name; 7638 } else if (exec->name_fn != nullptr) { 7639 Buf *name = buf_alloc(); 7640 buf_append_buf(name, &exec->name_fn->symbol_name); 7641 buf_appendf(name, "("); 7642 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope); 7643 buf_appendf(name, ")"); 7644 buf_init_from_buf(out_bare_name, name); 7645 return name; 7646 } else { 7647 ZigType *import = get_scope_import(scope); 7648 Buf *namespace_name = buf_create_from_buf(&import->name); 7649 if (buf_len(namespace_name) != 0) buf_append_char(namespace_name, NAMESPACE_SEP_CHAR); 7650 buf_appendf(namespace_name, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, kind_name, 7651 source_node->line + 1, source_node->column + 1); 7652 buf_init_from_buf(out_bare_name, namespace_name); 7653 return namespace_name; 7654 } 7655 } 7656 7657 static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 7658 assert(node->type == NodeTypeContainerDecl); 7659 7660 ContainerKind kind = node->data.container_decl.kind; 7661 Buf *bare_name = buf_alloc(); 7662 Buf *name = get_anon_type_name(irb->codegen, irb->exec, container_string(kind), parent_scope, node, bare_name); 7663 7664 ContainerLayout layout = node->data.container_decl.layout; 7665 ZigType *container_type = get_partial_container_type(irb->codegen, parent_scope, 7666 kind, node, buf_ptr(name), bare_name, layout); 7667 ScopeDecls *child_scope = get_container_scope(container_type); 7668 7669 for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) { 7670 AstNode *child_node = node->data.container_decl.decls.at(i); 7671 scan_decls(irb->codegen, child_scope, child_node); 7672 } 7673 7674 TldContainer *tld_container = allocate<TldContainer>(1); 7675 init_tld(&tld_container->base, TldIdContainer, bare_name, VisibModPub, node, parent_scope); 7676 tld_container->type_entry = container_type; 7677 tld_container->decls_scope = child_scope; 7678 irb->codegen->resolve_queue.append(&tld_container->base); 7679 7680 // Add this to the list to mark as invalid if analyzing this exec fails. 7681 irb->exec->tld_list.append(&tld_container->base); 7682 7683 return ir_build_const_type(irb, parent_scope, node, container_type); 7684 } 7685 7686 // errors should be populated with set1's values 7687 static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigType *set1, ZigType *set2) { 7688 assert(set1->id == ZigTypeIdErrorSet); 7689 assert(set2->id == ZigTypeIdErrorSet); 7690 7691 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 7692 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 7693 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 7694 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 7695 buf_resize(&err_set_type->name, 0); 7696 buf_appendf(&err_set_type->name, "error{"); 7697 7698 for (uint32_t i = 0, count = set1->data.error_set.err_count; i < count; i += 1) { 7699 assert(errors[set1->data.error_set.errors[i]->value] == set1->data.error_set.errors[i]); 7700 } 7701 7702 uint32_t count = set1->data.error_set.err_count; 7703 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 7704 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 7705 if (errors[error_entry->value] == nullptr) { 7706 count += 1; 7707 } 7708 } 7709 7710 err_set_type->data.error_set.err_count = count; 7711 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(count); 7712 7713 for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { 7714 ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; 7715 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 7716 err_set_type->data.error_set.errors[i] = error_entry; 7717 } 7718 7719 uint32_t index = set1->data.error_set.err_count; 7720 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 7721 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 7722 if (errors[error_entry->value] == nullptr) { 7723 errors[error_entry->value] = error_entry; 7724 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 7725 err_set_type->data.error_set.errors[index] = error_entry; 7726 index += 1; 7727 } 7728 } 7729 assert(index == count); 7730 assert(count != 0); 7731 7732 buf_appendf(&err_set_type->name, "}"); 7733 7734 return err_set_type; 7735 7736 } 7737 7738 static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstNode *node, 7739 ErrorTableEntry *err_entry) 7740 { 7741 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 7742 buf_resize(&err_set_type->name, 0); 7743 buf_appendf(&err_set_type->name, "error{%s}", buf_ptr(&err_entry->name)); 7744 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 7745 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 7746 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 7747 err_set_type->data.error_set.err_count = 1; 7748 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1); 7749 7750 err_set_type->data.error_set.errors[0] = err_entry; 7751 7752 return err_set_type; 7753 } 7754 7755 static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 7756 assert(node->type == NodeTypeErrorSetDecl); 7757 7758 uint32_t err_count = node->data.err_set_decl.decls.length; 7759 7760 Buf bare_name = BUF_INIT; 7761 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", parent_scope, node, &bare_name); 7762 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 7763 buf_init_from_buf(&err_set_type->name, type_name); 7764 err_set_type->data.error_set.err_count = err_count; 7765 err_set_type->size_in_bits = irb->codegen->builtin_types.entry_global_error_set->size_in_bits; 7766 err_set_type->abi_align = irb->codegen->builtin_types.entry_global_error_set->abi_align; 7767 err_set_type->abi_size = irb->codegen->builtin_types.entry_global_error_set->abi_size; 7768 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(err_count); 7769 7770 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(irb->codegen->errors_by_index.length + err_count); 7771 7772 for (uint32_t i = 0; i < err_count; i += 1) { 7773 AstNode *symbol_node = node->data.err_set_decl.decls.at(i); 7774 assert(symbol_node->type == NodeTypeSymbol); 7775 Buf *err_name = symbol_node->data.symbol_expr.symbol; 7776 ErrorTableEntry *err = allocate<ErrorTableEntry>(1); 7777 err->decl_node = symbol_node; 7778 buf_init_from_buf(&err->name, err_name); 7779 7780 auto existing_entry = irb->codegen->error_table.put_unique(err_name, err); 7781 if (existing_entry) { 7782 err->value = existing_entry->value->value; 7783 } else { 7784 size_t error_value_count = irb->codegen->errors_by_index.length; 7785 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)irb->codegen->err_tag_type->data.integral.bit_count)); 7786 err->value = error_value_count; 7787 irb->codegen->errors_by_index.append(err); 7788 } 7789 err_set_type->data.error_set.errors[i] = err; 7790 7791 ErrorTableEntry *prev_err = errors[err->value]; 7792 if (prev_err != nullptr) { 7793 ErrorMsg *msg = add_node_error(irb->codegen, err->decl_node, buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name))); 7794 add_error_note(irb->codegen, msg, prev_err->decl_node, buf_sprintf("other error here")); 7795 return irb->codegen->invalid_instruction; 7796 } 7797 errors[err->value] = err; 7798 } 7799 free(errors); 7800 return ir_build_const_type(irb, parent_scope, node, err_set_type); 7801 } 7802 7803 static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 7804 assert(node->type == NodeTypeFnProto); 7805 7806 size_t param_count = node->data.fn_proto.params.length; 7807 IrInstruction **param_types = allocate<IrInstruction*>(param_count); 7808 7809 bool is_var_args = false; 7810 for (size_t i = 0; i < param_count; i += 1) { 7811 AstNode *param_node = node->data.fn_proto.params.at(i); 7812 if (param_node->data.param_decl.is_var_args) { 7813 is_var_args = true; 7814 break; 7815 } 7816 if (param_node->data.param_decl.var_token == nullptr) { 7817 AstNode *type_node = param_node->data.param_decl.type; 7818 IrInstruction *type_value = ir_gen_node(irb, type_node, parent_scope); 7819 if (type_value == irb->codegen->invalid_instruction) 7820 return irb->codegen->invalid_instruction; 7821 param_types[i] = type_value; 7822 } else { 7823 param_types[i] = nullptr; 7824 } 7825 } 7826 7827 IrInstruction *align_value = nullptr; 7828 if (node->data.fn_proto.align_expr != nullptr) { 7829 align_value = ir_gen_node(irb, node->data.fn_proto.align_expr, parent_scope); 7830 if (align_value == irb->codegen->invalid_instruction) 7831 return irb->codegen->invalid_instruction; 7832 } 7833 7834 IrInstruction *return_type; 7835 if (node->data.fn_proto.return_var_token == nullptr) { 7836 if (node->data.fn_proto.return_type == nullptr) { 7837 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void); 7838 } else { 7839 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope); 7840 if (return_type == irb->codegen->invalid_instruction) 7841 return irb->codegen->invalid_instruction; 7842 } 7843 } else { 7844 add_node_error(irb->codegen, node, 7845 buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); 7846 return irb->codegen->invalid_instruction; 7847 //return_type = nullptr; 7848 } 7849 7850 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args); 7851 } 7852 7853 static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) { 7854 assert(node->type == NodeTypeResume); 7855 7856 IrInstruction *target_inst = ir_gen_node_extra(irb, node->data.resume_expr.expr, scope, LValPtr, nullptr); 7857 if (target_inst == irb->codegen->invalid_instruction) 7858 return irb->codegen->invalid_instruction; 7859 7860 return ir_build_resume(irb, scope, node, target_inst); 7861 } 7862 7863 static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 7864 ResultLoc *result_loc) 7865 { 7866 assert(node->type == NodeTypeAwaitExpr); 7867 7868 ZigFn *fn_entry = exec_fn_entry(irb->exec); 7869 if (!fn_entry) { 7870 add_node_error(irb->codegen, node, buf_sprintf("await outside function definition")); 7871 return irb->codegen->invalid_instruction; 7872 } 7873 ScopeSuspend *existing_suspend_scope = get_scope_suspend(scope); 7874 if (existing_suspend_scope) { 7875 if (!existing_suspend_scope->reported_err) { 7876 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot await inside suspend block")); 7877 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("suspend block here")); 7878 existing_suspend_scope->reported_err = true; 7879 } 7880 return irb->codegen->invalid_instruction; 7881 } 7882 7883 IrInstruction *target_inst = ir_gen_node_extra(irb, node->data.await_expr.expr, scope, LValPtr, nullptr); 7884 if (target_inst == irb->codegen->invalid_instruction) 7885 return irb->codegen->invalid_instruction; 7886 7887 IrInstruction *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc); 7888 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc); 7889 } 7890 7891 static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 7892 assert(node->type == NodeTypeSuspend); 7893 7894 ZigFn *fn_entry = exec_fn_entry(irb->exec); 7895 if (!fn_entry) { 7896 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition")); 7897 return irb->codegen->invalid_instruction; 7898 } 7899 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope); 7900 if (existing_suspend_scope) { 7901 if (!existing_suspend_scope->reported_err) { 7902 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block")); 7903 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here")); 7904 existing_suspend_scope->reported_err = true; 7905 } 7906 return irb->codegen->invalid_instruction; 7907 } 7908 7909 IrInstructionSuspendBegin *begin = ir_build_suspend_begin(irb, parent_scope, node); 7910 if (node->data.suspend.block != nullptr) { 7911 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); 7912 Scope *child_scope = &suspend_scope->base; 7913 IrInstruction *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); 7914 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res)); 7915 } 7916 7917 return ir_build_suspend_finish(irb, parent_scope, node, begin); 7918 } 7919 7920 static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, 7921 LVal lval, ResultLoc *result_loc) 7922 { 7923 assert(scope); 7924 switch (node->type) { 7925 case NodeTypeStructValueField: 7926 case NodeTypeParamDecl: 7927 case NodeTypeUsingNamespace: 7928 case NodeTypeSwitchProng: 7929 case NodeTypeSwitchRange: 7930 case NodeTypeStructField: 7931 case NodeTypeFnDef: 7932 case NodeTypeTestDecl: 7933 zig_unreachable(); 7934 case NodeTypeBlock: 7935 return ir_gen_block(irb, scope, node, lval, result_loc); 7936 case NodeTypeGroupedExpr: 7937 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc); 7938 case NodeTypeBinOpExpr: 7939 return ir_gen_bin_op(irb, scope, node, lval, result_loc); 7940 case NodeTypeIntLiteral: 7941 return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc); 7942 case NodeTypeFloatLiteral: 7943 return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval, result_loc); 7944 case NodeTypeCharLiteral: 7945 return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval, result_loc); 7946 case NodeTypeSymbol: 7947 return ir_gen_symbol(irb, scope, node, lval, result_loc); 7948 case NodeTypeFnCallExpr: 7949 return ir_gen_fn_call(irb, scope, node, lval, result_loc); 7950 case NodeTypeIfBoolExpr: 7951 return ir_gen_if_bool_expr(irb, scope, node, lval, result_loc); 7952 case NodeTypePrefixOpExpr: 7953 return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc); 7954 case NodeTypeContainerInitExpr: 7955 return ir_gen_container_init_expr(irb, scope, node, lval, result_loc); 7956 case NodeTypeVariableDeclaration: 7957 return ir_gen_var_decl(irb, scope, node); 7958 case NodeTypeWhileExpr: 7959 return ir_gen_while_expr(irb, scope, node, lval, result_loc); 7960 case NodeTypeForExpr: 7961 return ir_gen_for_expr(irb, scope, node, lval, result_loc); 7962 case NodeTypeArrayAccessExpr: 7963 return ir_gen_array_access(irb, scope, node, lval, result_loc); 7964 case NodeTypeReturnExpr: 7965 return ir_gen_return(irb, scope, node, lval, result_loc); 7966 case NodeTypeFieldAccessExpr: 7967 { 7968 IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); 7969 if (ptr_instruction == irb->codegen->invalid_instruction) 7970 return ptr_instruction; 7971 if (lval == LValPtr) 7972 return ptr_instruction; 7973 7974 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 7975 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 7976 } 7977 case NodeTypePtrDeref: { 7978 AstNode *expr_node = node->data.ptr_deref_expr.target; 7979 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); 7980 if (value == irb->codegen->invalid_instruction) 7981 return value; 7982 7983 // We essentially just converted any lvalue from &(x.*) to (&x).*; 7984 // this inhibits checking that x is a pointer later, so we directly 7985 // record whether the pointer check is needed 7986 IrInstruction *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc); 7987 return ir_expr_wrap(irb, scope, un_op, result_loc); 7988 } 7989 case NodeTypeUnwrapOptional: { 7990 AstNode *expr_node = node->data.unwrap_optional.expr; 7991 7992 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 7993 if (maybe_ptr == irb->codegen->invalid_instruction) 7994 return irb->codegen->invalid_instruction; 7995 7996 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true, false); 7997 if (lval == LValPtr) 7998 return unwrapped_ptr; 7999 8000 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr); 8001 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 8002 } 8003 case NodeTypeBoolLiteral: 8004 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval, result_loc); 8005 case NodeTypeArrayType: 8006 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc); 8007 case NodeTypePointerType: 8008 return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc); 8009 case NodeTypeAnyFrameType: 8010 return ir_lval_wrap(irb, scope, ir_gen_anyframe_type(irb, scope, node), lval, result_loc); 8011 case NodeTypeStringLiteral: 8012 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc); 8013 case NodeTypeUndefinedLiteral: 8014 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval, result_loc); 8015 case NodeTypeAsmExpr: 8016 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval, result_loc); 8017 case NodeTypeNullLiteral: 8018 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc); 8019 case NodeTypeIfErrorExpr: 8020 return ir_gen_if_err_expr(irb, scope, node, lval, result_loc); 8021 case NodeTypeIfOptional: 8022 return ir_gen_if_optional_expr(irb, scope, node, lval, result_loc); 8023 case NodeTypeSwitchExpr: 8024 return ir_gen_switch_expr(irb, scope, node, lval, result_loc); 8025 case NodeTypeCompTime: 8026 return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); 8027 case NodeTypeErrorType: 8028 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc); 8029 case NodeTypeBreak: 8030 return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval, result_loc); 8031 case NodeTypeContinue: 8032 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc); 8033 case NodeTypeUnreachable: 8034 return ir_build_unreachable(irb, scope, node); 8035 case NodeTypeDefer: 8036 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc); 8037 case NodeTypeSliceExpr: 8038 return ir_gen_slice(irb, scope, node, lval, result_loc); 8039 case NodeTypeCatchExpr: 8040 return ir_gen_catch(irb, scope, node, lval, result_loc); 8041 case NodeTypeContainerDecl: 8042 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval, result_loc); 8043 case NodeTypeFnProto: 8044 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval, result_loc); 8045 case NodeTypeErrorSetDecl: 8046 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval, result_loc); 8047 case NodeTypeResume: 8048 return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval, result_loc); 8049 case NodeTypeAwaitExpr: 8050 return ir_gen_await_expr(irb, scope, node, lval, result_loc); 8051 case NodeTypeSuspend: 8052 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval, result_loc); 8053 case NodeTypeEnumLiteral: 8054 return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval, result_loc); 8055 case NodeTypeInferredArrayType: 8056 add_node_error(irb->codegen, node, 8057 buf_sprintf("inferred array size invalid here")); 8058 return irb->codegen->invalid_instruction; 8059 } 8060 zig_unreachable(); 8061 } 8062 8063 static ResultLoc *no_result_loc(void) { 8064 ResultLocNone *result_loc_none = allocate<ResultLocNone>(1); 8065 result_loc_none->base.id = ResultLocIdNone; 8066 return &result_loc_none->base; 8067 } 8068 8069 static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, 8070 ResultLoc *result_loc) 8071 { 8072 if (result_loc == nullptr) { 8073 // Create a result location indicating there is none - but if one gets created 8074 // it will be properly distributed. 8075 result_loc = no_result_loc(); 8076 ir_build_reset_result(irb, scope, node, result_loc); 8077 } 8078 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc); 8079 irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); 8080 return result; 8081 } 8082 8083 static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { 8084 return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); 8085 } 8086 8087 static void invalidate_exec(IrExecutable *exec) { 8088 if (exec->invalid) 8089 return; 8090 8091 exec->invalid = true; 8092 8093 for (size_t i = 0; i < exec->tld_list.length; i += 1) { 8094 exec->tld_list.items[i]->resolution = TldResolutionInvalid; 8095 } 8096 8097 if (exec->source_exec != nullptr) 8098 invalidate_exec(exec->source_exec); 8099 } 8100 8101 8102 bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) { 8103 assert(node->owner); 8104 8105 IrBuilder ir_builder = {0}; 8106 IrBuilder *irb = &ir_builder; 8107 8108 irb->codegen = codegen; 8109 irb->exec = ir_executable; 8110 irb->main_block_node = node; 8111 8112 IrBasicBlock *entry_block = ir_create_basic_block(irb, scope, "Entry"); 8113 ir_set_cursor_at_end_and_append_block(irb, entry_block); 8114 // Entry block gets a reference because we enter it to begin. 8115 ir_ref_bb(irb->current_basic_block); 8116 8117 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); 8118 assert(result); 8119 if (irb->exec->invalid) 8120 return false; 8121 8122 if (!instr_is_unreachable(result)) { 8123 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result)); 8124 // no need for save_err_ret_addr because this cannot return error 8125 ir_mark_gen(ir_build_return(irb, scope, result->source_node, result)); 8126 } 8127 8128 return true; 8129 } 8130 8131 bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { 8132 assert(fn_entry); 8133 8134 IrExecutable *ir_executable = &fn_entry->ir_executable; 8135 AstNode *body_node = fn_entry->body_node; 8136 8137 assert(fn_entry->child_scope); 8138 8139 return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); 8140 } 8141 8142 static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) { 8143 if (!exec || !exec->source_node || limit < 0) return; 8144 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); 8145 8146 ir_add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1); 8147 } 8148 8149 void ir_add_analysis_trace(IrAnalyze *ira, ErrorMsg *err_msg, Buf *text) { 8150 IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 8151 add_error_note(ira->codegen, err_msg, old_instruction->source_node, text); 8152 ir_add_call_stack_errors(ira->codegen, ira->new_irb.exec, err_msg, 10); 8153 } 8154 8155 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) { 8156 invalidate_exec(exec); 8157 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); 8158 if (exec->parent_exec) { 8159 ir_add_call_stack_errors(codegen, exec, err_msg, 10); 8160 } 8161 return err_msg; 8162 } 8163 8164 static ErrorMsg *ir_add_error_node(IrAnalyze *ira, AstNode *source_node, Buf *msg) { 8165 return exec_add_error_node(ira->codegen, ira->new_irb.exec, source_node, msg); 8166 } 8167 8168 static ErrorMsg *opt_ir_add_error_node(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, Buf *msg) { 8169 if (ira != nullptr) 8170 return exec_add_error_node(codegen, ira->new_irb.exec, source_node, msg); 8171 else 8172 return add_node_error(codegen, source_node, msg); 8173 } 8174 8175 static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction, Buf *msg) { 8176 return ir_add_error_node(ira, source_instruction->source_node, msg); 8177 } 8178 8179 static void ir_assert(bool ok, IrInstruction *source_instruction) { 8180 if (ok) return; 8181 src_assert(ok, source_instruction->source_node); 8182 } 8183 8184 // This function takes a comptime ptr and makes the child const value conform to the type 8185 // described by the pointer. 8186 static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 8187 ConstExprValue *ptr_val) 8188 { 8189 Error err; 8190 assert(ptr_val->type->id == ZigTypeIdPointer); 8191 ConstExprValue tmp = {}; 8192 tmp.special = ConstValSpecialStatic; 8193 tmp.type = ptr_val->type->data.pointer.child_type; 8194 if ((err = ir_read_const_ptr(ira, codegen, source_node, &tmp, ptr_val))) 8195 return err; 8196 ConstExprValue *child_val = const_ptr_pointee_unchecked(codegen, ptr_val); 8197 copy_const_val(child_val, &tmp, false); 8198 return ErrorNone; 8199 } 8200 8201 ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprValue *const_val, 8202 AstNode *source_node) 8203 { 8204 Error err; 8205 ConstExprValue *val = const_ptr_pointee_unchecked(codegen, const_val); 8206 assert(val != nullptr); 8207 assert(const_val->type->id == ZigTypeIdPointer); 8208 ZigType *expected_type = const_val->type->data.pointer.child_type; 8209 if (!types_have_same_zig_comptime_repr(val->type, expected_type)) { 8210 if ((err = eval_comptime_ptr_reinterpret(ira, codegen, source_node, const_val))) 8211 return nullptr; 8212 return const_ptr_pointee_unchecked(codegen, const_val); 8213 } 8214 return val; 8215 } 8216 8217 static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec) { 8218 IrBasicBlock *bb = exec->basic_block_list.at(0); 8219 for (size_t i = 0; i < bb->instruction_list.length; i += 1) { 8220 IrInstruction *instruction = bb->instruction_list.at(i); 8221 if (instruction->id == IrInstructionIdReturn) { 8222 IrInstructionReturn *ret_inst = (IrInstructionReturn *)instruction; 8223 IrInstruction *operand = ret_inst->operand; 8224 if (operand->value.special == ConstValSpecialRuntime) { 8225 exec_add_error_node(codegen, exec, operand->source_node, 8226 buf_sprintf("unable to evaluate constant expression")); 8227 return &codegen->invalid_instruction->value; 8228 } 8229 return &operand->value; 8230 } else if (ir_has_side_effects(instruction)) { 8231 if (instr_is_comptime(instruction)) { 8232 switch (instruction->id) { 8233 case IrInstructionIdUnwrapErrPayload: 8234 case IrInstructionIdUnionFieldPtr: 8235 continue; 8236 default: 8237 break; 8238 } 8239 } 8240 exec_add_error_node(codegen, exec, instruction->source_node, 8241 buf_sprintf("unable to evaluate constant expression")); 8242 return &codegen->invalid_instruction->value; 8243 } 8244 } 8245 zig_unreachable(); 8246 } 8247 8248 static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) { 8249 if (ir_should_inline(ira->new_irb.exec, source_instruction->scope)) { 8250 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression")); 8251 return false; 8252 } 8253 return true; 8254 } 8255 8256 static bool const_val_fits_in_num_lit(ConstExprValue *const_val, ZigType *num_lit_type) { 8257 return ((num_lit_type->id == ZigTypeIdComptimeFloat && 8258 (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat)) || 8259 (num_lit_type->id == ZigTypeIdComptimeInt && 8260 (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt))); 8261 } 8262 8263 static bool float_has_fraction(ConstExprValue *const_val) { 8264 if (const_val->type->id == ZigTypeIdComptimeFloat) { 8265 return bigfloat_has_fraction(&const_val->data.x_bigfloat); 8266 } else if (const_val->type->id == ZigTypeIdFloat) { 8267 switch (const_val->type->data.floating.bit_count) { 8268 case 16: 8269 { 8270 float16_t floored = f16_roundToInt(const_val->data.x_f16, softfloat_round_minMag, false); 8271 return !f16_eq(floored, const_val->data.x_f16); 8272 } 8273 case 32: 8274 return floorf(const_val->data.x_f32) != const_val->data.x_f32; 8275 case 64: 8276 return floor(const_val->data.x_f64) != const_val->data.x_f64; 8277 case 128: 8278 { 8279 float128_t floored; 8280 f128M_roundToInt(&const_val->data.x_f128, softfloat_round_minMag, false, &floored); 8281 return !f128M_eq(&floored, &const_val->data.x_f128); 8282 } 8283 default: 8284 zig_unreachable(); 8285 } 8286 } else { 8287 zig_unreachable(); 8288 } 8289 } 8290 8291 static void float_append_buf(Buf *buf, ConstExprValue *const_val) { 8292 if (const_val->type->id == ZigTypeIdComptimeFloat) { 8293 bigfloat_append_buf(buf, &const_val->data.x_bigfloat); 8294 } else if (const_val->type->id == ZigTypeIdFloat) { 8295 switch (const_val->type->data.floating.bit_count) { 8296 case 16: 8297 buf_appendf(buf, "%f", zig_f16_to_double(const_val->data.x_f16)); 8298 break; 8299 case 32: 8300 buf_appendf(buf, "%f", const_val->data.x_f32); 8301 break; 8302 case 64: 8303 buf_appendf(buf, "%f", const_val->data.x_f64); 8304 break; 8305 case 128: 8306 { 8307 // TODO actual implementation 8308 const size_t extra_len = 100; 8309 size_t old_len = buf_len(buf); 8310 buf_resize(buf, old_len + extra_len); 8311 8312 float64_t f64_value = f128M_to_f64(&const_val->data.x_f128); 8313 double double_value; 8314 memcpy(&double_value, &f64_value, sizeof(double)); 8315 8316 int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value); 8317 assert(len > 0); 8318 buf_resize(buf, old_len + len); 8319 break; 8320 } 8321 default: 8322 zig_unreachable(); 8323 } 8324 } else { 8325 zig_unreachable(); 8326 } 8327 } 8328 8329 static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) { 8330 if (const_val->type->id == ZigTypeIdComptimeFloat) { 8331 bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat); 8332 } else if (const_val->type->id == ZigTypeIdFloat) { 8333 switch (const_val->type->data.floating.bit_count) { 8334 case 16: 8335 { 8336 double x = zig_f16_to_double(const_val->data.x_f16); 8337 if (x >= 0) { 8338 bigint_init_unsigned(bigint, (uint64_t)x); 8339 } else { 8340 bigint_init_unsigned(bigint, (uint64_t)-x); 8341 bigint->is_negative = true; 8342 } 8343 break; 8344 } 8345 case 32: 8346 if (const_val->data.x_f32 >= 0) { 8347 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f32)); 8348 } else { 8349 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f32)); 8350 bigint->is_negative = true; 8351 } 8352 break; 8353 case 64: 8354 if (const_val->data.x_f64 >= 0) { 8355 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f64)); 8356 } else { 8357 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f64)); 8358 bigint->is_negative = true; 8359 } 8360 break; 8361 case 128: 8362 { 8363 BigFloat tmp_float; 8364 bigfloat_init_128(&tmp_float, const_val->data.x_f128); 8365 bigint_init_bigfloat(bigint, &tmp_float); 8366 } 8367 break; 8368 default: 8369 zig_unreachable(); 8370 } 8371 } else { 8372 zig_unreachable(); 8373 } 8374 } 8375 8376 static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) { 8377 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8378 bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat); 8379 } else if (dest_val->type->id == ZigTypeIdFloat) { 8380 switch (dest_val->type->data.floating.bit_count) { 8381 case 16: 8382 dest_val->data.x_f16 = bigfloat_to_f16(bigfloat); 8383 break; 8384 case 32: 8385 dest_val->data.x_f32 = bigfloat_to_f32(bigfloat); 8386 break; 8387 case 64: 8388 dest_val->data.x_f64 = bigfloat_to_f64(bigfloat); 8389 break; 8390 case 80: 8391 zig_panic("TODO"); 8392 case 128: 8393 dest_val->data.x_f128 = bigfloat_to_f128(bigfloat); 8394 break; 8395 default: 8396 zig_unreachable(); 8397 } 8398 } else { 8399 zig_unreachable(); 8400 } 8401 } 8402 8403 static void float_init_f16(ConstExprValue *dest_val, float16_t x) { 8404 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8405 bigfloat_init_16(&dest_val->data.x_bigfloat, x); 8406 } else if (dest_val->type->id == ZigTypeIdFloat) { 8407 switch (dest_val->type->data.floating.bit_count) { 8408 case 16: 8409 dest_val->data.x_f16 = x; 8410 break; 8411 case 32: 8412 dest_val->data.x_f32 = zig_f16_to_double(x); 8413 break; 8414 case 64: 8415 dest_val->data.x_f64 = zig_f16_to_double(x); 8416 break; 8417 case 128: 8418 f16_to_f128M(x, &dest_val->data.x_f128); 8419 break; 8420 default: 8421 zig_unreachable(); 8422 } 8423 } else { 8424 zig_unreachable(); 8425 } 8426 } 8427 8428 static void float_init_f32(ConstExprValue *dest_val, float x) { 8429 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8430 bigfloat_init_32(&dest_val->data.x_bigfloat, x); 8431 } else if (dest_val->type->id == ZigTypeIdFloat) { 8432 switch (dest_val->type->data.floating.bit_count) { 8433 case 16: 8434 dest_val->data.x_f16 = zig_double_to_f16(x); 8435 break; 8436 case 32: 8437 dest_val->data.x_f32 = x; 8438 break; 8439 case 64: 8440 dest_val->data.x_f64 = x; 8441 break; 8442 case 128: 8443 { 8444 float32_t x_f32; 8445 memcpy(&x_f32, &x, sizeof(float)); 8446 f32_to_f128M(x_f32, &dest_val->data.x_f128); 8447 break; 8448 } 8449 default: 8450 zig_unreachable(); 8451 } 8452 } else { 8453 zig_unreachable(); 8454 } 8455 } 8456 8457 static void float_init_f64(ConstExprValue *dest_val, double x) { 8458 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8459 bigfloat_init_64(&dest_val->data.x_bigfloat, x); 8460 } else if (dest_val->type->id == ZigTypeIdFloat) { 8461 switch (dest_val->type->data.floating.bit_count) { 8462 case 16: 8463 dest_val->data.x_f16 = zig_double_to_f16(x); 8464 break; 8465 case 32: 8466 dest_val->data.x_f32 = x; 8467 break; 8468 case 64: 8469 dest_val->data.x_f64 = x; 8470 break; 8471 case 128: 8472 { 8473 float64_t x_f64; 8474 memcpy(&x_f64, &x, sizeof(double)); 8475 f64_to_f128M(x_f64, &dest_val->data.x_f128); 8476 break; 8477 } 8478 default: 8479 zig_unreachable(); 8480 } 8481 } else { 8482 zig_unreachable(); 8483 } 8484 } 8485 8486 static void float_init_f128(ConstExprValue *dest_val, float128_t x) { 8487 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8488 bigfloat_init_128(&dest_val->data.x_bigfloat, x); 8489 } else if (dest_val->type->id == ZigTypeIdFloat) { 8490 switch (dest_val->type->data.floating.bit_count) { 8491 case 16: 8492 dest_val->data.x_f16 = f128M_to_f16(&x); 8493 break; 8494 case 32: 8495 { 8496 float32_t f32_val = f128M_to_f32(&x); 8497 memcpy(&dest_val->data.x_f32, &f32_val, sizeof(float)); 8498 break; 8499 } 8500 case 64: 8501 { 8502 float64_t f64_val = f128M_to_f64(&x); 8503 memcpy(&dest_val->data.x_f64, &f64_val, sizeof(double)); 8504 break; 8505 } 8506 case 128: 8507 { 8508 memcpy(&dest_val->data.x_f128, &x, sizeof(float128_t)); 8509 break; 8510 } 8511 default: 8512 zig_unreachable(); 8513 } 8514 } else { 8515 zig_unreachable(); 8516 } 8517 } 8518 8519 static void float_init_float(ConstExprValue *dest_val, ConstExprValue *src_val) { 8520 if (src_val->type->id == ZigTypeIdComptimeFloat) { 8521 float_init_bigfloat(dest_val, &src_val->data.x_bigfloat); 8522 } else if (src_val->type->id == ZigTypeIdFloat) { 8523 switch (src_val->type->data.floating.bit_count) { 8524 case 16: 8525 float_init_f16(dest_val, src_val->data.x_f16); 8526 break; 8527 case 32: 8528 float_init_f32(dest_val, src_val->data.x_f32); 8529 break; 8530 case 64: 8531 float_init_f64(dest_val, src_val->data.x_f64); 8532 break; 8533 case 128: 8534 float_init_f128(dest_val, src_val->data.x_f128); 8535 break; 8536 default: 8537 zig_unreachable(); 8538 } 8539 } else { 8540 zig_unreachable(); 8541 } 8542 } 8543 8544 static bool float_is_nan(ConstExprValue *op) { 8545 if (op->type->id == ZigTypeIdComptimeFloat) { 8546 return bigfloat_is_nan(&op->data.x_bigfloat); 8547 } else if (op->type->id == ZigTypeIdFloat) { 8548 switch (op->type->data.floating.bit_count) { 8549 case 16: 8550 return f16_isSignalingNaN(op->data.x_f16); 8551 case 32: 8552 return op->data.x_f32 != op->data.x_f32; 8553 case 64: 8554 return op->data.x_f64 != op->data.x_f64; 8555 case 128: 8556 return f128M_isSignalingNaN(&op->data.x_f128); 8557 default: 8558 zig_unreachable(); 8559 } 8560 } else { 8561 zig_unreachable(); 8562 } 8563 } 8564 8565 static Cmp float_cmp(ConstExprValue *op1, ConstExprValue *op2) { 8566 assert(op1->type == op2->type); 8567 if (op1->type->id == ZigTypeIdComptimeFloat) { 8568 return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat); 8569 } else if (op1->type->id == ZigTypeIdFloat) { 8570 switch (op1->type->data.floating.bit_count) { 8571 case 16: 8572 if (f16_lt(op1->data.x_f16, op2->data.x_f16)) { 8573 return CmpLT; 8574 } else if (f16_lt(op2->data.x_f16, op1->data.x_f16)) { 8575 return CmpGT; 8576 } else { 8577 return CmpEQ; 8578 } 8579 case 32: 8580 if (op1->data.x_f32 > op2->data.x_f32) { 8581 return CmpGT; 8582 } else if (op1->data.x_f32 < op2->data.x_f32) { 8583 return CmpLT; 8584 } else { 8585 return CmpEQ; 8586 } 8587 case 64: 8588 if (op1->data.x_f64 > op2->data.x_f64) { 8589 return CmpGT; 8590 } else if (op1->data.x_f64 < op2->data.x_f64) { 8591 return CmpLT; 8592 } else { 8593 return CmpEQ; 8594 } 8595 case 128: 8596 if (f128M_lt(&op1->data.x_f128, &op2->data.x_f128)) { 8597 return CmpLT; 8598 } else if (f128M_eq(&op1->data.x_f128, &op2->data.x_f128)) { 8599 return CmpEQ; 8600 } else { 8601 return CmpGT; 8602 } 8603 default: 8604 zig_unreachable(); 8605 } 8606 } else { 8607 zig_unreachable(); 8608 } 8609 } 8610 8611 static Cmp float_cmp_zero(ConstExprValue *op) { 8612 if (op->type->id == ZigTypeIdComptimeFloat) { 8613 return bigfloat_cmp_zero(&op->data.x_bigfloat); 8614 } else if (op->type->id == ZigTypeIdFloat) { 8615 switch (op->type->data.floating.bit_count) { 8616 case 16: 8617 { 8618 const float16_t zero = zig_double_to_f16(0); 8619 if (f16_lt(op->data.x_f16, zero)) { 8620 return CmpLT; 8621 } else if (f16_lt(zero, op->data.x_f16)) { 8622 return CmpGT; 8623 } else { 8624 return CmpEQ; 8625 } 8626 } 8627 case 32: 8628 if (op->data.x_f32 < 0.0) { 8629 return CmpLT; 8630 } else if (op->data.x_f32 > 0.0) { 8631 return CmpGT; 8632 } else { 8633 return CmpEQ; 8634 } 8635 case 64: 8636 if (op->data.x_f64 < 0.0) { 8637 return CmpLT; 8638 } else if (op->data.x_f64 > 0.0) { 8639 return CmpGT; 8640 } else { 8641 return CmpEQ; 8642 } 8643 case 128: 8644 float128_t zero_float; 8645 ui32_to_f128M(0, &zero_float); 8646 if (f128M_lt(&op->data.x_f128, &zero_float)) { 8647 return CmpLT; 8648 } else if (f128M_eq(&op->data.x_f128, &zero_float)) { 8649 return CmpEQ; 8650 } else { 8651 return CmpGT; 8652 } 8653 default: 8654 zig_unreachable(); 8655 } 8656 } else { 8657 zig_unreachable(); 8658 } 8659 } 8660 8661 static void float_add(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8662 assert(op1->type == op2->type); 8663 out_val->type = op1->type; 8664 if (op1->type->id == ZigTypeIdComptimeFloat) { 8665 bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8666 } else if (op1->type->id == ZigTypeIdFloat) { 8667 switch (op1->type->data.floating.bit_count) { 8668 case 16: 8669 out_val->data.x_f16 = f16_add(op1->data.x_f16, op2->data.x_f16); 8670 return; 8671 case 32: 8672 out_val->data.x_f32 = op1->data.x_f32 + op2->data.x_f32; 8673 return; 8674 case 64: 8675 out_val->data.x_f64 = op1->data.x_f64 + op2->data.x_f64; 8676 return; 8677 case 128: 8678 f128M_add(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8679 return; 8680 default: 8681 zig_unreachable(); 8682 } 8683 } else { 8684 zig_unreachable(); 8685 } 8686 } 8687 8688 static void float_sub(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8689 assert(op1->type == op2->type); 8690 out_val->type = op1->type; 8691 if (op1->type->id == ZigTypeIdComptimeFloat) { 8692 bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8693 } else if (op1->type->id == ZigTypeIdFloat) { 8694 switch (op1->type->data.floating.bit_count) { 8695 case 16: 8696 out_val->data.x_f16 = f16_sub(op1->data.x_f16, op2->data.x_f16); 8697 return; 8698 case 32: 8699 out_val->data.x_f32 = op1->data.x_f32 - op2->data.x_f32; 8700 return; 8701 case 64: 8702 out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64; 8703 return; 8704 case 128: 8705 f128M_sub(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8706 return; 8707 default: 8708 zig_unreachable(); 8709 } 8710 } else { 8711 zig_unreachable(); 8712 } 8713 } 8714 8715 static void float_mul(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8716 assert(op1->type == op2->type); 8717 out_val->type = op1->type; 8718 if (op1->type->id == ZigTypeIdComptimeFloat) { 8719 bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8720 } else if (op1->type->id == ZigTypeIdFloat) { 8721 switch (op1->type->data.floating.bit_count) { 8722 case 16: 8723 out_val->data.x_f16 = f16_mul(op1->data.x_f16, op2->data.x_f16); 8724 return; 8725 case 32: 8726 out_val->data.x_f32 = op1->data.x_f32 * op2->data.x_f32; 8727 return; 8728 case 64: 8729 out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64; 8730 return; 8731 case 128: 8732 f128M_mul(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8733 return; 8734 default: 8735 zig_unreachable(); 8736 } 8737 } else { 8738 zig_unreachable(); 8739 } 8740 } 8741 8742 static void float_div(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8743 assert(op1->type == op2->type); 8744 out_val->type = op1->type; 8745 if (op1->type->id == ZigTypeIdComptimeFloat) { 8746 bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8747 } else if (op1->type->id == ZigTypeIdFloat) { 8748 switch (op1->type->data.floating.bit_count) { 8749 case 16: 8750 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 8751 return; 8752 case 32: 8753 out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32; 8754 return; 8755 case 64: 8756 out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64; 8757 return; 8758 case 128: 8759 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8760 return; 8761 default: 8762 zig_unreachable(); 8763 } 8764 } else { 8765 zig_unreachable(); 8766 } 8767 } 8768 8769 static void float_div_trunc(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8770 assert(op1->type == op2->type); 8771 out_val->type = op1->type; 8772 if (op1->type->id == ZigTypeIdComptimeFloat) { 8773 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8774 } else if (op1->type->id == ZigTypeIdFloat) { 8775 switch (op1->type->data.floating.bit_count) { 8776 case 16: 8777 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 8778 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_minMag, false); 8779 return; 8780 case 32: 8781 out_val->data.x_f32 = truncf(op1->data.x_f32 / op2->data.x_f32); 8782 return; 8783 case 64: 8784 out_val->data.x_f64 = trunc(op1->data.x_f64 / op2->data.x_f64); 8785 return; 8786 case 128: 8787 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8788 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_minMag, false, &out_val->data.x_f128); 8789 return; 8790 default: 8791 zig_unreachable(); 8792 } 8793 } else { 8794 zig_unreachable(); 8795 } 8796 } 8797 8798 static void float_div_floor(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8799 assert(op1->type == op2->type); 8800 out_val->type = op1->type; 8801 if (op1->type->id == ZigTypeIdComptimeFloat) { 8802 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8803 } else if (op1->type->id == ZigTypeIdFloat) { 8804 switch (op1->type->data.floating.bit_count) { 8805 case 16: 8806 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 8807 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_min, false); 8808 return; 8809 case 32: 8810 out_val->data.x_f32 = floorf(op1->data.x_f32 / op2->data.x_f32); 8811 return; 8812 case 64: 8813 out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64); 8814 return; 8815 case 128: 8816 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8817 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_min, false, &out_val->data.x_f128); 8818 return; 8819 default: 8820 zig_unreachable(); 8821 } 8822 } else { 8823 zig_unreachable(); 8824 } 8825 } 8826 8827 static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8828 assert(op1->type == op2->type); 8829 out_val->type = op1->type; 8830 if (op1->type->id == ZigTypeIdComptimeFloat) { 8831 bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8832 } else if (op1->type->id == ZigTypeIdFloat) { 8833 switch (op1->type->data.floating.bit_count) { 8834 case 16: 8835 out_val->data.x_f16 = f16_rem(op1->data.x_f16, op2->data.x_f16); 8836 return; 8837 case 32: 8838 out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32); 8839 return; 8840 case 64: 8841 out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64); 8842 return; 8843 case 128: 8844 f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8845 return; 8846 default: 8847 zig_unreachable(); 8848 } 8849 } else { 8850 zig_unreachable(); 8851 } 8852 } 8853 8854 // c = a - b * trunc(a / b) 8855 static float16_t zig_f16_mod(float16_t a, float16_t b) { 8856 float16_t c; 8857 c = f16_div(a, b); 8858 c = f16_roundToInt(c, softfloat_round_min, true); 8859 c = f16_mul(b, c); 8860 c = f16_sub(a, c); 8861 return c; 8862 } 8863 8864 // c = a - b * trunc(a / b) 8865 static void zig_f128M_mod(const float128_t* a, const float128_t* b, float128_t* c) { 8866 f128M_div(a, b, c); 8867 f128M_roundToInt(c, softfloat_round_min, true, c); 8868 f128M_mul(b, c, c); 8869 f128M_sub(a, c, c); 8870 } 8871 8872 static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 8873 assert(op1->type == op2->type); 8874 out_val->type = op1->type; 8875 if (op1->type->id == ZigTypeIdComptimeFloat) { 8876 bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 8877 } else if (op1->type->id == ZigTypeIdFloat) { 8878 switch (op1->type->data.floating.bit_count) { 8879 case 16: 8880 out_val->data.x_f16 = zig_f16_mod(op1->data.x_f16, op2->data.x_f16); 8881 return; 8882 case 32: 8883 out_val->data.x_f32 = fmodf(fmodf(op1->data.x_f32, op2->data.x_f32) + op2->data.x_f32, op2->data.x_f32); 8884 return; 8885 case 64: 8886 out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64); 8887 return; 8888 case 128: 8889 zig_f128M_mod(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 8890 return; 8891 default: 8892 zig_unreachable(); 8893 } 8894 } else { 8895 zig_unreachable(); 8896 } 8897 } 8898 8899 static void float_negate(ConstExprValue *out_val, ConstExprValue *op) { 8900 out_val->type = op->type; 8901 if (op->type->id == ZigTypeIdComptimeFloat) { 8902 bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat); 8903 } else if (op->type->id == ZigTypeIdFloat) { 8904 switch (op->type->data.floating.bit_count) { 8905 case 16: 8906 { 8907 const float16_t zero = zig_double_to_f16(0); 8908 out_val->data.x_f16 = f16_sub(zero, op->data.x_f16); 8909 return; 8910 } 8911 case 32: 8912 out_val->data.x_f32 = -op->data.x_f32; 8913 return; 8914 case 64: 8915 out_val->data.x_f64 = -op->data.x_f64; 8916 return; 8917 case 128: 8918 float128_t zero_f128; 8919 ui32_to_f128M(0, &zero_f128); 8920 f128M_sub(&zero_f128, &op->data.x_f128, &out_val->data.x_f128); 8921 return; 8922 default: 8923 zig_unreachable(); 8924 } 8925 } else { 8926 zig_unreachable(); 8927 } 8928 } 8929 8930 void float_write_ieee597(ConstExprValue *op, uint8_t *buf, bool is_big_endian) { 8931 if (op->type->id == ZigTypeIdFloat) { 8932 switch (op->type->data.floating.bit_count) { 8933 case 16: 8934 memcpy(buf, &op->data.x_f16, 2); // TODO wrong when compiler is big endian 8935 return; 8936 case 32: 8937 memcpy(buf, &op->data.x_f32, 4); // TODO wrong when compiler is big endian 8938 return; 8939 case 64: 8940 memcpy(buf, &op->data.x_f64, 8); // TODO wrong when compiler is big endian 8941 return; 8942 case 128: 8943 memcpy(buf, &op->data.x_f128, 16); // TODO wrong when compiler is big endian 8944 return; 8945 default: 8946 zig_unreachable(); 8947 } 8948 } else { 8949 zig_unreachable(); 8950 } 8951 } 8952 8953 void float_read_ieee597(ConstExprValue *val, uint8_t *buf, bool is_big_endian) { 8954 if (val->type->id == ZigTypeIdFloat) { 8955 switch (val->type->data.floating.bit_count) { 8956 case 16: 8957 memcpy(&val->data.x_f16, buf, 2); // TODO wrong when compiler is big endian 8958 return; 8959 case 32: 8960 memcpy(&val->data.x_f32, buf, 4); // TODO wrong when compiler is big endian 8961 return; 8962 case 64: 8963 memcpy(&val->data.x_f64, buf, 8); // TODO wrong when compiler is big endian 8964 return; 8965 case 128: 8966 memcpy(&val->data.x_f128, buf, 16); // TODO wrong when compiler is big endian 8967 return; 8968 default: 8969 zig_unreachable(); 8970 } 8971 } else { 8972 zig_unreachable(); 8973 } 8974 } 8975 8976 static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, ZigType *other_type, 8977 bool explicit_cast) 8978 { 8979 if (type_is_invalid(other_type)) { 8980 return false; 8981 } 8982 8983 ConstExprValue *const_val = ir_resolve_const(ira, instruction, UndefBad); 8984 assert(const_val != nullptr); 8985 8986 bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt); 8987 bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); 8988 assert(const_val_is_int || const_val_is_float); 8989 8990 if (const_val_is_int && other_type->id == ZigTypeIdComptimeFloat) { 8991 return true; 8992 } 8993 if (other_type->id == ZigTypeIdFloat) { 8994 if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) { 8995 return true; 8996 } 8997 if (const_val->type->id == ZigTypeIdInt) { 8998 BigFloat tmp_bf; 8999 bigfloat_init_bigint(&tmp_bf, &const_val->data.x_bigint); 9000 BigFloat orig_bf; 9001 switch (other_type->data.floating.bit_count) { 9002 case 16: { 9003 float16_t tmp = bigfloat_to_f16(&tmp_bf); 9004 bigfloat_init_16(&orig_bf, tmp); 9005 break; 9006 } 9007 case 32: { 9008 float tmp = bigfloat_to_f32(&tmp_bf); 9009 bigfloat_init_32(&orig_bf, tmp); 9010 break; 9011 } 9012 case 64: { 9013 double tmp = bigfloat_to_f64(&tmp_bf); 9014 bigfloat_init_64(&orig_bf, tmp); 9015 break; 9016 } 9017 case 80: 9018 zig_panic("TODO"); 9019 case 128: { 9020 float128_t tmp = bigfloat_to_f128(&tmp_bf); 9021 bigfloat_init_128(&orig_bf, tmp); 9022 break; 9023 } 9024 default: 9025 zig_unreachable(); 9026 } 9027 BigInt orig_bi; 9028 bigint_init_bigfloat(&orig_bi, &orig_bf); 9029 if (bigint_cmp(&orig_bi, &const_val->data.x_bigint) == CmpEQ) { 9030 return true; 9031 } 9032 Buf *val_buf = buf_alloc(); 9033 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 9034 ir_add_error(ira, instruction, 9035 buf_sprintf("integer value %s has no representation in type '%s'", 9036 buf_ptr(val_buf), 9037 buf_ptr(&other_type->name))); 9038 return false; 9039 } 9040 if (other_type->data.floating.bit_count >= const_val->type->data.floating.bit_count) { 9041 return true; 9042 } 9043 switch (other_type->data.floating.bit_count) { 9044 case 16: 9045 switch (const_val->type->data.floating.bit_count) { 9046 case 32: { 9047 float16_t tmp = zig_double_to_f16(const_val->data.x_f32); 9048 float orig = zig_f16_to_double(tmp); 9049 if (const_val->data.x_f32 == orig) { 9050 return true; 9051 } 9052 break; 9053 } 9054 case 64: { 9055 float16_t tmp = zig_double_to_f16(const_val->data.x_f64); 9056 double orig = zig_f16_to_double(tmp); 9057 if (const_val->data.x_f64 == orig) { 9058 return true; 9059 } 9060 break; 9061 } 9062 case 80: 9063 zig_panic("TODO"); 9064 case 128: { 9065 float16_t tmp = f128M_to_f16(&const_val->data.x_f128); 9066 float128_t orig; 9067 f16_to_f128M(tmp, &orig); 9068 if (f128M_eq(&orig, &const_val->data.x_f128)) { 9069 return true; 9070 } 9071 break; 9072 } 9073 default: 9074 zig_unreachable(); 9075 } 9076 break; 9077 case 32: 9078 switch (const_val->type->data.floating.bit_count) { 9079 case 64: { 9080 float tmp = const_val->data.x_f64; 9081 double orig = tmp; 9082 if (const_val->data.x_f64 == orig) { 9083 return true; 9084 } 9085 break; 9086 } 9087 case 80: 9088 zig_panic("TODO"); 9089 case 128: { 9090 float32_t tmp = f128M_to_f32(&const_val->data.x_f128); 9091 float128_t orig; 9092 f32_to_f128M(tmp, &orig); 9093 if (f128M_eq(&orig, &const_val->data.x_f128)) { 9094 return true; 9095 } 9096 break; 9097 } 9098 default: 9099 zig_unreachable(); 9100 } 9101 break; 9102 case 64: 9103 switch (const_val->type->data.floating.bit_count) { 9104 case 80: 9105 zig_panic("TODO"); 9106 case 128: { 9107 float64_t tmp = f128M_to_f64(&const_val->data.x_f128); 9108 float128_t orig; 9109 f64_to_f128M(tmp, &orig); 9110 if (f128M_eq(&orig, &const_val->data.x_f128)) { 9111 return true; 9112 } 9113 break; 9114 } 9115 default: 9116 zig_unreachable(); 9117 } 9118 break; 9119 case 80: 9120 assert(const_val->type->data.floating.bit_count == 128); 9121 zig_panic("TODO"); 9122 case 128: 9123 return true; 9124 default: 9125 zig_unreachable(); 9126 } 9127 Buf *val_buf = buf_alloc(); 9128 float_append_buf(val_buf, const_val); 9129 ir_add_error(ira, instruction, 9130 buf_sprintf("cast of value %s to type '%s' loses information", 9131 buf_ptr(val_buf), 9132 buf_ptr(&other_type->name))); 9133 return false; 9134 } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { 9135 if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 9136 Buf *val_buf = buf_alloc(); 9137 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 9138 ir_add_error(ira, instruction, 9139 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 9140 buf_ptr(val_buf), 9141 buf_ptr(&other_type->name))); 9142 return false; 9143 } 9144 if (bigint_fits_in_bits(&const_val->data.x_bigint, other_type->data.integral.bit_count, 9145 other_type->data.integral.is_signed)) 9146 { 9147 return true; 9148 } 9149 } else if (const_val_fits_in_num_lit(const_val, other_type)) { 9150 return true; 9151 } else if (other_type->id == ZigTypeIdOptional) { 9152 ZigType *child_type = other_type->data.maybe.child_type; 9153 if (const_val_fits_in_num_lit(const_val, child_type)) { 9154 return true; 9155 } else if (child_type->id == ZigTypeIdInt && const_val_is_int) { 9156 if (!child_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 9157 Buf *val_buf = buf_alloc(); 9158 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 9159 ir_add_error(ira, instruction, 9160 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 9161 buf_ptr(val_buf), 9162 buf_ptr(&child_type->name))); 9163 return false; 9164 } 9165 if (bigint_fits_in_bits(&const_val->data.x_bigint, 9166 child_type->data.integral.bit_count, 9167 child_type->data.integral.is_signed)) 9168 { 9169 return true; 9170 } 9171 } else if (child_type->id == ZigTypeIdFloat && const_val_is_float) { 9172 return true; 9173 } 9174 } 9175 if (explicit_cast && (other_type->id == ZigTypeIdInt || other_type->id == ZigTypeIdComptimeInt) && 9176 const_val_is_float) 9177 { 9178 if (float_has_fraction(const_val)) { 9179 Buf *val_buf = buf_alloc(); 9180 float_append_buf(val_buf, const_val); 9181 9182 ir_add_error(ira, instruction, 9183 buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", 9184 buf_ptr(val_buf), 9185 buf_ptr(&other_type->name))); 9186 return false; 9187 } else { 9188 if (other_type->id == ZigTypeIdComptimeInt) { 9189 return true; 9190 } else { 9191 BigInt bigint; 9192 float_init_bigint(&bigint, const_val); 9193 if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count, 9194 other_type->data.integral.is_signed)) 9195 { 9196 return true; 9197 } 9198 } 9199 } 9200 } 9201 9202 const char *num_lit_str; 9203 Buf *val_buf = buf_alloc(); 9204 if (const_val_is_float) { 9205 num_lit_str = "float"; 9206 float_append_buf(val_buf, const_val); 9207 } else { 9208 num_lit_str = "integer"; 9209 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 9210 } 9211 9212 ir_add_error(ira, instruction, 9213 buf_sprintf("%s value %s cannot be implicitly casted to type '%s'", 9214 num_lit_str, 9215 buf_ptr(val_buf), 9216 buf_ptr(&other_type->name))); 9217 return false; 9218 } 9219 9220 static bool is_tagged_union(ZigType *type) { 9221 if (type->id != ZigTypeIdUnion) 9222 return false; 9223 return (type->data.unionation.decl_node->data.container_decl.auto_enum || 9224 type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr); 9225 } 9226 9227 static void populate_error_set_table(ErrorTableEntry **errors, ZigType *set) { 9228 assert(set->id == ZigTypeIdErrorSet); 9229 for (uint32_t i = 0; i < set->data.error_set.err_count; i += 1) { 9230 ErrorTableEntry *error_entry = set->data.error_set.errors[i]; 9231 assert(errors[error_entry->value] == nullptr); 9232 errors[error_entry->value] = error_entry; 9233 } 9234 } 9235 9236 static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigType *set2, 9237 AstNode *source_node) 9238 { 9239 assert(set1->id == ZigTypeIdErrorSet); 9240 assert(set2->id == ZigTypeIdErrorSet); 9241 9242 if (!resolve_inferred_error_set(ira->codegen, set1, source_node)) { 9243 return ira->codegen->builtin_types.entry_invalid; 9244 } 9245 if (!resolve_inferred_error_set(ira->codegen, set2, source_node)) { 9246 return ira->codegen->builtin_types.entry_invalid; 9247 } 9248 if (type_is_global_error_set(set1)) { 9249 return set2; 9250 } 9251 if (type_is_global_error_set(set2)) { 9252 return set1; 9253 } 9254 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 9255 populate_error_set_table(errors, set1); 9256 ZigList<ErrorTableEntry *> intersection_list = {}; 9257 9258 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9259 buf_resize(&err_set_type->name, 0); 9260 buf_appendf(&err_set_type->name, "error{"); 9261 9262 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 9263 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 9264 ErrorTableEntry *existing_entry = errors[error_entry->value]; 9265 if (existing_entry != nullptr) { 9266 intersection_list.append(existing_entry); 9267 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&existing_entry->name)); 9268 } 9269 } 9270 free(errors); 9271 9272 err_set_type->data.error_set.err_count = intersection_list.length; 9273 err_set_type->data.error_set.errors = intersection_list.items; 9274 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 9275 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 9276 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 9277 9278 buf_appendf(&err_set_type->name, "}"); 9279 9280 return err_set_type; 9281 } 9282 9283 static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted_type, 9284 ZigType *actual_type, AstNode *source_node, bool wanted_is_mutable) 9285 { 9286 CodeGen *g = ira->codegen; 9287 ConstCastOnly result = {}; 9288 result.id = ConstCastResultIdOk; 9289 9290 Error err; 9291 9292 if (wanted_type == actual_type) 9293 return result; 9294 9295 // If pointers have the same representation in memory, they can be "const-casted". 9296 // `const` attribute can be gained 9297 // `volatile` attribute can be gained 9298 // `allowzero` attribute can be gained (whether from explicit attribute, C pointer, or optional pointer) 9299 // but only if !wanted_is_mutable 9300 // alignment can be decreased 9301 // bit offset attributes must match exactly 9302 // PtrLenSingle/PtrLenUnknown must match exactly, but PtrLenC matches either one 9303 ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type); 9304 ZigType *actual_ptr_type = get_src_ptr_type(actual_type); 9305 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 9306 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 9307 bool wanted_is_c_ptr = wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC; 9308 bool actual_is_c_ptr = actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenC; 9309 bool wanted_opt_or_ptr = wanted_ptr_type != nullptr && 9310 (wanted_type->id == ZigTypeIdPointer || wanted_type->id == ZigTypeIdOptional); 9311 bool actual_opt_or_ptr = actual_ptr_type != nullptr && 9312 (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional); 9313 if (wanted_opt_or_ptr && actual_opt_or_ptr) { 9314 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 9315 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 9316 if (child.id == ConstCastResultIdInvalid) 9317 return child; 9318 if (child.id != ConstCastResultIdOk) { 9319 result.id = ConstCastResultIdPointerChild; 9320 result.data.pointer_mismatch = allocate_nonzero<ConstCastPointerMismatch>(1); 9321 result.data.pointer_mismatch->child = child; 9322 result.data.pointer_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 9323 result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 9324 return result; 9325 } 9326 bool ok_allows_zero = (wanted_allows_zero && 9327 (actual_allows_zero || !wanted_is_mutable)) || 9328 (!wanted_allows_zero && !actual_allows_zero); 9329 if (!ok_allows_zero) { 9330 result.id = ConstCastResultIdBadAllowsZero; 9331 result.data.bad_allows_zero = allocate_nonzero<ConstCastBadAllowsZero>(1); 9332 result.data.bad_allows_zero->wanted_type = wanted_type; 9333 result.data.bad_allows_zero->actual_type = actual_type; 9334 return result; 9335 } 9336 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 9337 result.id = ConstCastResultIdInvalid; 9338 return result; 9339 } 9340 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 9341 result.id = ConstCastResultIdInvalid; 9342 return result; 9343 } 9344 bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; 9345 if ((ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr) && 9346 type_has_bits(wanted_type) == type_has_bits(actual_type) && 9347 (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 9348 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && 9349 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 9350 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 9351 get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type)) 9352 { 9353 return result; 9354 } 9355 } 9356 9357 // slice const 9358 if (is_slice(wanted_type) && is_slice(actual_type)) { 9359 ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry; 9360 ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 9361 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 9362 result.id = ConstCastResultIdInvalid; 9363 return result; 9364 } 9365 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 9366 result.id = ConstCastResultIdInvalid; 9367 return result; 9368 } 9369 if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 9370 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && 9371 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 9372 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 9373 get_ptr_align(g, actual_ptr_type) >= get_ptr_align(g, wanted_ptr_type)) 9374 { 9375 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 9376 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 9377 if (child.id == ConstCastResultIdInvalid) 9378 return child; 9379 if (child.id != ConstCastResultIdOk) { 9380 result.id = ConstCastResultIdSliceChild; 9381 result.data.slice_mismatch = allocate_nonzero<ConstCastSliceMismatch>(1); 9382 result.data.slice_mismatch->child = child; 9383 result.data.slice_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 9384 result.data.slice_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 9385 } 9386 return result; 9387 } 9388 } 9389 9390 // maybe 9391 if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdOptional) { 9392 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, 9393 actual_type->data.maybe.child_type, source_node, wanted_is_mutable); 9394 if (child.id == ConstCastResultIdInvalid) 9395 return child; 9396 if (child.id != ConstCastResultIdOk) { 9397 result.id = ConstCastResultIdOptionalChild; 9398 result.data.optional = allocate_nonzero<ConstCastOptionalMismatch>(1); 9399 result.data.optional->child = child; 9400 result.data.optional->wanted_child = wanted_type->data.maybe.child_type; 9401 result.data.optional->actual_child = actual_type->data.maybe.child_type; 9402 } 9403 return result; 9404 } 9405 9406 // error union 9407 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id == ZigTypeIdErrorUnion) { 9408 ConstCastOnly payload_child = types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, 9409 actual_type->data.error_union.payload_type, source_node, wanted_is_mutable); 9410 if (payload_child.id == ConstCastResultIdInvalid) 9411 return payload_child; 9412 if (payload_child.id != ConstCastResultIdOk) { 9413 result.id = ConstCastResultIdErrorUnionPayload; 9414 result.data.error_union_payload = allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1); 9415 result.data.error_union_payload->child = payload_child; 9416 result.data.error_union_payload->wanted_payload = wanted_type->data.error_union.payload_type; 9417 result.data.error_union_payload->actual_payload = actual_type->data.error_union.payload_type; 9418 return result; 9419 } 9420 ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type, 9421 actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable); 9422 if (error_set_child.id == ConstCastResultIdInvalid) 9423 return error_set_child; 9424 if (error_set_child.id != ConstCastResultIdOk) { 9425 result.id = ConstCastResultIdErrorUnionErrorSet; 9426 result.data.error_union_error_set = allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1); 9427 result.data.error_union_error_set->child = error_set_child; 9428 result.data.error_union_error_set->wanted_err_set = wanted_type->data.error_union.err_set_type; 9429 result.data.error_union_error_set->actual_err_set = actual_type->data.error_union.err_set_type; 9430 return result; 9431 } 9432 return result; 9433 } 9434 9435 // error set 9436 if (wanted_type->id == ZigTypeIdErrorSet && actual_type->id == ZigTypeIdErrorSet) { 9437 ZigType *contained_set = actual_type; 9438 ZigType *container_set = wanted_type; 9439 9440 // if the container set is inferred, then this will always work. 9441 if (container_set->data.error_set.infer_fn != nullptr) { 9442 return result; 9443 } 9444 // if the container set is the global one, it will always work. 9445 if (type_is_global_error_set(container_set)) { 9446 return result; 9447 } 9448 9449 if (!resolve_inferred_error_set(ira->codegen, contained_set, source_node)) { 9450 result.id = ConstCastResultIdUnresolvedInferredErrSet; 9451 return result; 9452 } 9453 9454 if (type_is_global_error_set(contained_set)) { 9455 result.id = ConstCastResultIdErrSetGlobal; 9456 return result; 9457 } 9458 9459 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(g->errors_by_index.length); 9460 for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) { 9461 ErrorTableEntry *error_entry = container_set->data.error_set.errors[i]; 9462 assert(errors[error_entry->value] == nullptr); 9463 errors[error_entry->value] = error_entry; 9464 } 9465 for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) { 9466 ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i]; 9467 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9468 if (error_entry == nullptr) { 9469 if (result.id == ConstCastResultIdOk) { 9470 result.id = ConstCastResultIdErrSet; 9471 result.data.error_set_mismatch = allocate<ConstCastErrSetMismatch>(1); 9472 } 9473 result.data.error_set_mismatch->missing_errors.append(contained_error_entry); 9474 } 9475 } 9476 free(errors); 9477 return result; 9478 } 9479 9480 // fn 9481 if (wanted_type->id == ZigTypeIdFn && 9482 actual_type->id == ZigTypeIdFn) 9483 { 9484 if (wanted_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) { 9485 result.id = ConstCastResultIdFnAlign; 9486 return result; 9487 } 9488 if (wanted_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) { 9489 result.id = ConstCastResultIdFnCC; 9490 return result; 9491 } 9492 if (wanted_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) { 9493 result.id = ConstCastResultIdFnVarArgs; 9494 return result; 9495 } 9496 if (wanted_type->data.fn.is_generic != actual_type->data.fn.is_generic) { 9497 result.id = ConstCastResultIdFnIsGeneric; 9498 return result; 9499 } 9500 if (!wanted_type->data.fn.is_generic && 9501 actual_type->data.fn.fn_type_id.return_type->id != ZigTypeIdUnreachable) 9502 { 9503 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.fn.fn_type_id.return_type, 9504 actual_type->data.fn.fn_type_id.return_type, source_node, false); 9505 if (child.id == ConstCastResultIdInvalid) 9506 return child; 9507 if (child.id != ConstCastResultIdOk) { 9508 result.id = ConstCastResultIdFnReturnType; 9509 result.data.return_type = allocate_nonzero<ConstCastOnly>(1); 9510 *result.data.return_type = child; 9511 return result; 9512 } 9513 } 9514 if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { 9515 result.id = ConstCastResultIdFnArgCount; 9516 return result; 9517 } 9518 if (wanted_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) { 9519 result.id = ConstCastResultIdFnGenericArgCount; 9520 return result; 9521 } 9522 assert(wanted_type->data.fn.is_generic || 9523 wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count); 9524 for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.next_param_index; i += 1) { 9525 // note it's reversed for parameters 9526 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i]; 9527 FnTypeParamInfo *expected_param_info = &wanted_type->data.fn.fn_type_id.param_info[i]; 9528 9529 ConstCastOnly arg_child = types_match_const_cast_only(ira, actual_param_info->type, 9530 expected_param_info->type, source_node, false); 9531 if (arg_child.id == ConstCastResultIdInvalid) 9532 return arg_child; 9533 if (arg_child.id != ConstCastResultIdOk) { 9534 result.id = ConstCastResultIdFnArg; 9535 result.data.fn_arg.arg_index = i; 9536 result.data.fn_arg.actual_param_type = actual_param_info->type; 9537 result.data.fn_arg.expected_param_type = expected_param_info->type; 9538 result.data.fn_arg.child = allocate_nonzero<ConstCastOnly>(1); 9539 *result.data.fn_arg.child = arg_child; 9540 return result; 9541 } 9542 9543 if (expected_param_info->is_noalias != actual_param_info->is_noalias) { 9544 result.id = ConstCastResultIdFnArgNoAlias; 9545 result.data.arg_no_alias.arg_index = i; 9546 return result; 9547 } 9548 } 9549 return result; 9550 } 9551 9552 result.id = ConstCastResultIdType; 9553 result.data.type_mismatch = allocate_nonzero<ConstCastTypeMismatch>(1); 9554 result.data.type_mismatch->wanted_type = wanted_type; 9555 result.data.type_mismatch->actual_type = actual_type; 9556 return result; 9557 } 9558 9559 static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) { 9560 size_t old_errors_count = *errors_count; 9561 *errors_count = g->errors_by_index.length; 9562 *errors = reallocate(*errors, old_errors_count, *errors_count); 9563 } 9564 9565 static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type, 9566 IrInstruction **instructions, size_t instruction_count) 9567 { 9568 Error err; 9569 assert(instruction_count >= 1); 9570 IrInstruction *prev_inst; 9571 size_t i = 0; 9572 for (;;) { 9573 prev_inst = instructions[i]; 9574 if (type_is_invalid(prev_inst->value.type)) { 9575 return ira->codegen->builtin_types.entry_invalid; 9576 } 9577 if (prev_inst->value.type->id == ZigTypeIdUnreachable) { 9578 i += 1; 9579 if (i == instruction_count) { 9580 return prev_inst->value.type; 9581 } 9582 continue; 9583 } 9584 break; 9585 } 9586 ErrorTableEntry **errors = nullptr; 9587 size_t errors_count = 0; 9588 ZigType *err_set_type = nullptr; 9589 if (prev_inst->value.type->id == ZigTypeIdErrorSet) { 9590 if (!resolve_inferred_error_set(ira->codegen, prev_inst->value.type, prev_inst->source_node)) { 9591 return ira->codegen->builtin_types.entry_invalid; 9592 } 9593 if (type_is_global_error_set(prev_inst->value.type)) { 9594 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9595 } else { 9596 err_set_type = prev_inst->value.type; 9597 update_errors_helper(ira->codegen, &errors, &errors_count); 9598 9599 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9600 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9601 assert(errors[error_entry->value] == nullptr); 9602 errors[error_entry->value] = error_entry; 9603 } 9604 } 9605 } 9606 9607 bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull); 9608 bool convert_to_const_slice = false; 9609 for (; i < instruction_count; i += 1) { 9610 IrInstruction *cur_inst = instructions[i]; 9611 ZigType *cur_type = cur_inst->value.type; 9612 ZigType *prev_type = prev_inst->value.type; 9613 9614 if (type_is_invalid(cur_type)) { 9615 return cur_type; 9616 } 9617 9618 if (prev_type->id == ZigTypeIdUnreachable) { 9619 prev_inst = cur_inst; 9620 continue; 9621 } 9622 9623 if (cur_type->id == ZigTypeIdUnreachable) { 9624 continue; 9625 } 9626 9627 if (prev_type->id == ZigTypeIdErrorSet) { 9628 ir_assert(err_set_type != nullptr, prev_inst); 9629 if (cur_type->id == ZigTypeIdErrorSet) { 9630 if (type_is_global_error_set(err_set_type)) { 9631 continue; 9632 } 9633 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { 9634 return ira->codegen->builtin_types.entry_invalid; 9635 } 9636 if (type_is_global_error_set(cur_type)) { 9637 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9638 prev_inst = cur_inst; 9639 continue; 9640 } 9641 9642 // number of declared errors might have increased now 9643 update_errors_helper(ira->codegen, &errors, &errors_count); 9644 9645 // if err_set_type is a superset of cur_type, keep err_set_type. 9646 // if cur_type is a superset of err_set_type, switch err_set_type to cur_type 9647 bool prev_is_superset = true; 9648 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 9649 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 9650 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9651 if (error_entry == nullptr) { 9652 prev_is_superset = false; 9653 break; 9654 } 9655 } 9656 if (prev_is_superset) { 9657 continue; 9658 } 9659 9660 // unset everything in errors 9661 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9662 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9663 errors[error_entry->value] = nullptr; 9664 } 9665 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 9666 assert(errors[i] == nullptr); 9667 } 9668 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 9669 ErrorTableEntry *error_entry = cur_type->data.error_set.errors[i]; 9670 assert(errors[error_entry->value] == nullptr); 9671 errors[error_entry->value] = error_entry; 9672 } 9673 bool cur_is_superset = true; 9674 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9675 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 9676 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9677 if (error_entry == nullptr) { 9678 cur_is_superset = false; 9679 break; 9680 } 9681 } 9682 if (cur_is_superset) { 9683 err_set_type = cur_type; 9684 prev_inst = cur_inst; 9685 assert(errors != nullptr); 9686 continue; 9687 } 9688 9689 // neither of them are supersets. so we invent a new error set type that is a union of both of them 9690 err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type); 9691 assert(errors != nullptr); 9692 continue; 9693 } else if (cur_type->id == ZigTypeIdErrorUnion) { 9694 if (type_is_global_error_set(err_set_type)) { 9695 prev_inst = cur_inst; 9696 continue; 9697 } 9698 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 9699 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 9700 return ira->codegen->builtin_types.entry_invalid; 9701 } 9702 if (type_is_global_error_set(cur_err_set_type)) { 9703 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9704 prev_inst = cur_inst; 9705 continue; 9706 } 9707 9708 update_errors_helper(ira->codegen, &errors, &errors_count); 9709 9710 // test if err_set_type is a subset of cur_type's error set 9711 // unset everything in errors 9712 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9713 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9714 errors[error_entry->value] = nullptr; 9715 } 9716 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 9717 assert(errors[i] == nullptr); 9718 } 9719 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 9720 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 9721 assert(errors[error_entry->value] == nullptr); 9722 errors[error_entry->value] = error_entry; 9723 } 9724 bool cur_is_superset = true; 9725 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9726 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 9727 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9728 if (error_entry == nullptr) { 9729 cur_is_superset = false; 9730 break; 9731 } 9732 } 9733 if (cur_is_superset) { 9734 err_set_type = cur_err_set_type; 9735 prev_inst = cur_inst; 9736 assert(errors != nullptr); 9737 continue; 9738 } 9739 9740 // not a subset. invent new error set type, union of both of them 9741 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type); 9742 prev_inst = cur_inst; 9743 assert(errors != nullptr); 9744 continue; 9745 } else { 9746 prev_inst = cur_inst; 9747 continue; 9748 } 9749 } 9750 9751 if (cur_type->id == ZigTypeIdErrorSet) { 9752 if (prev_type->id == ZigTypeIdArray) { 9753 convert_to_const_slice = true; 9754 } 9755 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { 9756 return ira->codegen->builtin_types.entry_invalid; 9757 } 9758 if (type_is_global_error_set(cur_type)) { 9759 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9760 continue; 9761 } 9762 if (err_set_type != nullptr && type_is_global_error_set(err_set_type)) { 9763 continue; 9764 } 9765 9766 update_errors_helper(ira->codegen, &errors, &errors_count); 9767 9768 if (err_set_type == nullptr) { 9769 if (prev_type->id == ZigTypeIdErrorUnion) { 9770 err_set_type = prev_type->data.error_union.err_set_type; 9771 } else { 9772 err_set_type = cur_type; 9773 } 9774 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9775 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9776 assert(errors[error_entry->value] == nullptr); 9777 errors[error_entry->value] = error_entry; 9778 } 9779 if (err_set_type == cur_type) { 9780 continue; 9781 } 9782 } 9783 // check if the cur type error set is a subset 9784 bool prev_is_superset = true; 9785 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 9786 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 9787 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9788 if (error_entry == nullptr) { 9789 prev_is_superset = false; 9790 break; 9791 } 9792 } 9793 if (prev_is_superset) { 9794 continue; 9795 } 9796 // not a subset. invent new error set type, union of both of them 9797 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type); 9798 assert(errors != nullptr); 9799 continue; 9800 } 9801 9802 if (prev_type->id == ZigTypeIdErrorUnion && cur_type->id == ZigTypeIdErrorUnion) { 9803 ZigType *prev_payload_type = prev_type->data.error_union.payload_type; 9804 ZigType *cur_payload_type = cur_type->data.error_union.payload_type; 9805 9806 bool const_cast_prev = types_match_const_cast_only(ira, prev_payload_type, cur_payload_type, 9807 source_node, false).id == ConstCastResultIdOk; 9808 bool const_cast_cur = types_match_const_cast_only(ira, cur_payload_type, prev_payload_type, 9809 source_node, false).id == ConstCastResultIdOk; 9810 9811 if (const_cast_prev || const_cast_cur) { 9812 if (const_cast_cur) { 9813 prev_inst = cur_inst; 9814 } 9815 9816 ZigType *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type; 9817 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 9818 if (prev_err_set_type == cur_err_set_type) 9819 continue; 9820 9821 if (!resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) { 9822 return ira->codegen->builtin_types.entry_invalid; 9823 } 9824 9825 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 9826 return ira->codegen->builtin_types.entry_invalid; 9827 } 9828 9829 if (type_is_global_error_set(prev_err_set_type) || type_is_global_error_set(cur_err_set_type)) { 9830 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 9831 continue; 9832 } 9833 9834 update_errors_helper(ira->codegen, &errors, &errors_count); 9835 9836 if (err_set_type == nullptr) { 9837 err_set_type = prev_err_set_type; 9838 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 9839 ErrorTableEntry *error_entry = prev_err_set_type->data.error_set.errors[i]; 9840 assert(errors[error_entry->value] == nullptr); 9841 errors[error_entry->value] = error_entry; 9842 } 9843 } 9844 bool prev_is_superset = true; 9845 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 9846 ErrorTableEntry *contained_error_entry = cur_err_set_type->data.error_set.errors[i]; 9847 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9848 if (error_entry == nullptr) { 9849 prev_is_superset = false; 9850 break; 9851 } 9852 } 9853 if (prev_is_superset) { 9854 continue; 9855 } 9856 // unset all the errors 9857 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 9858 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 9859 errors[error_entry->value] = nullptr; 9860 } 9861 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 9862 assert(errors[i] == nullptr); 9863 } 9864 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 9865 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 9866 assert(errors[error_entry->value] == nullptr); 9867 errors[error_entry->value] = error_entry; 9868 } 9869 bool cur_is_superset = true; 9870 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 9871 ErrorTableEntry *contained_error_entry = prev_err_set_type->data.error_set.errors[i]; 9872 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 9873 if (error_entry == nullptr) { 9874 cur_is_superset = false; 9875 break; 9876 } 9877 } 9878 if (cur_is_superset) { 9879 err_set_type = cur_err_set_type; 9880 continue; 9881 } 9882 9883 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, prev_err_set_type); 9884 continue; 9885 } 9886 } 9887 9888 if (prev_type->id == ZigTypeIdNull) { 9889 prev_inst = cur_inst; 9890 any_are_null = true; 9891 continue; 9892 } 9893 9894 if (cur_type->id == ZigTypeIdNull) { 9895 any_are_null = true; 9896 continue; 9897 } 9898 9899 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdEnumLiteral) { 9900 TypeEnumField *field = find_enum_type_field(prev_type, cur_inst->value.data.x_enum_literal); 9901 if (field != nullptr) { 9902 continue; 9903 } 9904 } 9905 if (is_tagged_union(prev_type) && cur_type->id == ZigTypeIdEnumLiteral) { 9906 TypeUnionField *field = find_union_type_field(prev_type, cur_inst->value.data.x_enum_literal); 9907 if (field != nullptr) { 9908 continue; 9909 } 9910 } 9911 9912 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdEnumLiteral) { 9913 TypeEnumField *field = find_enum_type_field(cur_type, prev_inst->value.data.x_enum_literal); 9914 if (field != nullptr) { 9915 prev_inst = cur_inst; 9916 continue; 9917 } 9918 } 9919 9920 if (is_tagged_union(cur_type) && prev_type->id == ZigTypeIdEnumLiteral) { 9921 TypeUnionField *field = find_union_type_field(cur_type, prev_inst->value.data.x_enum_literal); 9922 if (field != nullptr) { 9923 prev_inst = cur_inst; 9924 continue; 9925 } 9926 } 9927 9928 if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenC && 9929 (cur_type->id == ZigTypeIdComptimeInt || cur_type->id == ZigTypeIdInt)) 9930 { 9931 continue; 9932 } 9933 9934 if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenC && 9935 (prev_type->id == ZigTypeIdComptimeInt || prev_type->id == ZigTypeIdInt)) 9936 { 9937 prev_inst = cur_inst; 9938 continue; 9939 } 9940 9941 if (prev_type->id == ZigTypeIdPointer && cur_type->id == ZigTypeIdPointer) { 9942 if (prev_type->data.pointer.ptr_len == PtrLenC && 9943 types_match_const_cast_only(ira, prev_type->data.pointer.child_type, 9944 cur_type->data.pointer.child_type, source_node, 9945 !prev_type->data.pointer.is_const).id == ConstCastResultIdOk) 9946 { 9947 continue; 9948 } 9949 if (cur_type->data.pointer.ptr_len == PtrLenC && 9950 types_match_const_cast_only(ira, cur_type->data.pointer.child_type, 9951 prev_type->data.pointer.child_type, source_node, 9952 !cur_type->data.pointer.is_const).id == ConstCastResultIdOk) 9953 { 9954 prev_inst = cur_inst; 9955 continue; 9956 } 9957 } 9958 9959 if (types_match_const_cast_only(ira, prev_type, cur_type, source_node, false).id == ConstCastResultIdOk) { 9960 continue; 9961 } 9962 9963 if (types_match_const_cast_only(ira, cur_type, prev_type, source_node, false).id == ConstCastResultIdOk) { 9964 prev_inst = cur_inst; 9965 continue; 9966 } 9967 9968 if (prev_type->id == ZigTypeIdInt && 9969 cur_type->id == ZigTypeIdInt && 9970 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed) 9971 { 9972 if (cur_type->data.integral.bit_count > prev_type->data.integral.bit_count) { 9973 prev_inst = cur_inst; 9974 } 9975 continue; 9976 } 9977 9978 if (prev_type->id == ZigTypeIdFloat && cur_type->id == ZigTypeIdFloat) { 9979 if (cur_type->data.floating.bit_count > prev_type->data.floating.bit_count) { 9980 prev_inst = cur_inst; 9981 } 9982 continue; 9983 } 9984 9985 if (prev_type->id == ZigTypeIdErrorUnion && 9986 types_match_const_cast_only(ira, prev_type->data.error_union.payload_type, cur_type, 9987 source_node, false).id == ConstCastResultIdOk) 9988 { 9989 continue; 9990 } 9991 9992 if (cur_type->id == ZigTypeIdErrorUnion && 9993 types_match_const_cast_only(ira, cur_type->data.error_union.payload_type, prev_type, 9994 source_node, false).id == ConstCastResultIdOk) 9995 { 9996 if (err_set_type != nullptr) { 9997 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 9998 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 9999 return ira->codegen->builtin_types.entry_invalid; 10000 } 10001 if (type_is_global_error_set(cur_err_set_type) || type_is_global_error_set(err_set_type)) { 10002 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 10003 prev_inst = cur_inst; 10004 continue; 10005 } 10006 10007 update_errors_helper(ira->codegen, &errors, &errors_count); 10008 10009 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_err_set_type); 10010 } 10011 prev_inst = cur_inst; 10012 continue; 10013 } 10014 10015 if (prev_type->id == ZigTypeIdOptional && 10016 types_match_const_cast_only(ira, prev_type->data.maybe.child_type, cur_type, 10017 source_node, false).id == ConstCastResultIdOk) 10018 { 10019 continue; 10020 } 10021 10022 if (cur_type->id == ZigTypeIdOptional && 10023 types_match_const_cast_only(ira, cur_type->data.maybe.child_type, prev_type, 10024 source_node, false).id == ConstCastResultIdOk) 10025 { 10026 prev_inst = cur_inst; 10027 continue; 10028 } 10029 10030 if (prev_type->id == ZigTypeIdOptional && 10031 types_match_const_cast_only(ira, cur_type, prev_type->data.maybe.child_type, 10032 source_node, false).id == ConstCastResultIdOk) 10033 { 10034 prev_inst = cur_inst; 10035 any_are_null = true; 10036 continue; 10037 } 10038 10039 if (cur_type->id == ZigTypeIdOptional && 10040 types_match_const_cast_only(ira, prev_type, cur_type->data.maybe.child_type, 10041 source_node, false).id == ConstCastResultIdOk) 10042 { 10043 any_are_null = true; 10044 continue; 10045 } 10046 10047 if (cur_type->id == ZigTypeIdUndefined) { 10048 continue; 10049 } 10050 10051 if (prev_type->id == ZigTypeIdUndefined) { 10052 prev_inst = cur_inst; 10053 continue; 10054 } 10055 10056 if (prev_type->id == ZigTypeIdComptimeInt || 10057 prev_type->id == ZigTypeIdComptimeFloat) 10058 { 10059 if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) { 10060 prev_inst = cur_inst; 10061 continue; 10062 } else { 10063 return ira->codegen->builtin_types.entry_invalid; 10064 } 10065 } 10066 10067 if (cur_type->id == ZigTypeIdComptimeInt || 10068 cur_type->id == ZigTypeIdComptimeFloat) 10069 { 10070 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) { 10071 continue; 10072 } else { 10073 return ira->codegen->builtin_types.entry_invalid; 10074 } 10075 } 10076 10077 if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && 10078 cur_type->data.array.len != prev_type->data.array.len && 10079 types_match_const_cast_only(ira, cur_type->data.array.child_type, prev_type->data.array.child_type, 10080 source_node, false).id == ConstCastResultIdOk) 10081 { 10082 convert_to_const_slice = true; 10083 prev_inst = cur_inst; 10084 continue; 10085 } 10086 10087 if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && 10088 cur_type->data.array.len != prev_type->data.array.len && 10089 types_match_const_cast_only(ira, prev_type->data.array.child_type, cur_type->data.array.child_type, 10090 source_node, false).id == ConstCastResultIdOk) 10091 { 10092 convert_to_const_slice = true; 10093 continue; 10094 } 10095 10096 if (cur_type->id == ZigTypeIdArray && is_slice(prev_type) && 10097 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || 10098 cur_type->data.array.len == 0) && 10099 types_match_const_cast_only(ira, 10100 prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, 10101 cur_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 10102 { 10103 convert_to_const_slice = false; 10104 continue; 10105 } 10106 10107 if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) && 10108 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || 10109 prev_type->data.array.len == 0) && 10110 types_match_const_cast_only(ira, 10111 cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, 10112 prev_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 10113 { 10114 prev_inst = cur_inst; 10115 convert_to_const_slice = false; 10116 continue; 10117 } 10118 10119 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdUnion && 10120 (cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 10121 { 10122 if ((err = type_resolve(ira->codegen, cur_type, ResolveStatusZeroBitsKnown))) 10123 return ira->codegen->builtin_types.entry_invalid; 10124 if (cur_type->data.unionation.tag_type == prev_type) { 10125 continue; 10126 } 10127 } 10128 10129 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdUnion && 10130 (prev_type->data.unionation.decl_node->data.container_decl.auto_enum || prev_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 10131 { 10132 if ((err = type_resolve(ira->codegen, prev_type, ResolveStatusZeroBitsKnown))) 10133 return ira->codegen->builtin_types.entry_invalid; 10134 if (prev_type->data.unionation.tag_type == cur_type) { 10135 prev_inst = cur_inst; 10136 continue; 10137 } 10138 } 10139 10140 ErrorMsg *msg = ir_add_error_node(ira, source_node, 10141 buf_sprintf("incompatible types: '%s' and '%s'", 10142 buf_ptr(&prev_type->name), buf_ptr(&cur_type->name))); 10143 add_error_note(ira->codegen, msg, prev_inst->source_node, 10144 buf_sprintf("type '%s' here", buf_ptr(&prev_type->name))); 10145 add_error_note(ira->codegen, msg, cur_inst->source_node, 10146 buf_sprintf("type '%s' here", buf_ptr(&cur_type->name))); 10147 10148 return ira->codegen->builtin_types.entry_invalid; 10149 } 10150 10151 free(errors); 10152 10153 if (convert_to_const_slice) { 10154 assert(prev_inst->value.type->id == ZigTypeIdArray); 10155 ZigType *ptr_type = get_pointer_to_type_extra( 10156 ira->codegen, prev_inst->value.type->data.array.child_type, 10157 true, false, PtrLenUnknown, 10158 0, 0, 0, false); 10159 ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); 10160 if (err_set_type != nullptr) { 10161 return get_error_union_type(ira->codegen, err_set_type, slice_type); 10162 } else { 10163 return slice_type; 10164 } 10165 } else if (err_set_type != nullptr) { 10166 if (prev_inst->value.type->id == ZigTypeIdErrorSet) { 10167 return err_set_type; 10168 } else if (prev_inst->value.type->id == ZigTypeIdErrorUnion) { 10169 ZigType *payload_type = prev_inst->value.type->data.error_union.payload_type; 10170 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 10171 return ira->codegen->builtin_types.entry_invalid; 10172 return get_error_union_type(ira->codegen, err_set_type, payload_type); 10173 } else if (expected_type != nullptr && expected_type->id == ZigTypeIdErrorUnion) { 10174 ZigType *payload_type = expected_type->data.error_union.payload_type; 10175 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 10176 return ira->codegen->builtin_types.entry_invalid; 10177 return get_error_union_type(ira->codegen, err_set_type, payload_type); 10178 } else { 10179 if (prev_inst->value.type->id == ZigTypeIdComptimeInt || 10180 prev_inst->value.type->id == ZigTypeIdComptimeFloat) 10181 { 10182 ir_add_error_node(ira, source_node, 10183 buf_sprintf("unable to make error union out of number literal")); 10184 return ira->codegen->builtin_types.entry_invalid; 10185 } else if (prev_inst->value.type->id == ZigTypeIdNull) { 10186 ir_add_error_node(ira, source_node, 10187 buf_sprintf("unable to make error union out of null literal")); 10188 return ira->codegen->builtin_types.entry_invalid; 10189 } else { 10190 if ((err = type_resolve(ira->codegen, prev_inst->value.type, ResolveStatusSizeKnown))) 10191 return ira->codegen->builtin_types.entry_invalid; 10192 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value.type); 10193 } 10194 } 10195 } else if (any_are_null && prev_inst->value.type->id != ZigTypeIdNull) { 10196 if (prev_inst->value.type->id == ZigTypeIdComptimeInt || 10197 prev_inst->value.type->id == ZigTypeIdComptimeFloat) 10198 { 10199 ir_add_error_node(ira, source_node, 10200 buf_sprintf("unable to make maybe out of number literal")); 10201 return ira->codegen->builtin_types.entry_invalid; 10202 } else if (prev_inst->value.type->id == ZigTypeIdOptional) { 10203 return prev_inst->value.type; 10204 } else { 10205 if ((err = type_resolve(ira->codegen, prev_inst->value.type, ResolveStatusSizeKnown))) 10206 return ira->codegen->builtin_types.entry_invalid; 10207 return get_optional_type(ira->codegen, prev_inst->value.type); 10208 } 10209 } else { 10210 return prev_inst->value.type; 10211 } 10212 } 10213 10214 static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { 10215 ConstGlobalRefs *global_refs = dest->global_refs; 10216 memcpy(dest, src, sizeof(ConstExprValue)); 10217 if (!same_global_refs) { 10218 dest->global_refs = global_refs; 10219 if (src->special == ConstValSpecialUndef) 10220 return; 10221 if (dest->type->id == ZigTypeIdStruct) { 10222 dest->data.x_struct.fields = create_const_vals(dest->type->data.structure.src_field_count); 10223 for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { 10224 copy_const_val(&dest->data.x_struct.fields[i], &src->data.x_struct.fields[i], false); 10225 } 10226 } 10227 } 10228 } 10229 10230 static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_instr, 10231 CastOp cast_op, 10232 ConstExprValue *other_val, ZigType *other_type, 10233 ConstExprValue *const_val, ZigType *new_type) 10234 { 10235 const_val->special = other_val->special; 10236 10237 assert(other_val != const_val); 10238 switch (cast_op) { 10239 case CastOpNoCast: 10240 zig_unreachable(); 10241 case CastOpErrSet: 10242 case CastOpBitCast: 10243 zig_panic("TODO"); 10244 case CastOpNoop: 10245 { 10246 bool same_global_refs = other_val->special == ConstValSpecialStatic; 10247 copy_const_val(const_val, other_val, same_global_refs); 10248 const_val->type = new_type; 10249 break; 10250 } 10251 case CastOpNumLitToConcrete: 10252 if (other_val->type->id == ZigTypeIdComptimeFloat) { 10253 assert(new_type->id == ZigTypeIdFloat); 10254 switch (new_type->data.floating.bit_count) { 10255 case 16: 10256 const_val->data.x_f16 = bigfloat_to_f16(&other_val->data.x_bigfloat); 10257 break; 10258 case 32: 10259 const_val->data.x_f32 = bigfloat_to_f32(&other_val->data.x_bigfloat); 10260 break; 10261 case 64: 10262 const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat); 10263 break; 10264 case 80: 10265 zig_panic("TODO"); 10266 case 128: 10267 const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat); 10268 break; 10269 default: 10270 zig_unreachable(); 10271 } 10272 } else if (other_val->type->id == ZigTypeIdComptimeInt) { 10273 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint); 10274 } else { 10275 zig_unreachable(); 10276 } 10277 const_val->type = new_type; 10278 break; 10279 case CastOpIntToFloat: 10280 { 10281 assert(new_type->id == ZigTypeIdFloat); 10282 10283 BigFloat bigfloat; 10284 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint); 10285 switch (new_type->data.floating.bit_count) { 10286 case 16: 10287 const_val->data.x_f16 = bigfloat_to_f16(&bigfloat); 10288 break; 10289 case 32: 10290 const_val->data.x_f32 = bigfloat_to_f32(&bigfloat); 10291 break; 10292 case 64: 10293 const_val->data.x_f64 = bigfloat_to_f64(&bigfloat); 10294 break; 10295 case 80: 10296 zig_panic("TODO"); 10297 case 128: 10298 const_val->data.x_f128 = bigfloat_to_f128(&bigfloat); 10299 break; 10300 default: 10301 zig_unreachable(); 10302 } 10303 const_val->special = ConstValSpecialStatic; 10304 break; 10305 } 10306 case CastOpFloatToInt: 10307 float_init_bigint(&const_val->data.x_bigint, other_val); 10308 if (new_type->id == ZigTypeIdInt) { 10309 if (!bigint_fits_in_bits(&const_val->data.x_bigint, new_type->data.integral.bit_count, 10310 new_type->data.integral.is_signed)) 10311 { 10312 Buf *int_buf = buf_alloc(); 10313 bigint_append_buf(int_buf, &const_val->data.x_bigint, 10); 10314 10315 ir_add_error(ira, source_instr, 10316 buf_sprintf("integer value '%s' cannot be stored in type '%s'", 10317 buf_ptr(int_buf), buf_ptr(&new_type->name))); 10318 return false; 10319 } 10320 } 10321 10322 const_val->special = ConstValSpecialStatic; 10323 break; 10324 case CastOpBoolToInt: 10325 bigint_init_unsigned(&const_val->data.x_bigint, other_val->data.x_bool ? 1 : 0); 10326 const_val->special = ConstValSpecialStatic; 10327 break; 10328 } 10329 return true; 10330 } 10331 10332 static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, ZigType *ty) { 10333 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 10334 old_instruction->scope, old_instruction->source_node); 10335 IrInstruction *new_instruction = &const_instruction->base; 10336 new_instruction->value.type = ty; 10337 new_instruction->value.special = ConstValSpecialStatic; 10338 return new_instruction; 10339 } 10340 10341 static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 10342 ZigType *wanted_type, CastOp cast_op) 10343 { 10344 if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { 10345 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10346 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, &value->value, value->value.type, 10347 &result->value, wanted_type)) 10348 { 10349 return ira->codegen->invalid_instruction; 10350 } 10351 return result; 10352 } else { 10353 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op); 10354 result->value.type = wanted_type; 10355 return result; 10356 } 10357 } 10358 10359 static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrInstruction *source_instr, 10360 IrInstruction *value, ZigType *wanted_type) 10361 { 10362 assert(value->value.type->id == ZigTypeIdPointer); 10363 10364 Error err; 10365 10366 if ((err = type_resolve(ira->codegen, value->value.type->data.pointer.child_type, 10367 ResolveStatusAlignmentKnown))) 10368 { 10369 return ira->codegen->invalid_instruction; 10370 } 10371 10372 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value.type)); 10373 10374 if (instr_is_comptime(value)) { 10375 ConstExprValue *pointee = const_ptr_pointee(ira, ira->codegen, &value->value, source_instr->source_node); 10376 if (pointee == nullptr) 10377 return ira->codegen->invalid_instruction; 10378 if (pointee->special != ConstValSpecialRuntime) { 10379 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10380 result->value.data.x_ptr.special = ConstPtrSpecialBaseArray; 10381 result->value.data.x_ptr.mut = value->value.data.x_ptr.mut; 10382 result->value.data.x_ptr.data.base_array.array_val = pointee; 10383 result->value.data.x_ptr.data.base_array.elem_index = 0; 10384 result->value.data.x_ptr.data.base_array.is_cstr = false; 10385 return result; 10386 } 10387 } 10388 10389 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 10390 wanted_type, value, CastOpBitCast); 10391 result->value.type = wanted_type; 10392 return result; 10393 } 10394 10395 static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, 10396 IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) 10397 { 10398 Error err; 10399 10400 if ((err = type_resolve(ira->codegen, value->value.type->data.pointer.child_type, 10401 ResolveStatusAlignmentKnown))) 10402 { 10403 return ira->codegen->invalid_instruction; 10404 } 10405 10406 wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value.type)); 10407 10408 if (instr_is_comptime(value)) { 10409 ConstExprValue *pointee = const_ptr_pointee(ira, ira->codegen, &value->value, source_instr->source_node); 10410 if (pointee == nullptr) 10411 return ira->codegen->invalid_instruction; 10412 if (pointee->special != ConstValSpecialRuntime) { 10413 assert(value->value.type->id == ZigTypeIdPointer); 10414 ZigType *array_type = value->value.type->data.pointer.child_type; 10415 assert(is_slice(wanted_type)); 10416 bool is_const = wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; 10417 10418 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 10419 init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const); 10420 result->value.data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = 10421 value->value.data.x_ptr.mut; 10422 result->value.type = wanted_type; 10423 return result; 10424 } 10425 } 10426 10427 if (result_loc == nullptr) result_loc = no_result_loc(); 10428 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, 10429 false, true); 10430 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { 10431 return result_loc_inst; 10432 } 10433 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, value, result_loc_inst); 10434 } 10435 10436 static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { 10437 assert(old_bb); 10438 10439 if (old_bb->other) { 10440 if (ref_old_instruction == nullptr || old_bb->other->ref_instruction != ref_old_instruction) { 10441 return old_bb->other; 10442 } 10443 } 10444 10445 IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb); 10446 new_bb->ref_instruction = ref_old_instruction; 10447 10448 return new_bb; 10449 } 10450 10451 static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { 10452 assert(ref_old_instruction != nullptr); 10453 IrBasicBlock *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction); 10454 if (new_bb->must_be_comptime_source_instr) { 10455 ErrorMsg *msg = ir_add_error(ira, ref_old_instruction, 10456 buf_sprintf("control flow attempts to use compile-time variable at runtime")); 10457 add_error_note(ira->codegen, msg, new_bb->must_be_comptime_source_instr->source_node, 10458 buf_sprintf("compile-time variable assigned here")); 10459 return nullptr; 10460 } 10461 return new_bb; 10462 } 10463 10464 static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { 10465 ir_assert(!old_bb->suspended, (old_bb->instruction_list.length != 0) ? old_bb->instruction_list.at(0) : nullptr); 10466 ira->instruction_index = 0; 10467 ira->old_irb.current_basic_block = old_bb; 10468 ira->const_predecessor_bb = const_predecessor_bb; 10469 ira->old_bb_index = old_bb->index; 10470 } 10471 10472 static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, 10473 IrSuspendPosition *suspend_pos) 10474 { 10475 if (ira->codegen->verbose_ir) { 10476 fprintf(stderr, "suspend %s_%zu %s_%zu #%zu (%zu,%zu)\n", ira->old_irb.current_basic_block->name_hint, 10477 ira->old_irb.current_basic_block->debug_id, 10478 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint, 10479 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id, 10480 ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id, 10481 ira->old_bb_index, ira->instruction_index); 10482 } 10483 suspend_pos->basic_block_index = ira->old_bb_index; 10484 suspend_pos->instruction_index = ira->instruction_index; 10485 10486 ira->old_irb.current_basic_block->suspended = true; 10487 10488 // null next_bb means that the caller plans to call ira_resume before returning 10489 if (next_bb != nullptr) { 10490 ira->old_bb_index = next_bb->index; 10491 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 10492 assert(ira->old_irb.current_basic_block == next_bb); 10493 ira->instruction_index = 0; 10494 ira->const_predecessor_bb = nullptr; 10495 next_bb->other = ir_get_new_bb_runtime(ira, next_bb, old_instruction); 10496 ira->new_irb.current_basic_block = next_bb->other; 10497 } 10498 return ira->codegen->unreach_instruction; 10499 } 10500 10501 static IrInstruction *ira_resume(IrAnalyze *ira) { 10502 IrSuspendPosition pos = ira->resume_stack.pop(); 10503 if (ira->codegen->verbose_ir) { 10504 fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); 10505 } 10506 ira->old_bb_index = pos.basic_block_index; 10507 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 10508 assert(ira->old_irb.current_basic_block->in_resume_stack); 10509 ira->old_irb.current_basic_block->in_resume_stack = false; 10510 ira->old_irb.current_basic_block->suspended = false; 10511 ira->instruction_index = pos.instruction_index; 10512 assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); 10513 if (ira->codegen->verbose_ir) { 10514 fprintf(stderr, "%s_%zu #%zu\n", ira->old_irb.current_basic_block->name_hint, 10515 ira->old_irb.current_basic_block->debug_id, 10516 ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id); 10517 } 10518 ira->const_predecessor_bb = nullptr; 10519 ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other; 10520 assert(ira->new_irb.current_basic_block != nullptr); 10521 return ira->codegen->unreach_instruction; 10522 } 10523 10524 static void ir_start_next_bb(IrAnalyze *ira) { 10525 ira->old_bb_index += 1; 10526 10527 bool need_repeat = true; 10528 for (;;) { 10529 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 10530 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 10531 if (old_bb->other == nullptr && old_bb->suspend_instruction_ref == nullptr) { 10532 ira->old_bb_index += 1; 10533 continue; 10534 } 10535 // if it's already started, or 10536 // if it's a suspended block, 10537 // then skip it 10538 if (old_bb->suspended || 10539 (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0) || 10540 (old_bb->other != nullptr && old_bb->other->already_appended)) 10541 { 10542 ira->old_bb_index += 1; 10543 continue; 10544 } 10545 10546 // if there is a resume_stack, pop one from there rather than moving on. 10547 // the last item of the resume stack will be a basic block that will 10548 // move on to the next one below 10549 if (ira->resume_stack.length != 0) { 10550 ira_resume(ira); 10551 return; 10552 } 10553 10554 if (old_bb->other == nullptr) { 10555 old_bb->other = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref); 10556 } 10557 ira->new_irb.current_basic_block = old_bb->other; 10558 ir_start_bb(ira, old_bb, nullptr); 10559 return; 10560 } 10561 if (!need_repeat) { 10562 if (ira->resume_stack.length != 0) { 10563 ira_resume(ira); 10564 } 10565 return; 10566 } 10567 need_repeat = false; 10568 ira->old_bb_index = 0; 10569 continue; 10570 } 10571 } 10572 10573 static void ir_finish_bb(IrAnalyze *ira) { 10574 if (!ira->new_irb.current_basic_block->already_appended) { 10575 ira->new_irb.current_basic_block->already_appended = true; 10576 if (ira->codegen->verbose_ir) { 10577 fprintf(stderr, "append new bb %s_%zu\n", ira->new_irb.current_basic_block->name_hint, 10578 ira->new_irb.current_basic_block->debug_id); 10579 } 10580 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); 10581 } 10582 ira->instruction_index += 1; 10583 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { 10584 IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 10585 if (!next_instruction->is_gen) { 10586 ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); 10587 break; 10588 } 10589 ira->instruction_index += 1; 10590 } 10591 10592 ir_start_next_bb(ira); 10593 } 10594 10595 static IrInstruction *ir_unreach_error(IrAnalyze *ira) { 10596 ira->old_bb_index = SIZE_MAX; 10597 ira->new_irb.exec->invalid = true; 10598 return ira->codegen->unreach_instruction; 10599 } 10600 10601 static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instruction) { 10602 size_t *bbc = ira->new_irb.exec->backward_branch_count; 10603 size_t *quota = ira->new_irb.exec->backward_branch_quota; 10604 10605 // If we're already over quota, we've already given an error message for this. 10606 if (*bbc > *quota) { 10607 assert(ira->codegen->errors.length > 0); 10608 return false; 10609 } 10610 10611 *bbc += 1; 10612 if (*bbc > *quota) { 10613 ir_add_error(ira, source_instruction, 10614 buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", *quota)); 10615 return false; 10616 } 10617 return true; 10618 } 10619 10620 static IrInstruction *ir_inline_bb(IrAnalyze *ira, IrInstruction *source_instruction, IrBasicBlock *old_bb) { 10621 if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) { 10622 if (!ir_emit_backward_branch(ira, source_instruction)) 10623 return ir_unreach_error(ira); 10624 } 10625 10626 old_bb->other = ira->old_irb.current_basic_block->other; 10627 ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block); 10628 return ira->codegen->unreach_instruction; 10629 } 10630 10631 static IrInstruction *ir_finish_anal(IrAnalyze *ira, IrInstruction *instruction) { 10632 if (instruction->value.type->id == ZigTypeIdUnreachable) 10633 ir_finish_bb(ira); 10634 return instruction; 10635 } 10636 10637 static IrInstruction *ir_const_type(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { 10638 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_type); 10639 result->value.data.x_type = ty; 10640 return result; 10641 } 10642 10643 static IrInstruction *ir_const_bool(IrAnalyze *ira, IrInstruction *source_instruction, bool value) { 10644 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_bool); 10645 result->value.data.x_bool = value; 10646 return result; 10647 } 10648 10649 static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { 10650 IrInstruction *result = ir_const(ira, source_instruction, ty); 10651 result->value.special = ConstValSpecialUndef; 10652 return result; 10653 } 10654 10655 static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) { 10656 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_unreachable); 10657 result->value.special = ConstValSpecialStatic; 10658 return result; 10659 } 10660 10661 static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { 10662 return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void); 10663 } 10664 10665 static IrInstruction *ir_const_unsigned(IrAnalyze *ira, IrInstruction *source_instruction, uint64_t value) { 10666 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_num_lit_int); 10667 bigint_init_unsigned(&result->value.data.x_bigint, value); 10668 return result; 10669 } 10670 10671 static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instruction, 10672 ConstExprValue *pointee, ZigType *pointee_type, 10673 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align) 10674 { 10675 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type, 10676 ptr_is_const, ptr_is_volatile, PtrLenSingle, ptr_align, 0, 0, false); 10677 IrInstruction *const_instr = ir_const(ira, instruction, ptr_type); 10678 ConstExprValue *const_val = &const_instr->value; 10679 const_val->data.x_ptr.special = ConstPtrSpecialRef; 10680 const_val->data.x_ptr.mut = ptr_mut; 10681 const_val->data.x_ptr.data.ref.pointee = pointee; 10682 return const_instr; 10683 } 10684 10685 static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { 10686 switch (value->value.special) { 10687 case ConstValSpecialStatic: 10688 return &value->value; 10689 case ConstValSpecialRuntime: 10690 if (!type_has_bits(value->value.type)) { 10691 return &value->value; 10692 } 10693 ir_add_error(ira, value, buf_sprintf("unable to evaluate constant expression")); 10694 return nullptr; 10695 case ConstValSpecialUndef: 10696 if (undef_allowed == UndefOk) { 10697 return &value->value; 10698 } else { 10699 ir_add_error(ira, value, buf_sprintf("use of undefined value here causes undefined behavior")); 10700 return nullptr; 10701 } 10702 } 10703 zig_unreachable(); 10704 } 10705 10706 ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, 10707 ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota, 10708 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, 10709 IrExecutable *parent_exec, AstNode *expected_type_source_node) 10710 { 10711 if (expected_type != nullptr && type_is_invalid(expected_type)) 10712 return &codegen->invalid_instruction->value; 10713 10714 IrExecutable *ir_executable = allocate<IrExecutable>(1); 10715 ir_executable->source_node = source_node; 10716 ir_executable->parent_exec = parent_exec; 10717 ir_executable->name = exec_name; 10718 ir_executable->is_inline = true; 10719 ir_executable->fn_entry = fn_entry; 10720 ir_executable->c_import_buf = c_import_buf; 10721 ir_executable->begin_scope = scope; 10722 ir_gen(codegen, node, scope, ir_executable); 10723 10724 if (ir_executable->invalid) 10725 return &codegen->invalid_instruction->value; 10726 10727 if (codegen->verbose_ir) { 10728 fprintf(stderr, "\nSource: "); 10729 ast_render(stderr, node, 4); 10730 fprintf(stderr, "\n{ // (IR)\n"); 10731 ir_print(codegen, stderr, ir_executable, 2); 10732 fprintf(stderr, "}\n"); 10733 } 10734 IrExecutable *analyzed_executable = allocate<IrExecutable>(1); 10735 analyzed_executable->source_node = source_node; 10736 analyzed_executable->parent_exec = parent_exec; 10737 analyzed_executable->source_exec = ir_executable; 10738 analyzed_executable->name = exec_name; 10739 analyzed_executable->is_inline = true; 10740 analyzed_executable->fn_entry = fn_entry; 10741 analyzed_executable->c_import_buf = c_import_buf; 10742 analyzed_executable->backward_branch_count = backward_branch_count; 10743 analyzed_executable->backward_branch_quota = backward_branch_quota; 10744 analyzed_executable->begin_scope = scope; 10745 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, expected_type_source_node); 10746 if (type_is_invalid(result_type)) 10747 return &codegen->invalid_instruction->value; 10748 10749 if (codegen->verbose_ir) { 10750 fprintf(stderr, "{ // (analyzed)\n"); 10751 ir_print(codegen, stderr, analyzed_executable, 2); 10752 fprintf(stderr, "}\n"); 10753 } 10754 10755 return ir_exec_const_result(codegen, analyzed_executable); 10756 } 10757 10758 static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_value) { 10759 if (type_is_invalid(err_value->value.type)) 10760 return nullptr; 10761 10762 if (err_value->value.type->id != ZigTypeIdErrorSet) { 10763 ir_add_error(ira, err_value, 10764 buf_sprintf("expected error, found '%s'", buf_ptr(&err_value->value.type->name))); 10765 return nullptr; 10766 } 10767 10768 ConstExprValue *const_val = ir_resolve_const(ira, err_value, UndefBad); 10769 if (!const_val) 10770 return nullptr; 10771 10772 assert(const_val->data.x_err_set != nullptr); 10773 return const_val->data.x_err_set; 10774 } 10775 10776 static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { 10777 if (type_is_invalid(type_value->value.type)) 10778 return ira->codegen->builtin_types.entry_invalid; 10779 10780 if (type_value->value.type->id != ZigTypeIdMetaType) { 10781 ir_add_error(ira, type_value, 10782 buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value.type->name))); 10783 return ira->codegen->builtin_types.entry_invalid; 10784 } 10785 10786 ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad); 10787 if (!const_val) 10788 return ira->codegen->builtin_types.entry_invalid; 10789 10790 assert(const_val->data.x_type != nullptr); 10791 return const_val->data.x_type; 10792 } 10793 10794 static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) { 10795 ZigType *ty = ir_resolve_type(ira, type_value); 10796 if (type_is_invalid(ty)) 10797 return ira->codegen->builtin_types.entry_invalid; 10798 10799 if (ty->id != ZigTypeIdInt) { 10800 ir_add_error(ira, type_value, 10801 buf_sprintf("expected integer type, found '%s'", buf_ptr(&ty->name))); 10802 return ira->codegen->builtin_types.entry_invalid; 10803 } 10804 10805 return ty; 10806 } 10807 10808 static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInstruction *op_source, IrInstruction *type_value) { 10809 if (type_is_invalid(type_value->value.type)) 10810 return ira->codegen->builtin_types.entry_invalid; 10811 10812 if (type_value->value.type->id != ZigTypeIdMetaType) { 10813 ErrorMsg *msg = ir_add_error(ira, type_value, 10814 buf_sprintf("expected error set type, found '%s'", buf_ptr(&type_value->value.type->name))); 10815 add_error_note(ira->codegen, msg, op_source->source_node, 10816 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 10817 return ira->codegen->builtin_types.entry_invalid; 10818 } 10819 10820 ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad); 10821 if (!const_val) 10822 return ira->codegen->builtin_types.entry_invalid; 10823 10824 assert(const_val->data.x_type != nullptr); 10825 ZigType *result_type = const_val->data.x_type; 10826 if (result_type->id != ZigTypeIdErrorSet) { 10827 ErrorMsg *msg = ir_add_error(ira, type_value, 10828 buf_sprintf("expected error set type, found type '%s'", buf_ptr(&result_type->name))); 10829 add_error_note(ira->codegen, msg, op_source->source_node, 10830 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 10831 return ira->codegen->builtin_types.entry_invalid; 10832 } 10833 return result_type; 10834 } 10835 10836 static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { 10837 if (fn_value == ira->codegen->invalid_instruction) 10838 return nullptr; 10839 10840 if (type_is_invalid(fn_value->value.type)) 10841 return nullptr; 10842 10843 if (fn_value->value.type->id != ZigTypeIdFn) { 10844 ir_add_error_node(ira, fn_value->source_node, 10845 buf_sprintf("expected function type, found '%s'", buf_ptr(&fn_value->value.type->name))); 10846 return nullptr; 10847 } 10848 10849 ConstExprValue *const_val = ir_resolve_const(ira, fn_value, UndefBad); 10850 if (!const_val) 10851 return nullptr; 10852 10853 assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction); 10854 return const_val->data.x_ptr.data.fn.fn_entry; 10855 } 10856 10857 static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 10858 ZigType *wanted_type, ResultLoc *result_loc) 10859 { 10860 assert(wanted_type->id == ZigTypeIdOptional); 10861 10862 if (instr_is_comptime(value)) { 10863 ZigType *payload_type = wanted_type->data.maybe.child_type; 10864 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); 10865 if (type_is_invalid(casted_payload->value.type)) 10866 return ira->codegen->invalid_instruction; 10867 10868 ConstExprValue *val = ir_resolve_const(ira, casted_payload, UndefOk); 10869 if (!val) 10870 return ira->codegen->invalid_instruction; 10871 10872 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 10873 source_instr->scope, source_instr->source_node); 10874 const_instruction->base.value.special = ConstValSpecialStatic; 10875 if (types_have_same_zig_comptime_repr(wanted_type, payload_type)) { 10876 copy_const_val(&const_instruction->base.value, val, val->data.x_ptr.mut == ConstPtrMutComptimeConst); 10877 } else { 10878 const_instruction->base.value.data.x_optional = val; 10879 } 10880 const_instruction->base.value.type = wanted_type; 10881 return &const_instruction->base; 10882 } 10883 10884 if (result_loc == nullptr && handle_is_ptr(wanted_type)) { 10885 result_loc = no_result_loc(); 10886 } 10887 IrInstruction *result_loc_inst = nullptr; 10888 if (result_loc != nullptr) { 10889 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); 10890 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { 10891 return result_loc_inst; 10892 } 10893 } 10894 IrInstruction *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst); 10895 result->value.data.rh_maybe = RuntimeHintOptionalNonNull; 10896 return result; 10897 } 10898 10899 static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, 10900 IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) 10901 { 10902 assert(wanted_type->id == ZigTypeIdErrorUnion); 10903 10904 ZigType *payload_type = wanted_type->data.error_union.payload_type; 10905 ZigType *err_set_type = wanted_type->data.error_union.err_set_type; 10906 if (instr_is_comptime(value)) { 10907 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); 10908 if (type_is_invalid(casted_payload->value.type)) 10909 return ira->codegen->invalid_instruction; 10910 10911 ConstExprValue *val = ir_resolve_const(ira, casted_payload, UndefBad); 10912 if (!val) 10913 return ira->codegen->invalid_instruction; 10914 10915 ConstExprValue *err_set_val = create_const_vals(1); 10916 err_set_val->type = err_set_type; 10917 err_set_val->special = ConstValSpecialStatic; 10918 err_set_val->data.x_err_set = nullptr; 10919 10920 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 10921 source_instr->scope, source_instr->source_node); 10922 const_instruction->base.value.type = wanted_type; 10923 const_instruction->base.value.special = ConstValSpecialStatic; 10924 const_instruction->base.value.data.x_err_union.error_set = err_set_val; 10925 const_instruction->base.value.data.x_err_union.payload = val; 10926 return &const_instruction->base; 10927 } 10928 10929 IrInstruction *result_loc_inst; 10930 if (handle_is_ptr(wanted_type)) { 10931 if (result_loc == nullptr) result_loc = no_result_loc(); 10932 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); 10933 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { 10934 return result_loc_inst; 10935 } 10936 } else { 10937 result_loc_inst = nullptr; 10938 } 10939 10940 IrInstruction *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst); 10941 result->value.data.rh_error_union = RuntimeHintErrorUnionNonError; 10942 return result; 10943 } 10944 10945 static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 10946 ZigType *wanted_type) 10947 { 10948 assert(value->value.type->id == ZigTypeIdErrorSet); 10949 assert(wanted_type->id == ZigTypeIdErrorSet); 10950 10951 if (instr_is_comptime(value)) { 10952 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 10953 if (!val) 10954 return ira->codegen->invalid_instruction; 10955 10956 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 10957 return ira->codegen->invalid_instruction; 10958 } 10959 if (!type_is_global_error_set(wanted_type)) { 10960 bool subset = false; 10961 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 10962 if (wanted_type->data.error_set.errors[i]->value == val->data.x_err_set->value) { 10963 subset = true; 10964 break; 10965 } 10966 } 10967 if (!subset) { 10968 ir_add_error(ira, source_instr, 10969 buf_sprintf("error.%s not a member of error set '%s'", 10970 buf_ptr(&val->data.x_err_set->name), buf_ptr(&wanted_type->name))); 10971 return ira->codegen->invalid_instruction; 10972 } 10973 } 10974 10975 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 10976 source_instr->scope, source_instr->source_node); 10977 const_instruction->base.value.type = wanted_type; 10978 const_instruction->base.value.special = ConstValSpecialStatic; 10979 const_instruction->base.value.data.x_err_set = val->data.x_err_set; 10980 return &const_instruction->base; 10981 } 10982 10983 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, CastOpErrSet); 10984 result->value.type = wanted_type; 10985 return result; 10986 } 10987 10988 static IrInstruction *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInstruction *source_instr, 10989 IrInstruction *value, ZigType *wanted_type) 10990 { 10991 if (instr_is_comptime(value)) { 10992 zig_panic("TODO comptime frame pointer"); 10993 } 10994 10995 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 10996 wanted_type, value, CastOpBitCast); 10997 result->value.type = wanted_type; 10998 return result; 10999 } 11000 11001 static IrInstruction *ir_analyze_anyframe_to_anyframe(IrAnalyze *ira, IrInstruction *source_instr, 11002 IrInstruction *value, ZigType *wanted_type) 11003 { 11004 if (instr_is_comptime(value)) { 11005 zig_panic("TODO comptime anyframe->T to anyframe"); 11006 } 11007 11008 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 11009 wanted_type, value, CastOpBitCast); 11010 result->value.type = wanted_type; 11011 return result; 11012 } 11013 11014 11015 static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 11016 ZigType *wanted_type, ResultLoc *result_loc) 11017 { 11018 assert(wanted_type->id == ZigTypeIdErrorUnion); 11019 11020 IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); 11021 11022 if (instr_is_comptime(casted_value)) { 11023 ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad); 11024 if (!val) 11025 return ira->codegen->invalid_instruction; 11026 11027 ConstExprValue *err_set_val = create_const_vals(1); 11028 err_set_val->special = ConstValSpecialStatic; 11029 err_set_val->type = wanted_type->data.error_union.err_set_type; 11030 err_set_val->data.x_err_set = val->data.x_err_set; 11031 11032 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 11033 source_instr->scope, source_instr->source_node); 11034 const_instruction->base.value.type = wanted_type; 11035 const_instruction->base.value.special = ConstValSpecialStatic; 11036 const_instruction->base.value.data.x_err_union.error_set = err_set_val; 11037 const_instruction->base.value.data.x_err_union.payload = nullptr; 11038 return &const_instruction->base; 11039 } 11040 11041 IrInstruction *result_loc_inst; 11042 if (handle_is_ptr(wanted_type)) { 11043 if (result_loc == nullptr) result_loc = no_result_loc(); 11044 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); 11045 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { 11046 return result_loc_inst; 11047 } 11048 } else { 11049 result_loc_inst = nullptr; 11050 } 11051 11052 11053 IrInstruction *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst); 11054 result->value.data.rh_error_union = RuntimeHintErrorUnionError; 11055 return result; 11056 } 11057 11058 static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { 11059 assert(wanted_type->id == ZigTypeIdOptional); 11060 assert(instr_is_comptime(value)); 11061 11062 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 11063 assert(val != nullptr); 11064 11065 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11066 result->value.special = ConstValSpecialStatic; 11067 if (get_codegen_ptr_type(wanted_type) != nullptr) { 11068 result->value.data.x_ptr.special = ConstPtrSpecialNull; 11069 } else if (is_opt_err_set(wanted_type)) { 11070 result->value.data.x_err_set = nullptr; 11071 } else { 11072 result->value.data.x_optional = nullptr; 11073 } 11074 return result; 11075 } 11076 11077 static IrInstruction *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInstruction *source_instr, 11078 IrInstruction *value, ZigType *wanted_type) 11079 { 11080 assert(wanted_type->id == ZigTypeIdPointer); 11081 assert(wanted_type->data.pointer.ptr_len == PtrLenC); 11082 assert(instr_is_comptime(value)); 11083 11084 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 11085 assert(val != nullptr); 11086 11087 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11088 result->value.data.x_ptr.special = ConstPtrSpecialNull; 11089 result->value.data.x_ptr.mut = ConstPtrMutComptimeConst; 11090 return result; 11091 } 11092 11093 static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value, 11094 bool is_const, bool is_volatile) 11095 { 11096 Error err; 11097 11098 if (type_is_invalid(value->value.type)) 11099 return ira->codegen->invalid_instruction; 11100 11101 if ((err = type_resolve(ira->codegen, value->value.type, ResolveStatusZeroBitsKnown))) 11102 return ira->codegen->invalid_instruction; 11103 11104 if (instr_is_comptime(value)) { 11105 ConstExprValue *val = ir_resolve_const(ira, value, UndefOk); 11106 if (!val) 11107 return ira->codegen->invalid_instruction; 11108 return ir_get_const_ptr(ira, source_instruction, val, value->value.type, 11109 ConstPtrMutComptimeConst, is_const, is_volatile, 0); 11110 } 11111 11112 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, 11113 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 11114 11115 IrInstruction *result_loc; 11116 if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) { 11117 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true, 11118 false, true); 11119 } else { 11120 result_loc = nullptr; 11121 } 11122 11123 IrInstruction *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc); 11124 new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; 11125 return new_instruction; 11126 } 11127 11128 static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, 11129 IrInstruction *array_arg, ZigType *wanted_type, ResultLoc *result_loc) 11130 { 11131 assert(is_slice(wanted_type)); 11132 // In this function we honor the const-ness of wanted_type, because 11133 // we may be casting [0]T to []const T which is perfectly valid. 11134 11135 IrInstruction *array_ptr = nullptr; 11136 IrInstruction *array; 11137 if (array_arg->value.type->id == ZigTypeIdPointer) { 11138 array = ir_get_deref(ira, source_instr, array_arg, nullptr); 11139 array_ptr = array_arg; 11140 } else { 11141 array = array_arg; 11142 } 11143 ZigType *array_type = array->value.type; 11144 assert(array_type->id == ZigTypeIdArray); 11145 11146 if (instr_is_comptime(array) || array_type->data.array.len == 0) { 11147 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11148 init_const_slice(ira->codegen, &result->value, &array->value, 0, array_type->data.array.len, true); 11149 result->value.type = wanted_type; 11150 return result; 11151 } 11152 11153 IrInstruction *start = ir_const(ira, source_instr, ira->codegen->builtin_types.entry_usize); 11154 init_const_usize(ira->codegen, &start->value, 0); 11155 11156 IrInstruction *end = ir_const(ira, source_instr, ira->codegen->builtin_types.entry_usize); 11157 init_const_usize(ira->codegen, &end->value, array_type->data.array.len); 11158 11159 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false); 11160 11161 if (result_loc == nullptr) result_loc = no_result_loc(); 11162 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, 11163 true, false, true); 11164 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { 11165 return result_loc_inst; 11166 } 11167 IrInstruction *result = ir_build_slice_gen(ira, source_instr, wanted_type, array_ptr, start, end, false, result_loc_inst); 11168 result->value.data.rh_slice.id = RuntimeHintSliceIdLen; 11169 result->value.data.rh_slice.len = array_type->data.array.len; 11170 11171 return result; 11172 } 11173 11174 static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, IrInstruction *source_instr, ZigType *union_type) { 11175 assert(union_type->id == ZigTypeIdUnion); 11176 11177 Error err; 11178 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) 11179 return ira->codegen->builtin_types.entry_invalid; 11180 11181 AstNode *decl_node = union_type->data.unionation.decl_node; 11182 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) { 11183 assert(union_type->data.unionation.tag_type != nullptr); 11184 return union_type->data.unionation.tag_type; 11185 } else { 11186 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union '%s' has no tag", 11187 buf_ptr(&union_type->name))); 11188 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here")); 11189 return ira->codegen->builtin_types.entry_invalid; 11190 } 11191 } 11192 11193 static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target) { 11194 Error err; 11195 11196 IrInstruction *enum_target; 11197 ZigType *enum_type; 11198 if (target->value.type->id == ZigTypeIdUnion) { 11199 enum_type = ir_resolve_union_tag_type(ira, target, target->value.type); 11200 if (type_is_invalid(enum_type)) 11201 return ira->codegen->invalid_instruction; 11202 enum_target = ir_implicit_cast(ira, target, enum_type); 11203 if (type_is_invalid(enum_target->value.type)) 11204 return ira->codegen->invalid_instruction; 11205 } else if (target->value.type->id == ZigTypeIdEnum) { 11206 enum_target = target; 11207 enum_type = target->value.type; 11208 } else { 11209 ir_add_error(ira, target, 11210 buf_sprintf("expected enum, found type '%s'", buf_ptr(&target->value.type->name))); 11211 return ira->codegen->invalid_instruction; 11212 } 11213 11214 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) 11215 return ira->codegen->invalid_instruction; 11216 11217 ZigType *tag_type = enum_type->data.enumeration.tag_int_type; 11218 assert(tag_type->id == ZigTypeIdInt || tag_type->id == ZigTypeIdComptimeInt); 11219 11220 // If there is only one possible tag, then we know at comptime what it is. 11221 if (enum_type->data.enumeration.layout == ContainerLayoutAuto && 11222 enum_type->data.enumeration.src_field_count == 1) 11223 { 11224 IrInstruction *result = ir_const(ira, source_instr, tag_type); 11225 init_const_bigint(&result->value, tag_type, 11226 &enum_type->data.enumeration.fields[0].value); 11227 return result; 11228 } 11229 11230 if (instr_is_comptime(enum_target)) { 11231 ConstExprValue *val = ir_resolve_const(ira, enum_target, UndefBad); 11232 if (!val) 11233 return ira->codegen->invalid_instruction; 11234 IrInstruction *result = ir_const(ira, source_instr, tag_type); 11235 init_const_bigint(&result->value, tag_type, &val->data.x_enum_tag); 11236 return result; 11237 } 11238 11239 IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, 11240 source_instr->source_node, enum_target); 11241 result->value.type = tag_type; 11242 return result; 11243 } 11244 11245 static IrInstruction *ir_analyze_union_to_tag(IrAnalyze *ira, IrInstruction *source_instr, 11246 IrInstruction *target, ZigType *wanted_type) 11247 { 11248 assert(target->value.type->id == ZigTypeIdUnion); 11249 assert(wanted_type->id == ZigTypeIdEnum); 11250 assert(wanted_type == target->value.type->data.unionation.tag_type); 11251 11252 if (instr_is_comptime(target)) { 11253 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11254 if (!val) 11255 return ira->codegen->invalid_instruction; 11256 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11257 result->value.special = ConstValSpecialStatic; 11258 result->value.type = wanted_type; 11259 bigint_init_bigint(&result->value.data.x_enum_tag, &val->data.x_union.tag); 11260 return result; 11261 } 11262 11263 // If there is only 1 possible tag, then we know at comptime what it is. 11264 if (wanted_type->data.enumeration.layout == ContainerLayoutAuto && 11265 wanted_type->data.enumeration.src_field_count == 1) 11266 { 11267 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11268 result->value.special = ConstValSpecialStatic; 11269 result->value.type = wanted_type; 11270 TypeEnumField *enum_field = target->value.type->data.unionation.fields[0].enum_field; 11271 bigint_init_bigint(&result->value.data.x_enum_tag, &enum_field->value); 11272 return result; 11273 } 11274 11275 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, 11276 source_instr->source_node, target); 11277 result->value.type = wanted_type; 11278 return result; 11279 } 11280 11281 static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruction *source_instr, 11282 IrInstruction *target, ZigType *wanted_type) 11283 { 11284 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11285 init_const_undefined(ira->codegen, &result->value); 11286 return result; 11287 } 11288 11289 static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *source_instr, 11290 IrInstruction *uncasted_target, ZigType *wanted_type) 11291 { 11292 Error err; 11293 assert(wanted_type->id == ZigTypeIdUnion); 11294 11295 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) 11296 return ira->codegen->invalid_instruction; 11297 11298 IrInstruction *target = ir_implicit_cast(ira, uncasted_target, wanted_type->data.unionation.tag_type); 11299 if (type_is_invalid(target->value.type)) 11300 return ira->codegen->invalid_instruction; 11301 11302 if (instr_is_comptime(target)) { 11303 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11304 if (!val) 11305 return ira->codegen->invalid_instruction; 11306 TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); 11307 assert(union_field != nullptr); 11308 if ((err = type_resolve(ira->codegen, union_field->type_entry, ResolveStatusZeroBitsKnown))) 11309 return ira->codegen->invalid_instruction; 11310 11311 switch (type_has_one_possible_value(ira->codegen, union_field->type_entry)) { 11312 case OnePossibleValueInvalid: 11313 return ira->codegen->invalid_instruction; 11314 case OnePossibleValueNo: { 11315 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at( 11316 union_field->enum_field->decl_index); 11317 ErrorMsg *msg = ir_add_error(ira, source_instr, 11318 buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", 11319 buf_ptr(&wanted_type->name), 11320 buf_ptr(&union_field->type_entry->name), 11321 buf_ptr(union_field->name))); 11322 add_error_note(ira->codegen, msg, field_node, 11323 buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); 11324 return ira->codegen->invalid_instruction; 11325 } 11326 case OnePossibleValueYes: 11327 break; 11328 } 11329 11330 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11331 result->value.special = ConstValSpecialStatic; 11332 result->value.type = wanted_type; 11333 bigint_init_bigint(&result->value.data.x_union.tag, &val->data.x_enum_tag); 11334 result->value.data.x_union.payload = create_const_vals(1); 11335 result->value.data.x_union.payload->special = ConstValSpecialStatic; 11336 result->value.data.x_union.payload->type = union_field->type_entry; 11337 return result; 11338 } 11339 11340 // if the union has all fields 0 bits, we can do it 11341 // and in fact it's a noop cast because the union value is just the enum value 11342 if (wanted_type->data.unionation.gen_field_count == 0) { 11343 IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, wanted_type, target, CastOpNoop); 11344 result->value.type = wanted_type; 11345 return result; 11346 } 11347 11348 ErrorMsg *msg = ir_add_error(ira, source_instr, 11349 buf_sprintf("runtime cast to union '%s' which has non-void fields", 11350 buf_ptr(&wanted_type->name))); 11351 for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { 11352 TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; 11353 if (type_has_bits(union_field->type_entry)) { 11354 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); 11355 add_error_note(ira->codegen, msg, field_node, 11356 buf_sprintf("field '%s' has type '%s'", 11357 buf_ptr(union_field->name), 11358 buf_ptr(&union_field->type_entry->name))); 11359 } 11360 } 11361 return ira->codegen->invalid_instruction; 11362 } 11363 11364 static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction *source_instr, 11365 IrInstruction *target, ZigType *wanted_type) 11366 { 11367 assert(wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdFloat); 11368 11369 if (instr_is_comptime(target)) { 11370 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11371 if (!val) 11372 return ira->codegen->invalid_instruction; 11373 if (wanted_type->id == ZigTypeIdInt) { 11374 if (bigint_cmp_zero(&val->data.x_bigint) == CmpLT && !wanted_type->data.integral.is_signed) { 11375 ir_add_error(ira, source_instr, 11376 buf_sprintf("attempt to cast negative value to unsigned integer")); 11377 return ira->codegen->invalid_instruction; 11378 } 11379 if (!bigint_fits_in_bits(&val->data.x_bigint, wanted_type->data.integral.bit_count, 11380 wanted_type->data.integral.is_signed)) 11381 { 11382 ir_add_error(ira, source_instr, 11383 buf_sprintf("cast from '%s' to '%s' truncates bits", 11384 buf_ptr(&target->value.type->name), buf_ptr(&wanted_type->name))); 11385 return ira->codegen->invalid_instruction; 11386 } 11387 } 11388 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11389 result->value.type = wanted_type; 11390 if (wanted_type->id == ZigTypeIdInt) { 11391 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); 11392 } else { 11393 float_init_float(&result->value, val); 11394 } 11395 return result; 11396 } 11397 11398 // If the destination integer type has no bits, then we can emit a comptime 11399 // zero. However, we still want to emit a runtime safety check to make sure 11400 // the target is zero. 11401 if (!type_has_bits(wanted_type)) { 11402 assert(wanted_type->id == ZigTypeIdInt); 11403 assert(type_has_bits(target->value.type)); 11404 ir_build_assert_zero(ira, source_instr, target); 11405 IrInstruction *result = ir_const_unsigned(ira, source_instr, 0); 11406 result->value.type = wanted_type; 11407 return result; 11408 } 11409 11410 IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, 11411 source_instr->source_node, target); 11412 result->value.type = wanted_type; 11413 return result; 11414 } 11415 11416 static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *source_instr, 11417 IrInstruction *target, ZigType *wanted_type) 11418 { 11419 Error err; 11420 assert(wanted_type->id == ZigTypeIdEnum); 11421 11422 ZigType *actual_type = target->value.type; 11423 11424 if ((err = ensure_complete_type(ira->codegen, wanted_type))) 11425 return ira->codegen->invalid_instruction; 11426 11427 if (actual_type != wanted_type->data.enumeration.tag_int_type) { 11428 ir_add_error(ira, source_instr, 11429 buf_sprintf("integer to enum cast from '%s' instead of its tag type, '%s'", 11430 buf_ptr(&actual_type->name), 11431 buf_ptr(&wanted_type->data.enumeration.tag_int_type->name))); 11432 return ira->codegen->invalid_instruction; 11433 } 11434 11435 assert(actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt); 11436 11437 if (instr_is_comptime(target)) { 11438 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11439 if (!val) 11440 return ira->codegen->invalid_instruction; 11441 11442 TypeEnumField *field = find_enum_field_by_tag(wanted_type, &val->data.x_bigint); 11443 if (field == nullptr) { 11444 Buf *val_buf = buf_alloc(); 11445 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 11446 ErrorMsg *msg = ir_add_error(ira, source_instr, 11447 buf_sprintf("enum '%s' has no tag matching integer value %s", 11448 buf_ptr(&wanted_type->name), buf_ptr(val_buf))); 11449 add_error_note(ira->codegen, msg, wanted_type->data.enumeration.decl_node, 11450 buf_sprintf("'%s' declared here", buf_ptr(&wanted_type->name))); 11451 return ira->codegen->invalid_instruction; 11452 } 11453 11454 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11455 bigint_init_bigint(&result->value.data.x_enum_tag, &val->data.x_bigint); 11456 return result; 11457 } 11458 11459 IrInstruction *result = ir_build_int_to_enum(&ira->new_irb, source_instr->scope, 11460 source_instr->source_node, nullptr, target); 11461 result->value.type = wanted_type; 11462 return result; 11463 } 11464 11465 static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction *source_instr, 11466 IrInstruction *target, ZigType *wanted_type) 11467 { 11468 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11469 if (!val) 11470 return ira->codegen->invalid_instruction; 11471 11472 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11473 if (wanted_type->id == ZigTypeIdComptimeFloat) { 11474 float_init_float(&result->value, val); 11475 } else if (wanted_type->id == ZigTypeIdComptimeInt) { 11476 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); 11477 } else { 11478 zig_unreachable(); 11479 } 11480 return result; 11481 } 11482 11483 static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 11484 ZigType *wanted_type) 11485 { 11486 assert(target->value.type->id == ZigTypeIdInt); 11487 assert(!target->value.type->data.integral.is_signed); 11488 assert(wanted_type->id == ZigTypeIdErrorSet); 11489 11490 if (instr_is_comptime(target)) { 11491 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11492 if (!val) 11493 return ira->codegen->invalid_instruction; 11494 11495 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11496 11497 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 11498 return ira->codegen->invalid_instruction; 11499 } 11500 11501 if (type_is_global_error_set(wanted_type)) { 11502 BigInt err_count; 11503 bigint_init_unsigned(&err_count, ira->codegen->errors_by_index.length); 11504 11505 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) { 11506 Buf *val_buf = buf_alloc(); 11507 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 11508 ir_add_error(ira, source_instr, 11509 buf_sprintf("integer value %s represents no error", buf_ptr(val_buf))); 11510 return ira->codegen->invalid_instruction; 11511 } 11512 11513 size_t index = bigint_as_unsigned(&val->data.x_bigint); 11514 result->value.data.x_err_set = ira->codegen->errors_by_index.at(index); 11515 return result; 11516 } else { 11517 ErrorTableEntry *err = nullptr; 11518 BigInt err_int; 11519 11520 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 11521 ErrorTableEntry *this_err = wanted_type->data.error_set.errors[i]; 11522 bigint_init_unsigned(&err_int, this_err->value); 11523 if (bigint_cmp(&val->data.x_bigint, &err_int) == CmpEQ) { 11524 err = this_err; 11525 break; 11526 } 11527 } 11528 11529 if (err == nullptr) { 11530 Buf *val_buf = buf_alloc(); 11531 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 11532 ir_add_error(ira, source_instr, 11533 buf_sprintf("integer value %s represents no error in '%s'", buf_ptr(val_buf), buf_ptr(&wanted_type->name))); 11534 return ira->codegen->invalid_instruction; 11535 } 11536 11537 result->value.data.x_err_set = err; 11538 return result; 11539 } 11540 } 11541 11542 IrInstruction *result = ir_build_int_to_err(&ira->new_irb, source_instr->scope, source_instr->source_node, target); 11543 result->value.type = wanted_type; 11544 return result; 11545 } 11546 11547 static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 11548 ZigType *wanted_type) 11549 { 11550 assert(wanted_type->id == ZigTypeIdInt); 11551 11552 ZigType *err_type = target->value.type; 11553 11554 if (instr_is_comptime(target)) { 11555 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11556 if (!val) 11557 return ira->codegen->invalid_instruction; 11558 11559 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11560 11561 ErrorTableEntry *err; 11562 if (err_type->id == ZigTypeIdErrorUnion) { 11563 err = val->data.x_err_union.error_set->data.x_err_set; 11564 } else if (err_type->id == ZigTypeIdErrorSet) { 11565 err = val->data.x_err_set; 11566 } else { 11567 zig_unreachable(); 11568 } 11569 result->value.type = wanted_type; 11570 uint64_t err_value = err ? err->value : 0; 11571 bigint_init_unsigned(&result->value.data.x_bigint, err_value); 11572 11573 if (!bigint_fits_in_bits(&result->value.data.x_bigint, 11574 wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) 11575 { 11576 ir_add_error_node(ira, source_instr->source_node, 11577 buf_sprintf("error code '%s' does not fit in '%s'", 11578 buf_ptr(&err->name), buf_ptr(&wanted_type->name))); 11579 return ira->codegen->invalid_instruction; 11580 } 11581 11582 return result; 11583 } 11584 11585 ZigType *err_set_type; 11586 if (err_type->id == ZigTypeIdErrorUnion) { 11587 err_set_type = err_type->data.error_union.err_set_type; 11588 } else if (err_type->id == ZigTypeIdErrorSet) { 11589 err_set_type = err_type; 11590 } else { 11591 zig_unreachable(); 11592 } 11593 if (!type_is_global_error_set(err_set_type)) { 11594 if (!resolve_inferred_error_set(ira->codegen, err_set_type, source_instr->source_node)) { 11595 return ira->codegen->invalid_instruction; 11596 } 11597 if (err_set_type->data.error_set.err_count == 0) { 11598 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11599 bigint_init_unsigned(&result->value.data.x_bigint, 0); 11600 return result; 11601 } else if (err_set_type->data.error_set.err_count == 1) { 11602 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11603 ErrorTableEntry *err = err_set_type->data.error_set.errors[0]; 11604 bigint_init_unsigned(&result->value.data.x_bigint, err->value); 11605 return result; 11606 } 11607 } 11608 11609 BigInt bn; 11610 bigint_init_unsigned(&bn, ira->codegen->errors_by_index.length); 11611 if (!bigint_fits_in_bits(&bn, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) { 11612 ir_add_error_node(ira, source_instr->source_node, 11613 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name))); 11614 return ira->codegen->invalid_instruction; 11615 } 11616 11617 IrInstruction *result = ir_build_err_to_int(&ira->new_irb, source_instr->scope, source_instr->source_node, target); 11618 result->value.type = wanted_type; 11619 return result; 11620 } 11621 11622 static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 11623 ZigType *wanted_type) 11624 { 11625 assert(wanted_type->id == ZigTypeIdPointer); 11626 Error err; 11627 if ((err = type_resolve(ira->codegen, target->value.type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 11628 return ira->codegen->invalid_instruction; 11629 assert((wanted_type->data.pointer.is_const && target->value.type->data.pointer.is_const) || !target->value.type->data.pointer.is_const); 11630 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, target->value.type)); 11631 ZigType *array_type = wanted_type->data.pointer.child_type; 11632 assert(array_type->id == ZigTypeIdArray); 11633 assert(array_type->data.array.len == 1); 11634 11635 if (instr_is_comptime(target)) { 11636 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 11637 if (!val) 11638 return ira->codegen->invalid_instruction; 11639 11640 assert(val->type->id == ZigTypeIdPointer); 11641 ConstExprValue *pointee = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 11642 if (pointee == nullptr) 11643 return ira->codegen->invalid_instruction; 11644 if (pointee->special != ConstValSpecialRuntime) { 11645 ConstExprValue *array_val = create_const_vals(1); 11646 array_val->special = ConstValSpecialStatic; 11647 array_val->type = array_type; 11648 array_val->data.x_array.special = ConstArraySpecialNone; 11649 array_val->data.x_array.data.s_none.elements = pointee; 11650 array_val->parent.id = ConstParentIdScalar; 11651 array_val->parent.data.p_scalar.scalar_val = pointee; 11652 11653 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 11654 source_instr->scope, source_instr->source_node); 11655 const_instruction->base.value.type = wanted_type; 11656 const_instruction->base.value.special = ConstValSpecialStatic; 11657 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialRef; 11658 const_instruction->base.value.data.x_ptr.data.ref.pointee = array_val; 11659 const_instruction->base.value.data.x_ptr.mut = val->data.x_ptr.mut; 11660 return &const_instruction->base; 11661 } 11662 } 11663 11664 // pointer to array and pointer to single item are represented the same way at runtime 11665 IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, 11666 wanted_type, target, CastOpBitCast); 11667 result->value.type = wanted_type; 11668 return result; 11669 } 11670 11671 static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCastOnly *cast_result, 11672 ErrorMsg *parent_msg) 11673 { 11674 switch (cast_result->id) { 11675 case ConstCastResultIdOk: 11676 zig_unreachable(); 11677 case ConstCastResultIdInvalid: 11678 zig_unreachable(); 11679 case ConstCastResultIdOptionalChild: { 11680 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11681 buf_sprintf("optional type child '%s' cannot cast into optional type child '%s'", 11682 buf_ptr(&cast_result->data.optional->actual_child->name), 11683 buf_ptr(&cast_result->data.optional->wanted_child->name))); 11684 report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg); 11685 break; 11686 } 11687 case ConstCastResultIdErrorUnionErrorSet: { 11688 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11689 buf_sprintf("error set '%s' cannot cast into error set '%s'", 11690 buf_ptr(&cast_result->data.error_union_error_set->actual_err_set->name), 11691 buf_ptr(&cast_result->data.error_union_error_set->wanted_err_set->name))); 11692 report_recursive_error(ira, source_node, &cast_result->data.error_union_error_set->child, msg); 11693 break; 11694 } 11695 case ConstCastResultIdErrSet: { 11696 ZigList<ErrorTableEntry *> *missing_errors = &cast_result->data.error_set_mismatch->missing_errors; 11697 for (size_t i = 0; i < missing_errors->length; i += 1) { 11698 ErrorTableEntry *error_entry = missing_errors->at(i); 11699 add_error_note(ira->codegen, parent_msg, error_entry->decl_node, 11700 buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name))); 11701 } 11702 break; 11703 } 11704 case ConstCastResultIdErrSetGlobal: { 11705 add_error_note(ira->codegen, parent_msg, source_node, 11706 buf_sprintf("cannot cast global error set into smaller set")); 11707 break; 11708 } 11709 case ConstCastResultIdPointerChild: { 11710 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11711 buf_sprintf("pointer type child '%s' cannot cast into pointer type child '%s'", 11712 buf_ptr(&cast_result->data.pointer_mismatch->actual_child->name), 11713 buf_ptr(&cast_result->data.pointer_mismatch->wanted_child->name))); 11714 report_recursive_error(ira, source_node, &cast_result->data.pointer_mismatch->child, msg); 11715 break; 11716 } 11717 case ConstCastResultIdSliceChild: { 11718 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11719 buf_sprintf("slice type child '%s' cannot cast into slice type child '%s'", 11720 buf_ptr(&cast_result->data.slice_mismatch->actual_child->name), 11721 buf_ptr(&cast_result->data.slice_mismatch->wanted_child->name))); 11722 report_recursive_error(ira, source_node, &cast_result->data.slice_mismatch->child, msg); 11723 break; 11724 } 11725 case ConstCastResultIdErrorUnionPayload: { 11726 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11727 buf_sprintf("error union payload '%s' cannot cast into error union payload '%s'", 11728 buf_ptr(&cast_result->data.error_union_payload->actual_payload->name), 11729 buf_ptr(&cast_result->data.error_union_payload->wanted_payload->name))); 11730 report_recursive_error(ira, source_node, &cast_result->data.error_union_payload->child, msg); 11731 break; 11732 } 11733 case ConstCastResultIdType: { 11734 AstNode *wanted_decl_node = type_decl_node(cast_result->data.type_mismatch->wanted_type); 11735 AstNode *actual_decl_node = type_decl_node(cast_result->data.type_mismatch->actual_type); 11736 if (wanted_decl_node != nullptr) { 11737 add_error_note(ira->codegen, parent_msg, wanted_decl_node, 11738 buf_sprintf("%s declared here", 11739 buf_ptr(&cast_result->data.type_mismatch->wanted_type->name))); 11740 } 11741 if (actual_decl_node != nullptr) { 11742 add_error_note(ira->codegen, parent_msg, actual_decl_node, 11743 buf_sprintf("%s declared here", 11744 buf_ptr(&cast_result->data.type_mismatch->actual_type->name))); 11745 } 11746 break; 11747 } 11748 case ConstCastResultIdFnArg: { 11749 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 11750 buf_sprintf("parameter %" ZIG_PRI_usize ": '%s' cannot cast into '%s'", 11751 cast_result->data.fn_arg.arg_index, 11752 buf_ptr(&cast_result->data.fn_arg.actual_param_type->name), 11753 buf_ptr(&cast_result->data.fn_arg.expected_param_type->name))); 11754 report_recursive_error(ira, source_node, cast_result->data.fn_arg.child, msg); 11755 break; 11756 } 11757 case ConstCastResultIdBadAllowsZero: { 11758 ZigType *wanted_type = cast_result->data.bad_allows_zero->wanted_type; 11759 ZigType *actual_type = cast_result->data.bad_allows_zero->actual_type; 11760 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 11761 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 11762 if (actual_allows_zero && !wanted_allows_zero) { 11763 add_error_note(ira->codegen, parent_msg, source_node, 11764 buf_sprintf("'%s' could have null values which are illegal in type '%s'", 11765 buf_ptr(&actual_type->name), 11766 buf_ptr(&wanted_type->name))); 11767 } else { 11768 add_error_note(ira->codegen, parent_msg, source_node, 11769 buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'", 11770 buf_ptr(&wanted_type->name), 11771 buf_ptr(&actual_type->name))); 11772 } 11773 break; 11774 } 11775 case ConstCastResultIdFnIsGeneric: 11776 add_error_note(ira->codegen, parent_msg, source_node, 11777 buf_sprintf("only one of the functions is generic")); 11778 break; 11779 case ConstCastResultIdFnAlign: // TODO 11780 case ConstCastResultIdFnCC: // TODO 11781 case ConstCastResultIdFnVarArgs: // TODO 11782 case ConstCastResultIdFnReturnType: // TODO 11783 case ConstCastResultIdFnArgCount: // TODO 11784 case ConstCastResultIdFnGenericArgCount: // TODO 11785 case ConstCastResultIdFnArgNoAlias: // TODO 11786 case ConstCastResultIdUnresolvedInferredErrSet: // TODO 11787 case ConstCastResultIdAsyncAllocatorType: // TODO 11788 break; 11789 } 11790 } 11791 11792 static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction *source_instr, 11793 IrInstruction *array, ZigType *vector_type) 11794 { 11795 if (instr_is_comptime(array)) { 11796 // arrays and vectors have the same ConstExprValue representation 11797 IrInstruction *result = ir_const(ira, source_instr, vector_type); 11798 copy_const_val(&result->value, &array->value, false); 11799 result->value.type = vector_type; 11800 return result; 11801 } 11802 return ir_build_array_to_vector(ira, source_instr, array, vector_type); 11803 } 11804 11805 static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr, 11806 IrInstruction *vector, ZigType *array_type, ResultLoc *result_loc) 11807 { 11808 if (instr_is_comptime(vector)) { 11809 // arrays and vectors have the same ConstExprValue representation 11810 IrInstruction *result = ir_const(ira, source_instr, array_type); 11811 copy_const_val(&result->value, &vector->value, false); 11812 result->value.type = array_type; 11813 return result; 11814 } 11815 if (result_loc == nullptr) { 11816 result_loc = no_result_loc(); 11817 } 11818 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, 11819 true, false, true); 11820 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { 11821 return result_loc_inst; 11822 } 11823 return ir_build_vector_to_array(ira, source_instr, array_type, vector, result_loc_inst); 11824 } 11825 11826 static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr, 11827 IrInstruction *integer, ZigType *dest_type) 11828 { 11829 IrInstruction *unsigned_integer; 11830 if (instr_is_comptime(integer)) { 11831 unsigned_integer = integer; 11832 } else { 11833 assert(integer->value.type->id == ZigTypeIdInt); 11834 11835 if (integer->value.type->data.integral.bit_count > 11836 ira->codegen->builtin_types.entry_usize->data.integral.bit_count) 11837 { 11838 ir_add_error(ira, source_instr, 11839 buf_sprintf("integer type '%s' too big for implicit @intToPtr to type '%s'", 11840 buf_ptr(&integer->value.type->name), 11841 buf_ptr(&dest_type->name))); 11842 return ira->codegen->invalid_instruction; 11843 } 11844 11845 if (integer->value.type->data.integral.is_signed) { 11846 ZigType *unsigned_int_type = get_int_type(ira->codegen, false, 11847 integer->value.type->data.integral.bit_count); 11848 unsigned_integer = ir_analyze_bit_cast(ira, source_instr, integer, unsigned_int_type); 11849 if (type_is_invalid(unsigned_integer->value.type)) 11850 return ira->codegen->invalid_instruction; 11851 } else { 11852 unsigned_integer = integer; 11853 } 11854 } 11855 11856 return ir_analyze_int_to_ptr(ira, source_instr, unsigned_integer, dest_type); 11857 } 11858 11859 static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { 11860 if (ty->id == ZigTypeIdPointer) return ty->data.pointer.child_type->id != ZigTypeIdPointer; 11861 if (ty->id == ZigTypeIdFn) return true; 11862 if (ty->id == ZigTypeIdOptional) { 11863 ZigType *ptr_ty = ty->data.maybe.child_type; 11864 if (ptr_ty->id == ZigTypeIdPointer) return ptr_ty->data.pointer.child_type->id != ZigTypeIdPointer; 11865 if (ptr_ty->id == ZigTypeIdFn) return true; 11866 } 11867 return false; 11868 } 11869 11870 static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, 11871 ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc) 11872 { 11873 Error err; 11874 ZigType *actual_type = value->value.type; 11875 AstNode *source_node = source_instr->source_node; 11876 11877 if (type_is_invalid(wanted_type) || type_is_invalid(actual_type)) { 11878 return ira->codegen->invalid_instruction; 11879 } 11880 11881 // perfect match or non-const to const 11882 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, 11883 source_node, false); 11884 if (const_cast_result.id == ConstCastResultIdInvalid) 11885 return ira->codegen->invalid_instruction; 11886 if (const_cast_result.id == ConstCastResultIdOk) { 11887 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); 11888 } 11889 11890 // cast from T to ?T 11891 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism 11892 if (wanted_type->id == ZigTypeIdOptional) { 11893 ZigType *wanted_child_type = wanted_type->data.maybe.child_type; 11894 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, 11895 false).id == ConstCastResultIdOk) 11896 { 11897 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, result_loc); 11898 } else if (actual_type->id == ZigTypeIdComptimeInt || 11899 actual_type->id == ZigTypeIdComptimeFloat) 11900 { 11901 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { 11902 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, result_loc); 11903 } else { 11904 return ira->codegen->invalid_instruction; 11905 } 11906 } else if ( 11907 wanted_child_type->id == ZigTypeIdPointer && 11908 wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && 11909 actual_type->id == ZigTypeIdPointer && 11910 actual_type->data.pointer.ptr_len == PtrLenSingle && 11911 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 11912 { 11913 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 11914 return ira->codegen->invalid_instruction; 11915 if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 11916 return ira->codegen->invalid_instruction; 11917 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && 11918 types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, 11919 actual_type->data.pointer.child_type->data.array.child_type, source_node, 11920 !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) 11921 { 11922 IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, 11923 wanted_child_type); 11924 if (type_is_invalid(cast1->value.type)) 11925 return ira->codegen->invalid_instruction; 11926 return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type, result_loc); 11927 } 11928 } 11929 } 11930 11931 // T to E!T 11932 if (wanted_type->id == ZigTypeIdErrorUnion) { 11933 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, 11934 source_node, false).id == ConstCastResultIdOk) 11935 { 11936 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc); 11937 } else if (actual_type->id == ZigTypeIdComptimeInt || 11938 actual_type->id == ZigTypeIdComptimeFloat) 11939 { 11940 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { 11941 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc); 11942 } else { 11943 return ira->codegen->invalid_instruction; 11944 } 11945 } 11946 } 11947 11948 // cast from T to E!?T 11949 if (wanted_type->id == ZigTypeIdErrorUnion && 11950 wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && 11951 actual_type->id != ZigTypeIdOptional) 11952 { 11953 ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; 11954 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || 11955 actual_type->id == ZigTypeIdNull || 11956 actual_type->id == ZigTypeIdComptimeInt || 11957 actual_type->id == ZigTypeIdComptimeFloat) 11958 { 11959 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr); 11960 if (type_is_invalid(cast1->value.type)) 11961 return ira->codegen->invalid_instruction; 11962 11963 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); 11964 if (type_is_invalid(cast2->value.type)) 11965 return ira->codegen->invalid_instruction; 11966 11967 return cast2; 11968 } 11969 } 11970 11971 11972 // cast from comptime-known number to another number type 11973 if (instr_is_comptime(value) && 11974 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt || 11975 actual_type->id == ZigTypeIdFloat || actual_type->id == ZigTypeIdComptimeFloat) && 11976 (wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdComptimeInt || 11977 wanted_type->id == ZigTypeIdFloat || wanted_type->id == ZigTypeIdComptimeFloat)) 11978 { 11979 if (value->value.special == ConstValSpecialUndef) { 11980 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11981 result->value.special = ConstValSpecialUndef; 11982 return result; 11983 } 11984 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { 11985 if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { 11986 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11987 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 11988 bigint_init_bigint(&result->value.data.x_bigint, &value->value.data.x_bigint); 11989 } else { 11990 float_init_bigint(&result->value.data.x_bigint, &value->value); 11991 } 11992 return result; 11993 } else if (wanted_type->id == ZigTypeIdComptimeFloat || wanted_type->id == ZigTypeIdFloat) { 11994 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11995 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 11996 BigFloat bf; 11997 bigfloat_init_bigint(&bf, &value->value.data.x_bigint); 11998 float_init_bigfloat(&result->value, &bf); 11999 } else { 12000 float_init_float(&result->value, &value->value); 12001 } 12002 return result; 12003 } 12004 zig_unreachable(); 12005 } else { 12006 return ira->codegen->invalid_instruction; 12007 } 12008 } 12009 12010 // widening conversion 12011 if (wanted_type->id == ZigTypeIdInt && 12012 actual_type->id == ZigTypeIdInt && 12013 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed && 12014 wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count) 12015 { 12016 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 12017 } 12018 12019 // small enough unsigned ints can get casted to large enough signed ints 12020 if (wanted_type->id == ZigTypeIdInt && wanted_type->data.integral.is_signed && 12021 actual_type->id == ZigTypeIdInt && !actual_type->data.integral.is_signed && 12022 wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count) 12023 { 12024 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 12025 } 12026 12027 // float widening conversion 12028 if (wanted_type->id == ZigTypeIdFloat && 12029 actual_type->id == ZigTypeIdFloat && 12030 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count) 12031 { 12032 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 12033 } 12034 12035 12036 // cast from [N]T to []const T 12037 // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this 12038 if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) { 12039 ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 12040 assert(ptr_type->id == ZigTypeIdPointer); 12041 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 12042 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 12043 source_node, false).id == ConstCastResultIdOk) 12044 { 12045 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type, result_loc); 12046 } 12047 } 12048 12049 // cast from [N]T to ?[]const T 12050 // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this 12051 if (wanted_type->id == ZigTypeIdOptional && 12052 is_slice(wanted_type->data.maybe.child_type) && 12053 actual_type->id == ZigTypeIdArray) 12054 { 12055 ZigType *ptr_type = 12056 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry; 12057 assert(ptr_type->id == ZigTypeIdPointer); 12058 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 12059 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 12060 source_node, false).id == ConstCastResultIdOk) 12061 { 12062 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value, nullptr); 12063 if (type_is_invalid(cast1->value.type)) 12064 return ira->codegen->invalid_instruction; 12065 12066 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); 12067 if (type_is_invalid(cast2->value.type)) 12068 return ira->codegen->invalid_instruction; 12069 12070 return cast2; 12071 } 12072 } 12073 12074 // *[N]T to [*]T and [*c]T 12075 if (wanted_type->id == ZigTypeIdPointer && 12076 (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC) && 12077 actual_type->id == ZigTypeIdPointer && 12078 actual_type->data.pointer.ptr_len == PtrLenSingle && 12079 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 12080 { 12081 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 12082 return ira->codegen->invalid_instruction; 12083 if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 12084 return ira->codegen->invalid_instruction; 12085 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) && 12086 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 12087 actual_type->data.pointer.child_type->data.array.child_type, source_node, 12088 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 12089 { 12090 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type); 12091 } 12092 } 12093 12094 // *[N]T to []T 12095 if (is_slice(wanted_type) && 12096 actual_type->id == ZigTypeIdPointer && 12097 actual_type->data.pointer.ptr_len == PtrLenSingle && 12098 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 12099 { 12100 ZigType *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 12101 assert(slice_ptr_type->id == ZigTypeIdPointer); 12102 ZigType *array_type = actual_type->data.pointer.child_type; 12103 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 12104 || !actual_type->data.pointer.is_const); 12105 if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 12106 array_type->data.array.child_type, source_node, 12107 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) 12108 { 12109 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type, result_loc); 12110 } 12111 } 12112 12113 // *@Frame(func) to anyframe->T or anyframe 12114 if (actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle && 12115 actual_type->data.pointer.child_type->id == ZigTypeIdFnFrame && wanted_type->id == ZigTypeIdAnyFrame) 12116 { 12117 bool ok = true; 12118 if (wanted_type->data.any_frame.result_type != nullptr) { 12119 ZigFn *fn = actual_type->data.pointer.child_type->data.frame.fn; 12120 ZigType *fn_return_type = fn->type_entry->data.fn.fn_type_id.return_type; 12121 if (wanted_type->data.any_frame.result_type != fn_return_type) { 12122 ok = false; 12123 } 12124 } 12125 if (ok) { 12126 return ir_analyze_frame_ptr_to_anyframe(ira, source_instr, value, wanted_type); 12127 } 12128 } 12129 12130 // anyframe->T to anyframe 12131 if (actual_type->id == ZigTypeIdAnyFrame && actual_type->data.any_frame.result_type != nullptr && 12132 wanted_type->id == ZigTypeIdAnyFrame && wanted_type->data.any_frame.result_type == nullptr) 12133 { 12134 return ir_analyze_anyframe_to_anyframe(ira, source_instr, value, wanted_type); 12135 } 12136 12137 // cast from null literal to maybe type 12138 if (wanted_type->id == ZigTypeIdOptional && 12139 actual_type->id == ZigTypeIdNull) 12140 { 12141 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); 12142 } 12143 12144 // cast from null literal to C pointer 12145 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 12146 actual_type->id == ZigTypeIdNull) 12147 { 12148 return ir_analyze_null_to_c_pointer(ira, source_instr, value, wanted_type); 12149 } 12150 12151 // cast from [N]T to E![]const T 12152 if (wanted_type->id == ZigTypeIdErrorUnion && 12153 is_slice(wanted_type->data.error_union.payload_type) && 12154 actual_type->id == ZigTypeIdArray) 12155 { 12156 ZigType *ptr_type = 12157 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry; 12158 assert(ptr_type->id == ZigTypeIdPointer); 12159 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 12160 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 12161 source_node, false).id == ConstCastResultIdOk) 12162 { 12163 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr); 12164 if (type_is_invalid(cast1->value.type)) 12165 return ira->codegen->invalid_instruction; 12166 12167 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); 12168 if (type_is_invalid(cast2->value.type)) 12169 return ira->codegen->invalid_instruction; 12170 12171 return cast2; 12172 } 12173 } 12174 12175 // cast from E to E!T 12176 if (wanted_type->id == ZigTypeIdErrorUnion && 12177 actual_type->id == ZigTypeIdErrorSet) 12178 { 12179 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type, result_loc); 12180 } 12181 12182 // cast from typed number to integer or float literal. 12183 // works when the number is known at compile time 12184 if (instr_is_comptime(value) && 12185 ((actual_type->id == ZigTypeIdInt && wanted_type->id == ZigTypeIdComptimeInt) || 12186 (actual_type->id == ZigTypeIdFloat && wanted_type->id == ZigTypeIdComptimeFloat))) 12187 { 12188 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type); 12189 } 12190 12191 // cast from enum literal to enum with matching field name 12192 if (actual_type->id == ZigTypeIdEnumLiteral && wanted_type->id == ZigTypeIdEnum) { 12193 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) 12194 return ira->codegen->invalid_instruction; 12195 12196 TypeEnumField *field = find_enum_type_field(wanted_type, value->value.data.x_enum_literal); 12197 if (field == nullptr) { 12198 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("enum '%s' has no field named '%s'", 12199 buf_ptr(&wanted_type->name), buf_ptr(value->value.data.x_enum_literal))); 12200 add_error_note(ira->codegen, msg, wanted_type->data.enumeration.decl_node, 12201 buf_sprintf("'%s' declared here", buf_ptr(&wanted_type->name))); 12202 return ira->codegen->invalid_instruction; 12203 } 12204 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12205 bigint_init_bigint(&result->value.data.x_enum_tag, &field->value); 12206 return result; 12207 } 12208 12209 // cast from union to the enum type of the union 12210 if (actual_type->id == ZigTypeIdUnion && wanted_type->id == ZigTypeIdEnum) { 12211 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) 12212 return ira->codegen->invalid_instruction; 12213 12214 if (actual_type->data.unionation.tag_type == wanted_type) { 12215 return ir_analyze_union_to_tag(ira, source_instr, value, wanted_type); 12216 } 12217 } 12218 12219 // enum to union which has the enum as the tag type, or 12220 // enum literal to union which has a matching enum as the tag type 12221 if (is_tagged_union(wanted_type) && (actual_type->id == ZigTypeIdEnum || 12222 actual_type->id == ZigTypeIdEnumLiteral)) 12223 { 12224 return ir_analyze_enum_to_union(ira, source_instr, value, wanted_type); 12225 } 12226 12227 // cast from *T to *[1]T 12228 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 12229 actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle) 12230 { 12231 ZigType *array_type = wanted_type->data.pointer.child_type; 12232 if (array_type->id == ZigTypeIdArray && array_type->data.array.len == 1 && 12233 types_match_const_cast_only(ira, array_type->data.array.child_type, 12234 actual_type->data.pointer.child_type, source_node, 12235 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk && 12236 // This should be the job of `types_match_const_cast_only` 12237 // but `types_match_const_cast_only` only gets info for child_types 12238 ((wanted_type->data.pointer.is_const && actual_type->data.pointer.is_const) || 12239 !actual_type->data.pointer.is_const)) 12240 { 12241 if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, 12242 ResolveStatusAlignmentKnown))) 12243 { 12244 return ira->codegen->invalid_instruction; 12245 } 12246 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, 12247 ResolveStatusAlignmentKnown))) 12248 { 12249 return ira->codegen->invalid_instruction; 12250 } 12251 uint32_t wanted_align = get_ptr_align(ira->codegen, wanted_type); 12252 uint32_t actual_align = get_ptr_align(ira->codegen, actual_type); 12253 if (wanted_align > actual_align) { 12254 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 12255 add_error_note(ira->codegen, msg, value->source_node, 12256 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&actual_type->name), actual_align)); 12257 add_error_note(ira->codegen, msg, source_instr->source_node, 12258 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&wanted_type->name), wanted_align)); 12259 return ira->codegen->invalid_instruction; 12260 } 12261 return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type); 12262 } 12263 } 12264 12265 // cast from *T and [*]T to *c_void and ?*c_void 12266 // but don't do it if the actual type is a double pointer 12267 if (is_pointery_and_elem_is_not_pointery(actual_type)) { 12268 ZigType *dest_ptr_type = nullptr; 12269 if (wanted_type->id == ZigTypeIdPointer && 12270 wanted_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 12271 { 12272 dest_ptr_type = wanted_type; 12273 } else if (wanted_type->id == ZigTypeIdOptional && 12274 wanted_type->data.maybe.child_type->id == ZigTypeIdPointer && 12275 wanted_type->data.maybe.child_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 12276 { 12277 dest_ptr_type = wanted_type->data.maybe.child_type; 12278 } 12279 if (dest_ptr_type != nullptr) { 12280 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true); 12281 } 12282 } 12283 12284 // cast from T to *T where T is zero bits 12285 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 12286 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 12287 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 12288 { 12289 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) { 12290 return ira->codegen->invalid_instruction; 12291 } 12292 if (!type_has_bits(actual_type)) { 12293 return ir_get_ref(ira, source_instr, value, false, false); 12294 } 12295 } 12296 12297 // cast from @Vector(N, T) to [N]T 12298 if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdVector && 12299 wanted_type->data.array.len == actual_type->data.vector.len && 12300 types_match_const_cast_only(ira, wanted_type->data.array.child_type, 12301 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 12302 { 12303 return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type, result_loc); 12304 } 12305 12306 // cast from [N]T to @Vector(N, T) 12307 if (actual_type->id == ZigTypeIdArray && wanted_type->id == ZigTypeIdVector && 12308 actual_type->data.array.len == wanted_type->data.vector.len && 12309 types_match_const_cast_only(ira, actual_type->data.array.child_type, 12310 wanted_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 12311 { 12312 return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type); 12313 } 12314 12315 // casting between C pointers and normal pointers 12316 if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer && 12317 (wanted_type->data.pointer.ptr_len == PtrLenC || actual_type->data.pointer.ptr_len == PtrLenC) && 12318 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 12319 actual_type->data.pointer.child_type, source_node, 12320 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 12321 { 12322 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true); 12323 } 12324 12325 // cast from integer to C pointer 12326 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 12327 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt)) 12328 { 12329 return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type); 12330 } 12331 12332 // cast from undefined to anything 12333 if (actual_type->id == ZigTypeIdUndefined) { 12334 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); 12335 } 12336 12337 ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, 12338 buf_sprintf("expected type '%s', found '%s'", 12339 buf_ptr(&wanted_type->name), 12340 buf_ptr(&actual_type->name))); 12341 report_recursive_error(ira, source_instr->source_node, &const_cast_result, parent_msg); 12342 return ira->codegen->invalid_instruction; 12343 } 12344 12345 static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type, 12346 ResultLoc *result_loc) 12347 { 12348 assert(value); 12349 assert(value != ira->codegen->invalid_instruction); 12350 assert(!expected_type || !type_is_invalid(expected_type)); 12351 assert(value->value.type); 12352 assert(!type_is_invalid(value->value.type)); 12353 if (expected_type == nullptr) 12354 return value; // anything will do 12355 if (expected_type == value->value.type) 12356 return value; // match 12357 if (value->value.type->id == ZigTypeIdUnreachable) 12358 return value; 12359 12360 return ir_analyze_cast(ira, value, expected_type, value, result_loc); 12361 } 12362 12363 static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { 12364 return ir_implicit_cast_with_result(ira, value, expected_type, nullptr); 12365 } 12366 12367 static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, 12368 ResultLoc *result_loc) 12369 { 12370 Error err; 12371 ZigType *type_entry = ptr->value.type; 12372 if (type_is_invalid(type_entry)) 12373 return ira->codegen->invalid_instruction; 12374 12375 if (type_entry->id != ZigTypeIdPointer) { 12376 ir_add_error_node(ira, source_instruction->source_node, 12377 buf_sprintf("attempt to dereference non-pointer type '%s'", 12378 buf_ptr(&type_entry->name))); 12379 return ira->codegen->invalid_instruction; 12380 } 12381 12382 ZigType *child_type = type_entry->data.pointer.child_type; 12383 // if the child type has one possible value, the deref is comptime 12384 switch (type_has_one_possible_value(ira->codegen, child_type)) { 12385 case OnePossibleValueInvalid: 12386 return ira->codegen->invalid_instruction; 12387 case OnePossibleValueYes: 12388 return ir_const(ira, source_instruction, child_type); 12389 case OnePossibleValueNo: 12390 break; 12391 } 12392 if (instr_is_comptime(ptr)) { 12393 if (ptr->value.special == ConstValSpecialUndef) { 12394 ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); 12395 return ira->codegen->invalid_instruction; 12396 } 12397 if (ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { 12398 ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); 12399 if (pointee->special != ConstValSpecialRuntime) { 12400 IrInstruction *result = ir_const(ira, source_instruction, child_type); 12401 12402 if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value, 12403 &ptr->value))) 12404 { 12405 return ira->codegen->invalid_instruction; 12406 } 12407 result->value.type = child_type; 12408 return result; 12409 } 12410 } 12411 } 12412 // if the instruction is a const ref instruction we can skip it 12413 if (ptr->id == IrInstructionIdRef) { 12414 IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr); 12415 return ref_inst->value; 12416 } 12417 12418 IrInstruction *result_loc_inst; 12419 if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { 12420 if (result_loc == nullptr) result_loc = no_result_loc(); 12421 result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, 12422 true, false, true); 12423 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { 12424 return result_loc_inst; 12425 } 12426 } else { 12427 result_loc_inst = nullptr; 12428 } 12429 12430 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); 12431 } 12432 12433 static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { 12434 if (type_is_invalid(value->value.type)) 12435 return false; 12436 12437 IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); 12438 if (type_is_invalid(casted_value->value.type)) 12439 return false; 12440 12441 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12442 if (!const_val) 12443 return false; 12444 12445 uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint); 12446 if (align_bytes == 0) { 12447 ir_add_error(ira, value, buf_sprintf("alignment must be >= 1")); 12448 return false; 12449 } 12450 12451 if (!is_power_of_2(align_bytes)) { 12452 ir_add_error(ira, value, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); 12453 return false; 12454 } 12455 12456 *out = align_bytes; 12457 return true; 12458 } 12459 12460 static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { 12461 if (type_is_invalid(value->value.type)) 12462 return false; 12463 12464 IrInstruction *casted_value = ir_implicit_cast(ira, value, int_type); 12465 if (type_is_invalid(casted_value->value.type)) 12466 return false; 12467 12468 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12469 if (!const_val) 12470 return false; 12471 12472 *out = bigint_as_unsigned(&const_val->data.x_bigint); 12473 return true; 12474 } 12475 12476 static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) { 12477 return ir_resolve_unsigned(ira, value, ira->codegen->builtin_types.entry_usize, out); 12478 } 12479 12480 static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) { 12481 if (type_is_invalid(value->value.type)) 12482 return false; 12483 12484 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_bool); 12485 if (type_is_invalid(casted_value->value.type)) 12486 return false; 12487 12488 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12489 if (!const_val) 12490 return false; 12491 12492 *out = const_val->data.x_bool; 12493 return true; 12494 } 12495 12496 static bool ir_resolve_comptime(IrAnalyze *ira, IrInstruction *value, bool *out) { 12497 if (!value) { 12498 *out = false; 12499 return true; 12500 } 12501 return ir_resolve_bool(ira, value, out); 12502 } 12503 12504 static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, AtomicOrder *out) { 12505 if (type_is_invalid(value->value.type)) 12506 return false; 12507 12508 ConstExprValue *atomic_order_val = get_builtin_value(ira->codegen, "AtomicOrder"); 12509 assert(atomic_order_val->type->id == ZigTypeIdMetaType); 12510 ZigType *atomic_order_type = atomic_order_val->data.x_type; 12511 12512 IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_order_type); 12513 if (type_is_invalid(casted_value->value.type)) 12514 return false; 12515 12516 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12517 if (!const_val) 12518 return false; 12519 12520 *out = (AtomicOrder)bigint_as_unsigned(&const_val->data.x_enum_tag); 12521 return true; 12522 } 12523 12524 static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstruction *value, AtomicRmwOp *out) { 12525 if (type_is_invalid(value->value.type)) 12526 return false; 12527 12528 ConstExprValue *atomic_rmw_op_val = get_builtin_value(ira->codegen, "AtomicRmwOp"); 12529 assert(atomic_rmw_op_val->type->id == ZigTypeIdMetaType); 12530 ZigType *atomic_rmw_op_type = atomic_rmw_op_val->data.x_type; 12531 12532 IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_rmw_op_type); 12533 if (type_is_invalid(casted_value->value.type)) 12534 return false; 12535 12536 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12537 if (!const_val) 12538 return false; 12539 12540 *out = (AtomicRmwOp)bigint_as_unsigned(&const_val->data.x_enum_tag); 12541 return true; 12542 } 12543 12544 static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstruction *value, GlobalLinkageId *out) { 12545 if (type_is_invalid(value->value.type)) 12546 return false; 12547 12548 ConstExprValue *global_linkage_val = get_builtin_value(ira->codegen, "GlobalLinkage"); 12549 assert(global_linkage_val->type->id == ZigTypeIdMetaType); 12550 ZigType *global_linkage_type = global_linkage_val->data.x_type; 12551 12552 IrInstruction *casted_value = ir_implicit_cast(ira, value, global_linkage_type); 12553 if (type_is_invalid(casted_value->value.type)) 12554 return false; 12555 12556 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12557 if (!const_val) 12558 return false; 12559 12560 *out = (GlobalLinkageId)bigint_as_unsigned(&const_val->data.x_enum_tag); 12561 return true; 12562 } 12563 12564 static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMode *out) { 12565 if (type_is_invalid(value->value.type)) 12566 return false; 12567 12568 ConstExprValue *float_mode_val = get_builtin_value(ira->codegen, "FloatMode"); 12569 assert(float_mode_val->type->id == ZigTypeIdMetaType); 12570 ZigType *float_mode_type = float_mode_val->data.x_type; 12571 12572 IrInstruction *casted_value = ir_implicit_cast(ira, value, float_mode_type); 12573 if (type_is_invalid(casted_value->value.type)) 12574 return false; 12575 12576 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12577 if (!const_val) 12578 return false; 12579 12580 *out = (FloatMode)bigint_as_unsigned(&const_val->data.x_enum_tag); 12581 return true; 12582 } 12583 12584 12585 static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { 12586 if (type_is_invalid(value->value.type)) 12587 return nullptr; 12588 12589 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 12590 true, false, PtrLenUnknown, 0, 0, 0, false); 12591 ZigType *str_type = get_slice_type(ira->codegen, ptr_type); 12592 IrInstruction *casted_value = ir_implicit_cast(ira, value, str_type); 12593 if (type_is_invalid(casted_value->value.type)) 12594 return nullptr; 12595 12596 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 12597 if (!const_val) 12598 return nullptr; 12599 12600 ConstExprValue *ptr_field = &const_val->data.x_struct.fields[slice_ptr_index]; 12601 ConstExprValue *len_field = &const_val->data.x_struct.fields[slice_len_index]; 12602 12603 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); 12604 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; 12605 if (array_val->data.x_array.special == ConstArraySpecialBuf) { 12606 return array_val->data.x_array.data.s_buf; 12607 } 12608 expand_undef_array(ira->codegen, array_val); 12609 size_t len = bigint_as_unsigned(&len_field->data.x_bigint); 12610 Buf *result = buf_alloc(); 12611 buf_resize(result, len); 12612 for (size_t i = 0; i < len; i += 1) { 12613 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; 12614 ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index]; 12615 if (char_val->special == ConstValSpecialUndef) { 12616 ir_add_error(ira, casted_value, buf_sprintf("use of undefined value")); 12617 return nullptr; 12618 } 12619 uint64_t big_c = bigint_as_unsigned(&char_val->data.x_bigint); 12620 assert(big_c <= UINT8_MAX); 12621 uint8_t c = (uint8_t)big_c; 12622 buf_ptr(result)[i] = c; 12623 } 12624 return result; 12625 } 12626 12627 static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, 12628 IrInstructionAddImplicitReturnType *instruction) 12629 { 12630 IrInstruction *value = instruction->value->child; 12631 if (type_is_invalid(value->value.type)) 12632 return ir_unreach_error(ira); 12633 12634 ira->src_implicit_return_type_list.append(value); 12635 12636 return ir_const_void(ira, &instruction->base); 12637 } 12638 12639 static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructionReturn *instruction) { 12640 IrInstruction *operand = instruction->operand->child; 12641 if (type_is_invalid(operand->value.type)) 12642 return ir_unreach_error(ira); 12643 12644 if (!instr_is_comptime(operand) && handle_is_ptr(ira->explicit_return_type)) { 12645 // result location mechanism took care of it. 12646 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, 12647 instruction->base.source_node, nullptr); 12648 result->value.type = ira->codegen->builtin_types.entry_unreachable; 12649 return ir_finish_anal(ira, result); 12650 } 12651 12652 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type); 12653 if (type_is_invalid(casted_operand->value.type)) { 12654 AstNode *source_node = ira->explicit_return_type_source_node; 12655 if (source_node != nullptr) { 12656 ErrorMsg *msg = ira->codegen->errors.last(); 12657 add_error_note(ira->codegen, msg, source_node, 12658 buf_sprintf("return type declared here")); 12659 } 12660 return ir_unreach_error(ira); 12661 } 12662 12663 if (casted_operand->value.special == ConstValSpecialRuntime && 12664 casted_operand->value.type->id == ZigTypeIdPointer && 12665 casted_operand->value.data.rh_ptr == RuntimeHintPtrStack) 12666 { 12667 ir_add_error(ira, casted_operand, buf_sprintf("function returns address of local variable")); 12668 return ir_unreach_error(ira); 12669 } 12670 12671 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, 12672 instruction->base.source_node, casted_operand); 12673 result->value.type = ira->codegen->builtin_types.entry_unreachable; 12674 return ir_finish_anal(ira, result); 12675 } 12676 12677 static IrInstruction *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *instruction) { 12678 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 12679 copy_const_val(&result->value, &instruction->base.value, true); 12680 return result; 12681 } 12682 12683 static IrInstruction *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 12684 IrInstruction *op1 = bin_op_instruction->op1->child; 12685 if (type_is_invalid(op1->value.type)) 12686 return ira->codegen->invalid_instruction; 12687 12688 IrInstruction *op2 = bin_op_instruction->op2->child; 12689 if (type_is_invalid(op2->value.type)) 12690 return ira->codegen->invalid_instruction; 12691 12692 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 12693 12694 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, bool_type); 12695 if (casted_op1 == ira->codegen->invalid_instruction) 12696 return ira->codegen->invalid_instruction; 12697 12698 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, bool_type); 12699 if (casted_op2 == ira->codegen->invalid_instruction) 12700 return ira->codegen->invalid_instruction; 12701 12702 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 12703 ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 12704 if (op1_val == nullptr) 12705 return ira->codegen->invalid_instruction; 12706 12707 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 12708 if (op2_val == nullptr) 12709 return ira->codegen->invalid_instruction; 12710 12711 assert(casted_op1->value.type->id == ZigTypeIdBool); 12712 assert(casted_op2->value.type->id == ZigTypeIdBool); 12713 bool result_bool; 12714 if (bin_op_instruction->op_id == IrBinOpBoolOr) { 12715 result_bool = op1_val->data.x_bool || op2_val->data.x_bool; 12716 } else if (bin_op_instruction->op_id == IrBinOpBoolAnd) { 12717 result_bool = op1_val->data.x_bool && op2_val->data.x_bool; 12718 } else { 12719 zig_unreachable(); 12720 } 12721 return ir_const_bool(ira, &bin_op_instruction->base, result_bool); 12722 } 12723 12724 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 12725 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 12726 bin_op_instruction->op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 12727 result->value.type = bool_type; 12728 return result; 12729 } 12730 12731 static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) { 12732 switch (op_id) { 12733 case IrBinOpCmpEq: 12734 return cmp == CmpEQ; 12735 case IrBinOpCmpNotEq: 12736 return cmp != CmpEQ; 12737 case IrBinOpCmpLessThan: 12738 return cmp == CmpLT; 12739 case IrBinOpCmpGreaterThan: 12740 return cmp == CmpGT; 12741 case IrBinOpCmpLessOrEq: 12742 return cmp != CmpGT; 12743 case IrBinOpCmpGreaterOrEq: 12744 return cmp != CmpLT; 12745 default: 12746 zig_unreachable(); 12747 } 12748 } 12749 12750 static bool optional_value_is_null(ConstExprValue *val) { 12751 assert(val->special == ConstValSpecialStatic); 12752 if (get_codegen_ptr_type(val->type) != nullptr) { 12753 if (val->data.x_ptr.special == ConstPtrSpecialNull) { 12754 return true; 12755 } else if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 12756 return val->data.x_ptr.data.hard_coded_addr.addr == 0; 12757 } else { 12758 return false; 12759 } 12760 } else if (is_opt_err_set(val->type)) { 12761 return val->data.x_err_set == nullptr; 12762 } else { 12763 return val->data.x_optional == nullptr; 12764 } 12765 } 12766 12767 static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 12768 IrInstruction *op1 = bin_op_instruction->op1->child; 12769 if (type_is_invalid(op1->value.type)) 12770 return ira->codegen->invalid_instruction; 12771 12772 IrInstruction *op2 = bin_op_instruction->op2->child; 12773 if (type_is_invalid(op2->value.type)) 12774 return ira->codegen->invalid_instruction; 12775 12776 AstNode *source_node = bin_op_instruction->base.source_node; 12777 12778 IrBinOp op_id = bin_op_instruction->op_id; 12779 bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 12780 if (is_equality_cmp && op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull) { 12781 return ir_const_bool(ira, &bin_op_instruction->base, (op_id == IrBinOpCmpEq)); 12782 } else if (is_equality_cmp && 12783 ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdOptional) || 12784 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdOptional))) 12785 { 12786 IrInstruction *maybe_op; 12787 if (op1->value.type->id == ZigTypeIdNull) { 12788 maybe_op = op2; 12789 } else if (op2->value.type->id == ZigTypeIdNull) { 12790 maybe_op = op1; 12791 } else { 12792 zig_unreachable(); 12793 } 12794 if (instr_is_comptime(maybe_op)) { 12795 ConstExprValue *maybe_val = ir_resolve_const(ira, maybe_op, UndefBad); 12796 if (!maybe_val) 12797 return ira->codegen->invalid_instruction; 12798 bool is_null = optional_value_is_null(maybe_val); 12799 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 12800 return ir_const_bool(ira, &bin_op_instruction->base, bool_result); 12801 } 12802 12803 IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope, 12804 source_node, maybe_op); 12805 is_non_null->value.type = ira->codegen->builtin_types.entry_bool; 12806 12807 if (op_id == IrBinOpCmpEq) { 12808 IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope, 12809 bin_op_instruction->base.source_node, is_non_null); 12810 result->value.type = ira->codegen->builtin_types.entry_bool; 12811 return result; 12812 } else { 12813 return is_non_null; 12814 } 12815 } else if (is_equality_cmp && 12816 ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer && 12817 op2->value.type->data.pointer.ptr_len == PtrLenC) || 12818 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer && 12819 op1->value.type->data.pointer.ptr_len == PtrLenC))) 12820 { 12821 IrInstruction *c_ptr_op; 12822 if (op1->value.type->id == ZigTypeIdNull) { 12823 c_ptr_op = op2; 12824 } else if (op2->value.type->id == ZigTypeIdNull) { 12825 c_ptr_op = op1; 12826 } else { 12827 zig_unreachable(); 12828 } 12829 if (instr_is_comptime(c_ptr_op)) { 12830 ConstExprValue *c_ptr_val = ir_resolve_const(ira, c_ptr_op, UndefOk); 12831 if (!c_ptr_val) 12832 return ira->codegen->invalid_instruction; 12833 if (c_ptr_val->special == ConstValSpecialUndef) 12834 return ir_const_undef(ira, &bin_op_instruction->base, ira->codegen->builtin_types.entry_bool); 12835 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 12836 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 12837 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 12838 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 12839 return ir_const_bool(ira, &bin_op_instruction->base, bool_result); 12840 } 12841 IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope, 12842 source_node, c_ptr_op); 12843 is_non_null->value.type = ira->codegen->builtin_types.entry_bool; 12844 12845 if (op_id == IrBinOpCmpEq) { 12846 IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope, 12847 bin_op_instruction->base.source_node, is_non_null); 12848 result->value.type = ira->codegen->builtin_types.entry_bool; 12849 return result; 12850 } else { 12851 return is_non_null; 12852 } 12853 } else if (op1->value.type->id == ZigTypeIdNull || op2->value.type->id == ZigTypeIdNull) { 12854 ZigType *non_null_type = (op1->value.type->id == ZigTypeIdNull) ? op2->value.type : op1->value.type; 12855 ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null", 12856 buf_ptr(&non_null_type->name))); 12857 return ira->codegen->invalid_instruction; 12858 } 12859 12860 if (op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) { 12861 if (!is_equality_cmp) { 12862 ir_add_error_node(ira, source_node, buf_sprintf("operator not allowed for errors")); 12863 return ira->codegen->invalid_instruction; 12864 } 12865 ZigType *intersect_type = get_error_set_intersection(ira, op1->value.type, op2->value.type, source_node); 12866 if (type_is_invalid(intersect_type)) { 12867 return ira->codegen->invalid_instruction; 12868 } 12869 12870 if (!resolve_inferred_error_set(ira->codegen, intersect_type, source_node)) { 12871 return ira->codegen->invalid_instruction; 12872 } 12873 12874 // exception if one of the operators has the type of the empty error set, we allow the comparison 12875 // (and make it comptime known) 12876 // this is a function which is evaluated at comptime and returns an inferred error set will have an empty 12877 // error set. 12878 if (op1->value.type->data.error_set.err_count == 0 || op2->value.type->data.error_set.err_count == 0) { 12879 bool are_equal = false; 12880 bool answer; 12881 if (op_id == IrBinOpCmpEq) { 12882 answer = are_equal; 12883 } else if (op_id == IrBinOpCmpNotEq) { 12884 answer = !are_equal; 12885 } else { 12886 zig_unreachable(); 12887 } 12888 return ir_const_bool(ira, &bin_op_instruction->base, answer); 12889 } 12890 12891 if (!type_is_global_error_set(intersect_type)) { 12892 if (intersect_type->data.error_set.err_count == 0) { 12893 ir_add_error_node(ira, source_node, 12894 buf_sprintf("error sets '%s' and '%s' have no common errors", 12895 buf_ptr(&op1->value.type->name), buf_ptr(&op2->value.type->name))); 12896 return ira->codegen->invalid_instruction; 12897 } 12898 if (op1->value.type->data.error_set.err_count == 1 && op2->value.type->data.error_set.err_count == 1) { 12899 bool are_equal = true; 12900 bool answer; 12901 if (op_id == IrBinOpCmpEq) { 12902 answer = are_equal; 12903 } else if (op_id == IrBinOpCmpNotEq) { 12904 answer = !are_equal; 12905 } else { 12906 zig_unreachable(); 12907 } 12908 return ir_const_bool(ira, &bin_op_instruction->base, answer); 12909 } 12910 } 12911 12912 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 12913 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 12914 if (op1_val == nullptr) 12915 return ira->codegen->invalid_instruction; 12916 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 12917 if (op2_val == nullptr) 12918 return ira->codegen->invalid_instruction; 12919 12920 bool answer; 12921 bool are_equal = op1_val->data.x_err_set->value == op2_val->data.x_err_set->value; 12922 if (op_id == IrBinOpCmpEq) { 12923 answer = are_equal; 12924 } else if (op_id == IrBinOpCmpNotEq) { 12925 answer = !are_equal; 12926 } else { 12927 zig_unreachable(); 12928 } 12929 12930 return ir_const_bool(ira, &bin_op_instruction->base, answer); 12931 } 12932 12933 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 12934 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 12935 op_id, op1, op2, bin_op_instruction->safety_check_on); 12936 result->value.type = ira->codegen->builtin_types.entry_bool; 12937 return result; 12938 } 12939 12940 IrInstruction *instructions[] = {op1, op2}; 12941 ZigType *resolved_type = ir_resolve_peer_types(ira, source_node, nullptr, instructions, 2); 12942 if (type_is_invalid(resolved_type)) 12943 return ira->codegen->invalid_instruction; 12944 12945 bool operator_allowed; 12946 switch (resolved_type->id) { 12947 case ZigTypeIdInvalid: 12948 zig_unreachable(); // handled above 12949 12950 case ZigTypeIdComptimeFloat: 12951 case ZigTypeIdComptimeInt: 12952 case ZigTypeIdInt: 12953 case ZigTypeIdFloat: 12954 case ZigTypeIdVector: 12955 operator_allowed = true; 12956 break; 12957 12958 case ZigTypeIdBool: 12959 case ZigTypeIdMetaType: 12960 case ZigTypeIdVoid: 12961 case ZigTypeIdErrorSet: 12962 case ZigTypeIdFn: 12963 case ZigTypeIdOpaque: 12964 case ZigTypeIdBoundFn: 12965 case ZigTypeIdArgTuple: 12966 case ZigTypeIdEnum: 12967 case ZigTypeIdEnumLiteral: 12968 case ZigTypeIdAnyFrame: 12969 operator_allowed = is_equality_cmp; 12970 break; 12971 12972 case ZigTypeIdPointer: 12973 operator_allowed = is_equality_cmp || (resolved_type->data.pointer.ptr_len == PtrLenC); 12974 break; 12975 12976 case ZigTypeIdUnreachable: 12977 case ZigTypeIdArray: 12978 case ZigTypeIdStruct: 12979 case ZigTypeIdUndefined: 12980 case ZigTypeIdNull: 12981 case ZigTypeIdErrorUnion: 12982 case ZigTypeIdUnion: 12983 case ZigTypeIdFnFrame: 12984 operator_allowed = false; 12985 break; 12986 case ZigTypeIdOptional: 12987 operator_allowed = is_equality_cmp && get_codegen_ptr_type(resolved_type) != nullptr; 12988 break; 12989 } 12990 if (!operator_allowed) { 12991 ir_add_error_node(ira, source_node, 12992 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); 12993 return ira->codegen->invalid_instruction; 12994 } 12995 12996 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 12997 if (casted_op1 == ira->codegen->invalid_instruction) 12998 return ira->codegen->invalid_instruction; 12999 13000 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 13001 if (casted_op2 == ira->codegen->invalid_instruction) 13002 return ira->codegen->invalid_instruction; 13003 13004 bool one_possible_value; 13005 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 13006 case OnePossibleValueInvalid: 13007 return ira->codegen->invalid_instruction; 13008 case OnePossibleValueYes: 13009 one_possible_value = true; 13010 break; 13011 case OnePossibleValueNo: 13012 one_possible_value = false; 13013 break; 13014 } 13015 13016 if (one_possible_value || (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2))) { 13017 ConstExprValue *op1_val = one_possible_value ? &casted_op1->value : ir_resolve_const(ira, casted_op1, UndefBad); 13018 if (op1_val == nullptr) 13019 return ira->codegen->invalid_instruction; 13020 ConstExprValue *op2_val = one_possible_value ? &casted_op2->value : ir_resolve_const(ira, casted_op2, UndefBad); 13021 if (op2_val == nullptr) 13022 return ira->codegen->invalid_instruction; 13023 13024 if (resolved_type->id == ZigTypeIdComptimeFloat || resolved_type->id == ZigTypeIdFloat) { 13025 if (float_is_nan(op1_val) || float_is_nan(op2_val)) { 13026 return ir_const_bool(ira, &bin_op_instruction->base, op_id == IrBinOpCmpNotEq); 13027 } 13028 Cmp cmp_result = float_cmp(op1_val, op2_val); 13029 bool answer = resolve_cmp_op_id(op_id, cmp_result); 13030 return ir_const_bool(ira, &bin_op_instruction->base, answer); 13031 } else if (resolved_type->id == ZigTypeIdComptimeInt || resolved_type->id == ZigTypeIdInt) { 13032 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); 13033 bool answer = resolve_cmp_op_id(op_id, cmp_result); 13034 return ir_const_bool(ira, &bin_op_instruction->base, answer); 13035 } else if (resolved_type->id == ZigTypeIdPointer && op_id != IrBinOpCmpEq && op_id != IrBinOpCmpNotEq) { 13036 if ((op1_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 13037 op1_val->data.x_ptr.special == ConstPtrSpecialNull) && 13038 (op2_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 13039 op2_val->data.x_ptr.special == ConstPtrSpecialNull)) 13040 { 13041 uint64_t op1_addr = op1_val->data.x_ptr.special == ConstPtrSpecialNull ? 13042 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; 13043 uint64_t op2_addr = op2_val->data.x_ptr.special == ConstPtrSpecialNull ? 13044 0 : op2_val->data.x_ptr.data.hard_coded_addr.addr; 13045 Cmp cmp_result; 13046 if (op1_addr > op2_addr) { 13047 cmp_result = CmpGT; 13048 } else if (op1_addr < op2_addr) { 13049 cmp_result = CmpLT; 13050 } else { 13051 cmp_result = CmpEQ; 13052 } 13053 bool answer = resolve_cmp_op_id(op_id, cmp_result); 13054 return ir_const_bool(ira, &bin_op_instruction->base, answer); 13055 } 13056 } else { 13057 bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val); 13058 bool answer; 13059 if (op_id == IrBinOpCmpEq) { 13060 answer = are_equal; 13061 } else if (op_id == IrBinOpCmpNotEq) { 13062 answer = !are_equal; 13063 } else { 13064 zig_unreachable(); 13065 } 13066 return ir_const_bool(ira, &bin_op_instruction->base, answer); 13067 } 13068 } 13069 13070 // some comparisons with unsigned numbers can be evaluated 13071 if (resolved_type->id == ZigTypeIdInt && !resolved_type->data.integral.is_signed) { 13072 ConstExprValue *known_left_val; 13073 IrBinOp flipped_op_id; 13074 if (instr_is_comptime(casted_op1)) { 13075 known_left_val = ir_resolve_const(ira, casted_op1, UndefBad); 13076 if (known_left_val == nullptr) 13077 return ira->codegen->invalid_instruction; 13078 13079 flipped_op_id = op_id; 13080 } else if (instr_is_comptime(casted_op2)) { 13081 known_left_val = ir_resolve_const(ira, casted_op2, UndefBad); 13082 if (known_left_val == nullptr) 13083 return ira->codegen->invalid_instruction; 13084 13085 if (op_id == IrBinOpCmpLessThan) { 13086 flipped_op_id = IrBinOpCmpGreaterThan; 13087 } else if (op_id == IrBinOpCmpGreaterThan) { 13088 flipped_op_id = IrBinOpCmpLessThan; 13089 } else if (op_id == IrBinOpCmpLessOrEq) { 13090 flipped_op_id = IrBinOpCmpGreaterOrEq; 13091 } else if (op_id == IrBinOpCmpGreaterOrEq) { 13092 flipped_op_id = IrBinOpCmpLessOrEq; 13093 } else { 13094 flipped_op_id = op_id; 13095 } 13096 } else { 13097 known_left_val = nullptr; 13098 } 13099 if (known_left_val != nullptr && bigint_cmp_zero(&known_left_val->data.x_bigint) == CmpEQ && 13100 (flipped_op_id == IrBinOpCmpLessOrEq || flipped_op_id == IrBinOpCmpGreaterThan)) 13101 { 13102 bool answer = (flipped_op_id == IrBinOpCmpLessOrEq); 13103 return ir_const_bool(ira, &bin_op_instruction->base, answer); 13104 } 13105 } 13106 13107 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 13108 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 13109 op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 13110 result->value.type = ira->codegen->builtin_types.entry_bool; 13111 return result; 13112 } 13113 13114 static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *type_entry, 13115 ConstExprValue *op1_val, IrBinOp op_id, ConstExprValue *op2_val, ConstExprValue *out_val) 13116 { 13117 bool is_int; 13118 bool is_float; 13119 Cmp op2_zcmp; 13120 if (type_entry->id == ZigTypeIdInt || type_entry->id == ZigTypeIdComptimeInt) { 13121 is_int = true; 13122 is_float = false; 13123 op2_zcmp = bigint_cmp_zero(&op2_val->data.x_bigint); 13124 } else if (type_entry->id == ZigTypeIdFloat || 13125 type_entry->id == ZigTypeIdComptimeFloat) 13126 { 13127 is_int = false; 13128 is_float = true; 13129 op2_zcmp = float_cmp_zero(op2_val); 13130 } else { 13131 zig_unreachable(); 13132 } 13133 13134 if ((op_id == IrBinOpDivUnspecified || op_id == IrBinOpRemRem || op_id == IrBinOpRemMod || 13135 op_id == IrBinOpDivTrunc || op_id == IrBinOpDivFloor) && op2_zcmp == CmpEQ) 13136 { 13137 return ir_add_error(ira, source_instr, buf_sprintf("division by zero")); 13138 } 13139 if ((op_id == IrBinOpRemRem || op_id == IrBinOpRemMod) && op2_zcmp == CmpLT) { 13140 return ir_add_error(ira, source_instr, buf_sprintf("negative denominator")); 13141 } 13142 13143 switch (op_id) { 13144 case IrBinOpInvalid: 13145 case IrBinOpBoolOr: 13146 case IrBinOpBoolAnd: 13147 case IrBinOpCmpEq: 13148 case IrBinOpCmpNotEq: 13149 case IrBinOpCmpLessThan: 13150 case IrBinOpCmpGreaterThan: 13151 case IrBinOpCmpLessOrEq: 13152 case IrBinOpCmpGreaterOrEq: 13153 case IrBinOpArrayCat: 13154 case IrBinOpArrayMult: 13155 case IrBinOpRemUnspecified: 13156 case IrBinOpMergeErrorSets: 13157 zig_unreachable(); 13158 case IrBinOpBinOr: 13159 assert(is_int); 13160 bigint_or(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13161 break; 13162 case IrBinOpBinXor: 13163 assert(is_int); 13164 bigint_xor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13165 break; 13166 case IrBinOpBinAnd: 13167 assert(is_int); 13168 bigint_and(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13169 break; 13170 case IrBinOpBitShiftLeftExact: 13171 assert(is_int); 13172 bigint_shl(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13173 break; 13174 case IrBinOpBitShiftLeftLossy: 13175 assert(type_entry->id == ZigTypeIdInt); 13176 bigint_shl_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 13177 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 13178 break; 13179 case IrBinOpBitShiftRightExact: 13180 { 13181 assert(is_int); 13182 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13183 BigInt orig_bigint; 13184 bigint_shl(&orig_bigint, &out_val->data.x_bigint, &op2_val->data.x_bigint); 13185 if (bigint_cmp(&op1_val->data.x_bigint, &orig_bigint) != CmpEQ) { 13186 return ir_add_error(ira, source_instr, buf_sprintf("exact shift shifted out 1 bits")); 13187 } 13188 break; 13189 } 13190 case IrBinOpBitShiftRightLossy: 13191 assert(is_int); 13192 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13193 break; 13194 case IrBinOpAdd: 13195 if (is_int) { 13196 bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13197 } else { 13198 float_add(out_val, op1_val, op2_val); 13199 } 13200 break; 13201 case IrBinOpAddWrap: 13202 assert(type_entry->id == ZigTypeIdInt); 13203 bigint_add_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 13204 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 13205 break; 13206 case IrBinOpSub: 13207 if (is_int) { 13208 bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13209 } else { 13210 float_sub(out_val, op1_val, op2_val); 13211 } 13212 break; 13213 case IrBinOpSubWrap: 13214 assert(type_entry->id == ZigTypeIdInt); 13215 bigint_sub_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 13216 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 13217 break; 13218 case IrBinOpMult: 13219 if (is_int) { 13220 bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13221 } else { 13222 float_mul(out_val, op1_val, op2_val); 13223 } 13224 break; 13225 case IrBinOpMultWrap: 13226 assert(type_entry->id == ZigTypeIdInt); 13227 bigint_mul_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 13228 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 13229 break; 13230 case IrBinOpDivUnspecified: 13231 assert(is_float); 13232 float_div(out_val, op1_val, op2_val); 13233 break; 13234 case IrBinOpDivTrunc: 13235 if (is_int) { 13236 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13237 } else { 13238 float_div_trunc(out_val, op1_val, op2_val); 13239 } 13240 break; 13241 case IrBinOpDivFloor: 13242 if (is_int) { 13243 bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13244 } else { 13245 float_div_floor(out_val, op1_val, op2_val); 13246 } 13247 break; 13248 case IrBinOpDivExact: 13249 if (is_int) { 13250 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13251 BigInt remainder; 13252 bigint_rem(&remainder, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13253 if (bigint_cmp_zero(&remainder) != CmpEQ) { 13254 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 13255 } 13256 } else { 13257 float_div_trunc(out_val, op1_val, op2_val); 13258 ConstExprValue remainder = {}; 13259 float_rem(&remainder, op1_val, op2_val); 13260 if (float_cmp_zero(&remainder) != CmpEQ) { 13261 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 13262 } 13263 } 13264 break; 13265 case IrBinOpRemRem: 13266 if (is_int) { 13267 bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13268 } else { 13269 float_rem(out_val, op1_val, op2_val); 13270 } 13271 break; 13272 case IrBinOpRemMod: 13273 if (is_int) { 13274 bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13275 } else { 13276 float_mod(out_val, op1_val, op2_val); 13277 } 13278 break; 13279 } 13280 13281 if (type_entry->id == ZigTypeIdInt) { 13282 if (!bigint_fits_in_bits(&out_val->data.x_bigint, type_entry->data.integral.bit_count, 13283 type_entry->data.integral.is_signed)) 13284 { 13285 return ir_add_error(ira, source_instr, buf_sprintf("operation caused overflow")); 13286 } 13287 } 13288 13289 out_val->type = type_entry; 13290 out_val->special = ConstValSpecialStatic; 13291 return nullptr; 13292 } 13293 13294 // This works on operands that have already been checked to be comptime known. 13295 static IrInstruction *ir_analyze_math_op(IrAnalyze *ira, IrInstruction *source_instr, 13296 ZigType *type_entry, ConstExprValue *op1_val, IrBinOp op_id, ConstExprValue *op2_val) 13297 { 13298 IrInstruction *result_instruction = ir_const(ira, source_instr, type_entry); 13299 ConstExprValue *out_val = &result_instruction->value; 13300 if (type_entry->id == ZigTypeIdVector) { 13301 expand_undef_array(ira->codegen, op1_val); 13302 expand_undef_array(ira->codegen, op2_val); 13303 out_val->special = ConstValSpecialUndef; 13304 expand_undef_array(ira->codegen, out_val); 13305 size_t len = type_entry->data.vector.len; 13306 ZigType *scalar_type = type_entry->data.vector.elem_type; 13307 for (size_t i = 0; i < len; i += 1) { 13308 ConstExprValue *scalar_op1_val = &op1_val->data.x_array.data.s_none.elements[i]; 13309 ConstExprValue *scalar_op2_val = &op2_val->data.x_array.data.s_none.elements[i]; 13310 ConstExprValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 13311 assert(scalar_op1_val->type == scalar_type); 13312 assert(scalar_op2_val->type == scalar_type); 13313 assert(scalar_out_val->type == scalar_type); 13314 ErrorMsg *msg = ir_eval_math_op_scalar(ira, source_instr, scalar_type, 13315 scalar_op1_val, op_id, scalar_op2_val, scalar_out_val); 13316 if (msg != nullptr) { 13317 add_error_note(ira->codegen, msg, source_instr->source_node, 13318 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 13319 return ira->codegen->invalid_instruction; 13320 } 13321 } 13322 out_val->type = type_entry; 13323 out_val->special = ConstValSpecialStatic; 13324 } else { 13325 if (ir_eval_math_op_scalar(ira, source_instr, type_entry, op1_val, op_id, op2_val, out_val) != nullptr) { 13326 return ira->codegen->invalid_instruction; 13327 } 13328 } 13329 return ir_implicit_cast(ira, result_instruction, type_entry); 13330 } 13331 13332 static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 13333 IrInstruction *op1 = bin_op_instruction->op1->child; 13334 if (type_is_invalid(op1->value.type)) 13335 return ira->codegen->invalid_instruction; 13336 13337 if (op1->value.type->id != ZigTypeIdInt && op1->value.type->id != ZigTypeIdComptimeInt) { 13338 ir_add_error(ira, &bin_op_instruction->base, 13339 buf_sprintf("bit shifting operation expected integer type, found '%s'", 13340 buf_ptr(&op1->value.type->name))); 13341 return ira->codegen->invalid_instruction; 13342 } 13343 13344 IrInstruction *op2 = bin_op_instruction->op2->child; 13345 if (type_is_invalid(op2->value.type)) 13346 return ira->codegen->invalid_instruction; 13347 13348 IrInstruction *casted_op2; 13349 IrBinOp op_id = bin_op_instruction->op_id; 13350 if (op1->value.type->id == ZigTypeIdComptimeInt) { 13351 casted_op2 = op2; 13352 13353 if (op_id == IrBinOpBitShiftLeftLossy) { 13354 op_id = IrBinOpBitShiftLeftExact; 13355 } 13356 13357 if (casted_op2->value.data.x_bigint.is_negative) { 13358 Buf *val_buf = buf_alloc(); 13359 bigint_append_buf(val_buf, &casted_op2->value.data.x_bigint, 10); 13360 ir_add_error(ira, casted_op2, buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); 13361 return ira->codegen->invalid_instruction; 13362 } 13363 } else { 13364 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 13365 op1->value.type->data.integral.bit_count - 1); 13366 if (bin_op_instruction->op_id == IrBinOpBitShiftLeftLossy && 13367 op2->value.type->id == ZigTypeIdComptimeInt) { 13368 if (!bigint_fits_in_bits(&op2->value.data.x_bigint, 13369 shift_amt_type->data.integral.bit_count, 13370 op2->value.data.x_bigint.is_negative)) { 13371 Buf *val_buf = buf_alloc(); 13372 bigint_append_buf(val_buf, &op2->value.data.x_bigint, 10); 13373 ErrorMsg* msg = ir_add_error(ira, 13374 &bin_op_instruction->base, 13375 buf_sprintf("RHS of shift is too large for LHS type")); 13376 add_error_note( 13377 ira->codegen, 13378 msg, 13379 op2->source_node, 13380 buf_sprintf("value %s cannot fit into type %s", 13381 buf_ptr(val_buf), 13382 buf_ptr(&shift_amt_type->name))); 13383 return ira->codegen->invalid_instruction; 13384 } 13385 } 13386 13387 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 13388 if (casted_op2 == ira->codegen->invalid_instruction) 13389 return ira->codegen->invalid_instruction; 13390 } 13391 13392 if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { 13393 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 13394 if (op1_val == nullptr) 13395 return ira->codegen->invalid_instruction; 13396 13397 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 13398 if (op2_val == nullptr) 13399 return ira->codegen->invalid_instruction; 13400 13401 return ir_analyze_math_op(ira, &bin_op_instruction->base, op1->value.type, op1_val, op_id, op2_val); 13402 } else if (op1->value.type->id == ZigTypeIdComptimeInt) { 13403 ir_add_error(ira, &bin_op_instruction->base, 13404 buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known")); 13405 return ira->codegen->invalid_instruction; 13406 } else if (instr_is_comptime(casted_op2) && bigint_cmp_zero(&casted_op2->value.data.x_bigint) == CmpEQ) { 13407 IrInstruction *result = ir_build_cast(&ira->new_irb, bin_op_instruction->base.scope, 13408 bin_op_instruction->base.source_node, op1->value.type, op1, CastOpNoop); 13409 result->value.type = op1->value.type; 13410 return result; 13411 } 13412 13413 IrInstruction *result = ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.scope, 13414 bin_op_instruction->base.source_node, op_id, 13415 op1, casted_op2, bin_op_instruction->safety_check_on); 13416 result->value.type = op1->value.type; 13417 return result; 13418 } 13419 13420 static bool ok_float_op(IrBinOp op) { 13421 switch (op) { 13422 case IrBinOpInvalid: 13423 zig_unreachable(); 13424 case IrBinOpAdd: 13425 case IrBinOpSub: 13426 case IrBinOpMult: 13427 case IrBinOpDivUnspecified: 13428 case IrBinOpDivTrunc: 13429 case IrBinOpDivFloor: 13430 case IrBinOpDivExact: 13431 case IrBinOpRemRem: 13432 case IrBinOpRemMod: 13433 return true; 13434 13435 case IrBinOpBoolOr: 13436 case IrBinOpBoolAnd: 13437 case IrBinOpCmpEq: 13438 case IrBinOpCmpNotEq: 13439 case IrBinOpCmpLessThan: 13440 case IrBinOpCmpGreaterThan: 13441 case IrBinOpCmpLessOrEq: 13442 case IrBinOpCmpGreaterOrEq: 13443 case IrBinOpBinOr: 13444 case IrBinOpBinXor: 13445 case IrBinOpBinAnd: 13446 case IrBinOpBitShiftLeftLossy: 13447 case IrBinOpBitShiftLeftExact: 13448 case IrBinOpBitShiftRightLossy: 13449 case IrBinOpBitShiftRightExact: 13450 case IrBinOpAddWrap: 13451 case IrBinOpSubWrap: 13452 case IrBinOpMultWrap: 13453 case IrBinOpRemUnspecified: 13454 case IrBinOpArrayCat: 13455 case IrBinOpArrayMult: 13456 case IrBinOpMergeErrorSets: 13457 return false; 13458 } 13459 zig_unreachable(); 13460 } 13461 13462 static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { 13463 if (lhs_type->id != ZigTypeIdPointer) 13464 return false; 13465 switch (op) { 13466 case IrBinOpAdd: 13467 case IrBinOpSub: 13468 break; 13469 default: 13470 return false; 13471 } 13472 switch (lhs_type->data.pointer.ptr_len) { 13473 case PtrLenSingle: 13474 return false; 13475 case PtrLenUnknown: 13476 case PtrLenC: 13477 break; 13478 } 13479 return true; 13480 } 13481 13482 static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) { 13483 Error err; 13484 13485 IrInstruction *op1 = instruction->op1->child; 13486 if (type_is_invalid(op1->value.type)) 13487 return ira->codegen->invalid_instruction; 13488 13489 IrInstruction *op2 = instruction->op2->child; 13490 if (type_is_invalid(op2->value.type)) 13491 return ira->codegen->invalid_instruction; 13492 13493 IrBinOp op_id = instruction->op_id; 13494 13495 // look for pointer math 13496 if (is_pointer_arithmetic_allowed(op1->value.type, op_id)) { 13497 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize); 13498 if (type_is_invalid(casted_op2->value.type)) 13499 return ira->codegen->invalid_instruction; 13500 13501 if (op1->value.special == ConstValSpecialUndef || casted_op2->value.special == ConstValSpecialUndef) { 13502 IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type); 13503 result->value.special = ConstValSpecialUndef; 13504 return result; 13505 } 13506 if (casted_op2->value.special == ConstValSpecialStatic && op1->value.special == ConstValSpecialStatic && 13507 (op1->value.data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 13508 op1->value.data.x_ptr.special == ConstPtrSpecialNull)) 13509 { 13510 uint64_t start_addr = (op1->value.data.x_ptr.special == ConstPtrSpecialNull) ? 13511 0 : op1->value.data.x_ptr.data.hard_coded_addr.addr; 13512 uint64_t elem_offset; 13513 if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) 13514 return ira->codegen->invalid_instruction; 13515 ZigType *elem_type = op1->value.type->data.pointer.child_type; 13516 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) 13517 return ira->codegen->invalid_instruction; 13518 uint64_t byte_offset = type_size(ira->codegen, elem_type) * elem_offset; 13519 uint64_t new_addr; 13520 if (op_id == IrBinOpAdd) { 13521 new_addr = start_addr + byte_offset; 13522 } else if (op_id == IrBinOpSub) { 13523 new_addr = start_addr - byte_offset; 13524 } else { 13525 zig_unreachable(); 13526 } 13527 IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type); 13528 result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 13529 result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar; 13530 result->value.data.x_ptr.data.hard_coded_addr.addr = new_addr; 13531 return result; 13532 } 13533 13534 IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope, 13535 instruction->base.source_node, op_id, op1, casted_op2, true); 13536 result->value.type = op1->value.type; 13537 return result; 13538 } 13539 13540 IrInstruction *instructions[] = {op1, op2}; 13541 ZigType *resolved_type = ir_resolve_peer_types(ira, instruction->base.source_node, nullptr, instructions, 2); 13542 if (type_is_invalid(resolved_type)) 13543 return ira->codegen->invalid_instruction; 13544 13545 bool is_int = resolved_type->id == ZigTypeIdInt || resolved_type->id == ZigTypeIdComptimeInt; 13546 bool is_float = resolved_type->id == ZigTypeIdFloat || resolved_type->id == ZigTypeIdComptimeFloat; 13547 bool is_signed_div = ( 13548 (resolved_type->id == ZigTypeIdInt && resolved_type->data.integral.is_signed) || 13549 resolved_type->id == ZigTypeIdFloat || 13550 (resolved_type->id == ZigTypeIdComptimeFloat && 13551 ((bigfloat_cmp_zero(&op1->value.data.x_bigfloat) != CmpGT) != 13552 (bigfloat_cmp_zero(&op2->value.data.x_bigfloat) != CmpGT))) || 13553 (resolved_type->id == ZigTypeIdComptimeInt && 13554 ((bigint_cmp_zero(&op1->value.data.x_bigint) != CmpGT) != 13555 (bigint_cmp_zero(&op2->value.data.x_bigint) != CmpGT))) 13556 ); 13557 if (op_id == IrBinOpDivUnspecified && is_int) { 13558 if (is_signed_div) { 13559 bool ok = false; 13560 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 13561 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 13562 if (op1_val == nullptr) 13563 return ira->codegen->invalid_instruction; 13564 13565 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 13566 if (op2_val == nullptr) 13567 return ira->codegen->invalid_instruction; 13568 13569 if (bigint_cmp_zero(&op2_val->data.x_bigint) == CmpEQ) { 13570 // the division by zero error will be caught later, but we don't have a 13571 // division function ambiguity problem. 13572 op_id = IrBinOpDivTrunc; 13573 ok = true; 13574 } else { 13575 BigInt trunc_result; 13576 BigInt floor_result; 13577 bigint_div_trunc(&trunc_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13578 bigint_div_floor(&floor_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13579 if (bigint_cmp(&trunc_result, &floor_result) == CmpEQ) { 13580 ok = true; 13581 op_id = IrBinOpDivTrunc; 13582 } 13583 } 13584 } 13585 if (!ok) { 13586 ir_add_error(ira, &instruction->base, 13587 buf_sprintf("division with '%s' and '%s': signed integers must use @divTrunc, @divFloor, or @divExact", 13588 buf_ptr(&op1->value.type->name), 13589 buf_ptr(&op2->value.type->name))); 13590 return ira->codegen->invalid_instruction; 13591 } 13592 } else { 13593 op_id = IrBinOpDivTrunc; 13594 } 13595 } else if (op_id == IrBinOpRemUnspecified) { 13596 if (is_signed_div && (is_int || is_float)) { 13597 bool ok = false; 13598 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 13599 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 13600 if (op1_val == nullptr) 13601 return ira->codegen->invalid_instruction; 13602 13603 if (is_int) { 13604 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 13605 if (op2_val == nullptr) 13606 return ira->codegen->invalid_instruction; 13607 13608 if (bigint_cmp_zero(&op2->value.data.x_bigint) == CmpEQ) { 13609 // the division by zero error will be caught later, but we don't 13610 // have a remainder function ambiguity problem 13611 ok = true; 13612 } else { 13613 BigInt rem_result; 13614 BigInt mod_result; 13615 bigint_rem(&rem_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13616 bigint_mod(&mod_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 13617 ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ; 13618 } 13619 } else { 13620 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 13621 if (casted_op2 == ira->codegen->invalid_instruction) 13622 return ira->codegen->invalid_instruction; 13623 13624 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 13625 if (op2_val == nullptr) 13626 return ira->codegen->invalid_instruction; 13627 13628 if (float_cmp_zero(&casted_op2->value) == CmpEQ) { 13629 // the division by zero error will be caught later, but we don't 13630 // have a remainder function ambiguity problem 13631 ok = true; 13632 } else { 13633 ConstExprValue rem_result = {}; 13634 ConstExprValue mod_result = {}; 13635 float_rem(&rem_result, op1_val, op2_val); 13636 float_mod(&mod_result, op1_val, op2_val); 13637 ok = float_cmp(&rem_result, &mod_result) == CmpEQ; 13638 } 13639 } 13640 } 13641 if (!ok) { 13642 ir_add_error(ira, &instruction->base, 13643 buf_sprintf("remainder division with '%s' and '%s': signed integers and floats must use @rem or @mod", 13644 buf_ptr(&op1->value.type->name), 13645 buf_ptr(&op2->value.type->name))); 13646 return ira->codegen->invalid_instruction; 13647 } 13648 } 13649 op_id = IrBinOpRemRem; 13650 } 13651 13652 bool ok = false; 13653 if (is_int) { 13654 ok = true; 13655 } else if (is_float && ok_float_op(op_id)) { 13656 ok = true; 13657 } else if (resolved_type->id == ZigTypeIdVector) { 13658 ZigType *elem_type = resolved_type->data.vector.elem_type; 13659 if (elem_type->id == ZigTypeIdInt || elem_type->id == ZigTypeIdComptimeInt) { 13660 ok = true; 13661 } else if ((elem_type->id == ZigTypeIdFloat || elem_type->id == ZigTypeIdComptimeFloat) && ok_float_op(op_id)) { 13662 ok = true; 13663 } 13664 } 13665 if (!ok) { 13666 AstNode *source_node = instruction->base.source_node; 13667 ir_add_error_node(ira, source_node, 13668 buf_sprintf("invalid operands to binary expression: '%s' and '%s'", 13669 buf_ptr(&op1->value.type->name), 13670 buf_ptr(&op2->value.type->name))); 13671 return ira->codegen->invalid_instruction; 13672 } 13673 13674 if (resolved_type->id == ZigTypeIdComptimeInt) { 13675 if (op_id == IrBinOpAddWrap) { 13676 op_id = IrBinOpAdd; 13677 } else if (op_id == IrBinOpSubWrap) { 13678 op_id = IrBinOpSub; 13679 } else if (op_id == IrBinOpMultWrap) { 13680 op_id = IrBinOpMult; 13681 } 13682 } 13683 13684 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 13685 if (casted_op1 == ira->codegen->invalid_instruction) 13686 return ira->codegen->invalid_instruction; 13687 13688 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 13689 if (casted_op2 == ira->codegen->invalid_instruction) 13690 return ira->codegen->invalid_instruction; 13691 13692 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 13693 ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 13694 if (op1_val == nullptr) 13695 return ira->codegen->invalid_instruction; 13696 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 13697 if (op2_val == nullptr) 13698 return ira->codegen->invalid_instruction; 13699 13700 return ir_analyze_math_op(ira, &instruction->base, resolved_type, op1_val, op_id, op2_val); 13701 } 13702 13703 IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope, 13704 instruction->base.source_node, op_id, casted_op1, casted_op2, instruction->safety_check_on); 13705 result->value.type = resolved_type; 13706 return result; 13707 } 13708 13709 static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruction) { 13710 IrInstruction *op1 = instruction->op1->child; 13711 ZigType *op1_type = op1->value.type; 13712 if (type_is_invalid(op1_type)) 13713 return ira->codegen->invalid_instruction; 13714 13715 IrInstruction *op2 = instruction->op2->child; 13716 ZigType *op2_type = op2->value.type; 13717 if (type_is_invalid(op2_type)) 13718 return ira->codegen->invalid_instruction; 13719 13720 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 13721 if (!op1_val) 13722 return ira->codegen->invalid_instruction; 13723 13724 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 13725 if (!op2_val) 13726 return ira->codegen->invalid_instruction; 13727 13728 ConstExprValue *op1_array_val; 13729 size_t op1_array_index; 13730 size_t op1_array_end; 13731 ZigType *child_type; 13732 if (op1_type->id == ZigTypeIdArray) { 13733 child_type = op1_type->data.array.child_type; 13734 op1_array_val = op1_val; 13735 op1_array_index = 0; 13736 op1_array_end = op1_type->data.array.len; 13737 } else if (op1_type->id == ZigTypeIdPointer && 13738 op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 13739 op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray && 13740 op1_val->data.x_ptr.data.base_array.is_cstr) 13741 { 13742 child_type = op1_type->data.pointer.child_type; 13743 op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; 13744 op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; 13745 op1_array_end = op1_array_val->type->data.array.len - 1; 13746 } else if (is_slice(op1_type)) { 13747 ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index].type_entry; 13748 child_type = ptr_type->data.pointer.child_type; 13749 ConstExprValue *ptr_val = &op1_val->data.x_struct.fields[slice_ptr_index]; 13750 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 13751 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 13752 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 13753 ConstExprValue *len_val = &op1_val->data.x_struct.fields[slice_len_index]; 13754 op1_array_end = op1_array_index + bigint_as_unsigned(&len_val->data.x_bigint); 13755 } else { 13756 ir_add_error(ira, op1, 13757 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name))); 13758 return ira->codegen->invalid_instruction; 13759 } 13760 13761 ConstExprValue *op2_array_val; 13762 size_t op2_array_index; 13763 size_t op2_array_end; 13764 bool op2_type_valid; 13765 if (op2_type->id == ZigTypeIdArray) { 13766 op2_type_valid = op2_type->data.array.child_type == child_type; 13767 op2_array_val = op2_val; 13768 op2_array_index = 0; 13769 op2_array_end = op2_array_val->type->data.array.len; 13770 } else if (op2_type->id == ZigTypeIdPointer && 13771 op2_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 13772 op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray && 13773 op2_val->data.x_ptr.data.base_array.is_cstr) 13774 { 13775 op2_type_valid = child_type == ira->codegen->builtin_types.entry_u8; 13776 op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; 13777 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; 13778 op2_array_end = op2_array_val->type->data.array.len - 1; 13779 } else if (is_slice(op2_type)) { 13780 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry; 13781 op2_type_valid = ptr_type->data.pointer.child_type == child_type; 13782 ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index]; 13783 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 13784 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 13785 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 13786 ConstExprValue *len_val = &op2_val->data.x_struct.fields[slice_len_index]; 13787 op2_array_end = op2_array_index + bigint_as_unsigned(&len_val->data.x_bigint); 13788 } else { 13789 ir_add_error(ira, op2, 13790 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name))); 13791 return ira->codegen->invalid_instruction; 13792 } 13793 if (!op2_type_valid) { 13794 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", 13795 buf_ptr(&child_type->name), 13796 buf_ptr(&op2->value.type->name))); 13797 return ira->codegen->invalid_instruction; 13798 } 13799 13800 // The type of result is populated in the following if blocks 13801 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 13802 ConstExprValue *out_val = &result->value; 13803 13804 ConstExprValue *out_array_val; 13805 size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); 13806 if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { 13807 result->value.type = get_array_type(ira->codegen, child_type, new_len); 13808 13809 out_array_val = out_val; 13810 } else if (is_slice(op1_type) || is_slice(op2_type)) { 13811 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, 13812 true, false, PtrLenUnknown, 0, 0, 0, false); 13813 result->value.type = get_slice_type(ira->codegen, ptr_type); 13814 out_array_val = create_const_vals(1); 13815 out_array_val->special = ConstValSpecialStatic; 13816 out_array_val->type = get_array_type(ira->codegen, child_type, new_len); 13817 13818 out_val->data.x_struct.fields = create_const_vals(2); 13819 13820 out_val->data.x_struct.fields[slice_ptr_index].type = ptr_type; 13821 out_val->data.x_struct.fields[slice_ptr_index].special = ConstValSpecialStatic; 13822 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.special = ConstPtrSpecialBaseArray; 13823 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.array_val = out_array_val; 13824 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.elem_index = 0; 13825 13826 out_val->data.x_struct.fields[slice_len_index].type = ira->codegen->builtin_types.entry_usize; 13827 out_val->data.x_struct.fields[slice_len_index].special = ConstValSpecialStatic; 13828 bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index].data.x_bigint, new_len); 13829 } else { 13830 new_len += 1; // null byte 13831 13832 // TODO make this `[*]null T` instead of `[*]T` 13833 result->value.type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, PtrLenUnknown, 0, 0, 0, false); 13834 13835 out_array_val = create_const_vals(1); 13836 out_array_val->special = ConstValSpecialStatic; 13837 out_array_val->type = get_array_type(ira->codegen, child_type, new_len); 13838 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 13839 out_val->data.x_ptr.data.base_array.is_cstr = true; 13840 out_val->data.x_ptr.data.base_array.array_val = out_array_val; 13841 out_val->data.x_ptr.data.base_array.elem_index = 0; 13842 } 13843 13844 if (op1_array_val->data.x_array.special == ConstArraySpecialUndef && 13845 op2_array_val->data.x_array.special == ConstArraySpecialUndef) { 13846 out_array_val->data.x_array.special = ConstArraySpecialUndef; 13847 return result; 13848 } 13849 13850 out_array_val->data.x_array.data.s_none.elements = create_const_vals(new_len); 13851 // TODO handle the buf case here for an optimization 13852 expand_undef_array(ira->codegen, op1_array_val); 13853 expand_undef_array(ira->codegen, op2_array_val); 13854 13855 size_t next_index = 0; 13856 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { 13857 copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], 13858 &op1_array_val->data.x_array.data.s_none.elements[i], true); 13859 } 13860 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { 13861 copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], 13862 &op2_array_val->data.x_array.data.s_none.elements[i], true); 13863 } 13864 if (next_index < new_len) { 13865 ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; 13866 init_const_unsigned_negative(null_byte, child_type, 0, false); 13867 next_index += 1; 13868 } 13869 assert(next_index == new_len); 13870 13871 return result; 13872 } 13873 13874 static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instruction) { 13875 IrInstruction *op1 = instruction->op1->child; 13876 if (type_is_invalid(op1->value.type)) 13877 return ira->codegen->invalid_instruction; 13878 13879 IrInstruction *op2 = instruction->op2->child; 13880 if (type_is_invalid(op2->value.type)) 13881 return ira->codegen->invalid_instruction; 13882 13883 ConstExprValue *array_val = ir_resolve_const(ira, op1, UndefBad); 13884 if (!array_val) 13885 return ira->codegen->invalid_instruction; 13886 13887 uint64_t mult_amt; 13888 if (!ir_resolve_usize(ira, op2, &mult_amt)) 13889 return ira->codegen->invalid_instruction; 13890 13891 ZigType *array_type = op1->value.type; 13892 if (array_type->id != ZigTypeIdArray) { 13893 ir_add_error(ira, op1, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value.type->name))); 13894 return ira->codegen->invalid_instruction; 13895 } 13896 13897 uint64_t old_array_len = array_type->data.array.len; 13898 uint64_t new_array_len; 13899 13900 if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) 13901 { 13902 ir_add_error(ira, &instruction->base, buf_sprintf("operation results in overflow")); 13903 return ira->codegen->invalid_instruction; 13904 } 13905 13906 ZigType *child_type = array_type->data.array.child_type; 13907 13908 IrInstruction *result = ir_const(ira, &instruction->base, 13909 get_array_type(ira->codegen, child_type, new_array_len)); 13910 ConstExprValue *out_val = &result->value; 13911 if (array_val->data.x_array.special == ConstArraySpecialUndef) { 13912 out_val->data.x_array.special = ConstArraySpecialUndef; 13913 return result; 13914 } 13915 13916 // TODO optimize the buf case 13917 expand_undef_array(ira->codegen, array_val); 13918 out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len); 13919 13920 uint64_t i = 0; 13921 for (uint64_t x = 0; x < mult_amt; x += 1) { 13922 for (uint64_t y = 0; y < old_array_len; y += 1) { 13923 copy_const_val(&out_val->data.x_array.data.s_none.elements[i], 13924 &array_val->data.x_array.data.s_none.elements[y], false); 13925 i += 1; 13926 } 13927 } 13928 assert(i == new_array_len); 13929 13930 return result; 13931 } 13932 13933 static IrInstruction *ir_analyze_merge_error_sets(IrAnalyze *ira, IrInstructionBinOp *instruction) { 13934 ZigType *op1_type = ir_resolve_error_set_type(ira, &instruction->base, instruction->op1->child); 13935 if (type_is_invalid(op1_type)) 13936 return ira->codegen->invalid_instruction; 13937 13938 ZigType *op2_type = ir_resolve_error_set_type(ira, &instruction->base, instruction->op2->child); 13939 if (type_is_invalid(op2_type)) 13940 return ira->codegen->invalid_instruction; 13941 13942 if (type_is_global_error_set(op1_type) || 13943 type_is_global_error_set(op2_type)) 13944 { 13945 return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_global_error_set); 13946 } 13947 13948 if (!resolve_inferred_error_set(ira->codegen, op1_type, instruction->op1->child->source_node)) { 13949 return ira->codegen->invalid_instruction; 13950 } 13951 13952 if (!resolve_inferred_error_set(ira->codegen, op2_type, instruction->op2->child->source_node)) { 13953 return ira->codegen->invalid_instruction; 13954 } 13955 13956 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 13957 for (uint32_t i = 0, count = op1_type->data.error_set.err_count; i < count; i += 1) { 13958 ErrorTableEntry *error_entry = op1_type->data.error_set.errors[i]; 13959 assert(errors[error_entry->value] == nullptr); 13960 errors[error_entry->value] = error_entry; 13961 } 13962 ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type); 13963 free(errors); 13964 13965 return ir_const_type(ira, &instruction->base, result_type); 13966 } 13967 13968 static IrInstruction *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 13969 IrBinOp op_id = bin_op_instruction->op_id; 13970 switch (op_id) { 13971 case IrBinOpInvalid: 13972 zig_unreachable(); 13973 case IrBinOpBoolOr: 13974 case IrBinOpBoolAnd: 13975 return ir_analyze_bin_op_bool(ira, bin_op_instruction); 13976 case IrBinOpCmpEq: 13977 case IrBinOpCmpNotEq: 13978 case IrBinOpCmpLessThan: 13979 case IrBinOpCmpGreaterThan: 13980 case IrBinOpCmpLessOrEq: 13981 case IrBinOpCmpGreaterOrEq: 13982 return ir_analyze_bin_op_cmp(ira, bin_op_instruction); 13983 case IrBinOpBitShiftLeftLossy: 13984 case IrBinOpBitShiftLeftExact: 13985 case IrBinOpBitShiftRightLossy: 13986 case IrBinOpBitShiftRightExact: 13987 return ir_analyze_bit_shift(ira, bin_op_instruction); 13988 case IrBinOpBinOr: 13989 case IrBinOpBinXor: 13990 case IrBinOpBinAnd: 13991 case IrBinOpAdd: 13992 case IrBinOpAddWrap: 13993 case IrBinOpSub: 13994 case IrBinOpSubWrap: 13995 case IrBinOpMult: 13996 case IrBinOpMultWrap: 13997 case IrBinOpDivUnspecified: 13998 case IrBinOpDivTrunc: 13999 case IrBinOpDivFloor: 14000 case IrBinOpDivExact: 14001 case IrBinOpRemUnspecified: 14002 case IrBinOpRemRem: 14003 case IrBinOpRemMod: 14004 return ir_analyze_bin_op_math(ira, bin_op_instruction); 14005 case IrBinOpArrayCat: 14006 return ir_analyze_array_cat(ira, bin_op_instruction); 14007 case IrBinOpArrayMult: 14008 return ir_analyze_array_mult(ira, bin_op_instruction); 14009 case IrBinOpMergeErrorSets: 14010 return ir_analyze_merge_error_sets(ira, bin_op_instruction); 14011 } 14012 zig_unreachable(); 14013 } 14014 14015 static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, 14016 IrInstructionDeclVarSrc *decl_var_instruction) 14017 { 14018 Error err; 14019 ZigVar *var = decl_var_instruction->var; 14020 14021 ZigType *explicit_type = nullptr; 14022 IrInstruction *var_type = nullptr; 14023 if (decl_var_instruction->var_type != nullptr) { 14024 var_type = decl_var_instruction->var_type->child; 14025 ZigType *proposed_type = ir_resolve_type(ira, var_type); 14026 explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type); 14027 if (type_is_invalid(explicit_type)) { 14028 var->var_type = ira->codegen->builtin_types.entry_invalid; 14029 return ira->codegen->invalid_instruction; 14030 } 14031 } 14032 14033 AstNode *source_node = decl_var_instruction->base.source_node; 14034 14035 bool is_comptime_var = ir_get_var_is_comptime(var); 14036 14037 bool var_class_requires_const = false; 14038 14039 IrInstruction *var_ptr = decl_var_instruction->ptr->child; 14040 // if this is null, a compiler error happened and did not initialize the variable. 14041 // if there are no compile errors there may be a missing ir_expr_wrap in pass1 IR generation. 14042 if (var_ptr == nullptr || type_is_invalid(var_ptr->value.type)) { 14043 ir_assert(var_ptr != nullptr || ira->codegen->errors.length != 0, &decl_var_instruction->base); 14044 var->var_type = ira->codegen->builtin_types.entry_invalid; 14045 return ira->codegen->invalid_instruction; 14046 } 14047 14048 // The ir_build_var_decl_src call is supposed to pass a pointer to the allocation, not an initialization value. 14049 ir_assert(var_ptr->value.type->id == ZigTypeIdPointer, &decl_var_instruction->base); 14050 14051 ZigType *result_type = var_ptr->value.type->data.pointer.child_type; 14052 if (type_is_invalid(result_type)) { 14053 result_type = ira->codegen->builtin_types.entry_invalid; 14054 } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { 14055 zig_unreachable(); 14056 } 14057 14058 ConstExprValue *init_val = nullptr; 14059 if (instr_is_comptime(var_ptr) && var_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { 14060 init_val = const_ptr_pointee(ira, ira->codegen, &var_ptr->value, decl_var_instruction->base.source_node); 14061 if (is_comptime_var) { 14062 if (var->gen_is_const) { 14063 var->const_value = init_val; 14064 } else { 14065 var->const_value = create_const_vals(1); 14066 copy_const_val(var->const_value, init_val, false); 14067 } 14068 } 14069 } 14070 14071 switch (type_requires_comptime(ira->codegen, result_type)) { 14072 case ReqCompTimeInvalid: 14073 result_type = ira->codegen->builtin_types.entry_invalid; 14074 break; 14075 case ReqCompTimeYes: 14076 var_class_requires_const = true; 14077 if (!var->gen_is_const && !is_comptime_var) { 14078 ir_add_error_node(ira, source_node, 14079 buf_sprintf("variable of type '%s' must be const or comptime", 14080 buf_ptr(&result_type->name))); 14081 result_type = ira->codegen->builtin_types.entry_invalid; 14082 } 14083 break; 14084 case ReqCompTimeNo: 14085 if (init_val != nullptr) { 14086 if (init_val->special == ConstValSpecialStatic && 14087 init_val->type->id == ZigTypeIdFn && 14088 init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 14089 init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) 14090 { 14091 var_class_requires_const = true; 14092 if (!var->src_is_const && !is_comptime_var) { 14093 ErrorMsg *msg = ir_add_error_node(ira, source_node, 14094 buf_sprintf("functions marked inline must be stored in const or comptime var")); 14095 AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node; 14096 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); 14097 result_type = ira->codegen->builtin_types.entry_invalid; 14098 } 14099 } 14100 } 14101 break; 14102 } 14103 14104 if (var->var_type != nullptr && !is_comptime_var) { 14105 // This is at least the second time we've seen this variable declaration during analysis. 14106 // This means that this is actually a different variable due to, e.g. an inline while loop. 14107 // We make a new variable so that it can hold a different type, and so the debug info can 14108 // be distinct. 14109 ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope, 14110 &var->name, var->src_is_const, var->gen_is_const, var->shadowable, var->is_comptime, true); 14111 new_var->owner_exec = var->owner_exec; 14112 new_var->align_bytes = var->align_bytes; 14113 if (var->mem_slot_index != SIZE_MAX) { 14114 ConstExprValue *vals = create_const_vals(1); 14115 new_var->mem_slot_index = ira->exec_context.mem_slot_list.length; 14116 ira->exec_context.mem_slot_list.append(vals); 14117 } 14118 14119 var->next_var = new_var; 14120 var = new_var; 14121 } 14122 14123 // This must be done after possibly creating a new variable above 14124 var->ref_count = 0; 14125 14126 var->var_type = result_type; 14127 assert(var->var_type); 14128 14129 if (type_is_invalid(result_type)) { 14130 return ir_const_void(ira, &decl_var_instruction->base); 14131 } 14132 14133 if (decl_var_instruction->align_value == nullptr) { 14134 if ((err = type_resolve(ira->codegen, result_type, ResolveStatusAlignmentKnown))) { 14135 var->var_type = ira->codegen->builtin_types.entry_invalid; 14136 return ir_const_void(ira, &decl_var_instruction->base); 14137 } 14138 var->align_bytes = get_abi_alignment(ira->codegen, result_type); 14139 } else { 14140 if (!ir_resolve_align(ira, decl_var_instruction->align_value->child, &var->align_bytes)) { 14141 var->var_type = ira->codegen->builtin_types.entry_invalid; 14142 } 14143 } 14144 14145 if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) { 14146 // Resolve ConstPtrMutInfer 14147 if (var->gen_is_const) { 14148 var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeConst; 14149 } else if (is_comptime_var) { 14150 var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeVar; 14151 } else { 14152 // we need a runtime ptr but we have a comptime val. 14153 // since it's a comptime val there are no instructions for it. 14154 // we memcpy the init value here 14155 IrInstruction *deref = ir_get_deref(ira, var_ptr, var_ptr, nullptr); 14156 // If this assertion trips, something is wrong with the IR instructions, because 14157 // we expected the above deref to return a constant value, but it created a runtime 14158 // instruction. 14159 assert(deref->value.special != ConstValSpecialRuntime); 14160 var_ptr->value.special = ConstValSpecialRuntime; 14161 ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref, false); 14162 } 14163 14164 if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) { 14165 assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); 14166 ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); 14167 copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); 14168 14169 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { 14170 return ir_const_void(ira, &decl_var_instruction->base); 14171 } 14172 } 14173 } else if (is_comptime_var) { 14174 ir_add_error(ira, &decl_var_instruction->base, 14175 buf_sprintf("cannot store runtime value in compile time variable")); 14176 var->var_type = ira->codegen->builtin_types.entry_invalid; 14177 return ira->codegen->invalid_instruction; 14178 } 14179 14180 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 14181 if (fn_entry) 14182 fn_entry->variable_list.append(var); 14183 14184 return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr); 14185 } 14186 14187 static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { 14188 IrInstruction *name = instruction->name->child; 14189 Buf *symbol_name = ir_resolve_str(ira, name); 14190 if (symbol_name == nullptr) { 14191 return ira->codegen->invalid_instruction; 14192 } 14193 14194 IrInstruction *target = instruction->target->child; 14195 if (type_is_invalid(target->value.type)) { 14196 return ira->codegen->invalid_instruction; 14197 } 14198 14199 GlobalLinkageId global_linkage_id = GlobalLinkageIdStrong; 14200 if (instruction->linkage != nullptr) { 14201 IrInstruction *linkage_value = instruction->linkage->child; 14202 if (!ir_resolve_global_linkage(ira, linkage_value, &global_linkage_id)) { 14203 return ira->codegen->invalid_instruction; 14204 } 14205 } 14206 14207 // TODO: This function needs to be audited. 14208 // It's not clear how all the different types are supposed to be handled. 14209 // Need comprehensive tests for exporting one thing in one file and declaring an extern var 14210 // in another file. 14211 TldFn *tld_fn = allocate<TldFn>(1); 14212 tld_fn->base.id = TldIdFn; 14213 tld_fn->base.source_node = instruction->base.source_node; 14214 14215 auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, &tld_fn->base); 14216 if (entry) { 14217 AstNode *other_export_node = entry->value->source_node; 14218 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 14219 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name))); 14220 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); 14221 return ira->codegen->invalid_instruction; 14222 } 14223 14224 bool want_var_export = false; 14225 switch (target->value.type->id) { 14226 case ZigTypeIdInvalid: 14227 case ZigTypeIdUnreachable: 14228 zig_unreachable(); 14229 case ZigTypeIdFn: { 14230 assert(target->value.data.x_ptr.special == ConstPtrSpecialFunction); 14231 ZigFn *fn_entry = target->value.data.x_ptr.data.fn.fn_entry; 14232 tld_fn->fn_entry = fn_entry; 14233 CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc; 14234 switch (cc) { 14235 case CallingConventionUnspecified: { 14236 ErrorMsg *msg = ir_add_error(ira, target, 14237 buf_sprintf("exported function must specify calling convention")); 14238 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 14239 } break; 14240 case CallingConventionAsync: { 14241 ErrorMsg *msg = ir_add_error(ira, target, 14242 buf_sprintf("exported function cannot be async")); 14243 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 14244 } break; 14245 case CallingConventionC: 14246 case CallingConventionNaked: 14247 case CallingConventionCold: 14248 case CallingConventionStdcall: 14249 add_fn_export(ira->codegen, fn_entry, symbol_name, global_linkage_id, cc == CallingConventionC); 14250 break; 14251 } 14252 } break; 14253 case ZigTypeIdStruct: 14254 if (is_slice(target->value.type)) { 14255 ir_add_error(ira, target, 14256 buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value.type->name))); 14257 } else if (target->value.type->data.structure.layout != ContainerLayoutExtern) { 14258 ErrorMsg *msg = ir_add_error(ira, target, 14259 buf_sprintf("exported struct value must be declared extern")); 14260 add_error_note(ira->codegen, msg, target->value.type->data.structure.decl_node, buf_sprintf("declared here")); 14261 } else { 14262 want_var_export = true; 14263 } 14264 break; 14265 case ZigTypeIdUnion: 14266 if (target->value.type->data.unionation.layout != ContainerLayoutExtern) { 14267 ErrorMsg *msg = ir_add_error(ira, target, 14268 buf_sprintf("exported union value must be declared extern")); 14269 add_error_note(ira->codegen, msg, target->value.type->data.unionation.decl_node, buf_sprintf("declared here")); 14270 } else { 14271 want_var_export = true; 14272 } 14273 break; 14274 case ZigTypeIdEnum: 14275 if (target->value.type->data.enumeration.layout != ContainerLayoutExtern) { 14276 ErrorMsg *msg = ir_add_error(ira, target, 14277 buf_sprintf("exported enum value must be declared extern")); 14278 add_error_note(ira->codegen, msg, target->value.type->data.enumeration.decl_node, buf_sprintf("declared here")); 14279 } else { 14280 want_var_export = true; 14281 } 14282 break; 14283 case ZigTypeIdArray: 14284 if (!type_allowed_in_extern(ira->codegen, target->value.type->data.array.child_type)) { 14285 ir_add_error(ira, target, 14286 buf_sprintf("array element type '%s' not extern-compatible", 14287 buf_ptr(&target->value.type->data.array.child_type->name))); 14288 } else { 14289 want_var_export = true; 14290 } 14291 break; 14292 case ZigTypeIdMetaType: { 14293 ZigType *type_value = target->value.data.x_type; 14294 switch (type_value->id) { 14295 case ZigTypeIdInvalid: 14296 zig_unreachable(); 14297 case ZigTypeIdStruct: 14298 if (is_slice(type_value)) { 14299 ir_add_error(ira, target, 14300 buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name))); 14301 } else if (type_value->data.structure.layout != ContainerLayoutExtern) { 14302 ErrorMsg *msg = ir_add_error(ira, target, 14303 buf_sprintf("exported struct must be declared extern")); 14304 add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here")); 14305 } 14306 break; 14307 case ZigTypeIdUnion: 14308 if (type_value->data.unionation.layout != ContainerLayoutExtern) { 14309 ErrorMsg *msg = ir_add_error(ira, target, 14310 buf_sprintf("exported union must be declared extern")); 14311 add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here")); 14312 } 14313 break; 14314 case ZigTypeIdEnum: 14315 if (type_value->data.enumeration.layout != ContainerLayoutExtern) { 14316 ErrorMsg *msg = ir_add_error(ira, target, 14317 buf_sprintf("exported enum must be declared extern")); 14318 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); 14319 } 14320 break; 14321 case ZigTypeIdFn: { 14322 if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 14323 ir_add_error(ira, target, 14324 buf_sprintf("exported function type must specify calling convention")); 14325 } 14326 } break; 14327 case ZigTypeIdInt: 14328 case ZigTypeIdFloat: 14329 case ZigTypeIdPointer: 14330 case ZigTypeIdArray: 14331 case ZigTypeIdBool: 14332 case ZigTypeIdVector: 14333 break; 14334 case ZigTypeIdMetaType: 14335 case ZigTypeIdVoid: 14336 case ZigTypeIdUnreachable: 14337 case ZigTypeIdComptimeFloat: 14338 case ZigTypeIdComptimeInt: 14339 case ZigTypeIdEnumLiteral: 14340 case ZigTypeIdUndefined: 14341 case ZigTypeIdNull: 14342 case ZigTypeIdOptional: 14343 case ZigTypeIdErrorUnion: 14344 case ZigTypeIdErrorSet: 14345 case ZigTypeIdBoundFn: 14346 case ZigTypeIdArgTuple: 14347 case ZigTypeIdOpaque: 14348 case ZigTypeIdFnFrame: 14349 case ZigTypeIdAnyFrame: 14350 ir_add_error(ira, target, 14351 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); 14352 break; 14353 } 14354 } break; 14355 case ZigTypeIdInt: 14356 break; 14357 case ZigTypeIdVoid: 14358 case ZigTypeIdBool: 14359 case ZigTypeIdFloat: 14360 case ZigTypeIdPointer: 14361 case ZigTypeIdComptimeFloat: 14362 case ZigTypeIdComptimeInt: 14363 case ZigTypeIdUndefined: 14364 case ZigTypeIdNull: 14365 case ZigTypeIdOptional: 14366 case ZigTypeIdErrorUnion: 14367 case ZigTypeIdErrorSet: 14368 case ZigTypeIdVector: 14369 zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name)); 14370 case ZigTypeIdBoundFn: 14371 case ZigTypeIdArgTuple: 14372 case ZigTypeIdOpaque: 14373 case ZigTypeIdEnumLiteral: 14374 case ZigTypeIdFnFrame: 14375 case ZigTypeIdAnyFrame: 14376 ir_add_error(ira, target, 14377 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name))); 14378 break; 14379 } 14380 14381 // TODO audit the various ways to use @export 14382 if (want_var_export && target->id == IrInstructionIdLoadPtrGen) { 14383 IrInstructionLoadPtrGen *load_ptr = reinterpret_cast<IrInstructionLoadPtrGen *>(target); 14384 if (load_ptr->ptr->id == IrInstructionIdVarPtr) { 14385 IrInstructionVarPtr *var_ptr = reinterpret_cast<IrInstructionVarPtr *>(load_ptr->ptr); 14386 ZigVar *var = var_ptr->var; 14387 add_var_export(ira->codegen, var, symbol_name, global_linkage_id); 14388 } 14389 } 14390 14391 return ir_const_void(ira, &instruction->base); 14392 } 14393 14394 static bool exec_has_err_ret_trace(CodeGen *g, IrExecutable *exec) { 14395 ZigFn *fn_entry = exec_fn_entry(exec); 14396 return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing; 14397 } 14398 14399 static IrInstruction *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, 14400 IrInstructionErrorReturnTrace *instruction) 14401 { 14402 ZigType *ptr_to_stack_trace_type = get_pointer_to_type(ira->codegen, get_stack_trace_type(ira->codegen), false); 14403 if (instruction->optional == IrInstructionErrorReturnTrace::Null) { 14404 ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type); 14405 if (!exec_has_err_ret_trace(ira->codegen, ira->new_irb.exec)) { 14406 IrInstruction *result = ir_const(ira, &instruction->base, optional_type); 14407 ConstExprValue *out_val = &result->value; 14408 assert(get_codegen_ptr_type(optional_type) != nullptr); 14409 out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 14410 out_val->data.x_ptr.data.hard_coded_addr.addr = 0; 14411 return result; 14412 } 14413 IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, 14414 instruction->base.source_node, instruction->optional); 14415 new_instruction->value.type = optional_type; 14416 return new_instruction; 14417 } else { 14418 assert(ira->codegen->have_err_ret_tracing); 14419 IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, 14420 instruction->base.source_node, instruction->optional); 14421 new_instruction->value.type = ptr_to_stack_trace_type; 14422 return new_instruction; 14423 } 14424 } 14425 14426 static IrInstruction *ir_analyze_instruction_error_union(IrAnalyze *ira, 14427 IrInstructionErrorUnion *instruction) 14428 { 14429 Error err; 14430 14431 ZigType *err_set_type = ir_resolve_type(ira, instruction->err_set->child); 14432 if (type_is_invalid(err_set_type)) 14433 return ira->codegen->invalid_instruction; 14434 14435 ZigType *payload_type = ir_resolve_type(ira, instruction->payload->child); 14436 if (type_is_invalid(payload_type)) 14437 return ira->codegen->invalid_instruction; 14438 14439 if (err_set_type->id != ZigTypeIdErrorSet) { 14440 ir_add_error(ira, instruction->err_set->child, 14441 buf_sprintf("expected error set type, found type '%s'", 14442 buf_ptr(&err_set_type->name))); 14443 return ira->codegen->invalid_instruction; 14444 } 14445 14446 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 14447 return ira->codegen->invalid_instruction; 14448 ZigType *result_type = get_error_union_type(ira->codegen, err_set_type, payload_type); 14449 14450 return ir_const_type(ira, &instruction->base, result_type); 14451 } 14452 14453 static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type, 14454 uint32_t align, const char *name_hint, bool force_comptime) 14455 { 14456 Error err; 14457 14458 ConstExprValue *pointee = create_const_vals(1); 14459 pointee->special = ConstValSpecialUndef; 14460 14461 IrInstructionAllocaGen *result = ir_build_alloca_gen(ira, source_inst, align, name_hint); 14462 result->base.value.special = ConstValSpecialStatic; 14463 result->base.value.data.x_ptr.special = ConstPtrSpecialRef; 14464 result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer; 14465 result->base.value.data.x_ptr.data.ref.pointee = pointee; 14466 14467 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown))) 14468 return ira->codegen->invalid_instruction; 14469 assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid); 14470 14471 pointee->type = var_type; 14472 result->base.value.type = get_pointer_to_type_extra(ira->codegen, var_type, false, false, 14473 PtrLenSingle, align, 0, 0, false); 14474 14475 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 14476 if (fn_entry != nullptr) { 14477 fn_entry->alloca_gen_list.append(result); 14478 } 14479 result->base.is_gen = true; 14480 return &result->base; 14481 } 14482 14483 static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspend_source_instr, 14484 ResultLoc *result_loc) 14485 { 14486 switch (result_loc->id) { 14487 case ResultLocIdInvalid: 14488 case ResultLocIdPeerParent: 14489 zig_unreachable(); 14490 case ResultLocIdNone: 14491 case ResultLocIdVar: 14492 case ResultLocIdBitCast: 14493 return nullptr; 14494 case ResultLocIdInstruction: 14495 return result_loc->source_instruction->child->value.type; 14496 case ResultLocIdReturn: 14497 return ira->explicit_return_type; 14498 case ResultLocIdPeer: 14499 return reinterpret_cast<ResultLocPeer*>(result_loc)->parent->resolved_type; 14500 } 14501 zig_unreachable(); 14502 } 14503 14504 static bool type_can_bit_cast(ZigType *t) { 14505 switch (t->id) { 14506 case ZigTypeIdInvalid: 14507 zig_unreachable(); 14508 case ZigTypeIdMetaType: 14509 case ZigTypeIdOpaque: 14510 case ZigTypeIdBoundFn: 14511 case ZigTypeIdArgTuple: 14512 case ZigTypeIdUnreachable: 14513 case ZigTypeIdComptimeFloat: 14514 case ZigTypeIdComptimeInt: 14515 case ZigTypeIdEnumLiteral: 14516 case ZigTypeIdUndefined: 14517 case ZigTypeIdNull: 14518 case ZigTypeIdPointer: 14519 return false; 14520 default: 14521 // TODO list these types out explicitly, there are probably some other invalid ones here 14522 return true; 14523 } 14524 } 14525 14526 static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { 14527 ConstExprValue *undef_child = create_const_vals(1); 14528 undef_child->type = ptr->value.type->data.pointer.child_type; 14529 undef_child->special = ConstValSpecialUndef; 14530 ptr->value.special = ConstValSpecialStatic; 14531 ptr->value.data.x_ptr.mut = ConstPtrMutInfer; 14532 ptr->value.data.x_ptr.special = ConstPtrSpecialRef; 14533 ptr->value.data.x_ptr.data.ref.pointee = undef_child; 14534 } 14535 14536 // when calling this function, at the callsite must check for result type noreturn and propagate it up 14537 static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, 14538 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) 14539 { 14540 Error err; 14541 if (result_loc->resolved_loc != nullptr) { 14542 // allow to redo the result location if the value is known and comptime and the previous one isn't 14543 if (value == nullptr || !instr_is_comptime(value) || instr_is_comptime(result_loc->resolved_loc)) { 14544 return result_loc->resolved_loc; 14545 } 14546 } 14547 result_loc->gen_instruction = value; 14548 result_loc->implicit_elem_type = value_type; 14549 switch (result_loc->id) { 14550 case ResultLocIdInvalid: 14551 case ResultLocIdPeerParent: 14552 zig_unreachable(); 14553 case ResultLocIdNone: { 14554 if (value != nullptr) { 14555 return nullptr; 14556 } 14557 // need to return a result location and don't have one. use a stack allocation 14558 IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, ""); 14559 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown))) 14560 return ira->codegen->invalid_instruction; 14561 alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, 14562 PtrLenSingle, 0, 0, 0, false); 14563 set_up_result_loc_for_inferred_comptime(&alloca_gen->base); 14564 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 14565 if (fn_entry != nullptr) { 14566 fn_entry->alloca_gen_list.append(alloca_gen); 14567 } 14568 result_loc->written = true; 14569 result_loc->resolved_loc = &alloca_gen->base; 14570 return result_loc->resolved_loc; 14571 } 14572 case ResultLocIdVar: { 14573 ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); 14574 assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc); 14575 14576 if (value_type->id == ZigTypeIdUnreachable || value_type->id == ZigTypeIdOpaque) { 14577 ir_add_error(ira, result_loc->source_instruction, 14578 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&value_type->name))); 14579 return ira->codegen->invalid_instruction; 14580 } 14581 14582 IrInstructionAllocaSrc *alloca_src = 14583 reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); 14584 bool force_comptime; 14585 if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) 14586 return ira->codegen->invalid_instruction; 14587 bool is_comptime = force_comptime || (value != nullptr && 14588 value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); 14589 14590 if (alloca_src->base.child == nullptr || is_comptime) { 14591 uint32_t align = 0; 14592 if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, &align)) { 14593 return ira->codegen->invalid_instruction; 14594 } 14595 IrInstruction *alloca_gen; 14596 if (is_comptime && value != nullptr) { 14597 if (align > value->value.global_refs->align) { 14598 value->value.global_refs->align = align; 14599 } 14600 alloca_gen = ir_get_ref(ira, result_loc->source_instruction, value, true, false); 14601 } else { 14602 alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, 14603 alloca_src->name_hint, force_comptime); 14604 } 14605 if (alloca_src->base.child != nullptr) { 14606 alloca_src->base.child->ref_count = 0; 14607 } 14608 alloca_src->base.child = alloca_gen; 14609 } 14610 result_loc->written = true; 14611 result_loc->resolved_loc = is_comptime ? nullptr : alloca_src->base.child; 14612 return result_loc->resolved_loc; 14613 } 14614 case ResultLocIdInstruction: { 14615 result_loc->written = true; 14616 result_loc->resolved_loc = result_loc->source_instruction->child; 14617 return result_loc->resolved_loc; 14618 } 14619 case ResultLocIdReturn: { 14620 if (!non_null_comptime) { 14621 bool is_comptime = value != nullptr && value->value.special != ConstValSpecialRuntime; 14622 if (is_comptime) 14623 return nullptr; 14624 } 14625 if ((err = type_resolve(ira->codegen, ira->explicit_return_type, ResolveStatusZeroBitsKnown))) { 14626 return ira->codegen->invalid_instruction; 14627 } 14628 if (!type_has_bits(ira->explicit_return_type) || !handle_is_ptr(ira->explicit_return_type)) { 14629 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 14630 if (fn_entry == nullptr || fn_entry->inferred_async_node == nullptr) { 14631 return nullptr; 14632 } 14633 } 14634 14635 ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false); 14636 result_loc->written = true; 14637 result_loc->resolved_loc = ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type); 14638 if (ir_should_inline(ira->old_irb.exec, result_loc->source_instruction->scope)) { 14639 set_up_result_loc_for_inferred_comptime(result_loc->resolved_loc); 14640 } 14641 return result_loc->resolved_loc; 14642 } 14643 case ResultLocIdPeer: { 14644 ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(result_loc); 14645 ResultLocPeerParent *peer_parent = result_peer->parent; 14646 14647 if (peer_parent->peers.length == 1) { 14648 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 14649 value_type, value, force_runtime, non_null_comptime, true); 14650 result_peer->suspend_pos.basic_block_index = SIZE_MAX; 14651 result_peer->suspend_pos.instruction_index = SIZE_MAX; 14652 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || 14653 parent_result_loc->value.type->id == ZigTypeIdUnreachable) 14654 { 14655 return parent_result_loc; 14656 } 14657 result_loc->written = true; 14658 result_loc->resolved_loc = parent_result_loc; 14659 return result_loc->resolved_loc; 14660 } 14661 14662 bool is_comptime; 14663 if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) 14664 return ira->codegen->invalid_instruction; 14665 peer_parent->skipped = is_comptime; 14666 if (peer_parent->skipped) { 14667 if (non_null_comptime) { 14668 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 14669 value_type, value, force_runtime, non_null_comptime, true); 14670 } 14671 return nullptr; 14672 } 14673 14674 if (peer_parent->resolved_type == nullptr) { 14675 if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { 14676 peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr; 14677 } 14678 IrInstruction *unreach_inst = ira_suspend(ira, suspend_source_instr, result_peer->next_bb, 14679 &result_peer->suspend_pos); 14680 if (result_peer->next_bb == nullptr) { 14681 ir_start_next_bb(ira); 14682 } 14683 return unreach_inst; 14684 } 14685 14686 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 14687 peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime, true); 14688 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || 14689 parent_result_loc->value.type->id == ZigTypeIdUnreachable) 14690 { 14691 return parent_result_loc; 14692 } 14693 // because is_comptime is false, we mark this a runtime pointer 14694 parent_result_loc->value.special = ConstValSpecialRuntime; 14695 result_loc->written = true; 14696 result_loc->resolved_loc = parent_result_loc; 14697 return result_loc->resolved_loc; 14698 } 14699 case ResultLocIdBitCast: { 14700 ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc); 14701 ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child); 14702 if (type_is_invalid(dest_type)) 14703 return ira->codegen->invalid_instruction; 14704 14705 if (get_codegen_ptr_type(dest_type) != nullptr) { 14706 ir_add_error(ira, result_loc->source_instruction, 14707 buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); 14708 return ira->codegen->invalid_instruction; 14709 } 14710 14711 if (!type_can_bit_cast(dest_type)) { 14712 ir_add_error(ira, result_loc->source_instruction, 14713 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); 14714 return ira->codegen->invalid_instruction; 14715 } 14716 14717 if (get_codegen_ptr_type(value_type) != nullptr) { 14718 ir_add_error(ira, suspend_source_instr, 14719 buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&value_type->name))); 14720 return ira->codegen->invalid_instruction; 14721 } 14722 14723 if (!type_can_bit_cast(value_type)) { 14724 ir_add_error(ira, suspend_source_instr, 14725 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&value_type->name))); 14726 return ira->codegen->invalid_instruction; 14727 } 14728 14729 IrInstruction *bitcasted_value; 14730 if (value != nullptr) { 14731 bitcasted_value = ir_analyze_bit_cast(ira, result_loc->source_instruction, value, dest_type); 14732 } else { 14733 bitcasted_value = nullptr; 14734 } 14735 14736 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent, 14737 dest_type, bitcasted_value, force_runtime, non_null_comptime, true); 14738 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || 14739 parent_result_loc->value.type->id == ZigTypeIdUnreachable) 14740 { 14741 return parent_result_loc; 14742 } 14743 ZigType *parent_ptr_type = parent_result_loc->value.type; 14744 assert(parent_ptr_type->id == ZigTypeIdPointer); 14745 if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, 14746 ResolveStatusAlignmentKnown))) 14747 { 14748 return ira->codegen->invalid_instruction; 14749 } 14750 uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); 14751 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, 14752 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, 14753 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); 14754 14755 result_loc->written = true; 14756 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, 14757 ptr_type, result_bit_cast->base.source_instruction, false); 14758 return result_loc->resolved_loc; 14759 } 14760 } 14761 zig_unreachable(); 14762 } 14763 14764 static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, 14765 ResultLoc *result_loc_pass1, ZigType *value_type, IrInstruction *value, bool force_runtime, 14766 bool non_null_comptime, bool allow_discard) 14767 { 14768 if (!allow_discard && result_loc_pass1->id == ResultLocIdInstruction && 14769 instr_is_comptime(result_loc_pass1->source_instruction) && 14770 result_loc_pass1->source_instruction->value.type->id == ZigTypeIdPointer && 14771 result_loc_pass1->source_instruction->value.data.x_ptr.special == ConstPtrSpecialDiscard) 14772 { 14773 result_loc_pass1 = no_result_loc(); 14774 } 14775 IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, 14776 value, force_runtime, non_null_comptime); 14777 if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type))) 14778 return result_loc; 14779 14780 if ((force_runtime || (value != nullptr && !instr_is_comptime(value))) && 14781 result_loc_pass1->written && result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) 14782 { 14783 result_loc->value.special = ConstValSpecialRuntime; 14784 } 14785 14786 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, suspend_source_instr); 14787 ZigType *actual_elem_type = result_loc->value.type->data.pointer.child_type; 14788 if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && 14789 value_type->id != ZigTypeIdNull) 14790 { 14791 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); 14792 } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { 14793 if (value_type->id == ZigTypeIdErrorSet) { 14794 return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); 14795 } else { 14796 IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, 14797 result_loc, false, true); 14798 ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; 14799 if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) { 14800 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); 14801 } else { 14802 return unwrapped_err_ptr; 14803 } 14804 } 14805 } else if (is_slice(actual_elem_type) && value_type->id == ZigTypeIdArray) { 14806 // need to allow EndExpr to do the implicit cast from array to slice 14807 result_loc_pass1->written = false; 14808 } 14809 return result_loc; 14810 } 14811 14812 static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) { 14813 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 14814 if (type_is_invalid(dest_type)) 14815 return ira->codegen->invalid_instruction; 14816 14817 IrInstruction *target = instruction->target->child; 14818 if (type_is_invalid(target->value.type)) 14819 return ira->codegen->invalid_instruction; 14820 14821 return ir_implicit_cast_with_result(ira, target, dest_type, instruction->result_loc); 14822 } 14823 14824 static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) { 14825 ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); 14826 if (type_is_invalid(implicit_elem_type)) 14827 return ira->codegen->invalid_instruction; 14828 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 14829 implicit_elem_type, nullptr, false, true, true); 14830 if (result_loc != nullptr) 14831 return result_loc; 14832 14833 ZigFn *fn = exec_fn_entry(ira->new_irb.exec); 14834 if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync && 14835 instruction->result_loc->id == ResultLocIdReturn) 14836 { 14837 result_loc = ir_resolve_result(ira, &instruction->base, no_result_loc(), 14838 implicit_elem_type, nullptr, false, true, true); 14839 if (result_loc != nullptr && 14840 (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) 14841 { 14842 return result_loc; 14843 } 14844 result_loc->value.special = ConstValSpecialRuntime; 14845 return result_loc; 14846 } 14847 14848 IrInstruction *result = ir_const(ira, &instruction->base, implicit_elem_type); 14849 result->value.special = ConstValSpecialUndef; 14850 IrInstruction *ptr = ir_get_ref(ira, &instruction->base, result, false, false); 14851 ptr->value.data.x_ptr.mut = ConstPtrMutComptimeVar; 14852 return ptr; 14853 } 14854 14855 static void ir_reset_result(ResultLoc *result_loc) { 14856 result_loc->written = false; 14857 result_loc->resolved_loc = nullptr; 14858 result_loc->gen_instruction = nullptr; 14859 result_loc->implicit_elem_type = nullptr; 14860 switch (result_loc->id) { 14861 case ResultLocIdInvalid: 14862 zig_unreachable(); 14863 case ResultLocIdPeerParent: { 14864 ResultLocPeerParent *peer_parent = reinterpret_cast<ResultLocPeerParent *>(result_loc); 14865 peer_parent->skipped = false; 14866 peer_parent->done_resuming = false; 14867 peer_parent->resolved_type = nullptr; 14868 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 14869 ir_reset_result(&peer_parent->peers.at(i)->base); 14870 } 14871 break; 14872 } 14873 case ResultLocIdVar: { 14874 IrInstructionAllocaSrc *alloca_src = 14875 reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); 14876 alloca_src->base.child = nullptr; 14877 break; 14878 } 14879 case ResultLocIdPeer: 14880 case ResultLocIdNone: 14881 case ResultLocIdReturn: 14882 case ResultLocIdInstruction: 14883 case ResultLocIdBitCast: 14884 break; 14885 } 14886 } 14887 14888 static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInstructionResetResult *instruction) { 14889 ir_reset_result(instruction->result_loc); 14890 return ir_const_void(ira, &instruction->base); 14891 } 14892 14893 static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry, 14894 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, 14895 IrInstruction *casted_new_stack) 14896 { 14897 if (casted_new_stack != nullptr) { 14898 // this is an @asyncCall 14899 14900 if (fn_type->data.fn.fn_type_id.cc != CallingConventionAsync) { 14901 ir_add_error(ira, fn_ref, 14902 buf_sprintf("expected async function, found '%s'", buf_ptr(&fn_type->name))); 14903 return ira->codegen->invalid_instruction; 14904 } 14905 14906 IrInstruction *ret_ptr = call_instruction->args[call_instruction->arg_count]->child; 14907 if (type_is_invalid(ret_ptr->value.type)) 14908 return ira->codegen->invalid_instruction; 14909 14910 ZigType *anyframe_type = get_any_frame_type(ira->codegen, fn_type->data.fn.fn_type_id.return_type); 14911 14912 IrInstructionCallGen *call_gen = ir_build_call_gen(ira, &call_instruction->base, nullptr, fn_ref, 14913 arg_count, casted_args, FnInlineAuto, true, casted_new_stack, ret_ptr, anyframe_type); 14914 return &call_gen->base; 14915 } else if (fn_entry == nullptr) { 14916 ir_add_error(ira, fn_ref, buf_sprintf("function is not comptime-known; @asyncCall required")); 14917 return ira->codegen->invalid_instruction; 14918 } 14919 14920 ZigType *frame_type = get_fn_frame_type(ira->codegen, fn_entry); 14921 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, 14922 frame_type, nullptr, true, true, false); 14923 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { 14924 return result_loc; 14925 } 14926 result_loc = ir_implicit_cast(ira, result_loc, get_pointer_to_type(ira->codegen, frame_type, false)); 14927 if (type_is_invalid(result_loc->value.type)) 14928 return ira->codegen->invalid_instruction; 14929 return &ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count, 14930 casted_args, FnInlineAuto, true, nullptr, result_loc, frame_type)->base; 14931 } 14932 static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, 14933 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) 14934 { 14935 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 14936 assert(param_decl_node->type == NodeTypeParamDecl); 14937 14938 IrInstruction *casted_arg; 14939 if (param_decl_node->data.param_decl.var_token == nullptr) { 14940 AstNode *param_type_node = param_decl_node->data.param_decl.type; 14941 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); 14942 if (type_is_invalid(param_type)) 14943 return false; 14944 14945 casted_arg = ir_implicit_cast(ira, arg, param_type); 14946 if (type_is_invalid(casted_arg->value.type)) 14947 return false; 14948 } else { 14949 casted_arg = arg; 14950 } 14951 14952 ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefOk); 14953 if (!arg_val) 14954 return false; 14955 14956 Buf *param_name = param_decl_node->data.param_decl.name; 14957 ZigVar *var = add_variable(ira->codegen, param_decl_node, 14958 *exec_scope, param_name, true, arg_val, nullptr, arg_val->type); 14959 *exec_scope = var->child_scope; 14960 *next_proto_i += 1; 14961 14962 return true; 14963 } 14964 14965 static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, 14966 IrInstruction *arg, Scope **child_scope, size_t *next_proto_i, 14967 GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args, 14968 ZigFn *impl_fn) 14969 { 14970 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 14971 assert(param_decl_node->type == NodeTypeParamDecl); 14972 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 14973 bool arg_part_of_generic_id = false; 14974 IrInstruction *casted_arg; 14975 if (is_var_args) { 14976 arg_part_of_generic_id = true; 14977 casted_arg = arg; 14978 } else { 14979 if (param_decl_node->data.param_decl.var_token == nullptr) { 14980 AstNode *param_type_node = param_decl_node->data.param_decl.type; 14981 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node); 14982 if (type_is_invalid(param_type)) 14983 return false; 14984 14985 casted_arg = ir_implicit_cast(ira, arg, param_type); 14986 if (type_is_invalid(casted_arg->value.type)) 14987 return false; 14988 } else { 14989 arg_part_of_generic_id = true; 14990 casted_arg = arg; 14991 } 14992 } 14993 14994 bool comptime_arg = param_decl_node->data.param_decl.is_inline || 14995 casted_arg->value.type->id == ZigTypeIdComptimeInt || casted_arg->value.type->id == ZigTypeIdComptimeFloat; 14996 14997 ConstExprValue *arg_val; 14998 14999 if (comptime_arg) { 15000 arg_part_of_generic_id = true; 15001 arg_val = ir_resolve_const(ira, casted_arg, UndefBad); 15002 if (!arg_val) 15003 return false; 15004 } else { 15005 arg_val = create_const_runtime(casted_arg->value.type); 15006 } 15007 if (arg_part_of_generic_id) { 15008 copy_const_val(&generic_id->params[generic_id->param_count], arg_val, true); 15009 generic_id->param_count += 1; 15010 } 15011 15012 Buf *param_name = param_decl_node->data.param_decl.name; 15013 if (!param_name) return false; 15014 if (!is_var_args) { 15015 ZigVar *var = add_variable(ira->codegen, param_decl_node, 15016 *child_scope, param_name, true, arg_val, nullptr, arg_val->type); 15017 *child_scope = var->child_scope; 15018 var->shadowable = !comptime_arg; 15019 15020 *next_proto_i += 1; 15021 } else if (casted_arg->value.type->id == ZigTypeIdComptimeInt || 15022 casted_arg->value.type->id == ZigTypeIdComptimeFloat) 15023 { 15024 ir_add_error(ira, casted_arg, 15025 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557")); 15026 return false; 15027 } 15028 15029 if (!comptime_arg) { 15030 switch (type_requires_comptime(ira->codegen, casted_arg->value.type)) { 15031 case ReqCompTimeYes: 15032 ir_add_error(ira, casted_arg, 15033 buf_sprintf("parameter of type '%s' requires comptime", buf_ptr(&casted_arg->value.type->name))); 15034 return false; 15035 case ReqCompTimeInvalid: 15036 return false; 15037 case ReqCompTimeNo: 15038 break; 15039 } 15040 15041 casted_args[fn_type_id->param_count] = casted_arg; 15042 FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count]; 15043 param_info->type = casted_arg->value.type; 15044 param_info->is_noalias = param_decl_node->data.param_decl.is_noalias; 15045 impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node; 15046 fn_type_id->param_count += 1; 15047 } 15048 15049 return true; 15050 } 15051 15052 static ZigVar *get_fn_var_by_index(ZigFn *fn_entry, size_t index) { 15053 FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[index]; 15054 if (!type_has_bits(src_param_info->type)) 15055 return nullptr; 15056 15057 size_t next_var_i = 0; 15058 for (size_t param_i = 0; param_i < index; param_i += 1) { 15059 FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[param_i]; 15060 if (!type_has_bits(src_param_info->type)) { 15061 continue; 15062 } 15063 15064 next_var_i += 1; 15065 } 15066 return fn_entry->variable_list.at(next_var_i); 15067 } 15068 15069 static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var) { 15070 while (var->next_var != nullptr) { 15071 var = var->next_var; 15072 } 15073 15074 if (var->mem_slot_index != SIZE_MAX && var->owner_exec->analysis == nullptr) { 15075 assert(ira->codegen->errors.length != 0); 15076 return ira->codegen->invalid_instruction; 15077 } 15078 if (var->var_type == nullptr || type_is_invalid(var->var_type)) 15079 return ira->codegen->invalid_instruction; 15080 15081 ConstExprValue *mem_slot = nullptr; 15082 15083 bool comptime_var_mem = ir_get_var_is_comptime(var); 15084 bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern; 15085 bool is_const = var->src_is_const; 15086 bool is_volatile = false; 15087 15088 if (linkage_makes_it_runtime) 15089 goto no_mem_slot; 15090 15091 if (var->const_value->special == ConstValSpecialStatic) { 15092 mem_slot = var->const_value; 15093 } else { 15094 if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { 15095 // find the relevant exec_context 15096 assert(var->owner_exec != nullptr); 15097 assert(var->owner_exec->analysis != nullptr); 15098 IrExecContext *exec_context = &var->owner_exec->analysis->exec_context; 15099 assert(var->mem_slot_index < exec_context->mem_slot_list.length); 15100 mem_slot = exec_context->mem_slot_list.at(var->mem_slot_index); 15101 } 15102 } 15103 15104 if (mem_slot != nullptr) { 15105 switch (mem_slot->special) { 15106 case ConstValSpecialRuntime: 15107 goto no_mem_slot; 15108 case ConstValSpecialStatic: // fallthrough 15109 case ConstValSpecialUndef: { 15110 ConstPtrMut ptr_mut; 15111 if (comptime_var_mem) { 15112 ptr_mut = ConstPtrMutComptimeVar; 15113 } else if (var->gen_is_const) { 15114 ptr_mut = ConstPtrMutComptimeConst; 15115 } else { 15116 assert(!comptime_var_mem); 15117 ptr_mut = ConstPtrMutRuntimeVar; 15118 } 15119 return ir_get_const_ptr(ira, instruction, mem_slot, var->var_type, 15120 ptr_mut, is_const, is_volatile, var->align_bytes); 15121 } 15122 } 15123 zig_unreachable(); 15124 } 15125 15126 no_mem_slot: 15127 15128 IrInstruction *var_ptr_instruction = ir_build_var_ptr(&ira->new_irb, 15129 instruction->scope, instruction->source_node, var); 15130 var_ptr_instruction->value.type = get_pointer_to_type_extra(ira->codegen, var->var_type, 15131 var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0, false); 15132 15133 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr); 15134 var_ptr_instruction->value.data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack; 15135 15136 return var_ptr_instruction; 15137 } 15138 15139 static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, 15140 IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const) 15141 { 15142 assert(ptr->value.type->id == ZigTypeIdPointer); 15143 15144 if (ptr->value.data.x_ptr.special == ConstPtrSpecialDiscard) { 15145 if (uncasted_value->value.type->id == ZigTypeIdErrorUnion || 15146 uncasted_value->value.type->id == ZigTypeIdErrorSet) 15147 { 15148 ir_add_error(ira, source_instr, buf_sprintf("error is discarded")); 15149 return ira->codegen->invalid_instruction; 15150 } 15151 return ir_const_void(ira, source_instr); 15152 } 15153 15154 ZigType *child_type = ptr->value.type->data.pointer.child_type; 15155 15156 if (ptr->value.type->data.pointer.is_const && !allow_write_through_const) { 15157 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 15158 return ira->codegen->invalid_instruction; 15159 } 15160 15161 IrInstruction *value = ir_implicit_cast(ira, uncasted_value, child_type); 15162 if (value == ira->codegen->invalid_instruction) 15163 return ira->codegen->invalid_instruction; 15164 15165 switch (type_has_one_possible_value(ira->codegen, child_type)) { 15166 case OnePossibleValueInvalid: 15167 return ira->codegen->invalid_instruction; 15168 case OnePossibleValueYes: 15169 return ir_const_void(ira, source_instr); 15170 case OnePossibleValueNo: 15171 break; 15172 } 15173 15174 if (instr_is_comptime(ptr) && ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 15175 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst) { 15176 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 15177 return ira->codegen->invalid_instruction; 15178 } 15179 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar || 15180 ptr->value.data.x_ptr.mut == ConstPtrMutInfer) 15181 { 15182 if (instr_is_comptime(value)) { 15183 ConstExprValue *dest_val = const_ptr_pointee(ira, ira->codegen, &ptr->value, source_instr->source_node); 15184 if (dest_val == nullptr) 15185 return ira->codegen->invalid_instruction; 15186 if (dest_val->special != ConstValSpecialRuntime) { 15187 // TODO this allows a value stored to have the original value modified and then 15188 // have that affect what should be a copy. We need some kind of advanced copy-on-write 15189 // system to make these two tests pass at the same time: 15190 // * "string literal used as comptime slice is memoized" 15191 // * "comptime modification of const struct field" - except modified to avoid 15192 // ConstPtrMutComptimeVar, thus defeating the logic below. 15193 bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; 15194 copy_const_val(dest_val, &value->value, same_global_refs); 15195 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar && 15196 !ira->new_irb.current_basic_block->must_be_comptime_source_instr) 15197 { 15198 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; 15199 } 15200 return ir_const_void(ira, source_instr); 15201 } 15202 } 15203 if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) { 15204 ptr->value.special = ConstValSpecialRuntime; 15205 } else { 15206 ir_add_error(ira, source_instr, 15207 buf_sprintf("cannot store runtime value in compile time variable")); 15208 ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); 15209 dest_val->type = ira->codegen->builtin_types.entry_invalid; 15210 15211 return ira->codegen->invalid_instruction; 15212 } 15213 } 15214 } 15215 15216 switch (type_requires_comptime(ira->codegen, child_type)) { 15217 case ReqCompTimeInvalid: 15218 return ira->codegen->invalid_instruction; 15219 case ReqCompTimeYes: 15220 switch (type_has_one_possible_value(ira->codegen, ptr->value.type)) { 15221 case OnePossibleValueInvalid: 15222 return ira->codegen->invalid_instruction; 15223 case OnePossibleValueNo: 15224 ir_add_error(ira, source_instr, 15225 buf_sprintf("cannot store runtime value in type '%s'", buf_ptr(&child_type->name))); 15226 return ira->codegen->invalid_instruction; 15227 case OnePossibleValueYes: 15228 return ir_const_void(ira, source_instr); 15229 } 15230 zig_unreachable(); 15231 case ReqCompTimeNo: 15232 break; 15233 } 15234 15235 IrInstructionStorePtr *store_ptr = ir_build_store_ptr(&ira->new_irb, source_instr->scope, 15236 source_instr->source_node, ptr, value); 15237 return &store_ptr->base; 15238 } 15239 15240 static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, 15241 ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, 15242 IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) 15243 { 15244 Error err; 15245 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 15246 size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0; 15247 15248 // for extern functions, the var args argument is not counted. 15249 // for zig functions, it is. 15250 size_t var_args_1_or_0; 15251 if (fn_type_id->cc == CallingConventionC) { 15252 var_args_1_or_0 = 0; 15253 } else { 15254 var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0; 15255 } 15256 size_t src_param_count = fn_type_id->param_count - var_args_1_or_0; 15257 15258 size_t call_param_count = call_instruction->arg_count + first_arg_1_or_0; 15259 for (size_t i = 0; i < call_instruction->arg_count; i += 1) { 15260 ConstExprValue *arg_tuple_value = &call_instruction->args[i]->child->value; 15261 if (arg_tuple_value->type->id == ZigTypeIdArgTuple) { 15262 call_param_count -= 1; 15263 call_param_count += arg_tuple_value->data.x_arg_tuple.end_index - 15264 arg_tuple_value->data.x_arg_tuple.start_index; 15265 } 15266 } 15267 AstNode *source_node = call_instruction->base.source_node; 15268 15269 AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;; 15270 15271 if (fn_type_id->cc == CallingConventionNaked) { 15272 ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("unable to call function with naked calling convention")); 15273 if (fn_proto_node) { 15274 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 15275 } 15276 return ira->codegen->invalid_instruction; 15277 } 15278 15279 15280 if (fn_type_id->is_var_args) { 15281 if (call_param_count < src_param_count) { 15282 ErrorMsg *msg = ir_add_error_node(ira, source_node, 15283 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 15284 if (fn_proto_node) { 15285 add_error_note(ira->codegen, msg, fn_proto_node, 15286 buf_sprintf("declared here")); 15287 } 15288 return ira->codegen->invalid_instruction; 15289 } 15290 } else if (src_param_count != call_param_count) { 15291 ErrorMsg *msg = ir_add_error_node(ira, source_node, 15292 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 15293 if (fn_proto_node) { 15294 add_error_note(ira->codegen, msg, fn_proto_node, 15295 buf_sprintf("declared here")); 15296 } 15297 return ira->codegen->invalid_instruction; 15298 } 15299 15300 if (comptime_fn_call) { 15301 // No special handling is needed for compile time evaluation of generic functions. 15302 if (!fn_entry || fn_entry->body_node == nullptr) { 15303 ir_add_error(ira, fn_ref, buf_sprintf("unable to evaluate constant expression")); 15304 return ira->codegen->invalid_instruction; 15305 } 15306 15307 if (!ir_emit_backward_branch(ira, &call_instruction->base)) 15308 return ira->codegen->invalid_instruction; 15309 15310 // Fork a scope of the function with known values for the parameters. 15311 Scope *exec_scope = &fn_entry->fndef_scope->base; 15312 15313 size_t next_proto_i = 0; 15314 if (first_arg_ptr) { 15315 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 15316 15317 bool first_arg_known_bare = false; 15318 if (fn_type_id->next_param_index >= 1) { 15319 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 15320 if (type_is_invalid(param_type)) 15321 return ira->codegen->invalid_instruction; 15322 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 15323 } 15324 15325 IrInstruction *first_arg; 15326 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { 15327 first_arg = first_arg_ptr; 15328 } else { 15329 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); 15330 if (type_is_invalid(first_arg->value.type)) 15331 return ira->codegen->invalid_instruction; 15332 } 15333 15334 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, first_arg, &exec_scope, &next_proto_i)) 15335 return ira->codegen->invalid_instruction; 15336 } 15337 15338 if (fn_proto_node->data.fn_proto.is_var_args) { 15339 ir_add_error(ira, &call_instruction->base, 15340 buf_sprintf("compiler bug: unable to call var args function at compile time. https://github.com/ziglang/zig/issues/313")); 15341 return ira->codegen->invalid_instruction; 15342 } 15343 15344 15345 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 15346 IrInstruction *old_arg = call_instruction->args[call_i]->child; 15347 if (type_is_invalid(old_arg->value.type)) 15348 return ira->codegen->invalid_instruction; 15349 15350 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i)) 15351 return ira->codegen->invalid_instruction; 15352 } 15353 15354 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 15355 ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node); 15356 if (type_is_invalid(specified_return_type)) 15357 return ira->codegen->invalid_instruction; 15358 ZigType *return_type; 15359 ZigType *inferred_err_set_type = nullptr; 15360 if (fn_proto_node->data.fn_proto.auto_err_set) { 15361 inferred_err_set_type = get_auto_err_set_type(ira->codegen, fn_entry); 15362 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 15363 return ira->codegen->invalid_instruction; 15364 return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 15365 } else { 15366 return_type = specified_return_type; 15367 } 15368 15369 bool cacheable = fn_eval_cacheable(exec_scope, return_type); 15370 ConstExprValue *result = nullptr; 15371 if (cacheable) { 15372 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope); 15373 if (entry) 15374 result = entry->value; 15375 } 15376 15377 if (result == nullptr) { 15378 // Analyze the fn body block like any other constant expression. 15379 AstNode *body_node = fn_entry->body_node; 15380 result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, 15381 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, 15382 nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node); 15383 15384 if (inferred_err_set_type != nullptr) { 15385 inferred_err_set_type->data.error_set.infer_fn = nullptr; 15386 if (result->type->id == ZigTypeIdErrorUnion) { 15387 ErrorTableEntry *err = result->data.x_err_union.error_set->data.x_err_set; 15388 if (err != nullptr) { 15389 inferred_err_set_type->data.error_set.err_count = 1; 15390 inferred_err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1); 15391 inferred_err_set_type->data.error_set.errors[0] = err; 15392 } 15393 ZigType *fn_inferred_err_set_type = result->type->data.error_union.err_set_type; 15394 inferred_err_set_type->data.error_set.err_count = fn_inferred_err_set_type->data.error_set.err_count; 15395 inferred_err_set_type->data.error_set.errors = fn_inferred_err_set_type->data.error_set.errors; 15396 } else if (result->type->id == ZigTypeIdErrorSet) { 15397 inferred_err_set_type->data.error_set.err_count = result->type->data.error_set.err_count; 15398 inferred_err_set_type->data.error_set.errors = result->type->data.error_set.errors; 15399 } 15400 } 15401 15402 if (cacheable) { 15403 ira->codegen->memoized_fn_eval_table.put(exec_scope, result); 15404 } 15405 15406 if (type_is_invalid(result->type)) 15407 return ira->codegen->invalid_instruction; 15408 } 15409 15410 IrInstruction *new_instruction = ir_const(ira, &call_instruction->base, result->type); 15411 copy_const_val(&new_instruction->value, result, true); 15412 new_instruction->value.type = return_type; 15413 return ir_finish_anal(ira, new_instruction); 15414 } 15415 15416 IrInstruction *casted_new_stack = nullptr; 15417 if (call_instruction->new_stack != nullptr) { 15418 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 15419 false, false, PtrLenUnknown, 0, 0, 0, false); 15420 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 15421 IrInstruction *new_stack = call_instruction->new_stack->child; 15422 if (type_is_invalid(new_stack->value.type)) 15423 return ira->codegen->invalid_instruction; 15424 15425 casted_new_stack = ir_implicit_cast(ira, new_stack, u8_slice); 15426 if (type_is_invalid(casted_new_stack->value.type)) 15427 return ira->codegen->invalid_instruction; 15428 } 15429 15430 if (fn_type->data.fn.is_generic) { 15431 if (!fn_entry) { 15432 ir_add_error(ira, call_instruction->fn_ref, 15433 buf_sprintf("calling a generic function requires compile-time known function value")); 15434 return ira->codegen->invalid_instruction; 15435 } 15436 15437 // Count the arguments of the function type id we are creating 15438 size_t new_fn_arg_count = first_arg_1_or_0; 15439 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 15440 IrInstruction *arg = call_instruction->args[call_i]->child; 15441 if (type_is_invalid(arg->value.type)) 15442 return ira->codegen->invalid_instruction; 15443 15444 if (arg->value.type->id == ZigTypeIdArgTuple) { 15445 new_fn_arg_count += arg->value.data.x_arg_tuple.end_index - arg->value.data.x_arg_tuple.start_index; 15446 } else { 15447 new_fn_arg_count += 1; 15448 } 15449 } 15450 15451 IrInstruction **casted_args = allocate<IrInstruction *>(new_fn_arg_count); 15452 15453 // Fork a scope of the function with known values for the parameters. 15454 Scope *parent_scope = fn_entry->fndef_scope->base.parent; 15455 ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node); 15456 impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count); 15457 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); 15458 impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); 15459 impl_fn->child_scope = &impl_fn->fndef_scope->base; 15460 FnTypeId inst_fn_type_id = {0}; 15461 init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count); 15462 inst_fn_type_id.param_count = 0; 15463 inst_fn_type_id.is_var_args = false; 15464 15465 // TODO maybe GenericFnTypeId can be replaced with using the child_scope directly 15466 // as the key in generic_table 15467 GenericFnTypeId *generic_id = allocate<GenericFnTypeId>(1); 15468 generic_id->fn_entry = fn_entry; 15469 generic_id->param_count = 0; 15470 generic_id->params = create_const_vals(new_fn_arg_count); 15471 size_t next_proto_i = 0; 15472 15473 if (first_arg_ptr) { 15474 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 15475 15476 bool first_arg_known_bare = false; 15477 if (fn_type_id->next_param_index >= 1) { 15478 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 15479 if (type_is_invalid(param_type)) 15480 return ira->codegen->invalid_instruction; 15481 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 15482 } 15483 15484 IrInstruction *first_arg; 15485 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { 15486 first_arg = first_arg_ptr; 15487 } else { 15488 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); 15489 if (type_is_invalid(first_arg->value.type)) 15490 return ira->codegen->invalid_instruction; 15491 } 15492 15493 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, &impl_fn->child_scope, 15494 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 15495 { 15496 return ira->codegen->invalid_instruction; 15497 } 15498 } 15499 15500 bool found_first_var_arg = false; 15501 size_t first_var_arg; 15502 15503 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 15504 assert(parent_fn_entry); 15505 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 15506 IrInstruction *arg = call_instruction->args[call_i]->child; 15507 if (type_is_invalid(arg->value.type)) 15508 return ira->codegen->invalid_instruction; 15509 15510 if (arg->value.type->id == ZigTypeIdArgTuple) { 15511 for (size_t arg_tuple_i = arg->value.data.x_arg_tuple.start_index; 15512 arg_tuple_i < arg->value.data.x_arg_tuple.end_index; arg_tuple_i += 1) 15513 { 15514 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 15515 assert(param_decl_node->type == NodeTypeParamDecl); 15516 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 15517 if (is_var_args && !found_first_var_arg) { 15518 first_var_arg = inst_fn_type_id.param_count; 15519 found_first_var_arg = true; 15520 } 15521 15522 ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i); 15523 if (arg_var == nullptr) { 15524 ir_add_error(ira, arg, 15525 buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557")); 15526 return ira->codegen->invalid_instruction; 15527 } 15528 IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, arg, arg_var); 15529 if (type_is_invalid(arg_var_ptr_inst->value.type)) 15530 return ira->codegen->invalid_instruction; 15531 15532 IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst, nullptr); 15533 if (type_is_invalid(arg_tuple_arg->value.type)) 15534 return ira->codegen->invalid_instruction; 15535 15536 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg_tuple_arg, &impl_fn->child_scope, 15537 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 15538 { 15539 return ira->codegen->invalid_instruction; 15540 } 15541 } 15542 } else { 15543 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 15544 assert(param_decl_node->type == NodeTypeParamDecl); 15545 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 15546 if (is_var_args && !found_first_var_arg) { 15547 first_var_arg = inst_fn_type_id.param_count; 15548 found_first_var_arg = true; 15549 } 15550 15551 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope, 15552 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 15553 { 15554 return ira->codegen->invalid_instruction; 15555 } 15556 } 15557 } 15558 15559 if (fn_proto_node->data.fn_proto.is_var_args) { 15560 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 15561 Buf *param_name = param_decl_node->data.param_decl.name; 15562 15563 if (!found_first_var_arg) { 15564 first_var_arg = inst_fn_type_id.param_count; 15565 } 15566 15567 ConstExprValue *var_args_val = create_const_arg_tuple(ira->codegen, 15568 first_var_arg, inst_fn_type_id.param_count); 15569 ZigVar *var = add_variable(ira->codegen, param_decl_node, 15570 impl_fn->child_scope, param_name, true, var_args_val, nullptr, var_args_val->type); 15571 impl_fn->child_scope = var->child_scope; 15572 } 15573 15574 if (fn_proto_node->data.fn_proto.align_expr != nullptr) { 15575 ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, 15576 fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), 15577 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 15578 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); 15579 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 15580 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); 15581 copy_const_val(&const_instruction->base.value, align_result, true); 15582 15583 uint32_t align_bytes = 0; 15584 ir_resolve_align(ira, &const_instruction->base, &align_bytes); 15585 impl_fn->align_bytes = align_bytes; 15586 inst_fn_type_id.alignment = align_bytes; 15587 } 15588 15589 if (fn_proto_node->data.fn_proto.return_var_token == nullptr) { 15590 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 15591 ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node); 15592 if (type_is_invalid(specified_return_type)) 15593 return ira->codegen->invalid_instruction; 15594 if (fn_proto_node->data.fn_proto.auto_err_set) { 15595 ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn); 15596 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 15597 return ira->codegen->invalid_instruction; 15598 inst_fn_type_id.return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 15599 } else { 15600 inst_fn_type_id.return_type = specified_return_type; 15601 } 15602 15603 switch (type_requires_comptime(ira->codegen, specified_return_type)) { 15604 case ReqCompTimeYes: 15605 // Throw out our work and call the function as if it were comptime. 15606 return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, 15607 true, FnInlineAuto); 15608 case ReqCompTimeInvalid: 15609 return ira->codegen->invalid_instruction; 15610 case ReqCompTimeNo: 15611 break; 15612 } 15613 } 15614 15615 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn); 15616 if (existing_entry) { 15617 // throw away all our work and use the existing function 15618 impl_fn = existing_entry->value; 15619 } else { 15620 // finish instantiating the function 15621 impl_fn->type_entry = get_fn_type(ira->codegen, &inst_fn_type_id); 15622 if (type_is_invalid(impl_fn->type_entry)) 15623 return ira->codegen->invalid_instruction; 15624 15625 impl_fn->ir_executable.source_node = call_instruction->base.source_node; 15626 impl_fn->ir_executable.parent_exec = ira->new_irb.exec; 15627 impl_fn->analyzed_executable.source_node = call_instruction->base.source_node; 15628 impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; 15629 impl_fn->analyzed_executable.backward_branch_quota = ira->new_irb.exec->backward_branch_quota; 15630 impl_fn->analyzed_executable.is_generic_instantiation = true; 15631 15632 ira->codegen->fn_defs.append(impl_fn); 15633 } 15634 15635 FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; 15636 IrInstruction *result_loc; 15637 if (handle_is_ptr(impl_fn_type_id->return_type)) { 15638 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, 15639 impl_fn_type_id->return_type, nullptr, true, true, false); 15640 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || 15641 instr_is_unreachable(result_loc))) 15642 { 15643 return result_loc; 15644 } 15645 } else { 15646 result_loc = nullptr; 15647 } 15648 15649 if (fn_type_can_fail(impl_fn_type_id)) { 15650 parent_fn_entry->calls_or_awaits_errorable_fn = true; 15651 } 15652 15653 size_t impl_param_count = impl_fn_type_id->param_count; 15654 if (call_instruction->is_async) { 15655 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, 15656 nullptr, casted_args, impl_param_count, casted_new_stack); 15657 return ir_finish_anal(ira, result); 15658 } 15659 15660 if (impl_fn_type_id->cc == CallingConventionAsync && parent_fn_entry->inferred_async_node == nullptr) { 15661 parent_fn_entry->inferred_async_node = fn_ref->source_node; 15662 parent_fn_entry->inferred_async_fn = impl_fn; 15663 } 15664 15665 IrInstructionCallGen *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, 15666 impl_fn, nullptr, impl_param_count, casted_args, fn_inline, 15667 false, casted_new_stack, result_loc, 15668 impl_fn_type_id->return_type); 15669 15670 parent_fn_entry->call_list.append(new_call_instruction); 15671 15672 return ir_finish_anal(ira, &new_call_instruction->base); 15673 } 15674 15675 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 15676 assert(fn_type_id->return_type != nullptr); 15677 assert(parent_fn_entry != nullptr); 15678 if (fn_type_can_fail(fn_type_id)) { 15679 parent_fn_entry->calls_or_awaits_errorable_fn = true; 15680 } 15681 15682 15683 IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count); 15684 size_t next_arg_index = 0; 15685 if (first_arg_ptr) { 15686 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 15687 15688 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 15689 if (type_is_invalid(param_type)) 15690 return ira->codegen->invalid_instruction; 15691 15692 IrInstruction *first_arg; 15693 if (param_type->id == ZigTypeIdPointer && 15694 handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) 15695 { 15696 first_arg = first_arg_ptr; 15697 } else { 15698 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); 15699 if (type_is_invalid(first_arg->value.type)) 15700 return ira->codegen->invalid_instruction; 15701 } 15702 15703 IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type); 15704 if (type_is_invalid(casted_arg->value.type)) 15705 return ira->codegen->invalid_instruction; 15706 15707 casted_args[next_arg_index] = casted_arg; 15708 next_arg_index += 1; 15709 } 15710 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 15711 IrInstruction *old_arg = call_instruction->args[call_i]->child; 15712 if (type_is_invalid(old_arg->value.type)) 15713 return ira->codegen->invalid_instruction; 15714 15715 if (old_arg->value.type->id == ZigTypeIdArgTuple) { 15716 for (size_t arg_tuple_i = old_arg->value.data.x_arg_tuple.start_index; 15717 arg_tuple_i < old_arg->value.data.x_arg_tuple.end_index; arg_tuple_i += 1) 15718 { 15719 ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i); 15720 if (arg_var == nullptr) { 15721 ir_add_error(ira, old_arg, 15722 buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557")); 15723 return ira->codegen->invalid_instruction; 15724 } 15725 IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, old_arg, arg_var); 15726 if (type_is_invalid(arg_var_ptr_inst->value.type)) 15727 return ira->codegen->invalid_instruction; 15728 15729 IrInstruction *arg_tuple_arg = ir_get_deref(ira, old_arg, arg_var_ptr_inst, nullptr); 15730 if (type_is_invalid(arg_tuple_arg->value.type)) 15731 return ira->codegen->invalid_instruction; 15732 15733 IrInstruction *casted_arg; 15734 if (next_arg_index < src_param_count) { 15735 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 15736 if (type_is_invalid(param_type)) 15737 return ira->codegen->invalid_instruction; 15738 casted_arg = ir_implicit_cast(ira, arg_tuple_arg, param_type); 15739 if (type_is_invalid(casted_arg->value.type)) 15740 return ira->codegen->invalid_instruction; 15741 } else { 15742 casted_arg = arg_tuple_arg; 15743 } 15744 15745 casted_args[next_arg_index] = casted_arg; 15746 next_arg_index += 1; 15747 } 15748 } else { 15749 IrInstruction *casted_arg; 15750 if (next_arg_index < src_param_count) { 15751 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 15752 if (type_is_invalid(param_type)) 15753 return ira->codegen->invalid_instruction; 15754 casted_arg = ir_implicit_cast(ira, old_arg, param_type); 15755 if (type_is_invalid(casted_arg->value.type)) 15756 return ira->codegen->invalid_instruction; 15757 } else { 15758 casted_arg = old_arg; 15759 } 15760 15761 casted_args[next_arg_index] = casted_arg; 15762 next_arg_index += 1; 15763 } 15764 } 15765 15766 assert(next_arg_index == call_param_count); 15767 15768 ZigType *return_type = fn_type_id->return_type; 15769 if (type_is_invalid(return_type)) 15770 return ira->codegen->invalid_instruction; 15771 15772 if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) { 15773 ir_add_error(ira, &call_instruction->base, 15774 buf_sprintf("no-inline call of inline function")); 15775 return ira->codegen->invalid_instruction; 15776 } 15777 15778 if (call_instruction->is_async) { 15779 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, 15780 casted_args, call_param_count, casted_new_stack); 15781 return ir_finish_anal(ira, result); 15782 } 15783 15784 if (fn_type_id->cc == CallingConventionAsync && parent_fn_entry->inferred_async_node == nullptr) { 15785 parent_fn_entry->inferred_async_node = fn_ref->source_node; 15786 parent_fn_entry->inferred_async_fn = fn_entry; 15787 } 15788 15789 IrInstruction *result_loc; 15790 if (handle_is_ptr(return_type)) { 15791 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, 15792 return_type, nullptr, true, true, false); 15793 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { 15794 return result_loc; 15795 } 15796 } else { 15797 result_loc = nullptr; 15798 } 15799 15800 IrInstructionCallGen *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, 15801 call_param_count, casted_args, fn_inline, false, casted_new_stack, 15802 result_loc, return_type); 15803 parent_fn_entry->call_list.append(new_call_instruction); 15804 return ir_finish_anal(ira, &new_call_instruction->base); 15805 } 15806 15807 static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) { 15808 IrInstruction *fn_ref = call_instruction->fn_ref->child; 15809 if (type_is_invalid(fn_ref->value.type)) 15810 return ira->codegen->invalid_instruction; 15811 15812 bool is_comptime = call_instruction->is_comptime || 15813 ir_should_inline(ira->new_irb.exec, call_instruction->base.scope); 15814 15815 if (is_comptime || instr_is_comptime(fn_ref)) { 15816 if (fn_ref->value.type->id == ZigTypeIdMetaType) { 15817 ZigType *dest_type = ir_resolve_type(ira, fn_ref); 15818 if (type_is_invalid(dest_type)) 15819 return ira->codegen->invalid_instruction; 15820 15821 size_t actual_param_count = call_instruction->arg_count; 15822 15823 if (actual_param_count != 1) { 15824 ir_add_error_node(ira, call_instruction->base.source_node, 15825 buf_sprintf("cast expression expects exactly one parameter")); 15826 return ira->codegen->invalid_instruction; 15827 } 15828 15829 IrInstruction *arg = call_instruction->args[0]->child; 15830 15831 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg, 15832 call_instruction->result_loc); 15833 if (type_is_invalid(cast_instruction->value.type)) 15834 return ira->codegen->invalid_instruction; 15835 return ir_finish_anal(ira, cast_instruction); 15836 } else if (fn_ref->value.type->id == ZigTypeIdFn) { 15837 ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); 15838 if (fn_table_entry == nullptr) 15839 return ira->codegen->invalid_instruction; 15840 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 15841 fn_ref, nullptr, is_comptime, call_instruction->fn_inline); 15842 } else if (fn_ref->value.type->id == ZigTypeIdBoundFn) { 15843 assert(fn_ref->value.special == ConstValSpecialStatic); 15844 ZigFn *fn_table_entry = fn_ref->value.data.x_bound_fn.fn; 15845 IrInstruction *first_arg_ptr = fn_ref->value.data.x_bound_fn.first_arg; 15846 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 15847 fn_ref, first_arg_ptr, is_comptime, call_instruction->fn_inline); 15848 } else { 15849 ir_add_error_node(ira, fn_ref->source_node, 15850 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value.type->name))); 15851 return ira->codegen->invalid_instruction; 15852 } 15853 } 15854 15855 if (fn_ref->value.type->id == ZigTypeIdFn) { 15856 return ir_analyze_fn_call(ira, call_instruction, nullptr, fn_ref->value.type, 15857 fn_ref, nullptr, false, FnInlineAuto); 15858 } else { 15859 ir_add_error_node(ira, fn_ref->source_node, 15860 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value.type->name))); 15861 return ira->codegen->invalid_instruction; 15862 } 15863 } 15864 15865 // out_val->type must be the type to read the pointer as 15866 // if the type is different than the actual type then it does a comptime byte reinterpretation 15867 static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 15868 ConstExprValue *out_val, ConstExprValue *ptr_val) 15869 { 15870 Error err; 15871 assert(out_val->type != nullptr); 15872 15873 ConstExprValue *pointee = const_ptr_pointee_unchecked(codegen, ptr_val); 15874 15875 if ((err = type_resolve(codegen, pointee->type, ResolveStatusSizeKnown))) 15876 return ErrorSemanticAnalyzeFail; 15877 if ((err = type_resolve(codegen, out_val->type, ResolveStatusSizeKnown))) 15878 return ErrorSemanticAnalyzeFail; 15879 15880 size_t src_size = type_size(codegen, pointee->type); 15881 size_t dst_size = type_size(codegen, out_val->type); 15882 15883 if (dst_size <= src_size) { 15884 if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { 15885 copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar); 15886 return ErrorNone; 15887 } 15888 Buf buf = BUF_INIT; 15889 buf_resize(&buf, src_size); 15890 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf), pointee); 15891 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 15892 return err; 15893 return ErrorNone; 15894 } 15895 15896 switch (ptr_val->data.x_ptr.special) { 15897 case ConstPtrSpecialInvalid: 15898 zig_unreachable(); 15899 case ConstPtrSpecialNull: 15900 if (dst_size == 0) 15901 return ErrorNone; 15902 opt_ir_add_error_node(ira, codegen, source_node, 15903 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from null pointer", 15904 dst_size)); 15905 return ErrorSemanticAnalyzeFail; 15906 case ConstPtrSpecialRef: { 15907 opt_ir_add_error_node(ira, codegen, source_node, 15908 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from pointer to %s which is %" ZIG_PRI_usize " bytes", 15909 dst_size, buf_ptr(&pointee->type->name), src_size)); 15910 return ErrorSemanticAnalyzeFail; 15911 } 15912 case ConstPtrSpecialBaseArray: { 15913 ConstExprValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val; 15914 assert(array_val->type->id == ZigTypeIdArray); 15915 if (array_val->data.x_array.special != ConstArraySpecialNone) 15916 zig_panic("TODO"); 15917 size_t elem_size = src_size; 15918 size_t elem_index = ptr_val->data.x_ptr.data.base_array.elem_index; 15919 src_size = elem_size * (array_val->type->data.array.len - elem_index); 15920 if (dst_size > src_size) { 15921 opt_ir_add_error_node(ira, codegen, source_node, 15922 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from %s at index %" ZIG_PRI_usize " which is %" ZIG_PRI_usize " bytes", 15923 dst_size, buf_ptr(&array_val->type->name), elem_index, src_size)); 15924 return ErrorSemanticAnalyzeFail; 15925 } 15926 size_t elem_count = (dst_size % elem_size == 0) ? (dst_size / elem_size) : (dst_size / elem_size + 1); 15927 Buf buf = BUF_INIT; 15928 buf_resize(&buf, elem_count * elem_size); 15929 for (size_t i = 0; i < elem_count; i += 1) { 15930 ConstExprValue *elem_val = &array_val->data.x_array.data.s_none.elements[elem_index + i]; 15931 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); 15932 } 15933 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 15934 return err; 15935 return ErrorNone; 15936 } 15937 case ConstPtrSpecialBaseStruct: 15938 case ConstPtrSpecialBaseErrorUnionCode: 15939 case ConstPtrSpecialBaseErrorUnionPayload: 15940 case ConstPtrSpecialBaseOptionalPayload: 15941 case ConstPtrSpecialDiscard: 15942 case ConstPtrSpecialHardCodedAddr: 15943 case ConstPtrSpecialFunction: 15944 zig_panic("TODO"); 15945 } 15946 zig_unreachable(); 15947 } 15948 15949 static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { 15950 Error err; 15951 IrInstruction *value = un_op_instruction->value->child; 15952 ZigType *type_entry = ir_resolve_type(ira, value); 15953 if (type_is_invalid(type_entry)) 15954 return ira->codegen->invalid_instruction; 15955 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 15956 return ira->codegen->invalid_instruction; 15957 15958 switch (type_entry->id) { 15959 case ZigTypeIdInvalid: 15960 zig_unreachable(); 15961 case ZigTypeIdMetaType: 15962 case ZigTypeIdVoid: 15963 case ZigTypeIdBool: 15964 case ZigTypeIdInt: 15965 case ZigTypeIdVector: 15966 case ZigTypeIdFloat: 15967 case ZigTypeIdPointer: 15968 case ZigTypeIdArray: 15969 case ZigTypeIdStruct: 15970 case ZigTypeIdComptimeFloat: 15971 case ZigTypeIdComptimeInt: 15972 case ZigTypeIdEnumLiteral: 15973 case ZigTypeIdUndefined: 15974 case ZigTypeIdNull: 15975 case ZigTypeIdOptional: 15976 case ZigTypeIdErrorUnion: 15977 case ZigTypeIdErrorSet: 15978 case ZigTypeIdEnum: 15979 case ZigTypeIdUnion: 15980 case ZigTypeIdFn: 15981 case ZigTypeIdBoundFn: 15982 case ZigTypeIdArgTuple: 15983 case ZigTypeIdFnFrame: 15984 case ZigTypeIdAnyFrame: 15985 return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry)); 15986 15987 case ZigTypeIdUnreachable: 15988 case ZigTypeIdOpaque: 15989 ir_add_error_node(ira, un_op_instruction->base.source_node, 15990 buf_sprintf("type '%s' not optional", buf_ptr(&type_entry->name))); 15991 return ira->codegen->invalid_instruction; 15992 } 15993 zig_unreachable(); 15994 } 15995 15996 static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *scalar_type, 15997 ConstExprValue *operand_val, ConstExprValue *scalar_out_val, bool is_wrap_op) 15998 { 15999 bool is_float = (scalar_type->id == ZigTypeIdFloat || scalar_type->id == ZigTypeIdComptimeFloat); 16000 16001 bool ok_type = ((scalar_type->id == ZigTypeIdInt && scalar_type->data.integral.is_signed) || 16002 scalar_type->id == ZigTypeIdComptimeInt || (is_float && !is_wrap_op)); 16003 16004 if (!ok_type) { 16005 const char *fmt = is_wrap_op ? "invalid wrapping negation type: '%s'" : "invalid negation type: '%s'"; 16006 return ir_add_error(ira, source_instr, buf_sprintf(fmt, buf_ptr(&scalar_type->name))); 16007 } 16008 16009 if (is_float) { 16010 float_negate(scalar_out_val, operand_val); 16011 } else if (is_wrap_op) { 16012 bigint_negate_wrap(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint, 16013 scalar_type->data.integral.bit_count); 16014 } else { 16015 bigint_negate(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint); 16016 } 16017 16018 scalar_out_val->type = scalar_type; 16019 scalar_out_val->special = ConstValSpecialStatic; 16020 16021 if (is_wrap_op || is_float || scalar_type->id == ZigTypeIdComptimeInt) { 16022 return nullptr; 16023 } 16024 16025 if (!bigint_fits_in_bits(&scalar_out_val->data.x_bigint, scalar_type->data.integral.bit_count, true)) { 16026 return ir_add_error(ira, source_instr, buf_sprintf("negation caused overflow")); 16027 } 16028 return nullptr; 16029 } 16030 16031 static IrInstruction *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *instruction) { 16032 IrInstruction *value = instruction->value->child; 16033 ZigType *expr_type = value->value.type; 16034 if (type_is_invalid(expr_type)) 16035 return ira->codegen->invalid_instruction; 16036 16037 bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap); 16038 16039 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 16040 16041 if (instr_is_comptime(value)) { 16042 ConstExprValue *operand_val = ir_resolve_const(ira, value, UndefBad); 16043 if (!operand_val) 16044 return ira->codegen->invalid_instruction; 16045 16046 IrInstruction *result_instruction = ir_const(ira, &instruction->base, expr_type); 16047 ConstExprValue *out_val = &result_instruction->value; 16048 if (expr_type->id == ZigTypeIdVector) { 16049 expand_undef_array(ira->codegen, operand_val); 16050 out_val->special = ConstValSpecialUndef; 16051 expand_undef_array(ira->codegen, out_val); 16052 size_t len = expr_type->data.vector.len; 16053 for (size_t i = 0; i < len; i += 1) { 16054 ConstExprValue *scalar_operand_val = &operand_val->data.x_array.data.s_none.elements[i]; 16055 ConstExprValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 16056 assert(scalar_operand_val->type == scalar_type); 16057 assert(scalar_out_val->type == scalar_type); 16058 ErrorMsg *msg = ir_eval_negation_scalar(ira, &instruction->base, scalar_type, 16059 scalar_operand_val, scalar_out_val, is_wrap_op); 16060 if (msg != nullptr) { 16061 add_error_note(ira->codegen, msg, instruction->base.source_node, 16062 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 16063 return ira->codegen->invalid_instruction; 16064 } 16065 } 16066 out_val->type = expr_type; 16067 out_val->special = ConstValSpecialStatic; 16068 } else { 16069 if (ir_eval_negation_scalar(ira, &instruction->base, scalar_type, operand_val, out_val, 16070 is_wrap_op) != nullptr) 16071 { 16072 return ira->codegen->invalid_instruction; 16073 } 16074 } 16075 return result_instruction; 16076 } 16077 16078 IrInstruction *result = ir_build_un_op(&ira->new_irb, 16079 instruction->base.scope, instruction->base.source_node, 16080 instruction->op_id, value); 16081 result->value.type = expr_type; 16082 return result; 16083 } 16084 16085 static IrInstruction *ir_analyze_bin_not(IrAnalyze *ira, IrInstructionUnOp *instruction) { 16086 IrInstruction *value = instruction->value->child; 16087 ZigType *expr_type = value->value.type; 16088 if (type_is_invalid(expr_type)) 16089 return ira->codegen->invalid_instruction; 16090 16091 if (expr_type->id == ZigTypeIdInt) { 16092 if (instr_is_comptime(value)) { 16093 ConstExprValue *target_const_val = ir_resolve_const(ira, value, UndefBad); 16094 if (target_const_val == nullptr) 16095 return ira->codegen->invalid_instruction; 16096 16097 IrInstruction *result = ir_const(ira, &instruction->base, expr_type); 16098 bigint_not(&result->value.data.x_bigint, &target_const_val->data.x_bigint, 16099 expr_type->data.integral.bit_count, expr_type->data.integral.is_signed); 16100 return result; 16101 } 16102 16103 IrInstruction *result = ir_build_un_op(&ira->new_irb, instruction->base.scope, 16104 instruction->base.source_node, IrUnOpBinNot, value); 16105 result->value.type = expr_type; 16106 return result; 16107 } 16108 16109 ir_add_error(ira, &instruction->base, 16110 buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name))); 16111 return ira->codegen->invalid_instruction; 16112 } 16113 16114 static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *instruction) { 16115 IrUnOp op_id = instruction->op_id; 16116 switch (op_id) { 16117 case IrUnOpInvalid: 16118 zig_unreachable(); 16119 case IrUnOpBinNot: 16120 return ir_analyze_bin_not(ira, instruction); 16121 case IrUnOpNegation: 16122 case IrUnOpNegationWrap: 16123 return ir_analyze_negation(ira, instruction); 16124 case IrUnOpDereference: { 16125 IrInstruction *ptr = instruction->value->child; 16126 if (type_is_invalid(ptr->value.type)) 16127 return ira->codegen->invalid_instruction; 16128 ZigType *ptr_type = ptr->value.type; 16129 if (ptr_type->id == ZigTypeIdPointer && ptr_type->data.pointer.ptr_len == PtrLenUnknown) { 16130 ir_add_error_node(ira, instruction->base.source_node, 16131 buf_sprintf("index syntax required for unknown-length pointer type '%s'", 16132 buf_ptr(&ptr_type->name))); 16133 return ira->codegen->invalid_instruction; 16134 } 16135 16136 IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr, instruction->result_loc); 16137 if (result == ira->codegen->invalid_instruction) 16138 return ira->codegen->invalid_instruction; 16139 16140 // If the result needs to be an lvalue, type check it 16141 if (instruction->lval == LValPtr && result->value.type->id != ZigTypeIdPointer) { 16142 ir_add_error(ira, &instruction->base, 16143 buf_sprintf("attempt to dereference non-pointer type '%s'", buf_ptr(&result->value.type->name))); 16144 return ira->codegen->invalid_instruction; 16145 } 16146 16147 return result; 16148 } 16149 case IrUnOpOptional: 16150 return ir_analyze_optional_type(ira, instruction); 16151 } 16152 zig_unreachable(); 16153 } 16154 16155 static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) { 16156 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index); 16157 if (old_bb->in_resume_stack) return; 16158 ira->resume_stack.append(pos); 16159 old_bb->in_resume_stack = true; 16160 } 16161 16162 static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlock *old_bb) { 16163 if (ira->resume_stack.length != 0) { 16164 ir_push_resume(ira, {old_bb->index, 0}); 16165 } 16166 } 16167 16168 static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { 16169 IrBasicBlock *old_dest_block = br_instruction->dest_block; 16170 16171 bool is_comptime; 16172 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) 16173 return ir_unreach_error(ira); 16174 16175 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) 16176 return ir_inline_bb(ira, &br_instruction->base, old_dest_block); 16177 16178 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); 16179 if (new_bb == nullptr) 16180 return ir_unreach_error(ira); 16181 16182 ir_push_resume_block(ira, old_dest_block); 16183 16184 IrInstruction *result = ir_build_br(&ira->new_irb, 16185 br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); 16186 result->value.type = ira->codegen->builtin_types.entry_unreachable; 16187 return ir_finish_anal(ira, result); 16188 } 16189 16190 static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) { 16191 IrInstruction *condition = cond_br_instruction->condition->child; 16192 if (type_is_invalid(condition->value.type)) 16193 return ir_unreach_error(ira); 16194 16195 bool is_comptime; 16196 if (!ir_resolve_comptime(ira, cond_br_instruction->is_comptime->child, &is_comptime)) 16197 return ir_unreach_error(ira); 16198 16199 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 16200 IrInstruction *casted_condition = ir_implicit_cast(ira, condition, bool_type); 16201 if (type_is_invalid(casted_condition->value.type)) 16202 return ir_unreach_error(ira); 16203 16204 if (is_comptime || instr_is_comptime(casted_condition)) { 16205 bool cond_is_true; 16206 if (!ir_resolve_bool(ira, casted_condition, &cond_is_true)) 16207 return ir_unreach_error(ira); 16208 16209 IrBasicBlock *old_dest_block = cond_is_true ? 16210 cond_br_instruction->then_block : cond_br_instruction->else_block; 16211 16212 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) 16213 return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); 16214 16215 IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); 16216 if (new_dest_block == nullptr) 16217 return ir_unreach_error(ira); 16218 16219 ir_push_resume_block(ira, old_dest_block); 16220 16221 IrInstruction *result = ir_build_br(&ira->new_irb, 16222 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); 16223 result->value.type = ira->codegen->builtin_types.entry_unreachable; 16224 return ir_finish_anal(ira, result); 16225 } 16226 16227 assert(cond_br_instruction->then_block != cond_br_instruction->else_block); 16228 IrBasicBlock *new_then_block = ir_get_new_bb_runtime(ira, cond_br_instruction->then_block, &cond_br_instruction->base); 16229 if (new_then_block == nullptr) 16230 return ir_unreach_error(ira); 16231 16232 IrBasicBlock *new_else_block = ir_get_new_bb_runtime(ira, cond_br_instruction->else_block, &cond_br_instruction->base); 16233 if (new_else_block == nullptr) 16234 return ir_unreach_error(ira); 16235 16236 ir_push_resume_block(ira, cond_br_instruction->else_block); 16237 ir_push_resume_block(ira, cond_br_instruction->then_block); 16238 16239 IrInstruction *result = ir_build_cond_br(&ira->new_irb, 16240 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, 16241 casted_condition, new_then_block, new_else_block, nullptr); 16242 result->value.type = ira->codegen->builtin_types.entry_unreachable; 16243 return ir_finish_anal(ira, result); 16244 } 16245 16246 static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira, 16247 IrInstructionUnreachable *unreachable_instruction) 16248 { 16249 IrInstruction *result = ir_build_unreachable(&ira->new_irb, 16250 unreachable_instruction->base.scope, unreachable_instruction->base.source_node); 16251 result->value.type = ira->codegen->builtin_types.entry_unreachable; 16252 return ir_finish_anal(ira, result); 16253 } 16254 16255 static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) { 16256 if (ira->const_predecessor_bb) { 16257 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 16258 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; 16259 if (predecessor != ira->const_predecessor_bb) 16260 continue; 16261 IrInstruction *value = phi_instruction->incoming_values[i]->child; 16262 assert(value->value.type); 16263 if (type_is_invalid(value->value.type)) 16264 return ira->codegen->invalid_instruction; 16265 16266 if (value->value.special != ConstValSpecialRuntime) { 16267 IrInstruction *result = ir_const(ira, &phi_instruction->base, nullptr); 16268 copy_const_val(&result->value, &value->value, true); 16269 return result; 16270 } else { 16271 return value; 16272 } 16273 } 16274 zig_unreachable(); 16275 } 16276 16277 ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; 16278 if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming && 16279 peer_parent->peers.length >= 2) 16280 { 16281 if (peer_parent->resolved_type == nullptr) { 16282 IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peers.length); 16283 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 16284 ResultLocPeer *this_peer = peer_parent->peers.at(i); 16285 16286 IrInstruction *gen_instruction = this_peer->base.gen_instruction; 16287 if (gen_instruction == nullptr) { 16288 // unreachable instructions will cause implicit_elem_type to be null 16289 if (this_peer->base.implicit_elem_type == nullptr) { 16290 instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction); 16291 } else { 16292 instructions[i] = ir_const(ira, this_peer->base.source_instruction, 16293 this_peer->base.implicit_elem_type); 16294 instructions[i]->value.special = ConstValSpecialRuntime; 16295 } 16296 } else { 16297 instructions[i] = gen_instruction; 16298 } 16299 16300 } 16301 ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent); 16302 peer_parent->resolved_type = ir_resolve_peer_types(ira, 16303 peer_parent->base.source_instruction->source_node, expected_type, instructions, 16304 peer_parent->peers.length); 16305 16306 // the logic below assumes there are no instructions in the new current basic block yet 16307 ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base); 16308 16309 // In case resolving the parent activates a suspend, do it now 16310 IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent, 16311 peer_parent->resolved_type, nullptr, false, false, true); 16312 if (parent_result_loc != nullptr && 16313 (type_is_invalid(parent_result_loc->value.type) || instr_is_unreachable(parent_result_loc))) 16314 { 16315 return parent_result_loc; 16316 } 16317 // If the above code generated any instructions in the current basic block, we need 16318 // to move them to the peer parent predecessor. 16319 ZigList<IrInstruction *> instrs_to_move = {}; 16320 while (ira->new_irb.current_basic_block->instruction_list.length != 0) { 16321 instrs_to_move.append(ira->new_irb.current_basic_block->instruction_list.pop()); 16322 } 16323 if (instrs_to_move.length != 0) { 16324 IrBasicBlock *predecessor = peer_parent->base.source_instruction->child->owner_bb; 16325 IrInstruction *branch_instruction = predecessor->instruction_list.pop(); 16326 ir_assert(branch_instruction->value.type->id == ZigTypeIdUnreachable, &phi_instruction->base); 16327 while (instrs_to_move.length != 0) { 16328 predecessor->instruction_list.append(instrs_to_move.pop()); 16329 } 16330 predecessor->instruction_list.append(branch_instruction); 16331 } 16332 } 16333 16334 IrSuspendPosition suspend_pos; 16335 ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); 16336 ir_push_resume(ira, suspend_pos); 16337 16338 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 16339 ResultLocPeer *opposite_peer = peer_parent->peers.at(peer_parent->peers.length - i - 1); 16340 if (opposite_peer->base.implicit_elem_type != nullptr && 16341 opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) 16342 { 16343 ir_push_resume(ira, opposite_peer->suspend_pos); 16344 } 16345 } 16346 16347 peer_parent->done_resuming = true; 16348 return ira_resume(ira); 16349 } 16350 16351 ZigList<IrBasicBlock*> new_incoming_blocks = {0}; 16352 ZigList<IrInstruction*> new_incoming_values = {0}; 16353 16354 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 16355 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; 16356 if (predecessor->ref_count == 0) 16357 continue; 16358 16359 16360 IrInstruction *old_value = phi_instruction->incoming_values[i]; 16361 assert(old_value); 16362 IrInstruction *new_value = old_value->child; 16363 if (!new_value || new_value->value.type->id == ZigTypeIdUnreachable || predecessor->other == nullptr) 16364 continue; 16365 16366 if (type_is_invalid(new_value->value.type)) 16367 return ira->codegen->invalid_instruction; 16368 16369 16370 assert(predecessor->other); 16371 new_incoming_blocks.append(predecessor->other); 16372 new_incoming_values.append(new_value); 16373 } 16374 16375 if (new_incoming_blocks.length == 0) { 16376 IrInstruction *result = ir_build_unreachable(&ira->new_irb, 16377 phi_instruction->base.scope, phi_instruction->base.source_node); 16378 result->value.type = ira->codegen->builtin_types.entry_unreachable; 16379 return ir_finish_anal(ira, result); 16380 } 16381 16382 if (new_incoming_blocks.length == 1) { 16383 return new_incoming_values.at(0); 16384 } 16385 16386 ZigType *resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, 16387 new_incoming_values.items, new_incoming_values.length); 16388 if (type_is_invalid(resolved_type)) 16389 return ira->codegen->invalid_instruction; 16390 16391 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 16392 case OnePossibleValueInvalid: 16393 return ira->codegen->invalid_instruction; 16394 case OnePossibleValueYes: 16395 return ir_const(ira, &phi_instruction->base, resolved_type); 16396 case OnePossibleValueNo: 16397 break; 16398 } 16399 16400 switch (type_requires_comptime(ira->codegen, resolved_type)) { 16401 case ReqCompTimeInvalid: 16402 return ira->codegen->invalid_instruction; 16403 case ReqCompTimeYes: 16404 ir_add_error_node(ira, phi_instruction->base.source_node, 16405 buf_sprintf("values of type '%s' must be comptime known", buf_ptr(&resolved_type->name))); 16406 return ira->codegen->invalid_instruction; 16407 case ReqCompTimeNo: 16408 break; 16409 } 16410 16411 bool all_stack_ptrs = (resolved_type->id == ZigTypeIdPointer); 16412 16413 // cast all values to the resolved type. however we can't put cast instructions in front of the phi instruction. 16414 // so we go back and insert the casts as the last instruction in the corresponding predecessor blocks, and 16415 // then make sure the branch instruction is preserved. 16416 IrBasicBlock *cur_bb = ira->new_irb.current_basic_block; 16417 for (size_t i = 0; i < new_incoming_values.length; i += 1) { 16418 IrInstruction *new_value = new_incoming_values.at(i); 16419 IrBasicBlock *predecessor = new_incoming_blocks.at(i); 16420 ir_assert(predecessor->instruction_list.length != 0, &phi_instruction->base); 16421 IrInstruction *branch_instruction = predecessor->instruction_list.pop(); 16422 ir_set_cursor_at_end(&ira->new_irb, predecessor); 16423 IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); 16424 if (type_is_invalid(casted_value->value.type)) { 16425 return ira->codegen->invalid_instruction; 16426 } 16427 new_incoming_values.items[i] = casted_value; 16428 predecessor->instruction_list.append(branch_instruction); 16429 16430 if (all_stack_ptrs && (casted_value->value.special != ConstValSpecialRuntime || 16431 casted_value->value.data.rh_ptr != RuntimeHintPtrStack)) 16432 { 16433 all_stack_ptrs = false; 16434 } 16435 } 16436 ir_set_cursor_at_end(&ira->new_irb, cur_bb); 16437 16438 IrInstruction *result = ir_build_phi(&ira->new_irb, 16439 phi_instruction->base.scope, phi_instruction->base.source_node, 16440 new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, nullptr); 16441 result->value.type = resolved_type; 16442 16443 if (all_stack_ptrs) { 16444 assert(result->value.special == ConstValSpecialRuntime); 16445 result->value.data.rh_ptr = RuntimeHintPtrStack; 16446 } 16447 16448 return result; 16449 } 16450 16451 static IrInstruction *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *instruction) { 16452 ZigVar *var = instruction->var; 16453 IrInstruction *result = ir_get_var_ptr(ira, &instruction->base, var); 16454 if (instruction->crossed_fndef_scope != nullptr && !instr_is_comptime(result)) { 16455 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 16456 buf_sprintf("'%s' not accessible from inner function", buf_ptr(&var->name))); 16457 add_error_note(ira->codegen, msg, instruction->crossed_fndef_scope->base.source_node, 16458 buf_sprintf("crossed function definition here")); 16459 add_error_note(ira->codegen, msg, var->decl_node, 16460 buf_sprintf("declared here")); 16461 return ira->codegen->invalid_instruction; 16462 } 16463 return result; 16464 } 16465 16466 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align) { 16467 assert(ptr_type->id == ZigTypeIdPointer); 16468 return get_pointer_to_type_extra(g, 16469 ptr_type->data.pointer.child_type, 16470 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 16471 ptr_type->data.pointer.ptr_len, 16472 new_align, 16473 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 16474 ptr_type->data.pointer.allow_zero); 16475 } 16476 16477 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) { 16478 assert(is_slice(slice_type)); 16479 ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index].type_entry, 16480 new_align); 16481 return get_slice_type(g, ptr_type); 16482 } 16483 16484 static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) { 16485 assert(ptr_type->id == ZigTypeIdPointer); 16486 return get_pointer_to_type_extra(g, 16487 ptr_type->data.pointer.child_type, 16488 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 16489 ptr_len, 16490 ptr_type->data.pointer.explicit_alignment, 16491 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 16492 ptr_type->data.pointer.allow_zero); 16493 } 16494 16495 static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { 16496 Error err; 16497 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->child; 16498 if (type_is_invalid(array_ptr->value.type)) 16499 return ira->codegen->invalid_instruction; 16500 16501 ConstExprValue *orig_array_ptr_val = &array_ptr->value; 16502 16503 IrInstruction *elem_index = elem_ptr_instruction->elem_index->child; 16504 if (type_is_invalid(elem_index->value.type)) 16505 return ira->codegen->invalid_instruction; 16506 16507 ZigType *ptr_type = orig_array_ptr_val->type; 16508 assert(ptr_type->id == ZigTypeIdPointer); 16509 16510 ZigType *array_type = ptr_type->data.pointer.child_type; 16511 16512 // At first return_type will be the pointer type we want to return, except with an optimistic alignment. 16513 // We will adjust return_type's alignment before returning it. 16514 ZigType *return_type; 16515 16516 if (type_is_invalid(array_type)) { 16517 return ira->codegen->invalid_instruction; 16518 } else if (array_type->id == ZigTypeIdArray || 16519 (array_type->id == ZigTypeIdPointer && 16520 array_type->data.pointer.ptr_len == PtrLenSingle && 16521 array_type->data.pointer.child_type->id == ZigTypeIdArray)) 16522 { 16523 if (array_type->id == ZigTypeIdPointer) { 16524 array_type = array_type->data.pointer.child_type; 16525 ptr_type = ptr_type->data.pointer.child_type; 16526 if (orig_array_ptr_val->special != ConstValSpecialRuntime) { 16527 orig_array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val, 16528 elem_ptr_instruction->base.source_node); 16529 if (orig_array_ptr_val == nullptr) 16530 return ira->codegen->invalid_instruction; 16531 } 16532 } 16533 if (array_type->data.array.len == 0) { 16534 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 16535 buf_sprintf("index 0 outside array of size 0")); 16536 return ira->codegen->invalid_instruction; 16537 } 16538 ZigType *child_type = array_type->data.array.child_type; 16539 if (ptr_type->data.pointer.host_int_bytes == 0) { 16540 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 16541 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 16542 elem_ptr_instruction->ptr_len, 16543 ptr_type->data.pointer.explicit_alignment, 0, 0, false); 16544 } else { 16545 uint64_t elem_val_scalar; 16546 if (!ir_resolve_usize(ira, elem_index, &elem_val_scalar)) 16547 return ira->codegen->invalid_instruction; 16548 16549 size_t bit_width = type_size_bits(ira->codegen, child_type); 16550 size_t bit_offset = bit_width * elem_val_scalar; 16551 16552 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 16553 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 16554 elem_ptr_instruction->ptr_len, 16555 1, (uint32_t)bit_offset, ptr_type->data.pointer.host_int_bytes, false); 16556 } 16557 } else if (array_type->id == ZigTypeIdPointer) { 16558 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 16559 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 16560 buf_sprintf("index of single-item pointer")); 16561 return ira->codegen->invalid_instruction; 16562 } 16563 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len); 16564 } else if (is_slice(array_type)) { 16565 return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index].type_entry, 16566 elem_ptr_instruction->ptr_len); 16567 } else if (array_type->id == ZigTypeIdArgTuple) { 16568 ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); 16569 if (!ptr_val) 16570 return ira->codegen->invalid_instruction; 16571 ConstExprValue *args_val = const_ptr_pointee(ira, ira->codegen, ptr_val, elem_ptr_instruction->base.source_node); 16572 if (args_val == nullptr) 16573 return ira->codegen->invalid_instruction; 16574 size_t start = args_val->data.x_arg_tuple.start_index; 16575 size_t end = args_val->data.x_arg_tuple.end_index; 16576 uint64_t elem_index_val; 16577 if (!ir_resolve_usize(ira, elem_index, &elem_index_val)) 16578 return ira->codegen->invalid_instruction; 16579 size_t index = elem_index_val; 16580 size_t len = end - start; 16581 if (index >= len) { 16582 ir_add_error(ira, &elem_ptr_instruction->base, 16583 buf_sprintf("index %" ZIG_PRI_usize " outside argument list of size %" ZIG_PRI_usize "", index, len)); 16584 return ira->codegen->invalid_instruction; 16585 } 16586 size_t abs_index = start + index; 16587 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 16588 assert(fn_entry); 16589 ZigVar *var = get_fn_var_by_index(fn_entry, abs_index); 16590 bool is_const = true; 16591 bool is_volatile = false; 16592 if (var) { 16593 return ir_get_var_ptr(ira, &elem_ptr_instruction->base, var); 16594 } else { 16595 return ir_get_const_ptr(ira, &elem_ptr_instruction->base, &ira->codegen->const_void_val, 16596 ira->codegen->builtin_types.entry_void, ConstPtrMutComptimeConst, is_const, is_volatile, 0); 16597 } 16598 } else { 16599 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 16600 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name))); 16601 return ira->codegen->invalid_instruction; 16602 } 16603 16604 ZigType *usize = ira->codegen->builtin_types.entry_usize; 16605 IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 16606 if (casted_elem_index == ira->codegen->invalid_instruction) 16607 return ira->codegen->invalid_instruction; 16608 16609 bool safety_check_on = elem_ptr_instruction->safety_check_on; 16610 if ((err = ensure_complete_type(ira->codegen, return_type->data.pointer.child_type))) 16611 return ira->codegen->invalid_instruction; 16612 16613 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); 16614 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); 16615 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type); 16616 if (instr_is_comptime(casted_elem_index)) { 16617 uint64_t index = bigint_as_unsigned(&casted_elem_index->value.data.x_bigint); 16618 if (array_type->id == ZigTypeIdArray) { 16619 uint64_t array_len = array_type->data.array.len; 16620 if (index >= array_len) { 16621 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 16622 buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, 16623 index, array_len)); 16624 return ira->codegen->invalid_instruction; 16625 } 16626 safety_check_on = false; 16627 } 16628 16629 { 16630 // figure out the largest alignment possible 16631 uint64_t chosen_align = abi_align; 16632 if (ptr_align >= abi_align) { 16633 while (ptr_align > abi_align) { 16634 if ((index * elem_size) % ptr_align == 0) { 16635 chosen_align = ptr_align; 16636 break; 16637 } 16638 ptr_align >>= 1; 16639 } 16640 } else if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 16641 chosen_align = ptr_align; 16642 } else { 16643 // can't get here because guaranteed elem_size >= abi_align 16644 zig_unreachable(); 16645 } 16646 return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align); 16647 } 16648 16649 if (orig_array_ptr_val->special != ConstValSpecialRuntime && 16650 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || 16651 array_type->id == ZigTypeIdArray)) 16652 { 16653 ConstExprValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val, 16654 elem_ptr_instruction->base.source_node); 16655 if (array_ptr_val == nullptr) 16656 return ira->codegen->invalid_instruction; 16657 16658 if (array_ptr_val->special == ConstValSpecialUndef && elem_ptr_instruction->init_array_type != nullptr) { 16659 if (array_type->id == ZigTypeIdArray) { 16660 array_ptr_val->data.x_array.special = ConstArraySpecialNone; 16661 array_ptr_val->data.x_array.data.s_none.elements = create_const_vals(array_type->data.array.len); 16662 array_ptr_val->special = ConstValSpecialStatic; 16663 for (size_t i = 0; i < array_type->data.array.len; i += 1) { 16664 ConstExprValue *elem_val = &array_ptr_val->data.x_array.data.s_none.elements[i]; 16665 elem_val->special = ConstValSpecialUndef; 16666 elem_val->type = array_type->data.array.child_type; 16667 elem_val->parent.id = ConstParentIdArray; 16668 elem_val->parent.data.p_array.array_val = array_ptr_val; 16669 elem_val->parent.data.p_array.elem_index = i; 16670 } 16671 } else if (is_slice(array_type)) { 16672 ZigType *actual_array_type = ir_resolve_type(ira, elem_ptr_instruction->init_array_type->child); 16673 if (type_is_invalid(actual_array_type)) 16674 return ira->codegen->invalid_instruction; 16675 if (actual_array_type->id != ZigTypeIdArray) { 16676 ir_add_error(ira, elem_ptr_instruction->init_array_type, 16677 buf_sprintf("expected array type or [_], found slice")); 16678 return ira->codegen->invalid_instruction; 16679 } 16680 16681 ConstExprValue *array_init_val = create_const_vals(1); 16682 array_init_val->special = ConstValSpecialStatic; 16683 array_init_val->type = actual_array_type; 16684 array_init_val->data.x_array.special = ConstArraySpecialNone; 16685 array_init_val->data.x_array.data.s_none.elements = create_const_vals(actual_array_type->data.array.len); 16686 array_init_val->special = ConstValSpecialStatic; 16687 for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) { 16688 ConstExprValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i]; 16689 elem_val->special = ConstValSpecialUndef; 16690 elem_val->type = actual_array_type->data.array.child_type; 16691 elem_val->parent.id = ConstParentIdArray; 16692 elem_val->parent.data.p_array.array_val = array_init_val; 16693 elem_val->parent.data.p_array.elem_index = i; 16694 } 16695 16696 init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len, 16697 false); 16698 array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer; 16699 } else { 16700 zig_unreachable(); 16701 } 16702 } 16703 16704 if (array_ptr_val->special != ConstValSpecialRuntime && 16705 (array_type->id != ZigTypeIdPointer || 16706 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) 16707 { 16708 if (array_type->id == ZigTypeIdPointer) { 16709 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); 16710 ConstExprValue *out_val = &result->value; 16711 out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 16712 size_t new_index; 16713 size_t mem_size; 16714 size_t old_size; 16715 switch (array_ptr_val->data.x_ptr.special) { 16716 case ConstPtrSpecialInvalid: 16717 case ConstPtrSpecialDiscard: 16718 zig_unreachable(); 16719 case ConstPtrSpecialRef: 16720 mem_size = 1; 16721 old_size = 1; 16722 new_index = index; 16723 16724 out_val->data.x_ptr.special = ConstPtrSpecialRef; 16725 out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee; 16726 break; 16727 case ConstPtrSpecialBaseArray: 16728 { 16729 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; 16730 new_index = offset + index; 16731 mem_size = array_ptr_val->data.x_ptr.data.base_array.array_val->type->data.array.len; 16732 old_size = mem_size - offset; 16733 16734 assert(array_ptr_val->data.x_ptr.data.base_array.array_val); 16735 16736 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 16737 out_val->data.x_ptr.data.base_array.array_val = 16738 array_ptr_val->data.x_ptr.data.base_array.array_val; 16739 out_val->data.x_ptr.data.base_array.elem_index = new_index; 16740 out_val->data.x_ptr.data.base_array.is_cstr = 16741 array_ptr_val->data.x_ptr.data.base_array.is_cstr; 16742 16743 break; 16744 } 16745 case ConstPtrSpecialBaseStruct: 16746 zig_panic("TODO elem ptr on a const inner struct"); 16747 case ConstPtrSpecialBaseErrorUnionCode: 16748 zig_panic("TODO elem ptr on a const inner error union code"); 16749 case ConstPtrSpecialBaseErrorUnionPayload: 16750 zig_panic("TODO elem ptr on a const inner error union payload"); 16751 case ConstPtrSpecialBaseOptionalPayload: 16752 zig_panic("TODO elem ptr on a const inner optional payload"); 16753 case ConstPtrSpecialHardCodedAddr: 16754 zig_unreachable(); 16755 case ConstPtrSpecialFunction: 16756 zig_panic("TODO element ptr of a function casted to a ptr"); 16757 case ConstPtrSpecialNull: 16758 zig_panic("TODO elem ptr on a null pointer"); 16759 } 16760 if (new_index >= mem_size) { 16761 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 16762 buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size)); 16763 return ira->codegen->invalid_instruction; 16764 } 16765 return result; 16766 } else if (is_slice(array_type)) { 16767 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; 16768 ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base); 16769 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 16770 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, 16771 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false, 16772 elem_ptr_instruction->ptr_len, nullptr); 16773 result->value.type = return_type; 16774 return result; 16775 } 16776 ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index]; 16777 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); 16778 ConstExprValue *out_val = &result->value; 16779 uint64_t slice_len = bigint_as_unsigned(&len_field->data.x_bigint); 16780 if (index >= slice_len) { 16781 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 16782 buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64, 16783 index, slice_len)); 16784 return ira->codegen->invalid_instruction; 16785 } 16786 out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut; 16787 switch (ptr_field->data.x_ptr.special) { 16788 case ConstPtrSpecialInvalid: 16789 case ConstPtrSpecialDiscard: 16790 zig_unreachable(); 16791 case ConstPtrSpecialRef: 16792 out_val->data.x_ptr.special = ConstPtrSpecialRef; 16793 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee; 16794 break; 16795 case ConstPtrSpecialBaseArray: 16796 { 16797 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index; 16798 uint64_t new_index = offset + index; 16799 assert(new_index < ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len); 16800 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 16801 out_val->data.x_ptr.data.base_array.array_val = 16802 ptr_field->data.x_ptr.data.base_array.array_val; 16803 out_val->data.x_ptr.data.base_array.elem_index = new_index; 16804 out_val->data.x_ptr.data.base_array.is_cstr = 16805 ptr_field->data.x_ptr.data.base_array.is_cstr; 16806 break; 16807 } 16808 case ConstPtrSpecialBaseStruct: 16809 zig_panic("TODO elem ptr on a slice backed by const inner struct"); 16810 case ConstPtrSpecialBaseErrorUnionCode: 16811 zig_panic("TODO elem ptr on a slice backed by const inner error union code"); 16812 case ConstPtrSpecialBaseErrorUnionPayload: 16813 zig_panic("TODO elem ptr on a slice backed by const inner error union payload"); 16814 case ConstPtrSpecialBaseOptionalPayload: 16815 zig_panic("TODO elem ptr on a slice backed by const optional payload"); 16816 case ConstPtrSpecialHardCodedAddr: 16817 zig_unreachable(); 16818 case ConstPtrSpecialFunction: 16819 zig_panic("TODO elem ptr on a slice that was ptrcast from a function"); 16820 case ConstPtrSpecialNull: 16821 zig_panic("TODO elem ptr on a slice has a null pointer"); 16822 } 16823 return result; 16824 } else if (array_type->id == ZigTypeIdArray) { 16825 IrInstruction *result; 16826 if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 16827 result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, 16828 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, 16829 false, elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type); 16830 result->value.type = return_type; 16831 result->value.special = ConstValSpecialStatic; 16832 } else { 16833 result = ir_const(ira, &elem_ptr_instruction->base, return_type); 16834 } 16835 ConstExprValue *out_val = &result->value; 16836 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 16837 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; 16838 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val; 16839 out_val->data.x_ptr.data.base_array.elem_index = index; 16840 return result; 16841 } else { 16842 zig_unreachable(); 16843 } 16844 } 16845 } 16846 } else { 16847 // runtime known element index 16848 switch (type_requires_comptime(ira->codegen, return_type)) { 16849 case ReqCompTimeYes: 16850 ir_add_error(ira, elem_index, 16851 buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known", 16852 buf_ptr(&return_type->data.pointer.child_type->name))); 16853 return ira->codegen->invalid_instruction; 16854 case ReqCompTimeInvalid: 16855 return ira->codegen->invalid_instruction; 16856 case ReqCompTimeNo: 16857 break; 16858 } 16859 if (ptr_align < abi_align) { 16860 if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 16861 return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align); 16862 } else { 16863 // can't get here because guaranteed elem_size >= abi_align 16864 zig_unreachable(); 16865 } 16866 } else { 16867 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align); 16868 } 16869 } 16870 16871 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, 16872 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on, 16873 elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type); 16874 result->value.type = return_type; 16875 return result; 16876 } 16877 16878 static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, 16879 ZigType *bare_struct_type, Buf *field_name, IrInstruction *source_instr, 16880 IrInstruction *container_ptr, ZigType *container_type) 16881 { 16882 if (!is_slice(bare_struct_type)) { 16883 ScopeDecls *container_scope = get_container_scope(bare_struct_type); 16884 assert(container_scope != nullptr); 16885 auto entry = container_scope->decl_table.maybe_get(field_name); 16886 Tld *tld = entry ? entry->value : nullptr; 16887 if (tld && tld->id == TldIdFn) { 16888 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node); 16889 if (tld->resolution == TldResolutionInvalid) 16890 return ira->codegen->invalid_instruction; 16891 TldFn *tld_fn = (TldFn *)tld; 16892 ZigFn *fn_entry = tld_fn->fn_entry; 16893 if (type_is_invalid(fn_entry->type_entry)) 16894 return ira->codegen->invalid_instruction; 16895 16896 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope, 16897 source_instr->source_node, fn_entry, container_ptr); 16898 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 16899 } 16900 } 16901 const char *prefix_name; 16902 if (is_slice(bare_struct_type)) { 16903 prefix_name = ""; 16904 } else if (bare_struct_type->id == ZigTypeIdStruct) { 16905 prefix_name = "struct "; 16906 } else if (bare_struct_type->id == ZigTypeIdEnum) { 16907 prefix_name = "enum "; 16908 } else if (bare_struct_type->id == ZigTypeIdUnion) { 16909 prefix_name = "union "; 16910 } else { 16911 prefix_name = ""; 16912 } 16913 ir_add_error_node(ira, source_instr->source_node, 16914 buf_sprintf("no member named '%s' in %s'%s'", buf_ptr(field_name), prefix_name, buf_ptr(&bare_struct_type->name))); 16915 return ira->codegen->invalid_instruction; 16916 } 16917 16918 static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, 16919 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing) 16920 { 16921 switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { 16922 case OnePossibleValueInvalid: 16923 return ira->codegen->invalid_instruction; 16924 case OnePossibleValueYes: { 16925 IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); 16926 return ir_get_ref(ira, source_instr, elem, false, false); 16927 } 16928 case OnePossibleValueNo: 16929 break; 16930 } 16931 assert(struct_ptr->value.type->id == ZigTypeIdPointer); 16932 bool is_packed = (struct_type->data.structure.layout == ContainerLayoutPacked); 16933 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 16934 uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host; 16935 uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes; 16936 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? 16937 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes; 16938 bool is_const = struct_ptr->value.type->data.pointer.is_const; 16939 bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile; 16940 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, 16941 is_const, is_volatile, PtrLenSingle, align_bytes, 16942 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), 16943 (uint32_t)host_int_bytes_for_result_type, false); 16944 if (instr_is_comptime(struct_ptr)) { 16945 ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); 16946 if (!ptr_val) 16947 return ira->codegen->invalid_instruction; 16948 16949 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 16950 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 16951 if (struct_val == nullptr) 16952 return ira->codegen->invalid_instruction; 16953 if (type_is_invalid(struct_val->type)) 16954 return ira->codegen->invalid_instruction; 16955 if (initializing && struct_val->special == ConstValSpecialUndef) { 16956 struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count); 16957 struct_val->special = ConstValSpecialStatic; 16958 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { 16959 ConstExprValue *field_val = &struct_val->data.x_struct.fields[i]; 16960 field_val->special = ConstValSpecialUndef; 16961 field_val->type = struct_type->data.structure.fields[i].type_entry; 16962 field_val->parent.id = ConstParentIdStruct; 16963 field_val->parent.data.p_struct.struct_val = struct_val; 16964 field_val->parent.data.p_struct.field_index = i; 16965 } 16966 } 16967 IrInstruction *result; 16968 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 16969 result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, 16970 source_instr->source_node, struct_ptr, field); 16971 result->value.type = ptr_type; 16972 result->value.special = ConstValSpecialStatic; 16973 } else { 16974 result = ir_const(ira, source_instr, ptr_type); 16975 } 16976 ConstExprValue *const_val = &result->value; 16977 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; 16978 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 16979 const_val->data.x_ptr.data.base_struct.struct_val = struct_val; 16980 const_val->data.x_ptr.data.base_struct.field_index = field->src_index; 16981 return result; 16982 } 16983 } 16984 IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, 16985 struct_ptr, field); 16986 result->value.type = ptr_type; 16987 return result; 16988 } 16989 16990 static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 16991 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing) 16992 { 16993 Error err; 16994 16995 ZigType *bare_type = container_ref_type(container_type); 16996 if ((err = ensure_complete_type(ira->codegen, bare_type))) 16997 return ira->codegen->invalid_instruction; 16998 16999 assert(container_ptr->value.type->id == ZigTypeIdPointer); 17000 if (bare_type->id == ZigTypeIdStruct) { 17001 TypeStructField *field = find_struct_type_field(bare_type, field_name); 17002 if (field != nullptr) { 17003 return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); 17004 } else { 17005 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 17006 source_instr, container_ptr, container_type); 17007 } 17008 } 17009 17010 if (bare_type->id == ZigTypeIdEnum) { 17011 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 17012 source_instr, container_ptr, container_type); 17013 } 17014 17015 if (bare_type->id == ZigTypeIdUnion) { 17016 bool is_const = container_ptr->value.type->data.pointer.is_const; 17017 bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; 17018 17019 TypeUnionField *field = find_union_type_field(bare_type, field_name); 17020 if (field == nullptr) { 17021 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 17022 source_instr, container_ptr, container_type); 17023 } 17024 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, 17025 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 17026 if (instr_is_comptime(container_ptr)) { 17027 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 17028 if (!ptr_val) 17029 return ira->codegen->invalid_instruction; 17030 17031 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 17032 ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 17033 if (union_val == nullptr) 17034 return ira->codegen->invalid_instruction; 17035 if (type_is_invalid(union_val->type)) 17036 return ira->codegen->invalid_instruction; 17037 17038 if (initializing) { 17039 ConstExprValue *payload_val = create_const_vals(1); 17040 payload_val->special = ConstValSpecialUndef; 17041 payload_val->type = field->type_entry; 17042 payload_val->parent.id = ConstParentIdUnion; 17043 payload_val->parent.data.p_union.union_val = union_val; 17044 17045 union_val->special = ConstValSpecialStatic; 17046 bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); 17047 union_val->data.x_union.payload = payload_val; 17048 } else { 17049 TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); 17050 if (actual_field == nullptr) 17051 zig_unreachable(); 17052 17053 if (field != actual_field) { 17054 ir_add_error_node(ira, source_instr->source_node, 17055 buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), 17056 buf_ptr(actual_field->name))); 17057 return ira->codegen->invalid_instruction; 17058 } 17059 } 17060 17061 ConstExprValue *payload_val = union_val->data.x_union.payload; 17062 17063 17064 IrInstruction *result; 17065 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 17066 result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, 17067 source_instr->source_node, container_ptr, field, true, initializing); 17068 result->value.type = ptr_type; 17069 result->value.special = ConstValSpecialStatic; 17070 } else { 17071 result = ir_const(ira, source_instr, ptr_type); 17072 } 17073 ConstExprValue *const_val = &result->value; 17074 const_val->data.x_ptr.special = ConstPtrSpecialRef; 17075 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; 17076 const_val->data.x_ptr.data.ref.pointee = payload_val; 17077 return result; 17078 } 17079 } 17080 17081 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, 17082 source_instr->source_node, container_ptr, field, true, initializing); 17083 result->value.type = ptr_type; 17084 return result; 17085 } 17086 17087 zig_unreachable(); 17088 } 17089 17090 static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { 17091 bool is_libc = target_is_libc_lib_name(ira->codegen->zig_target, buf_ptr(lib_name)); 17092 if (is_libc && ira->codegen->libc_link_lib == nullptr && !ira->codegen->reported_bad_link_libc_error) { 17093 ir_add_error_node(ira, source_node, 17094 buf_sprintf("dependency on library c must be explicitly specified in the build command")); 17095 ira->codegen->reported_bad_link_libc_error = true; 17096 } 17097 17098 LinkLib *link_lib = add_link_lib(ira->codegen, lib_name); 17099 for (size_t i = 0; i < link_lib->symbols.length; i += 1) { 17100 Buf *existing_symbol_name = link_lib->symbols.at(i); 17101 if (buf_eql_buf(existing_symbol_name, symbol_name)) { 17102 return; 17103 } 17104 } 17105 17106 if (!is_libc && !target_is_wasm(ira->codegen->zig_target) && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) { 17107 ErrorMsg *msg = ir_add_error_node(ira, source_node, 17108 buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code", 17109 buf_ptr(lib_name))); 17110 add_error_note(ira->codegen, msg, source_node, 17111 buf_sprintf("fixed by `--library %s` or `--enable-pic`", buf_ptr(lib_name))); 17112 ira->codegen->reported_bad_link_libc_error = true; 17113 } 17114 17115 for (size_t i = 0; i < ira->codegen->forbidden_libs.length; i += 1) { 17116 Buf *forbidden_lib_name = ira->codegen->forbidden_libs.at(i); 17117 if (buf_eql_buf(lib_name, forbidden_lib_name)) { 17118 ir_add_error_node(ira, source_node, 17119 buf_sprintf("linking against forbidden library '%s'", buf_ptr(symbol_name))); 17120 } 17121 } 17122 link_lib->symbols.append(symbol_name); 17123 } 17124 17125 static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { 17126 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); 17127 emit_error_notes_for_ref_stack(ira->codegen, msg); 17128 return ira->codegen->invalid_instruction; 17129 } 17130 17131 static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { 17132 resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); 17133 if (tld->resolution == TldResolutionInvalid) 17134 return ira->codegen->invalid_instruction; 17135 17136 switch (tld->id) { 17137 case TldIdContainer: 17138 case TldIdCompTime: 17139 case TldIdUsingNamespace: 17140 zig_unreachable(); 17141 case TldIdVar: 17142 { 17143 TldVar *tld_var = (TldVar *)tld; 17144 ZigVar *var = tld_var->var; 17145 if (var == nullptr) { 17146 return ir_error_dependency_loop(ira, source_instruction); 17147 } 17148 if (tld_var->extern_lib_name != nullptr) { 17149 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node); 17150 } 17151 17152 return ir_get_var_ptr(ira, source_instruction, var); 17153 } 17154 case TldIdFn: 17155 { 17156 TldFn *tld_fn = (TldFn *)tld; 17157 ZigFn *fn_entry = tld_fn->fn_entry; 17158 assert(fn_entry->type_entry); 17159 17160 if (type_is_invalid(fn_entry->type_entry)) 17161 return ira->codegen->invalid_instruction; 17162 17163 if (tld_fn->extern_lib_name != nullptr) { 17164 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); 17165 } 17166 17167 IrInstruction *fn_inst = ir_create_const_fn(&ira->new_irb, source_instruction->scope, 17168 source_instruction->source_node, fn_entry); 17169 return ir_get_ref(ira, source_instruction, fn_inst, true, false); 17170 } 17171 } 17172 zig_unreachable(); 17173 } 17174 17175 static ErrorTableEntry *find_err_table_entry(ZigType *err_set_type, Buf *field_name) { 17176 assert(err_set_type->id == ZigTypeIdErrorSet); 17177 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 17178 ErrorTableEntry *err_table_entry = err_set_type->data.error_set.errors[i]; 17179 if (buf_eql_buf(&err_table_entry->name, field_name)) { 17180 return err_table_entry; 17181 } 17182 } 17183 return nullptr; 17184 } 17185 17186 static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) { 17187 Error err; 17188 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->child; 17189 if (type_is_invalid(container_ptr->value.type)) 17190 return ira->codegen->invalid_instruction; 17191 17192 ZigType *container_type = container_ptr->value.type->data.pointer.child_type; 17193 17194 Buf *field_name = field_ptr_instruction->field_name_buffer; 17195 if (!field_name) { 17196 IrInstruction *field_name_expr = field_ptr_instruction->field_name_expr->child; 17197 field_name = ir_resolve_str(ira, field_name_expr); 17198 if (!field_name) 17199 return ira->codegen->invalid_instruction; 17200 } 17201 17202 17203 AstNode *source_node = field_ptr_instruction->base.source_node; 17204 17205 if (type_is_invalid(container_type)) { 17206 return ira->codegen->invalid_instruction; 17207 } else if (is_slice(container_type) || is_container_ref(container_type)) { 17208 assert(container_ptr->value.type->id == ZigTypeIdPointer); 17209 if (container_type->id == ZigTypeIdPointer) { 17210 ZigType *bare_type = container_ref_type(container_type); 17211 IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr, nullptr); 17212 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type, field_ptr_instruction->initializing); 17213 return result; 17214 } else { 17215 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type, field_ptr_instruction->initializing); 17216 return result; 17217 } 17218 } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) { 17219 if (buf_eql_str(field_name, "len")) { 17220 ConstExprValue *len_val = create_const_vals(1); 17221 if (container_type->id == ZigTypeIdPointer) { 17222 init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len); 17223 } else { 17224 init_const_usize(ira->codegen, len_val, container_type->data.array.len); 17225 } 17226 17227 ZigType *usize = ira->codegen->builtin_types.entry_usize; 17228 bool ptr_is_const = true; 17229 bool ptr_is_volatile = false; 17230 return ir_get_const_ptr(ira, &field_ptr_instruction->base, len_val, 17231 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17232 } else { 17233 ir_add_error_node(ira, source_node, 17234 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), 17235 buf_ptr(&container_type->name))); 17236 return ira->codegen->invalid_instruction; 17237 } 17238 } else if (container_type->id == ZigTypeIdArgTuple) { 17239 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 17240 if (!container_ptr_val) 17241 return ira->codegen->invalid_instruction; 17242 17243 assert(container_ptr->value.type->id == ZigTypeIdPointer); 17244 ConstExprValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node); 17245 if (child_val == nullptr) 17246 return ira->codegen->invalid_instruction; 17247 17248 if (buf_eql_str(field_name, "len")) { 17249 ConstExprValue *len_val = create_const_vals(1); 17250 size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index; 17251 init_const_usize(ira->codegen, len_val, len); 17252 17253 ZigType *usize = ira->codegen->builtin_types.entry_usize; 17254 bool ptr_is_const = true; 17255 bool ptr_is_volatile = false; 17256 return ir_get_const_ptr(ira, &field_ptr_instruction->base, len_val, 17257 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17258 } else { 17259 ir_add_error_node(ira, source_node, 17260 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), 17261 buf_ptr(&container_type->name))); 17262 return ira->codegen->invalid_instruction; 17263 } 17264 } else if (container_type->id == ZigTypeIdMetaType) { 17265 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 17266 if (!container_ptr_val) 17267 return ira->codegen->invalid_instruction; 17268 17269 assert(container_ptr->value.type->id == ZigTypeIdPointer); 17270 ConstExprValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node); 17271 if (child_val == nullptr) 17272 return ira->codegen->invalid_instruction; 17273 ZigType *child_type = child_val->data.x_type; 17274 17275 if (type_is_invalid(child_type)) { 17276 return ira->codegen->invalid_instruction; 17277 } else if (is_container(child_type)) { 17278 if (child_type->id == ZigTypeIdEnum) { 17279 if ((err = ensure_complete_type(ira->codegen, child_type))) 17280 return ira->codegen->invalid_instruction; 17281 17282 TypeEnumField *field = find_enum_type_field(child_type, field_name); 17283 if (field) { 17284 bool ptr_is_const = true; 17285 bool ptr_is_volatile = false; 17286 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17287 create_const_enum(child_type, &field->value), child_type, 17288 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17289 } 17290 } 17291 ScopeDecls *container_scope = get_container_scope(child_type); 17292 Tld *tld = find_container_decl(ira->codegen, container_scope, field_name); 17293 if (tld) { 17294 if (tld->visib_mod == VisibModPrivate && 17295 tld->import != get_scope_import(field_ptr_instruction->base.scope)) 17296 { 17297 ErrorMsg *msg = ir_add_error(ira, &field_ptr_instruction->base, 17298 buf_sprintf("'%s' is private", buf_ptr(field_name))); 17299 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); 17300 return ira->codegen->invalid_instruction; 17301 } 17302 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld); 17303 } 17304 if (child_type->id == ZigTypeIdUnion && 17305 (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr || 17306 child_type->data.unionation.decl_node->data.container_decl.auto_enum)) 17307 { 17308 if ((err = ensure_complete_type(ira->codegen, child_type))) 17309 return ira->codegen->invalid_instruction; 17310 TypeUnionField *field = find_union_type_field(child_type, field_name); 17311 if (field) { 17312 ZigType *enum_type = child_type->data.unionation.tag_type; 17313 bool ptr_is_const = true; 17314 bool ptr_is_volatile = false; 17315 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17316 create_const_enum(enum_type, &field->enum_field->value), enum_type, 17317 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17318 } 17319 } 17320 const char *container_name = (child_type == ira->codegen->root_import) ? 17321 "root source file" : buf_ptr(buf_sprintf("container '%s'", buf_ptr(&child_type->name))); 17322 ir_add_error(ira, &field_ptr_instruction->base, 17323 buf_sprintf("%s has no member called '%s'", 17324 container_name, buf_ptr(field_name))); 17325 return ira->codegen->invalid_instruction; 17326 } else if (child_type->id == ZigTypeIdErrorSet) { 17327 ErrorTableEntry *err_entry; 17328 ZigType *err_set_type; 17329 if (type_is_global_error_set(child_type)) { 17330 auto existing_entry = ira->codegen->error_table.maybe_get(field_name); 17331 if (existing_entry) { 17332 err_entry = existing_entry->value; 17333 } else { 17334 err_entry = allocate<ErrorTableEntry>(1); 17335 err_entry->decl_node = field_ptr_instruction->base.source_node; 17336 buf_init_from_buf(&err_entry->name, field_name); 17337 size_t error_value_count = ira->codegen->errors_by_index.length; 17338 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); 17339 err_entry->value = error_value_count; 17340 ira->codegen->errors_by_index.append(err_entry); 17341 ira->codegen->error_table.put(field_name, err_entry); 17342 } 17343 if (err_entry->set_with_only_this_in_it == nullptr) { 17344 err_entry->set_with_only_this_in_it = make_err_set_with_one_item(ira->codegen, 17345 field_ptr_instruction->base.scope, field_ptr_instruction->base.source_node, 17346 err_entry); 17347 } 17348 err_set_type = err_entry->set_with_only_this_in_it; 17349 } else { 17350 if (!resolve_inferred_error_set(ira->codegen, child_type, field_ptr_instruction->base.source_node)) { 17351 return ira->codegen->invalid_instruction; 17352 } 17353 err_entry = find_err_table_entry(child_type, field_name); 17354 if (err_entry == nullptr) { 17355 ir_add_error(ira, &field_ptr_instruction->base, 17356 buf_sprintf("no error named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&child_type->name))); 17357 return ira->codegen->invalid_instruction; 17358 } 17359 err_set_type = child_type; 17360 } 17361 ConstExprValue *const_val = create_const_vals(1); 17362 const_val->special = ConstValSpecialStatic; 17363 const_val->type = err_set_type; 17364 const_val->data.x_err_set = err_entry; 17365 17366 bool ptr_is_const = true; 17367 bool ptr_is_volatile = false; 17368 return ir_get_const_ptr(ira, &field_ptr_instruction->base, const_val, 17369 err_set_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17370 } else if (child_type->id == ZigTypeIdInt) { 17371 if (buf_eql_str(field_name, "bit_count")) { 17372 bool ptr_is_const = true; 17373 bool ptr_is_volatile = false; 17374 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17375 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 17376 child_type->data.integral.bit_count, false), 17377 ira->codegen->builtin_types.entry_num_lit_int, 17378 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17379 } else if (buf_eql_str(field_name, "is_signed")) { 17380 bool ptr_is_const = true; 17381 bool ptr_is_volatile = false; 17382 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17383 create_const_bool(ira->codegen, child_type->data.integral.is_signed), 17384 ira->codegen->builtin_types.entry_bool, 17385 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17386 } else { 17387 ir_add_error(ira, &field_ptr_instruction->base, 17388 buf_sprintf("type '%s' has no member called '%s'", 17389 buf_ptr(&child_type->name), buf_ptr(field_name))); 17390 return ira->codegen->invalid_instruction; 17391 } 17392 } else if (child_type->id == ZigTypeIdFloat) { 17393 if (buf_eql_str(field_name, "bit_count")) { 17394 bool ptr_is_const = true; 17395 bool ptr_is_volatile = false; 17396 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17397 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 17398 child_type->data.floating.bit_count, false), 17399 ira->codegen->builtin_types.entry_num_lit_int, 17400 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17401 } else { 17402 ir_add_error(ira, &field_ptr_instruction->base, 17403 buf_sprintf("type '%s' has no member called '%s'", 17404 buf_ptr(&child_type->name), buf_ptr(field_name))); 17405 return ira->codegen->invalid_instruction; 17406 } 17407 } else if (child_type->id == ZigTypeIdPointer) { 17408 if (buf_eql_str(field_name, "Child")) { 17409 bool ptr_is_const = true; 17410 bool ptr_is_volatile = false; 17411 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17412 create_const_type(ira->codegen, child_type->data.pointer.child_type), 17413 ira->codegen->builtin_types.entry_type, 17414 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17415 } else if (buf_eql_str(field_name, "alignment")) { 17416 bool ptr_is_const = true; 17417 bool ptr_is_volatile = false; 17418 if ((err = type_resolve(ira->codegen, child_type->data.pointer.child_type, 17419 ResolveStatusAlignmentKnown))) 17420 { 17421 return ira->codegen->invalid_instruction; 17422 } 17423 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17424 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 17425 get_ptr_align(ira->codegen, child_type), false), 17426 ira->codegen->builtin_types.entry_num_lit_int, 17427 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17428 } else { 17429 ir_add_error(ira, &field_ptr_instruction->base, 17430 buf_sprintf("type '%s' has no member called '%s'", 17431 buf_ptr(&child_type->name), buf_ptr(field_name))); 17432 return ira->codegen->invalid_instruction; 17433 } 17434 } else if (child_type->id == ZigTypeIdArray) { 17435 if (buf_eql_str(field_name, "Child")) { 17436 bool ptr_is_const = true; 17437 bool ptr_is_volatile = false; 17438 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17439 create_const_type(ira->codegen, child_type->data.array.child_type), 17440 ira->codegen->builtin_types.entry_type, 17441 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17442 } else if (buf_eql_str(field_name, "len")) { 17443 bool ptr_is_const = true; 17444 bool ptr_is_volatile = false; 17445 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17446 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 17447 child_type->data.array.len, false), 17448 ira->codegen->builtin_types.entry_num_lit_int, 17449 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17450 } else { 17451 ir_add_error(ira, &field_ptr_instruction->base, 17452 buf_sprintf("type '%s' has no member called '%s'", 17453 buf_ptr(&child_type->name), buf_ptr(field_name))); 17454 return ira->codegen->invalid_instruction; 17455 } 17456 } else if (child_type->id == ZigTypeIdErrorUnion) { 17457 if (buf_eql_str(field_name, "Payload")) { 17458 bool ptr_is_const = true; 17459 bool ptr_is_volatile = false; 17460 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17461 create_const_type(ira->codegen, child_type->data.error_union.payload_type), 17462 ira->codegen->builtin_types.entry_type, 17463 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17464 } else if (buf_eql_str(field_name, "ErrorSet")) { 17465 bool ptr_is_const = true; 17466 bool ptr_is_volatile = false; 17467 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17468 create_const_type(ira->codegen, child_type->data.error_union.err_set_type), 17469 ira->codegen->builtin_types.entry_type, 17470 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17471 } else { 17472 ir_add_error(ira, &field_ptr_instruction->base, 17473 buf_sprintf("type '%s' has no member called '%s'", 17474 buf_ptr(&child_type->name), buf_ptr(field_name))); 17475 return ira->codegen->invalid_instruction; 17476 } 17477 } else if (child_type->id == ZigTypeIdOptional) { 17478 if (buf_eql_str(field_name, "Child")) { 17479 bool ptr_is_const = true; 17480 bool ptr_is_volatile = false; 17481 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17482 create_const_type(ira->codegen, child_type->data.maybe.child_type), 17483 ira->codegen->builtin_types.entry_type, 17484 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17485 } else { 17486 ir_add_error(ira, &field_ptr_instruction->base, 17487 buf_sprintf("type '%s' has no member called '%s'", 17488 buf_ptr(&child_type->name), buf_ptr(field_name))); 17489 return ira->codegen->invalid_instruction; 17490 } 17491 } else if (child_type->id == ZigTypeIdFn) { 17492 if (buf_eql_str(field_name, "ReturnType")) { 17493 if (child_type->data.fn.fn_type_id.return_type == nullptr) { 17494 // Return type can only ever be null, if the function is generic 17495 assert(child_type->data.fn.is_generic); 17496 17497 ir_add_error(ira, &field_ptr_instruction->base, 17498 buf_sprintf("ReturnType has not been resolved because '%s' is generic", buf_ptr(&child_type->name))); 17499 return ira->codegen->invalid_instruction; 17500 } 17501 17502 bool ptr_is_const = true; 17503 bool ptr_is_volatile = false; 17504 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17505 create_const_type(ira->codegen, child_type->data.fn.fn_type_id.return_type), 17506 ira->codegen->builtin_types.entry_type, 17507 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17508 } else if (buf_eql_str(field_name, "is_var_args")) { 17509 bool ptr_is_const = true; 17510 bool ptr_is_volatile = false; 17511 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17512 create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), 17513 ira->codegen->builtin_types.entry_bool, 17514 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17515 } else if (buf_eql_str(field_name, "arg_count")) { 17516 bool ptr_is_const = true; 17517 bool ptr_is_volatile = false; 17518 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 17519 create_const_usize(ira->codegen, child_type->data.fn.fn_type_id.param_count), 17520 ira->codegen->builtin_types.entry_usize, 17521 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 17522 } else { 17523 ir_add_error(ira, &field_ptr_instruction->base, 17524 buf_sprintf("type '%s' has no member called '%s'", 17525 buf_ptr(&child_type->name), buf_ptr(field_name))); 17526 return ira->codegen->invalid_instruction; 17527 } 17528 } else { 17529 ir_add_error(ira, &field_ptr_instruction->base, 17530 buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); 17531 return ira->codegen->invalid_instruction; 17532 } 17533 } else if (field_ptr_instruction->initializing) { 17534 ir_add_error(ira, &field_ptr_instruction->base, 17535 buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name))); 17536 return ira->codegen->invalid_instruction; 17537 } else { 17538 ir_add_error_node(ira, field_ptr_instruction->base.source_node, 17539 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); 17540 return ira->codegen->invalid_instruction; 17541 } 17542 } 17543 17544 static IrInstruction *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstructionStorePtr *instruction) { 17545 IrInstruction *ptr = instruction->ptr->child; 17546 if (type_is_invalid(ptr->value.type)) 17547 return ira->codegen->invalid_instruction; 17548 17549 IrInstruction *value = instruction->value->child; 17550 if (type_is_invalid(value->value.type)) 17551 return ira->codegen->invalid_instruction; 17552 17553 return ir_analyze_store_ptr(ira, &instruction->base, ptr, value, instruction->allow_write_through_const); 17554 } 17555 17556 static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *instruction) { 17557 IrInstruction *ptr = instruction->ptr->child; 17558 if (type_is_invalid(ptr->value.type)) 17559 return ira->codegen->invalid_instruction; 17560 return ir_get_deref(ira, &instruction->base, ptr, nullptr); 17561 } 17562 17563 static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { 17564 IrInstruction *expr_value = typeof_instruction->value->child; 17565 ZigType *type_entry = expr_value->value.type; 17566 if (type_is_invalid(type_entry)) 17567 return ira->codegen->invalid_instruction; 17568 return ir_const_type(ira, &typeof_instruction->base, type_entry); 17569 } 17570 17571 static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { 17572 if (ira->new_irb.exec->is_inline) { 17573 // ignore setCold when running functions at compile time 17574 return ir_const_void(ira, &instruction->base); 17575 } 17576 17577 IrInstruction *is_cold_value = instruction->is_cold->child; 17578 bool want_cold; 17579 if (!ir_resolve_bool(ira, is_cold_value, &want_cold)) 17580 return ira->codegen->invalid_instruction; 17581 17582 ZigFn *fn_entry = scope_fn_entry(instruction->base.scope); 17583 if (fn_entry == nullptr) { 17584 ir_add_error(ira, &instruction->base, buf_sprintf("@setCold outside function")); 17585 return ira->codegen->invalid_instruction; 17586 } 17587 17588 if (fn_entry->set_cold_node != nullptr) { 17589 ErrorMsg *msg = ir_add_error(ira, &instruction->base, buf_sprintf("cold set twice in same function")); 17590 add_error_note(ira->codegen, msg, fn_entry->set_cold_node, buf_sprintf("first set here")); 17591 return ira->codegen->invalid_instruction; 17592 } 17593 17594 fn_entry->set_cold_node = instruction->base.source_node; 17595 fn_entry->is_cold = want_cold; 17596 17597 return ir_const_void(ira, &instruction->base); 17598 } 17599 17600 static IrInstruction *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira, 17601 IrInstructionSetRuntimeSafety *set_runtime_safety_instruction) 17602 { 17603 if (ira->new_irb.exec->is_inline) { 17604 // ignore setRuntimeSafety when running functions at compile time 17605 return ir_const_void(ira, &set_runtime_safety_instruction->base); 17606 } 17607 17608 bool *safety_off_ptr; 17609 AstNode **safety_set_node_ptr; 17610 17611 Scope *scope = set_runtime_safety_instruction->base.scope; 17612 while (scope != nullptr) { 17613 if (scope->id == ScopeIdBlock) { 17614 ScopeBlock *block_scope = (ScopeBlock *)scope; 17615 safety_off_ptr = &block_scope->safety_off; 17616 safety_set_node_ptr = &block_scope->safety_set_node; 17617 break; 17618 } else if (scope->id == ScopeIdFnDef) { 17619 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 17620 ZigFn *target_fn = def_scope->fn_entry; 17621 assert(target_fn->def_scope != nullptr); 17622 safety_off_ptr = &target_fn->def_scope->safety_off; 17623 safety_set_node_ptr = &target_fn->def_scope->safety_set_node; 17624 break; 17625 } else if (scope->id == ScopeIdDecls) { 17626 ScopeDecls *decls_scope = (ScopeDecls *)scope; 17627 safety_off_ptr = &decls_scope->safety_off; 17628 safety_set_node_ptr = &decls_scope->safety_set_node; 17629 break; 17630 } else { 17631 scope = scope->parent; 17632 continue; 17633 } 17634 } 17635 assert(scope != nullptr); 17636 17637 IrInstruction *safety_on_value = set_runtime_safety_instruction->safety_on->child; 17638 bool want_runtime_safety; 17639 if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety)) 17640 return ira->codegen->invalid_instruction; 17641 17642 AstNode *source_node = set_runtime_safety_instruction->base.source_node; 17643 if (*safety_set_node_ptr) { 17644 ErrorMsg *msg = ir_add_error_node(ira, source_node, 17645 buf_sprintf("runtime safety set twice for same scope")); 17646 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here")); 17647 return ira->codegen->invalid_instruction; 17648 } 17649 *safety_set_node_ptr = source_node; 17650 *safety_off_ptr = !want_runtime_safety; 17651 17652 return ir_const_void(ira, &set_runtime_safety_instruction->base); 17653 } 17654 17655 static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, 17656 IrInstructionSetFloatMode *instruction) 17657 { 17658 if (ira->new_irb.exec->is_inline) { 17659 // ignore setFloatMode when running functions at compile time 17660 return ir_const_void(ira, &instruction->base); 17661 } 17662 17663 bool *fast_math_on_ptr; 17664 AstNode **fast_math_set_node_ptr; 17665 17666 Scope *scope = instruction->base.scope; 17667 while (scope != nullptr) { 17668 if (scope->id == ScopeIdBlock) { 17669 ScopeBlock *block_scope = (ScopeBlock *)scope; 17670 fast_math_on_ptr = &block_scope->fast_math_on; 17671 fast_math_set_node_ptr = &block_scope->fast_math_set_node; 17672 break; 17673 } else if (scope->id == ScopeIdFnDef) { 17674 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 17675 ZigFn *target_fn = def_scope->fn_entry; 17676 assert(target_fn->def_scope != nullptr); 17677 fast_math_on_ptr = &target_fn->def_scope->fast_math_on; 17678 fast_math_set_node_ptr = &target_fn->def_scope->fast_math_set_node; 17679 break; 17680 } else if (scope->id == ScopeIdDecls) { 17681 ScopeDecls *decls_scope = (ScopeDecls *)scope; 17682 fast_math_on_ptr = &decls_scope->fast_math_on; 17683 fast_math_set_node_ptr = &decls_scope->fast_math_set_node; 17684 break; 17685 } else { 17686 scope = scope->parent; 17687 continue; 17688 } 17689 } 17690 assert(scope != nullptr); 17691 17692 IrInstruction *float_mode_value = instruction->mode_value->child; 17693 FloatMode float_mode_scalar; 17694 if (!ir_resolve_float_mode(ira, float_mode_value, &float_mode_scalar)) 17695 return ira->codegen->invalid_instruction; 17696 17697 AstNode *source_node = instruction->base.source_node; 17698 if (*fast_math_set_node_ptr) { 17699 ErrorMsg *msg = ir_add_error_node(ira, source_node, 17700 buf_sprintf("float mode set twice for same scope")); 17701 add_error_note(ira->codegen, msg, *fast_math_set_node_ptr, buf_sprintf("first set here")); 17702 return ira->codegen->invalid_instruction; 17703 } 17704 *fast_math_set_node_ptr = source_node; 17705 *fast_math_on_ptr = (float_mode_scalar == FloatModeOptimized); 17706 17707 return ir_const_void(ira, &instruction->base); 17708 } 17709 17710 static IrInstruction *ir_analyze_instruction_any_frame_type(IrAnalyze *ira, 17711 IrInstructionAnyFrameType *instruction) 17712 { 17713 ZigType *payload_type = nullptr; 17714 if (instruction->payload_type != nullptr) { 17715 payload_type = ir_resolve_type(ira, instruction->payload_type->child); 17716 if (type_is_invalid(payload_type)) 17717 return ira->codegen->invalid_instruction; 17718 } 17719 17720 ZigType *any_frame_type = get_any_frame_type(ira->codegen, payload_type); 17721 return ir_const_type(ira, &instruction->base, any_frame_type); 17722 } 17723 17724 static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, 17725 IrInstructionSliceType *slice_type_instruction) 17726 { 17727 Error err; 17728 uint32_t align_bytes = 0; 17729 if (slice_type_instruction->align_value != nullptr) { 17730 if (!ir_resolve_align(ira, slice_type_instruction->align_value->child, &align_bytes)) 17731 return ira->codegen->invalid_instruction; 17732 } 17733 17734 ZigType *child_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); 17735 if (type_is_invalid(child_type)) 17736 return ira->codegen->invalid_instruction; 17737 17738 bool is_const = slice_type_instruction->is_const; 17739 bool is_volatile = slice_type_instruction->is_volatile; 17740 bool is_allow_zero = slice_type_instruction->is_allow_zero; 17741 17742 switch (child_type->id) { 17743 case ZigTypeIdInvalid: // handled above 17744 zig_unreachable(); 17745 case ZigTypeIdUnreachable: 17746 case ZigTypeIdUndefined: 17747 case ZigTypeIdNull: 17748 case ZigTypeIdArgTuple: 17749 case ZigTypeIdOpaque: 17750 ir_add_error_node(ira, slice_type_instruction->base.source_node, 17751 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&child_type->name))); 17752 return ira->codegen->invalid_instruction; 17753 case ZigTypeIdMetaType: 17754 case ZigTypeIdVoid: 17755 case ZigTypeIdBool: 17756 case ZigTypeIdInt: 17757 case ZigTypeIdFloat: 17758 case ZigTypeIdPointer: 17759 case ZigTypeIdArray: 17760 case ZigTypeIdStruct: 17761 case ZigTypeIdComptimeFloat: 17762 case ZigTypeIdComptimeInt: 17763 case ZigTypeIdEnumLiteral: 17764 case ZigTypeIdOptional: 17765 case ZigTypeIdErrorUnion: 17766 case ZigTypeIdErrorSet: 17767 case ZigTypeIdEnum: 17768 case ZigTypeIdUnion: 17769 case ZigTypeIdFn: 17770 case ZigTypeIdBoundFn: 17771 case ZigTypeIdVector: 17772 case ZigTypeIdFnFrame: 17773 case ZigTypeIdAnyFrame: 17774 { 17775 ResolveStatus needed_status = (align_bytes == 0) ? 17776 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; 17777 if ((err = type_resolve(ira->codegen, child_type, needed_status))) 17778 return ira->codegen->invalid_instruction; 17779 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, 17780 is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0, is_allow_zero); 17781 ZigType *result_type = get_slice_type(ira->codegen, slice_ptr_type); 17782 return ir_const_type(ira, &slice_type_instruction->base, result_type); 17783 } 17784 } 17785 zig_unreachable(); 17786 } 17787 17788 static IrInstruction *ir_analyze_instruction_global_asm(IrAnalyze *ira, IrInstructionGlobalAsm *instruction) { 17789 buf_append_char(&ira->codegen->global_asm, '\n'); 17790 buf_append_buf(&ira->codegen->global_asm, instruction->asm_code); 17791 17792 return ir_const_void(ira, &instruction->base); 17793 } 17794 17795 static IrInstruction *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsm *asm_instruction) { 17796 assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr); 17797 17798 AstNodeAsmExpr *asm_expr = &asm_instruction->base.source_node->data.asm_expr; 17799 17800 if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base)) 17801 return ira->codegen->invalid_instruction; 17802 17803 // TODO validate the output types and variable types 17804 17805 IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length); 17806 IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length); 17807 17808 ZigType *return_type = ira->codegen->builtin_types.entry_void; 17809 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 17810 AsmOutput *asm_output = asm_expr->output_list.at(i); 17811 if (asm_output->return_type) { 17812 output_types[i] = asm_instruction->output_types[i]->child; 17813 return_type = ir_resolve_type(ira, output_types[i]); 17814 if (type_is_invalid(return_type)) 17815 return ira->codegen->invalid_instruction; 17816 } 17817 } 17818 17819 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 17820 IrInstruction *const input_value = asm_instruction->input_list[i]->child; 17821 if (type_is_invalid(input_value->value.type)) 17822 return ira->codegen->invalid_instruction; 17823 17824 if (instr_is_comptime(input_value) && 17825 (input_value->value.type->id == ZigTypeIdComptimeInt || 17826 input_value->value.type->id == ZigTypeIdComptimeFloat)) { 17827 ir_add_error_node(ira, input_value->source_node, 17828 buf_sprintf("expected sized integer or sized float, found %s", buf_ptr(&input_value->value.type->name))); 17829 return ira->codegen->invalid_instruction; 17830 } 17831 17832 input_list[i] = input_value; 17833 } 17834 17835 IrInstruction *result = ir_build_asm(&ira->new_irb, 17836 asm_instruction->base.scope, asm_instruction->base.source_node, 17837 asm_instruction->asm_template, asm_instruction->token_list, asm_instruction->token_list_len, 17838 input_list, output_types, asm_instruction->output_vars, asm_instruction->return_count, 17839 asm_instruction->has_side_effects); 17840 result->value.type = return_type; 17841 return result; 17842 } 17843 17844 static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, 17845 IrInstructionArrayType *array_type_instruction) 17846 { 17847 Error err; 17848 17849 IrInstruction *size_value = array_type_instruction->size->child; 17850 uint64_t size; 17851 if (!ir_resolve_usize(ira, size_value, &size)) 17852 return ira->codegen->invalid_instruction; 17853 17854 IrInstruction *child_type_value = array_type_instruction->child_type->child; 17855 ZigType *child_type = ir_resolve_type(ira, child_type_value); 17856 if (type_is_invalid(child_type)) 17857 return ira->codegen->invalid_instruction; 17858 switch (child_type->id) { 17859 case ZigTypeIdInvalid: // handled above 17860 zig_unreachable(); 17861 case ZigTypeIdUnreachable: 17862 case ZigTypeIdUndefined: 17863 case ZigTypeIdNull: 17864 case ZigTypeIdArgTuple: 17865 case ZigTypeIdOpaque: 17866 ir_add_error_node(ira, array_type_instruction->base.source_node, 17867 buf_sprintf("array of type '%s' not allowed", buf_ptr(&child_type->name))); 17868 return ira->codegen->invalid_instruction; 17869 case ZigTypeIdMetaType: 17870 case ZigTypeIdVoid: 17871 case ZigTypeIdBool: 17872 case ZigTypeIdInt: 17873 case ZigTypeIdFloat: 17874 case ZigTypeIdPointer: 17875 case ZigTypeIdArray: 17876 case ZigTypeIdStruct: 17877 case ZigTypeIdComptimeFloat: 17878 case ZigTypeIdComptimeInt: 17879 case ZigTypeIdEnumLiteral: 17880 case ZigTypeIdOptional: 17881 case ZigTypeIdErrorUnion: 17882 case ZigTypeIdErrorSet: 17883 case ZigTypeIdEnum: 17884 case ZigTypeIdUnion: 17885 case ZigTypeIdFn: 17886 case ZigTypeIdBoundFn: 17887 case ZigTypeIdVector: 17888 case ZigTypeIdFnFrame: 17889 case ZigTypeIdAnyFrame: 17890 { 17891 if ((err = ensure_complete_type(ira->codegen, child_type))) 17892 return ira->codegen->invalid_instruction; 17893 ZigType *result_type = get_array_type(ira->codegen, child_type, size); 17894 return ir_const_type(ira, &array_type_instruction->base, result_type); 17895 } 17896 } 17897 zig_unreachable(); 17898 } 17899 17900 static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, 17901 IrInstructionSizeOf *size_of_instruction) 17902 { 17903 Error err; 17904 IrInstruction *type_value = size_of_instruction->type_value->child; 17905 ZigType *type_entry = ir_resolve_type(ira, type_value); 17906 17907 if ((err = ensure_complete_type(ira->codegen, type_entry))) 17908 return ira->codegen->invalid_instruction; 17909 17910 switch (type_entry->id) { 17911 case ZigTypeIdInvalid: // handled above 17912 zig_unreachable(); 17913 case ZigTypeIdUnreachable: 17914 case ZigTypeIdUndefined: 17915 case ZigTypeIdNull: 17916 case ZigTypeIdBoundFn: 17917 case ZigTypeIdArgTuple: 17918 case ZigTypeIdOpaque: 17919 ir_add_error_node(ira, type_value->source_node, 17920 buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name))); 17921 return ira->codegen->invalid_instruction; 17922 case ZigTypeIdMetaType: 17923 case ZigTypeIdEnumLiteral: 17924 case ZigTypeIdComptimeFloat: 17925 case ZigTypeIdComptimeInt: 17926 case ZigTypeIdVoid: 17927 case ZigTypeIdBool: 17928 case ZigTypeIdInt: 17929 case ZigTypeIdFloat: 17930 case ZigTypeIdPointer: 17931 case ZigTypeIdArray: 17932 case ZigTypeIdStruct: 17933 case ZigTypeIdOptional: 17934 case ZigTypeIdErrorUnion: 17935 case ZigTypeIdErrorSet: 17936 case ZigTypeIdEnum: 17937 case ZigTypeIdUnion: 17938 case ZigTypeIdFn: 17939 case ZigTypeIdVector: 17940 case ZigTypeIdFnFrame: 17941 case ZigTypeIdAnyFrame: 17942 { 17943 uint64_t size_in_bytes = type_size(ira->codegen, type_entry); 17944 return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes); 17945 } 17946 } 17947 zig_unreachable(); 17948 } 17949 17950 static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) { 17951 ZigType *type_entry = value->value.type; 17952 17953 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) { 17954 if (instr_is_comptime(value)) { 17955 ConstExprValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk); 17956 if (c_ptr_val == nullptr) 17957 return ira->codegen->invalid_instruction; 17958 if (c_ptr_val->special == ConstValSpecialUndef) 17959 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 17960 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 17961 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 17962 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 17963 return ir_const_bool(ira, source_inst, !is_null); 17964 } 17965 17966 IrInstruction *result = ir_build_test_nonnull(&ira->new_irb, 17967 source_inst->scope, source_inst->source_node, value); 17968 result->value.type = ira->codegen->builtin_types.entry_bool; 17969 return result; 17970 } else if (type_entry->id == ZigTypeIdOptional) { 17971 if (instr_is_comptime(value)) { 17972 ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefOk); 17973 if (maybe_val == nullptr) 17974 return ira->codegen->invalid_instruction; 17975 if (maybe_val->special == ConstValSpecialUndef) 17976 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 17977 17978 return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val)); 17979 } 17980 17981 IrInstruction *result = ir_build_test_nonnull(&ira->new_irb, 17982 source_inst->scope, source_inst->source_node, value); 17983 result->value.type = ira->codegen->builtin_types.entry_bool; 17984 return result; 17985 } else if (type_entry->id == ZigTypeIdNull) { 17986 return ir_const_bool(ira, source_inst, false); 17987 } else { 17988 return ir_const_bool(ira, source_inst, true); 17989 } 17990 } 17991 17992 static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrInstructionTestNonNull *instruction) { 17993 IrInstruction *value = instruction->value->child; 17994 if (type_is_invalid(value->value.type)) 17995 return ira->codegen->invalid_instruction; 17996 17997 return ir_analyze_test_non_null(ira, &instruction->base, value); 17998 } 17999 18000 static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, 18001 IrInstruction *base_ptr, bool safety_check_on, bool initializing) 18002 { 18003 ZigType *ptr_type = base_ptr->value.type; 18004 assert(ptr_type->id == ZigTypeIdPointer); 18005 18006 ZigType *type_entry = ptr_type->data.pointer.child_type; 18007 if (type_is_invalid(type_entry)) 18008 return ira->codegen->invalid_instruction; 18009 18010 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.ptr_len == PtrLenC) { 18011 if (instr_is_comptime(base_ptr)) { 18012 ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad); 18013 if (!val) 18014 return ira->codegen->invalid_instruction; 18015 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 18016 ConstExprValue *c_ptr_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 18017 if (c_ptr_val == nullptr) 18018 return ira->codegen->invalid_instruction; 18019 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 18020 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 18021 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 18022 if (is_null) { 18023 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 18024 return ira->codegen->invalid_instruction; 18025 } 18026 return base_ptr; 18027 } 18028 } 18029 if (!safety_check_on) 18030 return base_ptr; 18031 IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr); 18032 ir_build_assert_non_null(ira, source_instr, c_ptr_val); 18033 return base_ptr; 18034 } 18035 18036 if (type_entry->id != ZigTypeIdOptional) { 18037 ir_add_error_node(ira, base_ptr->source_node, 18038 buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name))); 18039 return ira->codegen->invalid_instruction; 18040 } 18041 18042 ZigType *child_type = type_entry->data.maybe.child_type; 18043 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, 18044 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); 18045 18046 bool same_comptime_repr = types_have_same_zig_comptime_repr(type_entry, child_type); 18047 18048 if (instr_is_comptime(base_ptr)) { 18049 ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 18050 if (!ptr_val) 18051 return ira->codegen->invalid_instruction; 18052 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 18053 ConstExprValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 18054 if (optional_val == nullptr) 18055 return ira->codegen->invalid_instruction; 18056 18057 if (initializing) { 18058 switch (type_has_one_possible_value(ira->codegen, child_type)) { 18059 case OnePossibleValueInvalid: 18060 return ira->codegen->invalid_instruction; 18061 case OnePossibleValueNo: 18062 if (!same_comptime_repr) { 18063 ConstExprValue *payload_val = create_const_vals(1); 18064 payload_val->type = child_type; 18065 payload_val->special = ConstValSpecialUndef; 18066 payload_val->parent.id = ConstParentIdOptionalPayload; 18067 payload_val->parent.data.p_optional_payload.optional_val = optional_val; 18068 18069 optional_val->data.x_optional = payload_val; 18070 optional_val->special = ConstValSpecialStatic; 18071 } 18072 break; 18073 case OnePossibleValueYes: { 18074 ConstExprValue *pointee = create_const_vals(1); 18075 pointee->special = ConstValSpecialStatic; 18076 pointee->type = child_type; 18077 pointee->parent.id = ConstParentIdOptionalPayload; 18078 pointee->parent.data.p_optional_payload.optional_val = optional_val; 18079 18080 optional_val->special = ConstValSpecialStatic; 18081 optional_val->data.x_optional = pointee; 18082 break; 18083 } 18084 } 18085 } else if (optional_value_is_null(optional_val)) { 18086 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 18087 return ira->codegen->invalid_instruction; 18088 } 18089 18090 IrInstruction *result; 18091 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 18092 result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, 18093 source_instr->source_node, base_ptr, false, initializing); 18094 result->value.type = result_type; 18095 result->value.special = ConstValSpecialStatic; 18096 } else { 18097 result = ir_const(ira, source_instr, result_type); 18098 } 18099 ConstExprValue *result_val = &result->value; 18100 result_val->data.x_ptr.special = ConstPtrSpecialRef; 18101 result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 18102 switch (type_has_one_possible_value(ira->codegen, child_type)) { 18103 case OnePossibleValueInvalid: 18104 return ira->codegen->invalid_instruction; 18105 case OnePossibleValueNo: 18106 if (same_comptime_repr) { 18107 result_val->data.x_ptr.data.ref.pointee = optional_val; 18108 } else { 18109 assert(optional_val->data.x_optional != nullptr); 18110 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; 18111 } 18112 break; 18113 case OnePossibleValueYes: 18114 assert(optional_val->data.x_optional != nullptr); 18115 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; 18116 break; 18117 } 18118 return result; 18119 } 18120 } 18121 18122 IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, 18123 source_instr->source_node, base_ptr, safety_check_on, initializing); 18124 result->value.type = result_type; 18125 return result; 18126 } 18127 18128 static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, 18129 IrInstructionOptionalUnwrapPtr *instruction) 18130 { 18131 IrInstruction *base_ptr = instruction->base_ptr->child; 18132 if (type_is_invalid(base_ptr->value.type)) 18133 return ira->codegen->invalid_instruction; 18134 18135 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, 18136 instruction->safety_check_on, false); 18137 } 18138 18139 static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { 18140 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 18141 if (type_is_invalid(int_type)) 18142 return ira->codegen->invalid_instruction; 18143 18144 IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); 18145 if (type_is_invalid(op->value.type)) 18146 return ira->codegen->invalid_instruction; 18147 18148 if (int_type->data.integral.bit_count == 0) 18149 return ir_const_unsigned(ira, &instruction->base, 0); 18150 18151 if (instr_is_comptime(op)) { 18152 ConstExprValue *val = ir_resolve_const(ira, op, UndefOk); 18153 if (val == nullptr) 18154 return ira->codegen->invalid_instruction; 18155 if (val->special == ConstValSpecialUndef) 18156 return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); 18157 size_t result_usize = bigint_ctz(&op->value.data.x_bigint, int_type->data.integral.bit_count); 18158 return ir_const_unsigned(ira, &instruction->base, result_usize); 18159 } 18160 18161 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 18162 IrInstruction *result = ir_build_ctz(&ira->new_irb, instruction->base.scope, 18163 instruction->base.source_node, nullptr, op); 18164 result->value.type = return_type; 18165 return result; 18166 } 18167 18168 static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *instruction) { 18169 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 18170 if (type_is_invalid(int_type)) 18171 return ira->codegen->invalid_instruction; 18172 18173 IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); 18174 if (type_is_invalid(op->value.type)) 18175 return ira->codegen->invalid_instruction; 18176 18177 if (int_type->data.integral.bit_count == 0) 18178 return ir_const_unsigned(ira, &instruction->base, 0); 18179 18180 if (instr_is_comptime(op)) { 18181 ConstExprValue *val = ir_resolve_const(ira, op, UndefOk); 18182 if (val == nullptr) 18183 return ira->codegen->invalid_instruction; 18184 if (val->special == ConstValSpecialUndef) 18185 return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); 18186 size_t result_usize = bigint_clz(&op->value.data.x_bigint, int_type->data.integral.bit_count); 18187 return ir_const_unsigned(ira, &instruction->base, result_usize); 18188 } 18189 18190 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 18191 IrInstruction *result = ir_build_clz(&ira->new_irb, instruction->base.scope, 18192 instruction->base.source_node, nullptr, op); 18193 result->value.type = return_type; 18194 return result; 18195 } 18196 18197 static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) { 18198 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 18199 if (type_is_invalid(int_type)) 18200 return ira->codegen->invalid_instruction; 18201 18202 IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); 18203 if (type_is_invalid(op->value.type)) 18204 return ira->codegen->invalid_instruction; 18205 18206 if (int_type->data.integral.bit_count == 0) 18207 return ir_const_unsigned(ira, &instruction->base, 0); 18208 18209 if (instr_is_comptime(op)) { 18210 ConstExprValue *val = ir_resolve_const(ira, op, UndefOk); 18211 if (val == nullptr) 18212 return ira->codegen->invalid_instruction; 18213 if (val->special == ConstValSpecialUndef) 18214 return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); 18215 18216 if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { 18217 size_t result = bigint_popcount_unsigned(&val->data.x_bigint); 18218 return ir_const_unsigned(ira, &instruction->base, result); 18219 } 18220 size_t result = bigint_popcount_signed(&val->data.x_bigint, int_type->data.integral.bit_count); 18221 return ir_const_unsigned(ira, &instruction->base, result); 18222 } 18223 18224 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 18225 IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope, 18226 instruction->base.source_node, nullptr, op); 18227 result->value.type = return_type; 18228 return result; 18229 } 18230 18231 static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value) { 18232 if (type_is_invalid(value->value.type)) 18233 return ira->codegen->invalid_instruction; 18234 18235 if (value->value.type->id == ZigTypeIdEnum) { 18236 return value; 18237 } 18238 18239 if (value->value.type->id != ZigTypeIdUnion) { 18240 ir_add_error(ira, value, 18241 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value.type->name))); 18242 return ira->codegen->invalid_instruction; 18243 } 18244 if (!value->value.type->data.unionation.have_explicit_tag_type && !source_instr->is_gen) { 18245 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum")); 18246 if (value->value.type->data.unionation.decl_node != nullptr) { 18247 add_error_note(ira->codegen, msg, value->value.type->data.unionation.decl_node, 18248 buf_sprintf("declared here")); 18249 } 18250 return ira->codegen->invalid_instruction; 18251 } 18252 18253 ZigType *tag_type = value->value.type->data.unionation.tag_type; 18254 assert(tag_type->id == ZigTypeIdEnum); 18255 18256 if (instr_is_comptime(value)) { 18257 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 18258 if (!val) 18259 return ira->codegen->invalid_instruction; 18260 18261 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 18262 source_instr->scope, source_instr->source_node); 18263 const_instruction->base.value.type = tag_type; 18264 const_instruction->base.value.special = ConstValSpecialStatic; 18265 bigint_init_bigint(&const_instruction->base.value.data.x_enum_tag, &val->data.x_union.tag); 18266 return &const_instruction->base; 18267 } 18268 18269 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 18270 result->value.type = tag_type; 18271 return result; 18272 } 18273 18274 static IrInstruction *ir_analyze_instruction_switch_br(IrAnalyze *ira, 18275 IrInstructionSwitchBr *switch_br_instruction) 18276 { 18277 IrInstruction *target_value = switch_br_instruction->target_value->child; 18278 if (type_is_invalid(target_value->value.type)) 18279 return ir_unreach_error(ira); 18280 18281 if (switch_br_instruction->switch_prongs_void != nullptr) { 18282 if (type_is_invalid(switch_br_instruction->switch_prongs_void->child->value.type)) { 18283 return ir_unreach_error(ira); 18284 } 18285 } 18286 18287 18288 size_t case_count = switch_br_instruction->case_count; 18289 18290 bool is_comptime; 18291 if (!ir_resolve_comptime(ira, switch_br_instruction->is_comptime->child, &is_comptime)) 18292 return ira->codegen->invalid_instruction; 18293 18294 if (is_comptime || instr_is_comptime(target_value)) { 18295 ConstExprValue *target_val = ir_resolve_const(ira, target_value, UndefBad); 18296 if (!target_val) 18297 return ir_unreach_error(ira); 18298 18299 IrBasicBlock *old_dest_block = switch_br_instruction->else_block; 18300 for (size_t i = 0; i < case_count; i += 1) { 18301 IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 18302 IrInstruction *case_value = old_case->value->child; 18303 if (type_is_invalid(case_value->value.type)) 18304 return ir_unreach_error(ira); 18305 18306 if (case_value->value.type->id == ZigTypeIdEnum) { 18307 case_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, case_value); 18308 if (type_is_invalid(case_value->value.type)) 18309 return ir_unreach_error(ira); 18310 } 18311 18312 IrInstruction *casted_case_value = ir_implicit_cast(ira, case_value, target_value->value.type); 18313 if (type_is_invalid(casted_case_value->value.type)) 18314 return ir_unreach_error(ira); 18315 18316 ConstExprValue *case_val = ir_resolve_const(ira, casted_case_value, UndefBad); 18317 if (!case_val) 18318 return ir_unreach_error(ira); 18319 18320 if (const_values_equal(ira->codegen, target_val, case_val)) { 18321 old_dest_block = old_case->block; 18322 break; 18323 } 18324 } 18325 18326 if (is_comptime || old_dest_block->ref_count == 1) { 18327 return ir_inline_bb(ira, &switch_br_instruction->base, old_dest_block); 18328 } else { 18329 IrBasicBlock *new_dest_block = ir_get_new_bb(ira, old_dest_block, &switch_br_instruction->base); 18330 IrInstruction *result = ir_build_br(&ira->new_irb, 18331 switch_br_instruction->base.scope, switch_br_instruction->base.source_node, 18332 new_dest_block, nullptr); 18333 result->value.type = ira->codegen->builtin_types.entry_unreachable; 18334 return ir_finish_anal(ira, result); 18335 } 18336 } 18337 18338 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(case_count); 18339 for (size_t i = 0; i < case_count; i += 1) { 18340 IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 18341 IrInstructionSwitchBrCase *new_case = &cases[i]; 18342 new_case->block = ir_get_new_bb(ira, old_case->block, &switch_br_instruction->base); 18343 new_case->value = ira->codegen->invalid_instruction; 18344 18345 // Calling ir_get_new_bb set the ref_instruction on the new basic block. 18346 // However a switch br may branch to the same basic block which would trigger an 18347 // incorrect re-generation of the block. So we set it to null here and assign 18348 // it back after the loop. 18349 new_case->block->ref_instruction = nullptr; 18350 18351 IrInstruction *old_value = old_case->value; 18352 IrInstruction *new_value = old_value->child; 18353 if (type_is_invalid(new_value->value.type)) 18354 continue; 18355 18356 if (new_value->value.type->id == ZigTypeIdEnum) { 18357 new_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, new_value); 18358 if (type_is_invalid(new_value->value.type)) 18359 continue; 18360 } 18361 18362 IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, target_value->value.type); 18363 if (type_is_invalid(casted_new_value->value.type)) 18364 continue; 18365 18366 if (!ir_resolve_const(ira, casted_new_value, UndefBad)) 18367 continue; 18368 18369 new_case->value = casted_new_value; 18370 } 18371 18372 for (size_t i = 0; i < case_count; i += 1) { 18373 IrInstructionSwitchBrCase *new_case = &cases[i]; 18374 if (new_case->value == ira->codegen->invalid_instruction) 18375 return ir_unreach_error(ira); 18376 new_case->block->ref_instruction = &switch_br_instruction->base; 18377 } 18378 18379 IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); 18380 IrInstructionSwitchBr *switch_br = ir_build_switch_br(&ira->new_irb, 18381 switch_br_instruction->base.scope, switch_br_instruction->base.source_node, 18382 target_value, new_else_block, case_count, cases, nullptr, nullptr); 18383 switch_br->base.value.type = ira->codegen->builtin_types.entry_unreachable; 18384 return ir_finish_anal(ira, &switch_br->base); 18385 } 18386 18387 static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, 18388 IrInstructionSwitchTarget *switch_target_instruction) 18389 { 18390 Error err; 18391 IrInstruction *target_value_ptr = switch_target_instruction->target_value_ptr->child; 18392 if (type_is_invalid(target_value_ptr->value.type)) 18393 return ira->codegen->invalid_instruction; 18394 18395 if (target_value_ptr->value.type->id == ZigTypeIdMetaType) { 18396 assert(instr_is_comptime(target_value_ptr)); 18397 ZigType *ptr_type = target_value_ptr->value.data.x_type; 18398 assert(ptr_type->id == ZigTypeIdPointer); 18399 return ir_const_type(ira, &switch_target_instruction->base, ptr_type->data.pointer.child_type); 18400 } 18401 18402 ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type; 18403 ConstExprValue *pointee_val = nullptr; 18404 if (instr_is_comptime(target_value_ptr)) { 18405 pointee_val = const_ptr_pointee(ira, ira->codegen, &target_value_ptr->value, target_value_ptr->source_node); 18406 if (pointee_val == nullptr) 18407 return ira->codegen->invalid_instruction; 18408 18409 if (pointee_val->special == ConstValSpecialRuntime) 18410 pointee_val = nullptr; 18411 } 18412 if ((err = ensure_complete_type(ira->codegen, target_type))) 18413 return ira->codegen->invalid_instruction; 18414 18415 switch (target_type->id) { 18416 case ZigTypeIdInvalid: 18417 zig_unreachable(); 18418 case ZigTypeIdMetaType: 18419 case ZigTypeIdVoid: 18420 case ZigTypeIdBool: 18421 case ZigTypeIdInt: 18422 case ZigTypeIdFloat: 18423 case ZigTypeIdComptimeFloat: 18424 case ZigTypeIdComptimeInt: 18425 case ZigTypeIdEnumLiteral: 18426 case ZigTypeIdPointer: 18427 case ZigTypeIdFn: 18428 case ZigTypeIdErrorSet: { 18429 if (pointee_val) { 18430 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, nullptr); 18431 copy_const_val(&result->value, pointee_val, true); 18432 result->value.type = target_type; 18433 return result; 18434 } 18435 18436 IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); 18437 result->value.type = target_type; 18438 return result; 18439 } 18440 case ZigTypeIdUnion: { 18441 AstNode *decl_node = target_type->data.unionation.decl_node; 18442 if (!decl_node->data.container_decl.auto_enum && 18443 decl_node->data.container_decl.init_arg_expr == nullptr) 18444 { 18445 ErrorMsg *msg = ir_add_error(ira, target_value_ptr, 18446 buf_sprintf("switch on union which has no attached enum")); 18447 add_error_note(ira->codegen, msg, decl_node, 18448 buf_sprintf("consider 'union(enum)' here")); 18449 return ira->codegen->invalid_instruction; 18450 } 18451 ZigType *tag_type = target_type->data.unionation.tag_type; 18452 assert(tag_type != nullptr); 18453 assert(tag_type->id == ZigTypeIdEnum); 18454 if (pointee_val) { 18455 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, tag_type); 18456 bigint_init_bigint(&result->value.data.x_enum_tag, &pointee_val->data.x_union.tag); 18457 return result; 18458 } 18459 if (tag_type->data.enumeration.src_field_count == 1) { 18460 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, tag_type); 18461 TypeEnumField *only_field = &tag_type->data.enumeration.fields[0]; 18462 bigint_init_bigint(&result->value.data.x_enum_tag, &only_field->value); 18463 return result; 18464 } 18465 18466 IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); 18467 union_value->value.type = target_type; 18468 18469 IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, 18470 switch_target_instruction->base.source_node, union_value); 18471 union_tag_inst->value.type = tag_type; 18472 return union_tag_inst; 18473 } 18474 case ZigTypeIdEnum: { 18475 if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown))) 18476 return ira->codegen->invalid_instruction; 18477 if (target_type->data.enumeration.src_field_count < 2) { 18478 TypeEnumField *only_field = &target_type->data.enumeration.fields[0]; 18479 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type); 18480 bigint_init_bigint(&result->value.data.x_enum_tag, &only_field->value); 18481 return result; 18482 } 18483 18484 if (pointee_val) { 18485 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type); 18486 bigint_init_bigint(&result->value.data.x_enum_tag, &pointee_val->data.x_enum_tag); 18487 return result; 18488 } 18489 18490 IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); 18491 enum_value->value.type = target_type; 18492 return enum_value; 18493 } 18494 case ZigTypeIdErrorUnion: 18495 case ZigTypeIdUnreachable: 18496 case ZigTypeIdArray: 18497 case ZigTypeIdStruct: 18498 case ZigTypeIdUndefined: 18499 case ZigTypeIdNull: 18500 case ZigTypeIdOptional: 18501 case ZigTypeIdBoundFn: 18502 case ZigTypeIdArgTuple: 18503 case ZigTypeIdOpaque: 18504 case ZigTypeIdVector: 18505 case ZigTypeIdFnFrame: 18506 case ZigTypeIdAnyFrame: 18507 ir_add_error(ira, &switch_target_instruction->base, 18508 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); 18509 return ira->codegen->invalid_instruction; 18510 } 18511 zig_unreachable(); 18512 } 18513 18514 static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstructionSwitchVar *instruction) { 18515 IrInstruction *target_value_ptr = instruction->target_value_ptr->child; 18516 if (type_is_invalid(target_value_ptr->value.type)) 18517 return ira->codegen->invalid_instruction; 18518 18519 ZigType *ref_type = target_value_ptr->value.type; 18520 assert(ref_type->id == ZigTypeIdPointer); 18521 ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type; 18522 if (target_type->id == ZigTypeIdUnion) { 18523 ZigType *enum_type = target_type->data.unionation.tag_type; 18524 assert(enum_type != nullptr); 18525 assert(enum_type->id == ZigTypeIdEnum); 18526 assert(instruction->prongs_len > 0); 18527 18528 IrInstruction *first_prong_value = instruction->prongs_ptr[0]->child; 18529 if (type_is_invalid(first_prong_value->value.type)) 18530 return ira->codegen->invalid_instruction; 18531 18532 IrInstruction *first_casted_prong_value = ir_implicit_cast(ira, first_prong_value, enum_type); 18533 if (type_is_invalid(first_casted_prong_value->value.type)) 18534 return ira->codegen->invalid_instruction; 18535 18536 ConstExprValue *first_prong_val = ir_resolve_const(ira, first_casted_prong_value, UndefBad); 18537 if (first_prong_val == nullptr) 18538 return ira->codegen->invalid_instruction; 18539 18540 TypeUnionField *first_field = find_union_field_by_tag(target_type, &first_prong_val->data.x_enum_tag); 18541 18542 ErrorMsg *invalid_payload_msg = nullptr; 18543 for (size_t prong_i = 1; prong_i < instruction->prongs_len; prong_i += 1) { 18544 IrInstruction *this_prong_inst = instruction->prongs_ptr[prong_i]->child; 18545 if (type_is_invalid(this_prong_inst->value.type)) 18546 return ira->codegen->invalid_instruction; 18547 18548 IrInstruction *this_casted_prong_value = ir_implicit_cast(ira, this_prong_inst, enum_type); 18549 if (type_is_invalid(this_casted_prong_value->value.type)) 18550 return ira->codegen->invalid_instruction; 18551 18552 ConstExprValue *this_prong = ir_resolve_const(ira, this_casted_prong_value, UndefBad); 18553 if (this_prong == nullptr) 18554 return ira->codegen->invalid_instruction; 18555 18556 TypeUnionField *payload_field = find_union_field_by_tag(target_type, &this_prong->data.x_enum_tag); 18557 ZigType *payload_type = payload_field->type_entry; 18558 if (first_field->type_entry != payload_type) { 18559 if (invalid_payload_msg == nullptr) { 18560 invalid_payload_msg = ir_add_error(ira, &instruction->base, 18561 buf_sprintf("capture group with incompatible types")); 18562 add_error_note(ira->codegen, invalid_payload_msg, first_prong_value->source_node, 18563 buf_sprintf("type '%s' here", buf_ptr(&first_field->type_entry->name))); 18564 } 18565 add_error_note(ira->codegen, invalid_payload_msg, this_prong_inst->source_node, 18566 buf_sprintf("type '%s' here", buf_ptr(&payload_field->type_entry->name))); 18567 } 18568 } 18569 18570 if (invalid_payload_msg != nullptr) { 18571 return ira->codegen->invalid_instruction; 18572 } 18573 18574 if (instr_is_comptime(target_value_ptr)) { 18575 ConstExprValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad); 18576 if (!target_value_ptr) 18577 return ira->codegen->invalid_instruction; 18578 18579 ConstExprValue *pointee_val = const_ptr_pointee(ira, ira->codegen, target_val_ptr, instruction->base.source_node); 18580 if (pointee_val == nullptr) 18581 return ira->codegen->invalid_instruction; 18582 18583 IrInstruction *result = ir_const(ira, &instruction->base, 18584 get_pointer_to_type(ira->codegen, first_field->type_entry, 18585 target_val_ptr->type->data.pointer.is_const)); 18586 ConstExprValue *out_val = &result->value; 18587 out_val->data.x_ptr.special = ConstPtrSpecialRef; 18588 out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut; 18589 out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_union.payload; 18590 return result; 18591 } 18592 18593 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, 18594 instruction->base.scope, instruction->base.source_node, target_value_ptr, first_field, false, false); 18595 result->value.type = get_pointer_to_type(ira->codegen, first_field->type_entry, 18596 target_value_ptr->value.type->data.pointer.is_const); 18597 return result; 18598 } else if (target_type->id == ZigTypeIdErrorSet) { 18599 // construct an error set from the prong values 18600 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 18601 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 18602 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 18603 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 18604 ZigList<ErrorTableEntry *> error_list = {}; 18605 buf_resize(&err_set_type->name, 0); 18606 buf_appendf(&err_set_type->name, "error{"); 18607 for (size_t i = 0; i < instruction->prongs_len; i += 1) { 18608 ErrorTableEntry *err = ir_resolve_error(ira, instruction->prongs_ptr[i]->child); 18609 if (err == nullptr) 18610 return ira->codegen->invalid_instruction; 18611 error_list.append(err); 18612 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&err->name)); 18613 } 18614 err_set_type->data.error_set.errors = error_list.items; 18615 err_set_type->data.error_set.err_count = error_list.length; 18616 buf_appendf(&err_set_type->name, "}"); 18617 18618 18619 ZigType *new_target_value_ptr_type = get_pointer_to_type_extra(ira->codegen, 18620 err_set_type, 18621 ref_type->data.pointer.is_const, ref_type->data.pointer.is_volatile, 18622 ref_type->data.pointer.ptr_len, 18623 ref_type->data.pointer.explicit_alignment, 18624 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, 18625 ref_type->data.pointer.allow_zero); 18626 return ir_analyze_ptr_cast(ira, &instruction->base, target_value_ptr, new_target_value_ptr_type, 18627 &instruction->base, false); 18628 } else { 18629 ir_add_error(ira, &instruction->base, 18630 buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); 18631 return ira->codegen->invalid_instruction; 18632 } 18633 } 18634 18635 static IrInstruction *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, 18636 IrInstructionSwitchElseVar *instruction) 18637 { 18638 IrInstruction *target_value_ptr = instruction->target_value_ptr->child; 18639 if (type_is_invalid(target_value_ptr->value.type)) 18640 return ira->codegen->invalid_instruction; 18641 18642 ZigType *ref_type = target_value_ptr->value.type; 18643 assert(ref_type->id == ZigTypeIdPointer); 18644 ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type; 18645 if (target_type->id == ZigTypeIdErrorSet) { 18646 // make a new set that has the other cases removed 18647 if (!resolve_inferred_error_set(ira->codegen, target_type, instruction->base.source_node)) { 18648 return ira->codegen->invalid_instruction; 18649 } 18650 if (type_is_global_error_set(target_type)) { 18651 // the type of the else capture variable still has to be the global error set. 18652 // once the runtime hint system is more sophisticated, we could add some hint information here. 18653 return target_value_ptr; 18654 } 18655 // Make note of the errors handled by other cases 18656 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 18657 for (size_t case_i = 0; case_i < instruction->switch_br->case_count; case_i += 1) { 18658 IrInstructionSwitchBrCase *br_case = &instruction->switch_br->cases[case_i]; 18659 IrInstruction *case_expr = br_case->value->child; 18660 if (case_expr->value.type->id == ZigTypeIdErrorSet) { 18661 ErrorTableEntry *err = ir_resolve_error(ira, case_expr); 18662 if (err == nullptr) 18663 return ira->codegen->invalid_instruction; 18664 errors[err->value] = err; 18665 } else if (case_expr->value.type->id == ZigTypeIdMetaType) { 18666 ZigType *err_set_type = ir_resolve_type(ira, case_expr); 18667 if (type_is_invalid(err_set_type)) 18668 return ira->codegen->invalid_instruction; 18669 populate_error_set_table(errors, err_set_type); 18670 } else { 18671 zig_unreachable(); 18672 } 18673 } 18674 ZigList<ErrorTableEntry *> result_list = {}; 18675 18676 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 18677 buf_resize(&err_set_type->name, 0); 18678 buf_appendf(&err_set_type->name, "error{"); 18679 18680 // Look at all the errors in the type switched on and add them to the result_list 18681 // if they are not handled by cases. 18682 for (uint32_t i = 0; i < target_type->data.error_set.err_count; i += 1) { 18683 ErrorTableEntry *error_entry = target_type->data.error_set.errors[i]; 18684 ErrorTableEntry *existing_entry = errors[error_entry->value]; 18685 if (existing_entry == nullptr) { 18686 result_list.append(error_entry); 18687 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 18688 } 18689 } 18690 free(errors); 18691 18692 err_set_type->data.error_set.err_count = result_list.length; 18693 err_set_type->data.error_set.errors = result_list.items; 18694 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 18695 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 18696 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 18697 18698 buf_appendf(&err_set_type->name, "}"); 18699 18700 ZigType *new_target_value_ptr_type = get_pointer_to_type_extra(ira->codegen, 18701 err_set_type, 18702 ref_type->data.pointer.is_const, ref_type->data.pointer.is_volatile, 18703 ref_type->data.pointer.ptr_len, 18704 ref_type->data.pointer.explicit_alignment, 18705 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, 18706 ref_type->data.pointer.allow_zero); 18707 return ir_analyze_ptr_cast(ira, &instruction->base, target_value_ptr, new_target_value_ptr_type, 18708 &instruction->base, false); 18709 } 18710 18711 return target_value_ptr; 18712 } 18713 18714 static IrInstruction *ir_analyze_instruction_union_tag(IrAnalyze *ira, IrInstructionUnionTag *instruction) { 18715 IrInstruction *value = instruction->value->child; 18716 return ir_analyze_union_tag(ira, &instruction->base, value); 18717 } 18718 18719 static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) { 18720 Error err; 18721 18722 IrInstruction *name_value = import_instruction->name->child; 18723 Buf *import_target_str = ir_resolve_str(ira, name_value); 18724 if (!import_target_str) 18725 return ira->codegen->invalid_instruction; 18726 18727 AstNode *source_node = import_instruction->base.source_node; 18728 ZigType *import = source_node->owner; 18729 18730 Buf *import_target_path; 18731 Buf *search_dir; 18732 assert(import->data.structure.root_struct->package); 18733 ZigPackage *target_package; 18734 auto package_entry = import->data.structure.root_struct->package->package_table.maybe_get(import_target_str); 18735 SourceKind source_kind; 18736 if (package_entry) { 18737 target_package = package_entry->value; 18738 import_target_path = &target_package->root_src_path; 18739 search_dir = &target_package->root_src_dir; 18740 source_kind = SourceKindPkgMain; 18741 } else { 18742 // try it as a filename 18743 target_package = import->data.structure.root_struct->package; 18744 import_target_path = import_target_str; 18745 18746 // search relative to importing file 18747 search_dir = buf_alloc(); 18748 os_path_dirname(import->data.structure.root_struct->path, search_dir); 18749 18750 source_kind = SourceKindNonRoot; 18751 } 18752 18753 Buf full_path = BUF_INIT; 18754 os_path_join(search_dir, import_target_path, &full_path); 18755 18756 Buf *import_code = buf_alloc(); 18757 Buf *resolved_path = buf_alloc(); 18758 18759 Buf *resolve_paths[] = { &full_path, }; 18760 *resolved_path = os_path_resolve(resolve_paths, 1); 18761 18762 auto import_entry = ira->codegen->import_table.maybe_get(resolved_path); 18763 if (import_entry) { 18764 return ir_const_type(ira, &import_instruction->base, import_entry->value); 18765 } 18766 18767 if (source_kind == SourceKindNonRoot) { 18768 ZigPackage *cur_scope_pkg = scope_package(import_instruction->base.scope); 18769 Buf *pkg_root_src_dir = &cur_scope_pkg->root_src_dir; 18770 Buf resolved_root_src_dir = os_path_resolve(&pkg_root_src_dir, 1); 18771 if (!buf_starts_with_buf(resolved_path, &resolved_root_src_dir)) { 18772 ir_add_error_node(ira, source_node, 18773 buf_sprintf("import of file outside package path: '%s'", 18774 buf_ptr(import_target_path))); 18775 return ira->codegen->invalid_instruction; 18776 } 18777 } 18778 18779 if ((err = file_fetch(ira->codegen, resolved_path, import_code))) { 18780 if (err == ErrorFileNotFound) { 18781 ir_add_error_node(ira, source_node, 18782 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); 18783 return ira->codegen->invalid_instruction; 18784 } else { 18785 ir_add_error_node(ira, source_node, 18786 buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); 18787 return ira->codegen->invalid_instruction; 18788 } 18789 } 18790 18791 ZigType *target_import = add_source_file(ira->codegen, target_package, resolved_path, import_code, source_kind); 18792 18793 return ir_const_type(ira, &import_instruction->base, target_import); 18794 } 18795 18796 static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) { 18797 IrInstruction *value = ref_instruction->value->child; 18798 if (type_is_invalid(value->value.type)) 18799 return ira->codegen->invalid_instruction; 18800 return ir_get_ref(ira, &ref_instruction->base, value, ref_instruction->is_const, ref_instruction->is_volatile); 18801 } 18802 18803 static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *source_instruction, 18804 AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstruction *field_result_loc, 18805 IrInstruction *result_loc) 18806 { 18807 Error err; 18808 assert(union_type->id == ZigTypeIdUnion); 18809 18810 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) 18811 return ira->codegen->invalid_instruction; 18812 18813 TypeUnionField *type_field = find_union_type_field(union_type, field_name); 18814 if (type_field == nullptr) { 18815 ir_add_error_node(ira, field_source_node, 18816 buf_sprintf("no member named '%s' in union '%s'", 18817 buf_ptr(field_name), buf_ptr(&union_type->name))); 18818 return ira->codegen->invalid_instruction; 18819 } 18820 18821 if (type_is_invalid(type_field->type_entry)) 18822 return ira->codegen->invalid_instruction; 18823 18824 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { 18825 if (instr_is_comptime(field_result_loc) && 18826 field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) 18827 { 18828 // nothing 18829 } else { 18830 result_loc->value.special = ConstValSpecialRuntime; 18831 } 18832 } 18833 18834 bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instruction->scope) 18835 || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes; 18836 18837 IrInstruction *result = ir_get_deref(ira, source_instruction, result_loc, nullptr); 18838 if (is_comptime && !instr_is_comptime(result)) { 18839 ir_add_error(ira, field_result_loc, 18840 buf_sprintf("unable to evaluate constant expression")); 18841 return ira->codegen->invalid_instruction; 18842 } 18843 return result; 18844 } 18845 18846 static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, 18847 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, 18848 IrInstruction *result_loc) 18849 { 18850 Error err; 18851 if (container_type->id == ZigTypeIdUnion) { 18852 if (instr_field_count != 1) { 18853 ir_add_error(ira, instruction, 18854 buf_sprintf("union initialization expects exactly one field")); 18855 return ira->codegen->invalid_instruction; 18856 } 18857 IrInstructionContainerInitFieldsField *field = &fields[0]; 18858 IrInstruction *field_result_loc = field->result_loc->child; 18859 if (type_is_invalid(field_result_loc->value.type)) 18860 return ira->codegen->invalid_instruction; 18861 18862 return ir_analyze_union_init(ira, instruction, field->source_node, container_type, field->name, 18863 field_result_loc, result_loc); 18864 } 18865 if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { 18866 ir_add_error(ira, instruction, 18867 buf_sprintf("type '%s' does not support struct initialization syntax", 18868 buf_ptr(&container_type->name))); 18869 return ira->codegen->invalid_instruction; 18870 } 18871 18872 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 18873 return ira->codegen->invalid_instruction; 18874 18875 size_t actual_field_count = container_type->data.structure.src_field_count; 18876 18877 IrInstruction *first_non_const_instruction = nullptr; 18878 18879 AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); 18880 ZigList<IrInstruction *> const_ptrs = {}; 18881 18882 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) 18883 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; 18884 18885 18886 // Here we iterate over the fields that have been initialized, and emit 18887 // compile errors for missing fields and duplicate fields. 18888 // It is only now that we find out whether the struct initialization can be a comptime 18889 // value, but we have already emitted runtime instructions for the fields that 18890 // were initialized with runtime values, and have omitted instructions that would have 18891 // initialized fields with comptime values. 18892 // So now we must clean up this situation. If it turns out the struct initialization can 18893 // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst. 18894 // Otherwise, we must emit instructions to runtime-initialize the fields that have 18895 // comptime-known values. 18896 18897 for (size_t i = 0; i < instr_field_count; i += 1) { 18898 IrInstructionContainerInitFieldsField *field = &fields[i]; 18899 18900 IrInstruction *field_result_loc = field->result_loc->child; 18901 if (type_is_invalid(field_result_loc->value.type)) 18902 return ira->codegen->invalid_instruction; 18903 18904 TypeStructField *type_field = find_struct_type_field(container_type, field->name); 18905 if (!type_field) { 18906 ir_add_error_node(ira, field->source_node, 18907 buf_sprintf("no member named '%s' in struct '%s'", 18908 buf_ptr(field->name), buf_ptr(&container_type->name))); 18909 return ira->codegen->invalid_instruction; 18910 } 18911 18912 if (type_is_invalid(type_field->type_entry)) 18913 return ira->codegen->invalid_instruction; 18914 18915 size_t field_index = type_field->src_index; 18916 AstNode *existing_assign_node = field_assign_nodes[field_index]; 18917 if (existing_assign_node) { 18918 ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field")); 18919 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); 18920 return ira->codegen->invalid_instruction; 18921 } 18922 field_assign_nodes[field_index] = field->source_node; 18923 18924 if (instr_is_comptime(field_result_loc) && 18925 field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) 18926 { 18927 const_ptrs.append(field_result_loc); 18928 } else { 18929 first_non_const_instruction = field_result_loc; 18930 } 18931 } 18932 18933 bool any_missing = false; 18934 for (size_t i = 0; i < actual_field_count; i += 1) { 18935 if (field_assign_nodes[i] != nullptr) continue; 18936 18937 // look for a default field value 18938 TypeStructField *field = &container_type->data.structure.fields[i]; 18939 if (field->init_val == nullptr) { 18940 // it's not memoized. time to go analyze it 18941 assert(field->decl_node->type == NodeTypeStructField); 18942 AstNode *init_node = field->decl_node->data.struct_field.value; 18943 if (init_node == nullptr) { 18944 ir_add_error_node(ira, instruction->source_node, 18945 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name))); 18946 any_missing = true; 18947 continue; 18948 } 18949 // scope is not the scope of the struct init, it's the scope of the struct type decl 18950 Scope *analyze_scope = &get_container_scope(container_type)->base; 18951 // memoize it 18952 field->init_val = analyze_const_value(ira->codegen, analyze_scope, init_node, 18953 field->type_entry, nullptr); 18954 } 18955 if (type_is_invalid(field->init_val->type)) 18956 return ira->codegen->invalid_instruction; 18957 18958 IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); 18959 copy_const_val(&runtime_inst->value, field->init_val, true); 18960 18961 IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc, 18962 container_type, true); 18963 ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst, false); 18964 if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { 18965 const_ptrs.append(field_ptr); 18966 } else { 18967 first_non_const_instruction = result_loc; 18968 } 18969 } 18970 if (any_missing) 18971 return ira->codegen->invalid_instruction; 18972 18973 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { 18974 if (const_ptrs.length != actual_field_count) { 18975 result_loc->value.special = ConstValSpecialRuntime; 18976 for (size_t i = 0; i < const_ptrs.length; i += 1) { 18977 IrInstruction *field_result_loc = const_ptrs.at(i); 18978 IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr); 18979 field_result_loc->value.special = ConstValSpecialRuntime; 18980 ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref, false); 18981 } 18982 } 18983 } 18984 18985 IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); 18986 18987 if (is_comptime && !instr_is_comptime(result)) { 18988 ir_add_error_node(ira, first_non_const_instruction->source_node, 18989 buf_sprintf("unable to evaluate constant expression")); 18990 return ira->codegen->invalid_instruction; 18991 } 18992 18993 return result; 18994 } 18995 18996 static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, 18997 IrInstructionContainerInitList *instruction) 18998 { 18999 ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); 19000 if (type_is_invalid(container_type)) 19001 return ira->codegen->invalid_instruction; 19002 19003 size_t elem_count = instruction->item_count; 19004 19005 if (is_slice(container_type)) { 19006 ir_add_error(ira, instruction->container_type, 19007 buf_sprintf("expected array type or [_], found slice")); 19008 return ira->codegen->invalid_instruction; 19009 } 19010 19011 if (container_type->id == ZigTypeIdVoid) { 19012 if (elem_count != 0) { 19013 ir_add_error_node(ira, instruction->base.source_node, 19014 buf_sprintf("void expression expects no arguments")); 19015 return ira->codegen->invalid_instruction; 19016 } 19017 return ir_const_void(ira, &instruction->base); 19018 } 19019 19020 if (container_type->id == ZigTypeIdStruct && elem_count == 0) { 19021 ir_assert(instruction->result_loc != nullptr, &instruction->base); 19022 IrInstruction *result_loc = instruction->result_loc->child; 19023 if (type_is_invalid(result_loc->value.type)) 19024 return result_loc; 19025 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc); 19026 } 19027 19028 if (container_type->id != ZigTypeIdArray) { 19029 ir_add_error_node(ira, instruction->base.source_node, 19030 buf_sprintf("type '%s' does not support array initialization", 19031 buf_ptr(&container_type->name))); 19032 return ira->codegen->invalid_instruction; 19033 } 19034 19035 ir_assert(instruction->result_loc != nullptr, &instruction->base); 19036 IrInstruction *result_loc = instruction->result_loc->child; 19037 if (type_is_invalid(result_loc->value.type)) 19038 return result_loc; 19039 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base); 19040 19041 ZigType *child_type = container_type->data.array.child_type; 19042 if (container_type->data.array.len != elem_count) { 19043 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); 19044 19045 ir_add_error(ira, &instruction->base, 19046 buf_sprintf("expected %s literal, found %s literal", 19047 buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); 19048 return ira->codegen->invalid_instruction; 19049 } 19050 19051 switch (type_has_one_possible_value(ira->codegen, container_type)) { 19052 case OnePossibleValueInvalid: 19053 return ira->codegen->invalid_instruction; 19054 case OnePossibleValueYes: 19055 return ir_const(ira, &instruction->base, container_type); 19056 case OnePossibleValueNo: 19057 break; 19058 } 19059 19060 bool is_comptime; 19061 switch (type_requires_comptime(ira->codegen, container_type)) { 19062 case ReqCompTimeInvalid: 19063 return ira->codegen->invalid_instruction; 19064 case ReqCompTimeNo: 19065 is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); 19066 break; 19067 case ReqCompTimeYes: 19068 is_comptime = true; 19069 break; 19070 } 19071 19072 IrInstruction *first_non_const_instruction = nullptr; 19073 19074 // The Result Location Mechanism has already emitted runtime instructions to 19075 // initialize runtime elements and has omitted instructions for the comptime 19076 // elements. However it is only now that we find out whether the array initialization 19077 // can be a comptime value. So we must clean up the situation. If it turns out 19078 // array initialization can be a comptime value, overwrite ConstPtrMutInfer with 19079 // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the 19080 // elements that have comptime-known values. 19081 ZigList<IrInstruction *> const_ptrs = {}; 19082 19083 for (size_t i = 0; i < elem_count; i += 1) { 19084 IrInstruction *elem_result_loc = instruction->elem_result_loc_list[i]->child; 19085 if (type_is_invalid(elem_result_loc->value.type)) 19086 return ira->codegen->invalid_instruction; 19087 19088 assert(elem_result_loc->value.type->id == ZigTypeIdPointer); 19089 19090 if (instr_is_comptime(elem_result_loc) && 19091 elem_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) 19092 { 19093 const_ptrs.append(elem_result_loc); 19094 } else { 19095 first_non_const_instruction = elem_result_loc; 19096 } 19097 } 19098 19099 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { 19100 if (const_ptrs.length != elem_count) { 19101 result_loc->value.special = ConstValSpecialRuntime; 19102 for (size_t i = 0; i < const_ptrs.length; i += 1) { 19103 IrInstruction *elem_result_loc = const_ptrs.at(i); 19104 assert(elem_result_loc->value.special == ConstValSpecialStatic); 19105 IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr); 19106 elem_result_loc->value.special = ConstValSpecialRuntime; 19107 ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref, false); 19108 } 19109 } 19110 } 19111 19112 IrInstruction *result = ir_get_deref(ira, &instruction->base, result_loc, nullptr); 19113 if (instr_is_comptime(result)) 19114 return result; 19115 19116 if (is_comptime) { 19117 ir_add_error_node(ira, first_non_const_instruction->source_node, 19118 buf_sprintf("unable to evaluate constant expression")); 19119 return ira->codegen->invalid_instruction; 19120 } 19121 19122 ZigType *result_elem_type = result_loc->value.type->data.pointer.child_type; 19123 if (is_slice(result_elem_type)) { 19124 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 19125 buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", 19126 buf_ptr(&result_elem_type->name))); 19127 add_error_note(ira->codegen, msg, first_non_const_instruction->source_node, 19128 buf_sprintf("this value is not comptime-known")); 19129 return ira->codegen->invalid_instruction; 19130 } 19131 return result; 19132 } 19133 19134 static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, 19135 IrInstructionContainerInitFields *instruction) 19136 { 19137 IrInstruction *container_type_value = instruction->container_type->child; 19138 ZigType *container_type = ir_resolve_type(ira, container_type_value); 19139 if (type_is_invalid(container_type)) 19140 return ira->codegen->invalid_instruction; 19141 19142 ir_assert(instruction->result_loc != nullptr, &instruction->base); 19143 IrInstruction *result_loc = instruction->result_loc->child; 19144 if (type_is_invalid(result_loc->value.type)) 19145 return result_loc; 19146 19147 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 19148 instruction->field_count, instruction->fields, result_loc); 19149 } 19150 19151 static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, 19152 IrInstructionCompileErr *instruction) 19153 { 19154 IrInstruction *msg_value = instruction->msg->child; 19155 Buf *msg_buf = ir_resolve_str(ira, msg_value); 19156 if (!msg_buf) 19157 return ira->codegen->invalid_instruction; 19158 19159 ErrorMsg *msg = ir_add_error(ira, &instruction->base, msg_buf); 19160 emit_error_notes_for_ref_stack(ira->codegen, msg); 19161 19162 return ira->codegen->invalid_instruction; 19163 } 19164 19165 static IrInstruction *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstructionCompileLog *instruction) { 19166 Buf buf = BUF_INIT; 19167 fprintf(stderr, "| "); 19168 for (size_t i = 0; i < instruction->msg_count; i += 1) { 19169 IrInstruction *msg = instruction->msg_list[i]->child; 19170 if (type_is_invalid(msg->value.type)) 19171 return ira->codegen->invalid_instruction; 19172 buf_resize(&buf, 0); 19173 render_const_value(ira->codegen, &buf, &msg->value); 19174 const char *comma_str = (i != 0) ? ", " : ""; 19175 fprintf(stderr, "%s%s", comma_str, buf_ptr(&buf)); 19176 } 19177 fprintf(stderr, "\n"); 19178 19179 auto *expr = &instruction->base.source_node->data.fn_call_expr; 19180 if (!expr->seen) { 19181 // Here we bypass higher level functions such as ir_add_error because we do not want 19182 // invalidate_exec to be called. 19183 add_node_error(ira->codegen, instruction->base.source_node, buf_sprintf("found compile log statement")); 19184 } 19185 expr->seen = true; 19186 19187 return ir_const_void(ira, &instruction->base); 19188 } 19189 19190 static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstructionErrName *instruction) { 19191 IrInstruction *value = instruction->value->child; 19192 if (type_is_invalid(value->value.type)) 19193 return ira->codegen->invalid_instruction; 19194 19195 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_global_error_set); 19196 if (type_is_invalid(casted_value->value.type)) 19197 return ira->codegen->invalid_instruction; 19198 19199 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 19200 true, false, PtrLenUnknown, 0, 0, 0, false); 19201 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 19202 if (casted_value->value.special == ConstValSpecialStatic) { 19203 ErrorTableEntry *err = casted_value->value.data.x_err_set; 19204 if (!err->cached_error_name_val) { 19205 ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name); 19206 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); 19207 } 19208 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 19209 copy_const_val(&result->value, err->cached_error_name_val, true); 19210 result->value.type = str_type; 19211 return result; 19212 } 19213 19214 ira->codegen->generate_error_name_table = true; 19215 19216 IrInstruction *result = ir_build_err_name(&ira->new_irb, 19217 instruction->base.scope, instruction->base.source_node, value); 19218 result->value.type = str_type; 19219 return result; 19220 } 19221 19222 static IrInstruction *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionTagName *instruction) { 19223 Error err; 19224 IrInstruction *target = instruction->target->child; 19225 if (type_is_invalid(target->value.type)) 19226 return ira->codegen->invalid_instruction; 19227 19228 assert(target->value.type->id == ZigTypeIdEnum); 19229 19230 if (instr_is_comptime(target)) { 19231 if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusZeroBitsKnown))) 19232 return ira->codegen->invalid_instruction; 19233 TypeEnumField *field = find_enum_field_by_tag(target->value.type, &target->value.data.x_bigint); 19234 ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name); 19235 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 19236 init_const_slice(ira->codegen, &result->value, array_val, 0, buf_len(field->name), true); 19237 return result; 19238 } 19239 19240 IrInstruction *result = ir_build_tag_name(&ira->new_irb, instruction->base.scope, 19241 instruction->base.source_node, target); 19242 ZigType *u8_ptr_type = get_pointer_to_type_extra( 19243 ira->codegen, ira->codegen->builtin_types.entry_u8, 19244 true, false, PtrLenUnknown, 19245 0, 0, 0, false); 19246 result->value.type = get_slice_type(ira->codegen, u8_ptr_type); 19247 return result; 19248 } 19249 19250 static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, 19251 IrInstructionFieldParentPtr *instruction) 19252 { 19253 Error err; 19254 IrInstruction *type_value = instruction->type_value->child; 19255 ZigType *container_type = ir_resolve_type(ira, type_value); 19256 if (type_is_invalid(container_type)) 19257 return ira->codegen->invalid_instruction; 19258 19259 IrInstruction *field_name_value = instruction->field_name->child; 19260 Buf *field_name = ir_resolve_str(ira, field_name_value); 19261 if (!field_name) 19262 return ira->codegen->invalid_instruction; 19263 19264 IrInstruction *field_ptr = instruction->field_ptr->child; 19265 if (type_is_invalid(field_ptr->value.type)) 19266 return ira->codegen->invalid_instruction; 19267 19268 if (container_type->id != ZigTypeIdStruct) { 19269 ir_add_error(ira, type_value, 19270 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 19271 return ira->codegen->invalid_instruction; 19272 } 19273 19274 if ((err = ensure_complete_type(ira->codegen, container_type))) 19275 return ira->codegen->invalid_instruction; 19276 19277 TypeStructField *field = find_struct_type_field(container_type, field_name); 19278 if (field == nullptr) { 19279 ir_add_error(ira, field_name_value, 19280 buf_sprintf("struct '%s' has no field '%s'", 19281 buf_ptr(&container_type->name), buf_ptr(field_name))); 19282 return ira->codegen->invalid_instruction; 19283 } 19284 19285 if (field_ptr->value.type->id != ZigTypeIdPointer) { 19286 ir_add_error(ira, field_ptr, 19287 buf_sprintf("expected pointer, found '%s'", buf_ptr(&field_ptr->value.type->name))); 19288 return ira->codegen->invalid_instruction; 19289 } 19290 19291 bool is_packed = (container_type->data.structure.layout == ContainerLayoutPacked); 19292 uint32_t field_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 19293 uint32_t parent_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, container_type); 19294 19295 ZigType *field_ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, 19296 field_ptr->value.type->data.pointer.is_const, 19297 field_ptr->value.type->data.pointer.is_volatile, 19298 PtrLenSingle, 19299 field_ptr_align, 0, 0, false); 19300 IrInstruction *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type); 19301 if (type_is_invalid(casted_field_ptr->value.type)) 19302 return ira->codegen->invalid_instruction; 19303 19304 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, container_type, 19305 casted_field_ptr->value.type->data.pointer.is_const, 19306 casted_field_ptr->value.type->data.pointer.is_volatile, 19307 PtrLenSingle, 19308 parent_ptr_align, 0, 0, false); 19309 19310 if (instr_is_comptime(casted_field_ptr)) { 19311 ConstExprValue *field_ptr_val = ir_resolve_const(ira, casted_field_ptr, UndefBad); 19312 if (!field_ptr_val) 19313 return ira->codegen->invalid_instruction; 19314 19315 if (field_ptr_val->data.x_ptr.special != ConstPtrSpecialBaseStruct) { 19316 ir_add_error(ira, field_ptr, buf_sprintf("pointer value not based on parent struct")); 19317 return ira->codegen->invalid_instruction; 19318 } 19319 19320 size_t ptr_field_index = field_ptr_val->data.x_ptr.data.base_struct.field_index; 19321 if (ptr_field_index != field->src_index) { 19322 ir_add_error(ira, &instruction->base, 19323 buf_sprintf("field '%s' has index %" ZIG_PRI_usize " but pointer value is index %" ZIG_PRI_usize " of struct '%s'", 19324 buf_ptr(field->name), field->src_index, 19325 ptr_field_index, buf_ptr(&container_type->name))); 19326 return ira->codegen->invalid_instruction; 19327 } 19328 19329 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 19330 ConstExprValue *out_val = &result->value; 19331 out_val->data.x_ptr.special = ConstPtrSpecialRef; 19332 out_val->data.x_ptr.data.ref.pointee = field_ptr_val->data.x_ptr.data.base_struct.struct_val; 19333 out_val->data.x_ptr.mut = field_ptr_val->data.x_ptr.mut; 19334 return result; 19335 } 19336 19337 IrInstruction *result = ir_build_field_parent_ptr(&ira->new_irb, instruction->base.scope, 19338 instruction->base.source_node, type_value, field_name_value, casted_field_ptr, field); 19339 result->value.type = result_type; 19340 return result; 19341 } 19342 19343 static TypeStructField *validate_byte_offset(IrAnalyze *ira, 19344 IrInstruction *type_value, 19345 IrInstruction *field_name_value, 19346 size_t *byte_offset) 19347 { 19348 ZigType *container_type = ir_resolve_type(ira, type_value); 19349 if (type_is_invalid(container_type)) 19350 return nullptr; 19351 19352 Error err; 19353 if ((err = ensure_complete_type(ira->codegen, container_type))) 19354 return nullptr; 19355 19356 Buf *field_name = ir_resolve_str(ira, field_name_value); 19357 if (!field_name) 19358 return nullptr; 19359 19360 if (container_type->id != ZigTypeIdStruct) { 19361 ir_add_error(ira, type_value, 19362 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 19363 return nullptr; 19364 } 19365 19366 TypeStructField *field = find_struct_type_field(container_type, field_name); 19367 if (field == nullptr) { 19368 ir_add_error(ira, field_name_value, 19369 buf_sprintf("struct '%s' has no field '%s'", 19370 buf_ptr(&container_type->name), buf_ptr(field_name))); 19371 return nullptr; 19372 } 19373 19374 if (!type_has_bits(field->type_entry)) { 19375 ir_add_error(ira, field_name_value, 19376 buf_sprintf("zero-bit field '%s' in struct '%s' has no offset", 19377 buf_ptr(field_name), buf_ptr(&container_type->name))); 19378 return nullptr; 19379 } 19380 19381 *byte_offset = field->offset; 19382 return field; 19383 } 19384 19385 static IrInstruction *ir_analyze_instruction_byte_offset_of(IrAnalyze *ira, 19386 IrInstructionByteOffsetOf *instruction) 19387 { 19388 IrInstruction *type_value = instruction->type_value->child; 19389 if (type_is_invalid(type_value->value.type)) 19390 return ira->codegen->invalid_instruction; 19391 19392 IrInstruction *field_name_value = instruction->field_name->child; 19393 size_t byte_offset = 0; 19394 if (!validate_byte_offset(ira, type_value, field_name_value, &byte_offset)) 19395 return ira->codegen->invalid_instruction; 19396 19397 19398 return ir_const_unsigned(ira, &instruction->base, byte_offset); 19399 } 19400 19401 static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, 19402 IrInstructionBitOffsetOf *instruction) 19403 { 19404 IrInstruction *type_value = instruction->type_value->child; 19405 if (type_is_invalid(type_value->value.type)) 19406 return ira->codegen->invalid_instruction; 19407 IrInstruction *field_name_value = instruction->field_name->child; 19408 size_t byte_offset = 0; 19409 TypeStructField *field = nullptr; 19410 if (!(field = validate_byte_offset(ira, type_value, field_name_value, &byte_offset))) 19411 return ira->codegen->invalid_instruction; 19412 19413 size_t bit_offset = byte_offset * 8 + field->bit_offset_in_host; 19414 return ir_const_unsigned(ira, &instruction->base, bit_offset); 19415 } 19416 19417 static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { 19418 Buf *field_name_buf; 19419 19420 assert(type != nullptr && !type_is_invalid(type)); 19421 // Check for our field by creating a buffer in place then using the comma operator to free it so that we don't 19422 // leak memory in debug mode. 19423 assert(find_struct_type_field(type, field_name_buf = buf_create_from_str(field_name))->src_index == index && 19424 (buf_deinit(field_name_buf), true)); 19425 } 19426 19427 static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) { 19428 Error err; 19429 ConstExprValue *type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); 19430 assert(type_info_var->type->id == ZigTypeIdMetaType); 19431 ZigType *type_info_type = type_info_var->data.x_type; 19432 assert(type_info_type->id == ZigTypeIdUnion); 19433 if ((err = type_resolve(ira->codegen, type_info_type, ResolveStatusSizeKnown))) { 19434 zig_unreachable(); 19435 } 19436 19437 if (type_name == nullptr && root == nullptr) 19438 return type_info_type; 19439 else if (type_name == nullptr) 19440 return root; 19441 19442 ZigType *root_type = (root == nullptr) ? type_info_type : root; 19443 19444 ScopeDecls *type_info_scope = get_container_scope(root_type); 19445 assert(type_info_scope != nullptr); 19446 19447 Buf field_name = BUF_INIT; 19448 buf_init_from_str(&field_name, type_name); 19449 auto entry = type_info_scope->decl_table.get(&field_name); 19450 buf_deinit(&field_name); 19451 19452 TldVar *tld = (TldVar *)entry; 19453 assert(tld->base.id == TldIdVar); 19454 19455 ZigVar *var = tld->var; 19456 19457 if ((err = ensure_complete_type(ira->codegen, var->const_value->type))) 19458 return ira->codegen->builtin_types.entry_invalid; 19459 19460 assert(var->const_value->type->id == ZigTypeIdMetaType); 19461 return var->const_value->data.x_type; 19462 } 19463 19464 static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val, 19465 ScopeDecls *decls_scope) 19466 { 19467 Error err; 19468 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr); 19469 if ((err = type_resolve(ira->codegen, type_info_declaration_type, ResolveStatusSizeKnown))) 19470 return err; 19471 19472 ensure_field_index(type_info_declaration_type, "name", 0); 19473 ensure_field_index(type_info_declaration_type, "is_pub", 1); 19474 ensure_field_index(type_info_declaration_type, "data", 2); 19475 19476 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type); 19477 if ((err = ensure_complete_type(ira->codegen, type_info_declaration_data_type))) 19478 return err; 19479 19480 ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type); 19481 if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_type))) 19482 return err; 19483 19484 ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type); 19485 if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_inline_type))) 19486 return err; 19487 19488 // Loop through our declarations once to figure out how many declarations we will generate info for. 19489 auto decl_it = decls_scope->decl_table.entry_iterator(); 19490 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; 19491 int declaration_count = 0; 19492 19493 while ((curr_entry = decl_it.next()) != nullptr) { 19494 // If the declaration is unresolved, force it to be resolved again. 19495 if (curr_entry->value->resolution == TldResolutionUnresolved) { 19496 resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node); 19497 if (curr_entry->value->resolution != TldResolutionOk) { 19498 return ErrorSemanticAnalyzeFail; 19499 } 19500 } 19501 19502 // Skip comptime blocks and test functions. 19503 if (curr_entry->value->id != TldIdCompTime) { 19504 if (curr_entry->value->id == TldIdFn) { 19505 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 19506 if (fn_entry->is_test) 19507 continue; 19508 } 19509 19510 declaration_count += 1; 19511 } 19512 } 19513 19514 ConstExprValue *declaration_array = create_const_vals(1); 19515 declaration_array->special = ConstValSpecialStatic; 19516 declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count); 19517 declaration_array->data.x_array.special = ConstArraySpecialNone; 19518 declaration_array->data.x_array.data.s_none.elements = create_const_vals(declaration_count); 19519 init_const_slice(ira->codegen, out_val, declaration_array, 0, declaration_count, false); 19520 19521 // Loop through the declarations and generate info. 19522 decl_it = decls_scope->decl_table.entry_iterator(); 19523 curr_entry = nullptr; 19524 int declaration_index = 0; 19525 while ((curr_entry = decl_it.next()) != nullptr) { 19526 // Skip comptime blocks and test functions. 19527 if (curr_entry->value->id == TldIdCompTime) { 19528 continue; 19529 } else if (curr_entry->value->id == TldIdFn) { 19530 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 19531 if (fn_entry->is_test) 19532 continue; 19533 } 19534 19535 ConstExprValue *declaration_val = &declaration_array->data.x_array.data.s_none.elements[declaration_index]; 19536 19537 declaration_val->special = ConstValSpecialStatic; 19538 declaration_val->type = type_info_declaration_type; 19539 19540 ConstExprValue *inner_fields = create_const_vals(3); 19541 ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key); 19542 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(curr_entry->key), true); 19543 inner_fields[1].special = ConstValSpecialStatic; 19544 inner_fields[1].type = ira->codegen->builtin_types.entry_bool; 19545 inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub; 19546 inner_fields[2].special = ConstValSpecialStatic; 19547 inner_fields[2].type = type_info_declaration_data_type; 19548 inner_fields[2].parent.id = ConstParentIdStruct; 19549 inner_fields[2].parent.data.p_struct.struct_val = declaration_val; 19550 inner_fields[2].parent.data.p_struct.field_index = 1; 19551 19552 switch (curr_entry->value->id) { 19553 case TldIdVar: 19554 { 19555 ZigVar *var = ((TldVar *)curr_entry->value)->var; 19556 if ((err = ensure_complete_type(ira->codegen, var->const_value->type))) 19557 return ErrorSemanticAnalyzeFail; 19558 19559 if (var->const_value->type->id == ZigTypeIdMetaType) { 19560 // We have a variable of type 'type', so it's actually a type declaration. 19561 // 0: Data.Type: type 19562 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); 19563 inner_fields[2].data.x_union.payload = var->const_value; 19564 } else { 19565 // We have a variable of another type, so we store the type of the variable. 19566 // 1: Data.Var: type 19567 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 1); 19568 19569 ConstExprValue *payload = create_const_vals(1); 19570 payload->type = ira->codegen->builtin_types.entry_type; 19571 payload->data.x_type = var->const_value->type; 19572 19573 inner_fields[2].data.x_union.payload = payload; 19574 } 19575 19576 break; 19577 } 19578 case TldIdFn: 19579 { 19580 // 2: Data.Fn: Data.FnDecl 19581 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2); 19582 19583 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 19584 assert(!fn_entry->is_test); 19585 19586 if (fn_entry->type_entry == nullptr) { 19587 ir_error_dependency_loop(ira, source_instr); 19588 return ErrorSemanticAnalyzeFail; 19589 } 19590 19591 AstNodeFnProto *fn_node = &fn_entry->proto_node->data.fn_proto; 19592 19593 ConstExprValue *fn_decl_val = create_const_vals(1); 19594 fn_decl_val->special = ConstValSpecialStatic; 19595 fn_decl_val->type = type_info_fn_decl_type; 19596 fn_decl_val->parent.id = ConstParentIdUnion; 19597 fn_decl_val->parent.data.p_union.union_val = &inner_fields[2]; 19598 19599 ConstExprValue *fn_decl_fields = create_const_vals(9); 19600 fn_decl_val->data.x_struct.fields = fn_decl_fields; 19601 19602 // fn_type: type 19603 ensure_field_index(fn_decl_val->type, "fn_type", 0); 19604 fn_decl_fields[0].special = ConstValSpecialStatic; 19605 fn_decl_fields[0].type = ira->codegen->builtin_types.entry_type; 19606 fn_decl_fields[0].data.x_type = fn_entry->type_entry; 19607 // inline_type: Data.FnDecl.Inline 19608 ensure_field_index(fn_decl_val->type, "inline_type", 1); 19609 fn_decl_fields[1].special = ConstValSpecialStatic; 19610 fn_decl_fields[1].type = type_info_fn_decl_inline_type; 19611 bigint_init_unsigned(&fn_decl_fields[1].data.x_enum_tag, fn_entry->fn_inline); 19612 // calling_convention: TypeInfo.CallingConvention 19613 ensure_field_index(fn_decl_val->type, "calling_convention", 2); 19614 fn_decl_fields[2].special = ConstValSpecialStatic; 19615 fn_decl_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); 19616 bigint_init_unsigned(&fn_decl_fields[2].data.x_enum_tag, fn_node->cc); 19617 // is_var_args: bool 19618 ensure_field_index(fn_decl_val->type, "is_var_args", 3); 19619 bool is_varargs = fn_node->is_var_args; 19620 fn_decl_fields[3].special = ConstValSpecialStatic; 19621 fn_decl_fields[3].type = ira->codegen->builtin_types.entry_bool; 19622 fn_decl_fields[3].data.x_bool = is_varargs; 19623 // is_extern: bool 19624 ensure_field_index(fn_decl_val->type, "is_extern", 4); 19625 fn_decl_fields[4].special = ConstValSpecialStatic; 19626 fn_decl_fields[4].type = ira->codegen->builtin_types.entry_bool; 19627 fn_decl_fields[4].data.x_bool = fn_node->is_extern; 19628 // is_export: bool 19629 ensure_field_index(fn_decl_val->type, "is_export", 5); 19630 fn_decl_fields[5].special = ConstValSpecialStatic; 19631 fn_decl_fields[5].type = ira->codegen->builtin_types.entry_bool; 19632 fn_decl_fields[5].data.x_bool = fn_node->is_export; 19633 // lib_name: ?[]const u8 19634 ensure_field_index(fn_decl_val->type, "lib_name", 6); 19635 fn_decl_fields[6].special = ConstValSpecialStatic; 19636 ZigType *u8_ptr = get_pointer_to_type_extra( 19637 ira->codegen, ira->codegen->builtin_types.entry_u8, 19638 true, false, PtrLenUnknown, 19639 0, 0, 0, false); 19640 fn_decl_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); 19641 if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) { 19642 fn_decl_fields[6].data.x_optional = create_const_vals(1); 19643 ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name); 19644 init_const_slice(ira->codegen, fn_decl_fields[6].data.x_optional, lib_name, 0, 19645 buf_len(fn_node->lib_name), true); 19646 } else { 19647 fn_decl_fields[6].data.x_optional = nullptr; 19648 } 19649 // return_type: type 19650 ensure_field_index(fn_decl_val->type, "return_type", 7); 19651 fn_decl_fields[7].special = ConstValSpecialStatic; 19652 fn_decl_fields[7].type = ira->codegen->builtin_types.entry_type; 19653 fn_decl_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; 19654 // arg_names: [][] const u8 19655 ensure_field_index(fn_decl_val->type, "arg_names", 8); 19656 size_t fn_arg_count = fn_entry->variable_list.length; 19657 ConstExprValue *fn_arg_name_array = create_const_vals(1); 19658 fn_arg_name_array->special = ConstValSpecialStatic; 19659 fn_arg_name_array->type = get_array_type(ira->codegen, 19660 get_slice_type(ira->codegen, u8_ptr), fn_arg_count); 19661 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; 19662 fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); 19663 19664 init_const_slice(ira->codegen, &fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false); 19665 19666 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { 19667 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); 19668 ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index]; 19669 ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name); 19670 init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true); 19671 fn_arg_name_val->parent.id = ConstParentIdArray; 19672 fn_arg_name_val->parent.data.p_array.array_val = fn_arg_name_array; 19673 fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index; 19674 } 19675 19676 inner_fields[2].data.x_union.payload = fn_decl_val; 19677 break; 19678 } 19679 case TldIdContainer: 19680 { 19681 ZigType *type_entry = ((TldContainer *)curr_entry->value)->type_entry; 19682 if ((err = ensure_complete_type(ira->codegen, type_entry))) 19683 return ErrorSemanticAnalyzeFail; 19684 19685 // This is a type. 19686 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); 19687 19688 ConstExprValue *payload = create_const_vals(1); 19689 payload->type = ira->codegen->builtin_types.entry_type; 19690 payload->data.x_type = type_entry; 19691 19692 inner_fields[2].data.x_union.payload = payload; 19693 19694 break; 19695 } 19696 default: 19697 zig_unreachable(); 19698 } 19699 19700 declaration_val->data.x_struct.fields = inner_fields; 19701 declaration_index++; 19702 } 19703 19704 assert(declaration_index == declaration_count); 19705 return ErrorNone; 19706 } 19707 19708 static uint32_t ptr_len_to_size_enum_index(PtrLen ptr_len) { 19709 switch (ptr_len) { 19710 case PtrLenSingle: 19711 return 0; 19712 case PtrLenUnknown: 19713 return 1; 19714 case PtrLenC: 19715 return 3; 19716 } 19717 zig_unreachable(); 19718 } 19719 19720 static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) { 19721 Error err; 19722 ZigType *attrs_type; 19723 uint32_t size_enum_index; 19724 if (is_slice(ptr_type_entry)) { 19725 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index].type_entry; 19726 size_enum_index = 2; 19727 } else if (ptr_type_entry->id == ZigTypeIdPointer) { 19728 attrs_type = ptr_type_entry; 19729 size_enum_index = ptr_len_to_size_enum_index(ptr_type_entry->data.pointer.ptr_len); 19730 } else { 19731 zig_unreachable(); 19732 } 19733 19734 if ((err = type_resolve(ira->codegen, attrs_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 19735 return nullptr; 19736 19737 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 19738 assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_type)); 19739 19740 ConstExprValue *result = create_const_vals(1); 19741 result->special = ConstValSpecialStatic; 19742 result->type = type_info_pointer_type; 19743 19744 ConstExprValue *fields = create_const_vals(6); 19745 result->data.x_struct.fields = fields; 19746 19747 // size: Size 19748 ensure_field_index(result->type, "size", 0); 19749 ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); 19750 assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_size_type)); 19751 fields[0].special = ConstValSpecialStatic; 19752 fields[0].type = type_info_pointer_size_type; 19753 bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index); 19754 19755 // is_const: bool 19756 ensure_field_index(result->type, "is_const", 1); 19757 fields[1].special = ConstValSpecialStatic; 19758 fields[1].type = ira->codegen->builtin_types.entry_bool; 19759 fields[1].data.x_bool = attrs_type->data.pointer.is_const; 19760 // is_volatile: bool 19761 ensure_field_index(result->type, "is_volatile", 2); 19762 fields[2].special = ConstValSpecialStatic; 19763 fields[2].type = ira->codegen->builtin_types.entry_bool; 19764 fields[2].data.x_bool = attrs_type->data.pointer.is_volatile; 19765 // alignment: u32 19766 ensure_field_index(result->type, "alignment", 3); 19767 fields[3].special = ConstValSpecialStatic; 19768 fields[3].type = ira->codegen->builtin_types.entry_num_lit_int; 19769 bigint_init_unsigned(&fields[3].data.x_bigint, get_ptr_align(ira->codegen, attrs_type)); 19770 // child: type 19771 ensure_field_index(result->type, "child", 4); 19772 fields[4].special = ConstValSpecialStatic; 19773 fields[4].type = ira->codegen->builtin_types.entry_type; 19774 fields[4].data.x_type = attrs_type->data.pointer.child_type; 19775 // is_allowzero: bool 19776 ensure_field_index(result->type, "is_allowzero", 5); 19777 fields[5].special = ConstValSpecialStatic; 19778 fields[5].type = ira->codegen->builtin_types.entry_bool; 19779 fields[5].data.x_bool = attrs_type->data.pointer.allow_zero; 19780 19781 return result; 19782 }; 19783 19784 static void make_enum_field_val(IrAnalyze *ira, ConstExprValue *enum_field_val, TypeEnumField *enum_field, 19785 ZigType *type_info_enum_field_type) 19786 { 19787 enum_field_val->special = ConstValSpecialStatic; 19788 enum_field_val->type = type_info_enum_field_type; 19789 19790 ConstExprValue *inner_fields = create_const_vals(2); 19791 inner_fields[1].special = ConstValSpecialStatic; 19792 inner_fields[1].type = ira->codegen->builtin_types.entry_num_lit_int; 19793 19794 ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name); 19795 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(enum_field->name), true); 19796 19797 bigint_init_bigint(&inner_fields[1].data.x_bigint, &enum_field->value); 19798 19799 enum_field_val->data.x_struct.fields = inner_fields; 19800 } 19801 19802 static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr, ZigType *type_entry, 19803 ConstExprValue **out) 19804 { 19805 Error err; 19806 assert(type_entry != nullptr); 19807 assert(!type_is_invalid(type_entry)); 19808 19809 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 19810 return err; 19811 19812 auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); 19813 if (entry != nullptr) { 19814 *out = entry->value; 19815 return ErrorNone; 19816 } 19817 19818 ConstExprValue *result = nullptr; 19819 switch (type_entry->id) { 19820 case ZigTypeIdInvalid: 19821 zig_unreachable(); 19822 case ZigTypeIdMetaType: 19823 case ZigTypeIdVoid: 19824 case ZigTypeIdBool: 19825 case ZigTypeIdUnreachable: 19826 case ZigTypeIdComptimeFloat: 19827 case ZigTypeIdComptimeInt: 19828 case ZigTypeIdEnumLiteral: 19829 case ZigTypeIdUndefined: 19830 case ZigTypeIdNull: 19831 case ZigTypeIdArgTuple: 19832 case ZigTypeIdOpaque: 19833 result = &ira->codegen->const_void_val; 19834 break; 19835 case ZigTypeIdInt: 19836 { 19837 result = create_const_vals(1); 19838 result->special = ConstValSpecialStatic; 19839 result->type = ir_type_info_get_type(ira, "Int", nullptr); 19840 19841 ConstExprValue *fields = create_const_vals(2); 19842 result->data.x_struct.fields = fields; 19843 19844 // is_signed: bool 19845 ensure_field_index(result->type, "is_signed", 0); 19846 fields[0].special = ConstValSpecialStatic; 19847 fields[0].type = ira->codegen->builtin_types.entry_bool; 19848 fields[0].data.x_bool = type_entry->data.integral.is_signed; 19849 // bits: u8 19850 ensure_field_index(result->type, "bits", 1); 19851 fields[1].special = ConstValSpecialStatic; 19852 fields[1].type = ira->codegen->builtin_types.entry_num_lit_int; 19853 bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); 19854 19855 break; 19856 } 19857 case ZigTypeIdFloat: 19858 { 19859 result = create_const_vals(1); 19860 result->special = ConstValSpecialStatic; 19861 result->type = ir_type_info_get_type(ira, "Float", nullptr); 19862 19863 ConstExprValue *fields = create_const_vals(1); 19864 result->data.x_struct.fields = fields; 19865 19866 // bits: u8 19867 ensure_field_index(result->type, "bits", 0); 19868 fields[0].special = ConstValSpecialStatic; 19869 fields[0].type = ira->codegen->builtin_types.entry_num_lit_int; 19870 bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); 19871 19872 break; 19873 } 19874 case ZigTypeIdPointer: 19875 { 19876 result = create_ptr_like_type_info(ira, type_entry); 19877 if (result == nullptr) 19878 return ErrorSemanticAnalyzeFail; 19879 break; 19880 } 19881 case ZigTypeIdArray: 19882 { 19883 result = create_const_vals(1); 19884 result->special = ConstValSpecialStatic; 19885 result->type = ir_type_info_get_type(ira, "Array", nullptr); 19886 19887 ConstExprValue *fields = create_const_vals(2); 19888 result->data.x_struct.fields = fields; 19889 19890 // len: usize 19891 ensure_field_index(result->type, "len", 0); 19892 fields[0].special = ConstValSpecialStatic; 19893 fields[0].type = ira->codegen->builtin_types.entry_num_lit_int; 19894 bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); 19895 // child: type 19896 ensure_field_index(result->type, "child", 1); 19897 fields[1].special = ConstValSpecialStatic; 19898 fields[1].type = ira->codegen->builtin_types.entry_type; 19899 fields[1].data.x_type = type_entry->data.array.child_type; 19900 19901 break; 19902 } 19903 case ZigTypeIdVector: { 19904 result = create_const_vals(1); 19905 result->special = ConstValSpecialStatic; 19906 result->type = ir_type_info_get_type(ira, "Vector", nullptr); 19907 19908 ConstExprValue *fields = create_const_vals(2); 19909 result->data.x_struct.fields = fields; 19910 19911 // len: usize 19912 ensure_field_index(result->type, "len", 0); 19913 fields[0].special = ConstValSpecialStatic; 19914 fields[0].type = ira->codegen->builtin_types.entry_num_lit_int; 19915 bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.vector.len); 19916 // child: type 19917 ensure_field_index(result->type, "child", 1); 19918 fields[1].special = ConstValSpecialStatic; 19919 fields[1].type = ira->codegen->builtin_types.entry_type; 19920 fields[1].data.x_type = type_entry->data.vector.elem_type; 19921 19922 break; 19923 } 19924 case ZigTypeIdOptional: 19925 { 19926 result = create_const_vals(1); 19927 result->special = ConstValSpecialStatic; 19928 result->type = ir_type_info_get_type(ira, "Optional", nullptr); 19929 19930 ConstExprValue *fields = create_const_vals(1); 19931 result->data.x_struct.fields = fields; 19932 19933 // child: type 19934 ensure_field_index(result->type, "child", 0); 19935 fields[0].special = ConstValSpecialStatic; 19936 fields[0].type = ira->codegen->builtin_types.entry_type; 19937 fields[0].data.x_type = type_entry->data.maybe.child_type; 19938 19939 break; 19940 } 19941 case ZigTypeIdAnyFrame: { 19942 result = create_const_vals(1); 19943 result->special = ConstValSpecialStatic; 19944 result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr); 19945 19946 ConstExprValue *fields = create_const_vals(1); 19947 result->data.x_struct.fields = fields; 19948 19949 // child: ?type 19950 ensure_field_index(result->type, "child", 0); 19951 fields[0].special = ConstValSpecialStatic; 19952 fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 19953 fields[0].data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr : 19954 create_const_type(ira->codegen, type_entry->data.any_frame.result_type); 19955 break; 19956 } 19957 case ZigTypeIdEnum: 19958 { 19959 result = create_const_vals(1); 19960 result->special = ConstValSpecialStatic; 19961 result->type = ir_type_info_get_type(ira, "Enum", nullptr); 19962 19963 ConstExprValue *fields = create_const_vals(4); 19964 result->data.x_struct.fields = fields; 19965 19966 // layout: ContainerLayout 19967 ensure_field_index(result->type, "layout", 0); 19968 fields[0].special = ConstValSpecialStatic; 19969 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 19970 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.enumeration.layout); 19971 // tag_type: type 19972 ensure_field_index(result->type, "tag_type", 1); 19973 fields[1].special = ConstValSpecialStatic; 19974 fields[1].type = ira->codegen->builtin_types.entry_type; 19975 fields[1].data.x_type = type_entry->data.enumeration.tag_int_type; 19976 // fields: []TypeInfo.EnumField 19977 ensure_field_index(result->type, "fields", 2); 19978 19979 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 19980 if ((err = type_resolve(ira->codegen, type_info_enum_field_type, ResolveStatusSizeKnown))) { 19981 zig_unreachable(); 19982 } 19983 uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; 19984 19985 ConstExprValue *enum_field_array = create_const_vals(1); 19986 enum_field_array->special = ConstValSpecialStatic; 19987 enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count); 19988 enum_field_array->data.x_array.special = ConstArraySpecialNone; 19989 enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count); 19990 19991 init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false); 19992 19993 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) 19994 { 19995 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; 19996 ConstExprValue *enum_field_val = &enum_field_array->data.x_array.data.s_none.elements[enum_field_index]; 19997 make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type); 19998 enum_field_val->parent.id = ConstParentIdArray; 19999 enum_field_val->parent.data.p_array.array_val = enum_field_array; 20000 enum_field_val->parent.data.p_array.elem_index = enum_field_index; 20001 } 20002 // decls: []TypeInfo.Declaration 20003 ensure_field_index(result->type, "decls", 3); 20004 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3], 20005 type_entry->data.enumeration.decls_scope))) 20006 { 20007 return err; 20008 } 20009 20010 break; 20011 } 20012 case ZigTypeIdErrorSet: 20013 { 20014 result = create_const_vals(1); 20015 result->special = ConstValSpecialStatic; 20016 result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr); 20017 20018 ZigType *type_info_error_type = ir_type_info_get_type(ira, "Error", nullptr); 20019 if (!resolve_inferred_error_set(ira->codegen, type_entry, source_instr->source_node)) { 20020 return ErrorSemanticAnalyzeFail; 20021 } 20022 if (type_is_global_error_set(type_entry)) { 20023 result->data.x_optional = nullptr; 20024 break; 20025 } 20026 if ((err = type_resolve(ira->codegen, type_info_error_type, ResolveStatusSizeKnown))) { 20027 zig_unreachable(); 20028 } 20029 ConstExprValue *slice_val = create_const_vals(1); 20030 result->data.x_optional = slice_val; 20031 20032 uint32_t error_count = type_entry->data.error_set.err_count; 20033 ConstExprValue *error_array = create_const_vals(1); 20034 error_array->special = ConstValSpecialStatic; 20035 error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count); 20036 error_array->data.x_array.special = ConstArraySpecialNone; 20037 error_array->data.x_array.data.s_none.elements = create_const_vals(error_count); 20038 20039 init_const_slice(ira->codegen, slice_val, error_array, 0, error_count, false); 20040 for (uint32_t error_index = 0; error_index < error_count; error_index++) { 20041 ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; 20042 ConstExprValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index]; 20043 20044 error_val->special = ConstValSpecialStatic; 20045 error_val->type = type_info_error_type; 20046 20047 ConstExprValue *inner_fields = create_const_vals(2); 20048 inner_fields[1].special = ConstValSpecialStatic; 20049 inner_fields[1].type = ira->codegen->builtin_types.entry_num_lit_int; 20050 20051 ConstExprValue *name = nullptr; 20052 if (error->cached_error_name_val != nullptr) 20053 name = error->cached_error_name_val; 20054 if (name == nullptr) 20055 name = create_const_str_lit(ira->codegen, &error->name); 20056 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(&error->name), true); 20057 bigint_init_unsigned(&inner_fields[1].data.x_bigint, error->value); 20058 20059 error_val->data.x_struct.fields = inner_fields; 20060 error_val->parent.id = ConstParentIdArray; 20061 error_val->parent.data.p_array.array_val = error_array; 20062 error_val->parent.data.p_array.elem_index = error_index; 20063 } 20064 20065 break; 20066 } 20067 case ZigTypeIdErrorUnion: 20068 { 20069 result = create_const_vals(1); 20070 result->special = ConstValSpecialStatic; 20071 result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr); 20072 20073 ConstExprValue *fields = create_const_vals(2); 20074 result->data.x_struct.fields = fields; 20075 20076 // error_set: type 20077 ensure_field_index(result->type, "error_set", 0); 20078 fields[0].special = ConstValSpecialStatic; 20079 fields[0].type = ira->codegen->builtin_types.entry_type; 20080 fields[0].data.x_type = type_entry->data.error_union.err_set_type; 20081 20082 // payload: type 20083 ensure_field_index(result->type, "payload", 1); 20084 fields[1].special = ConstValSpecialStatic; 20085 fields[1].type = ira->codegen->builtin_types.entry_type; 20086 fields[1].data.x_type = type_entry->data.error_union.payload_type; 20087 20088 break; 20089 } 20090 case ZigTypeIdUnion: 20091 { 20092 result = create_const_vals(1); 20093 result->special = ConstValSpecialStatic; 20094 result->type = ir_type_info_get_type(ira, "Union", nullptr); 20095 20096 ConstExprValue *fields = create_const_vals(4); 20097 result->data.x_struct.fields = fields; 20098 20099 // layout: ContainerLayout 20100 ensure_field_index(result->type, "layout", 0); 20101 fields[0].special = ConstValSpecialStatic; 20102 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 20103 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout); 20104 // tag_type: ?type 20105 ensure_field_index(result->type, "tag_type", 1); 20106 fields[1].special = ConstValSpecialStatic; 20107 fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 20108 20109 AstNode *union_decl_node = type_entry->data.unionation.decl_node; 20110 if (union_decl_node->data.container_decl.auto_enum || 20111 union_decl_node->data.container_decl.init_arg_expr != nullptr) 20112 { 20113 ConstExprValue *tag_type = create_const_vals(1); 20114 tag_type->special = ConstValSpecialStatic; 20115 tag_type->type = ira->codegen->builtin_types.entry_type; 20116 tag_type->data.x_type = type_entry->data.unionation.tag_type; 20117 fields[1].data.x_optional = tag_type; 20118 } else { 20119 fields[1].data.x_optional = nullptr; 20120 } 20121 // fields: []TypeInfo.UnionField 20122 ensure_field_index(result->type, "fields", 2); 20123 20124 ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); 20125 if ((err = type_resolve(ira->codegen, type_info_union_field_type, ResolveStatusSizeKnown))) 20126 zig_unreachable(); 20127 uint32_t union_field_count = type_entry->data.unionation.src_field_count; 20128 20129 ConstExprValue *union_field_array = create_const_vals(1); 20130 union_field_array->special = ConstValSpecialStatic; 20131 union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count); 20132 union_field_array->data.x_array.special = ConstArraySpecialNone; 20133 union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count); 20134 20135 init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false); 20136 20137 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 20138 20139 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { 20140 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; 20141 ConstExprValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index]; 20142 20143 union_field_val->special = ConstValSpecialStatic; 20144 union_field_val->type = type_info_union_field_type; 20145 20146 ConstExprValue *inner_fields = create_const_vals(3); 20147 inner_fields[1].special = ConstValSpecialStatic; 20148 inner_fields[1].type = get_optional_type(ira->codegen, type_info_enum_field_type); 20149 20150 if (fields[1].data.x_optional == nullptr) { 20151 inner_fields[1].data.x_optional = nullptr; 20152 } else { 20153 inner_fields[1].data.x_optional = create_const_vals(1); 20154 make_enum_field_val(ira, inner_fields[1].data.x_optional, union_field->enum_field, type_info_enum_field_type); 20155 } 20156 20157 inner_fields[2].special = ConstValSpecialStatic; 20158 inner_fields[2].type = ira->codegen->builtin_types.entry_type; 20159 inner_fields[2].data.x_type = union_field->type_entry; 20160 20161 ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name); 20162 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(union_field->name), true); 20163 20164 union_field_val->data.x_struct.fields = inner_fields; 20165 union_field_val->parent.id = ConstParentIdArray; 20166 union_field_val->parent.data.p_array.array_val = union_field_array; 20167 union_field_val->parent.data.p_array.elem_index = union_field_index; 20168 } 20169 // decls: []TypeInfo.Declaration 20170 ensure_field_index(result->type, "decls", 3); 20171 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3], 20172 type_entry->data.unionation.decls_scope))) 20173 { 20174 return err; 20175 } 20176 20177 break; 20178 } 20179 case ZigTypeIdStruct: 20180 { 20181 if (type_entry->data.structure.is_slice) { 20182 result = create_ptr_like_type_info(ira, type_entry); 20183 if (result == nullptr) 20184 return ErrorSemanticAnalyzeFail; 20185 break; 20186 } 20187 20188 result = create_const_vals(1); 20189 result->special = ConstValSpecialStatic; 20190 result->type = ir_type_info_get_type(ira, "Struct", nullptr); 20191 20192 ConstExprValue *fields = create_const_vals(3); 20193 result->data.x_struct.fields = fields; 20194 20195 // layout: ContainerLayout 20196 ensure_field_index(result->type, "layout", 0); 20197 fields[0].special = ConstValSpecialStatic; 20198 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 20199 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.structure.layout); 20200 // fields: []TypeInfo.StructField 20201 ensure_field_index(result->type, "fields", 1); 20202 20203 ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); 20204 if ((err = type_resolve(ira->codegen, type_info_struct_field_type, ResolveStatusSizeKnown))) { 20205 zig_unreachable(); 20206 } 20207 uint32_t struct_field_count = type_entry->data.structure.src_field_count; 20208 20209 ConstExprValue *struct_field_array = create_const_vals(1); 20210 struct_field_array->special = ConstValSpecialStatic; 20211 struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count); 20212 struct_field_array->data.x_array.special = ConstArraySpecialNone; 20213 struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count); 20214 20215 init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false); 20216 20217 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { 20218 TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index]; 20219 ConstExprValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index]; 20220 20221 struct_field_val->special = ConstValSpecialStatic; 20222 struct_field_val->type = type_info_struct_field_type; 20223 20224 ConstExprValue *inner_fields = create_const_vals(3); 20225 inner_fields[1].special = ConstValSpecialStatic; 20226 inner_fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int); 20227 20228 if (!type_has_bits(struct_field->type_entry)) { 20229 inner_fields[1].data.x_optional = nullptr; 20230 } else { 20231 size_t byte_offset = struct_field->offset; 20232 inner_fields[1].data.x_optional = create_const_vals(1); 20233 inner_fields[1].data.x_optional->special = ConstValSpecialStatic; 20234 inner_fields[1].data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int; 20235 bigint_init_unsigned(&inner_fields[1].data.x_optional->data.x_bigint, byte_offset); 20236 } 20237 20238 inner_fields[2].special = ConstValSpecialStatic; 20239 inner_fields[2].type = ira->codegen->builtin_types.entry_type; 20240 inner_fields[2].data.x_type = struct_field->type_entry; 20241 20242 ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name); 20243 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(struct_field->name), true); 20244 20245 struct_field_val->data.x_struct.fields = inner_fields; 20246 struct_field_val->parent.id = ConstParentIdArray; 20247 struct_field_val->parent.data.p_array.array_val = struct_field_array; 20248 struct_field_val->parent.data.p_array.elem_index = struct_field_index; 20249 } 20250 // decls: []TypeInfo.Declaration 20251 ensure_field_index(result->type, "decls", 2); 20252 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[2], 20253 type_entry->data.structure.decls_scope))) 20254 { 20255 return err; 20256 } 20257 20258 break; 20259 } 20260 case ZigTypeIdFn: 20261 { 20262 result = create_const_vals(1); 20263 result->special = ConstValSpecialStatic; 20264 result->type = ir_type_info_get_type(ira, "Fn", nullptr); 20265 20266 ConstExprValue *fields = create_const_vals(5); 20267 result->data.x_struct.fields = fields; 20268 20269 // calling_convention: TypeInfo.CallingConvention 20270 ensure_field_index(result->type, "calling_convention", 0); 20271 fields[0].special = ConstValSpecialStatic; 20272 fields[0].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); 20273 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); 20274 // is_generic: bool 20275 ensure_field_index(result->type, "is_generic", 1); 20276 bool is_generic = type_entry->data.fn.is_generic; 20277 fields[1].special = ConstValSpecialStatic; 20278 fields[1].type = ira->codegen->builtin_types.entry_bool; 20279 fields[1].data.x_bool = is_generic; 20280 // is_varargs: bool 20281 ensure_field_index(result->type, "is_var_args", 2); 20282 bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; 20283 fields[2].special = ConstValSpecialStatic; 20284 fields[2].type = ira->codegen->builtin_types.entry_bool; 20285 fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; 20286 // return_type: ?type 20287 ensure_field_index(result->type, "return_type", 3); 20288 fields[3].special = ConstValSpecialStatic; 20289 fields[3].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 20290 if (type_entry->data.fn.fn_type_id.return_type == nullptr) 20291 fields[3].data.x_optional = nullptr; 20292 else { 20293 ConstExprValue *return_type = create_const_vals(1); 20294 return_type->special = ConstValSpecialStatic; 20295 return_type->type = ira->codegen->builtin_types.entry_type; 20296 return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; 20297 fields[3].data.x_optional = return_type; 20298 } 20299 // args: []TypeInfo.FnArg 20300 ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); 20301 if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { 20302 zig_unreachable(); 20303 } 20304 size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - 20305 (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); 20306 20307 ConstExprValue *fn_arg_array = create_const_vals(1); 20308 fn_arg_array->special = ConstValSpecialStatic; 20309 fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count); 20310 fn_arg_array->data.x_array.special = ConstArraySpecialNone; 20311 fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); 20312 20313 init_const_slice(ira->codegen, &fields[4], fn_arg_array, 0, fn_arg_count, false); 20314 20315 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { 20316 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; 20317 ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index]; 20318 20319 fn_arg_val->special = ConstValSpecialStatic; 20320 fn_arg_val->type = type_info_fn_arg_type; 20321 20322 bool arg_is_generic = fn_param_info->type == nullptr; 20323 if (arg_is_generic) assert(is_generic); 20324 20325 ConstExprValue *inner_fields = create_const_vals(3); 20326 inner_fields[0].special = ConstValSpecialStatic; 20327 inner_fields[0].type = ira->codegen->builtin_types.entry_bool; 20328 inner_fields[0].data.x_bool = arg_is_generic; 20329 inner_fields[1].special = ConstValSpecialStatic; 20330 inner_fields[1].type = ira->codegen->builtin_types.entry_bool; 20331 inner_fields[1].data.x_bool = fn_param_info->is_noalias; 20332 inner_fields[2].special = ConstValSpecialStatic; 20333 inner_fields[2].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 20334 20335 if (arg_is_generic) 20336 inner_fields[2].data.x_optional = nullptr; 20337 else { 20338 ConstExprValue *arg_type = create_const_vals(1); 20339 arg_type->special = ConstValSpecialStatic; 20340 arg_type->type = ira->codegen->builtin_types.entry_type; 20341 arg_type->data.x_type = fn_param_info->type; 20342 inner_fields[2].data.x_optional = arg_type; 20343 } 20344 20345 fn_arg_val->data.x_struct.fields = inner_fields; 20346 fn_arg_val->parent.id = ConstParentIdArray; 20347 fn_arg_val->parent.data.p_array.array_val = fn_arg_array; 20348 fn_arg_val->parent.data.p_array.elem_index = fn_arg_index; 20349 } 20350 20351 break; 20352 } 20353 case ZigTypeIdBoundFn: 20354 { 20355 ZigType *fn_type = type_entry->data.bound_fn.fn_type; 20356 assert(fn_type->id == ZigTypeIdFn); 20357 if ((err = ir_make_type_info_value(ira, source_instr, fn_type, &result))) 20358 return err; 20359 20360 break; 20361 } 20362 case ZigTypeIdFnFrame: 20363 zig_panic("TODO @typeInfo for async function frames"); 20364 } 20365 20366 assert(result != nullptr); 20367 ira->codegen->type_info_cache.put(type_entry, result); 20368 *out = result; 20369 return ErrorNone; 20370 } 20371 20372 static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira, 20373 IrInstructionTypeInfo *instruction) 20374 { 20375 Error err; 20376 IrInstruction *type_value = instruction->type_value->child; 20377 ZigType *type_entry = ir_resolve_type(ira, type_value); 20378 if (type_is_invalid(type_entry)) 20379 return ira->codegen->invalid_instruction; 20380 20381 ZigType *result_type = ir_type_info_get_type(ira, nullptr, nullptr); 20382 20383 ConstExprValue *payload; 20384 if ((err = ir_make_type_info_value(ira, &instruction->base, type_entry, &payload))) 20385 return ira->codegen->invalid_instruction; 20386 20387 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 20388 ConstExprValue *out_val = &result->value; 20389 bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry)); 20390 out_val->data.x_union.payload = payload; 20391 20392 if (payload != nullptr) { 20393 payload->parent.id = ConstParentIdUnion; 20394 payload->parent.data.p_union.union_val = out_val; 20395 } 20396 20397 return result; 20398 } 20399 20400 static IrInstruction *ir_analyze_instruction_type_id(IrAnalyze *ira, 20401 IrInstructionTypeId *instruction) 20402 { 20403 IrInstruction *type_value = instruction->type_value->child; 20404 ZigType *type_entry = ir_resolve_type(ira, type_value); 20405 if (type_is_invalid(type_entry)) 20406 return ira->codegen->invalid_instruction; 20407 20408 ConstExprValue *var_value = get_builtin_value(ira->codegen, "TypeId"); 20409 assert(var_value->type->id == ZigTypeIdMetaType); 20410 ZigType *result_type = var_value->data.x_type; 20411 20412 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 20413 bigint_init_unsigned(&result->value.data.x_enum_tag, type_id_index(type_entry)); 20414 return result; 20415 } 20416 20417 static IrInstruction *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira, 20418 IrInstructionSetEvalBranchQuota *instruction) 20419 { 20420 uint64_t new_quota; 20421 if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota)) 20422 return ira->codegen->invalid_instruction; 20423 20424 if (new_quota > *ira->new_irb.exec->backward_branch_quota) { 20425 *ira->new_irb.exec->backward_branch_quota = new_quota; 20426 } 20427 20428 return ir_const_void(ira, &instruction->base); 20429 } 20430 20431 static IrInstruction *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) { 20432 IrInstruction *type_value = instruction->type_value->child; 20433 ZigType *type_entry = ir_resolve_type(ira, type_value); 20434 if (type_is_invalid(type_entry)) 20435 return ira->codegen->invalid_instruction; 20436 20437 if (!type_entry->cached_const_name_val) { 20438 type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, type_bare_name(type_entry)); 20439 } 20440 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 20441 copy_const_val(&result->value, type_entry->cached_const_name_val, true); 20442 return result; 20443 } 20444 20445 static void ir_cimport_cache_paths(Buf *cache_dir, Buf *tmp_c_file_digest, Buf *out_zig_dir, Buf *out_zig_path) { 20446 buf_resize(out_zig_dir, 0); 20447 buf_resize(out_zig_path, 0); 20448 buf_appendf(out_zig_dir, "%s" OS_SEP "o" OS_SEP "%s", 20449 buf_ptr(cache_dir), buf_ptr(tmp_c_file_digest)); 20450 buf_appendf(out_zig_path, "%s" OS_SEP "cimport.zig", buf_ptr(out_zig_dir)); 20451 } 20452 static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCImport *instruction) { 20453 Error err; 20454 AstNode *node = instruction->base.source_node; 20455 assert(node->type == NodeTypeFnCallExpr); 20456 AstNode *block_node = node->data.fn_call_expr.params.at(0); 20457 20458 ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.scope); 20459 20460 // Execute the C import block like an inline function 20461 ZigType *void_type = ira->codegen->builtin_types.entry_void; 20462 ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, 20463 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, 20464 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr); 20465 if (type_is_invalid(cimport_result->type)) 20466 return ira->codegen->invalid_instruction; 20467 20468 ZigPackage *cur_scope_pkg = scope_package(instruction->base.scope); 20469 Buf *namespace_name = buf_sprintf("%s.cimport:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, 20470 buf_ptr(&cur_scope_pkg->pkg_path), node->line + 1, node->column + 1); 20471 20472 ZigPackage *cimport_pkg = new_anonymous_package(); 20473 cimport_pkg->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package); 20474 cimport_pkg->package_table.put(buf_create_from_str("std"), ira->codegen->std_package); 20475 buf_init_from_buf(&cimport_pkg->pkg_path, namespace_name); 20476 20477 CacheHash *cache_hash; 20478 if ((err = create_c_object_cache(ira->codegen, &cache_hash, false))) { 20479 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to create cache: %s", err_str(err))); 20480 return ira->codegen->invalid_instruction; 20481 } 20482 cache_buf(cache_hash, &cimport_scope->buf); 20483 20484 // Set this because we're not adding any files before checking for a hit. 20485 cache_hash->force_check_manifest = true; 20486 20487 Buf tmp_c_file_digest = BUF_INIT; 20488 buf_resize(&tmp_c_file_digest, 0); 20489 if ((err = cache_hit(cache_hash, &tmp_c_file_digest))) { 20490 if (err != ErrorInvalidFormat) { 20491 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to check cache: %s", err_str(err))); 20492 return ira->codegen->invalid_instruction; 20493 } 20494 } 20495 ira->codegen->caches_to_release.append(cache_hash); 20496 20497 Buf *out_zig_dir = buf_alloc(); 20498 Buf *out_zig_path = buf_alloc(); 20499 if (buf_len(&tmp_c_file_digest) == 0 || cache_hash->files.length == 0) { 20500 // Cache Miss 20501 Buf *tmp_c_file_dir = buf_sprintf("%s" OS_SEP "o" OS_SEP "%s", 20502 buf_ptr(ira->codegen->cache_dir), buf_ptr(&cache_hash->b64_digest)); 20503 Buf *resolve_paths[] = { 20504 tmp_c_file_dir, 20505 buf_create_from_str("cimport.h"), 20506 }; 20507 Buf tmp_c_file_path = os_path_resolve(resolve_paths, 2); 20508 20509 if ((err = os_make_path(tmp_c_file_dir))) { 20510 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); 20511 return ira->codegen->invalid_instruction; 20512 } 20513 20514 if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { 20515 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); 20516 return ira->codegen->invalid_instruction; 20517 } 20518 if (ira->codegen->verbose_cimport) { 20519 fprintf(stderr, "@cImport source: %s\n", buf_ptr(&tmp_c_file_path)); 20520 } 20521 20522 Buf *tmp_dep_file = buf_sprintf("%s.d", buf_ptr(&tmp_c_file_path)); 20523 20524 ZigList<const char *> clang_argv = {0}; 20525 20526 add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true); 20527 20528 clang_argv.append(buf_ptr(&tmp_c_file_path)); 20529 20530 if (ira->codegen->verbose_cc) { 20531 fprintf(stderr, "clang"); 20532 for (size_t i = 0; i < clang_argv.length; i += 1) { 20533 fprintf(stderr, " %s", clang_argv.at(i)); 20534 } 20535 fprintf(stderr, "\n"); 20536 } 20537 20538 clang_argv.append(nullptr); // to make the [start...end] argument work 20539 20540 AstNode *root_node; 20541 Stage2ErrorMsg *errors_ptr; 20542 size_t errors_len; 20543 20544 const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir); 20545 20546 if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len, 20547 &clang_argv.at(0), &clang_argv.last(), Stage2TranslateModeImport, resources_path))) 20548 { 20549 if (err != ErrorCCompileErrors) { 20550 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); 20551 return ira->codegen->invalid_instruction; 20552 } 20553 20554 ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed")); 20555 if (ira->codegen->libc_link_lib == nullptr) { 20556 add_error_note(ira->codegen, parent_err_msg, node, 20557 buf_sprintf("libc headers not available; compilation does not link against libc")); 20558 } 20559 for (size_t i = 0; i < errors_len; i += 1) { 20560 Stage2ErrorMsg *clang_err = &errors_ptr[i]; 20561 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null 20562 if (clang_err->source && clang_err->filename_ptr) { 20563 ErrorMsg *err_msg = err_msg_create_with_offset( 20564 clang_err->filename_ptr ? 20565 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), 20566 clang_err->line, clang_err->column, clang_err->offset, clang_err->source, 20567 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); 20568 err_msg_add_note(parent_err_msg, err_msg); 20569 } 20570 } 20571 20572 return ira->codegen->invalid_instruction; 20573 } 20574 if (ira->codegen->verbose_cimport) { 20575 fprintf(stderr, "@cImport .d file: %s\n", buf_ptr(tmp_dep_file)); 20576 } 20577 20578 if ((err = cache_add_dep_file(cache_hash, tmp_dep_file, false))) { 20579 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to parse .d file: %s", err_str(err))); 20580 return ira->codegen->invalid_instruction; 20581 } 20582 if ((err = cache_final(cache_hash, &tmp_c_file_digest))) { 20583 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to finalize cache: %s", err_str(err))); 20584 return ira->codegen->invalid_instruction; 20585 } 20586 20587 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 20588 if ((err = os_make_path(out_zig_dir))) { 20589 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make output dir: %s", err_str(err))); 20590 return ira->codegen->invalid_instruction; 20591 } 20592 FILE *out_file = fopen(buf_ptr(out_zig_path), "wb"); 20593 if (out_file == nullptr) { 20594 ir_add_error_node(ira, node, 20595 buf_sprintf("C import failed: unable to open output file: %s", strerror(errno))); 20596 return ira->codegen->invalid_instruction; 20597 } 20598 ast_render(out_file, root_node, 4); 20599 if (fclose(out_file) != 0) { 20600 ir_add_error_node(ira, node, 20601 buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno))); 20602 return ira->codegen->invalid_instruction; 20603 } 20604 20605 if (ira->codegen->verbose_cimport) { 20606 fprintf(stderr, "@cImport output: %s\n", buf_ptr(out_zig_path)); 20607 } 20608 20609 } else { 20610 // Cache Hit 20611 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 20612 if (ira->codegen->verbose_cimport) { 20613 fprintf(stderr, "@cImport cache hit: %s\n", buf_ptr(out_zig_path)); 20614 } 20615 } 20616 20617 Buf *import_code = buf_alloc(); 20618 if ((err = file_fetch(ira->codegen, out_zig_path, import_code))) { 20619 ir_add_error_node(ira, node, 20620 buf_sprintf("unable to open '%s': %s", buf_ptr(out_zig_path), err_str(err))); 20621 return ira->codegen->invalid_instruction; 20622 } 20623 ZigType *child_import = add_source_file(ira->codegen, cimport_pkg, out_zig_path, 20624 import_code, SourceKindCImport); 20625 return ir_const_type(ira, &instruction->base, child_import); 20626 } 20627 20628 static IrInstruction *ir_analyze_instruction_c_include(IrAnalyze *ira, IrInstructionCInclude *instruction) { 20629 IrInstruction *name_value = instruction->name->child; 20630 if (type_is_invalid(name_value->value.type)) 20631 return ira->codegen->invalid_instruction; 20632 20633 Buf *include_name = ir_resolve_str(ira, name_value); 20634 if (!include_name) 20635 return ira->codegen->invalid_instruction; 20636 20637 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 20638 // We check for this error in pass1 20639 assert(c_import_buf); 20640 20641 buf_appendf(c_import_buf, "#include <%s>\n", buf_ptr(include_name)); 20642 20643 return ir_const_void(ira, &instruction->base); 20644 } 20645 20646 static IrInstruction *ir_analyze_instruction_c_define(IrAnalyze *ira, IrInstructionCDefine *instruction) { 20647 IrInstruction *name = instruction->name->child; 20648 if (type_is_invalid(name->value.type)) 20649 return ira->codegen->invalid_instruction; 20650 20651 Buf *define_name = ir_resolve_str(ira, name); 20652 if (!define_name) 20653 return ira->codegen->invalid_instruction; 20654 20655 IrInstruction *value = instruction->value->child; 20656 if (type_is_invalid(value->value.type)) 20657 return ira->codegen->invalid_instruction; 20658 20659 Buf *define_value = ir_resolve_str(ira, value); 20660 if (!define_value) 20661 return ira->codegen->invalid_instruction; 20662 20663 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 20664 // We check for this error in pass1 20665 assert(c_import_buf); 20666 20667 buf_appendf(c_import_buf, "#define %s %s\n", buf_ptr(define_name), buf_ptr(define_value)); 20668 20669 return ir_const_void(ira, &instruction->base); 20670 } 20671 20672 static IrInstruction *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstructionCUndef *instruction) { 20673 IrInstruction *name = instruction->name->child; 20674 if (type_is_invalid(name->value.type)) 20675 return ira->codegen->invalid_instruction; 20676 20677 Buf *undef_name = ir_resolve_str(ira, name); 20678 if (!undef_name) 20679 return ira->codegen->invalid_instruction; 20680 20681 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 20682 // We check for this error in pass1 20683 assert(c_import_buf); 20684 20685 buf_appendf(c_import_buf, "#undef %s\n", buf_ptr(undef_name)); 20686 20687 return ir_const_void(ira, &instruction->base); 20688 } 20689 20690 static IrInstruction *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionEmbedFile *instruction) { 20691 IrInstruction *name = instruction->name->child; 20692 if (type_is_invalid(name->value.type)) 20693 return ira->codegen->invalid_instruction; 20694 20695 Buf *rel_file_path = ir_resolve_str(ira, name); 20696 if (!rel_file_path) 20697 return ira->codegen->invalid_instruction; 20698 20699 ZigType *import = get_scope_import(instruction->base.scope); 20700 // figure out absolute path to resource 20701 Buf source_dir_path = BUF_INIT; 20702 os_path_dirname(import->data.structure.root_struct->path, &source_dir_path); 20703 20704 Buf *resolve_paths[] = { 20705 &source_dir_path, 20706 rel_file_path, 20707 }; 20708 Buf *file_path = buf_alloc(); 20709 *file_path = os_path_resolve(resolve_paths, 2); 20710 20711 // load from file system into const expr 20712 Buf *file_contents = buf_alloc(); 20713 Error err; 20714 if ((err = file_fetch(ira->codegen, file_path, file_contents))) { 20715 if (err == ErrorFileNotFound) { 20716 ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(file_path))); 20717 return ira->codegen->invalid_instruction; 20718 } else { 20719 ir_add_error(ira, instruction->name, buf_sprintf("unable to open '%s': %s", buf_ptr(file_path), err_str(err))); 20720 return ira->codegen->invalid_instruction; 20721 } 20722 } 20723 20724 ZigType *result_type = get_array_type(ira->codegen, 20725 ira->codegen->builtin_types.entry_u8, buf_len(file_contents)); 20726 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 20727 init_const_str_lit(ira->codegen, &result->value, file_contents); 20728 return result; 20729 } 20730 20731 static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructionCmpxchgSrc *instruction) { 20732 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child); 20733 if (type_is_invalid(operand_type)) 20734 return ira->codegen->invalid_instruction; 20735 20736 IrInstruction *ptr = instruction->ptr->child; 20737 if (type_is_invalid(ptr->value.type)) 20738 return ira->codegen->invalid_instruction; 20739 20740 // TODO let this be volatile 20741 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 20742 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr, ptr_type); 20743 if (type_is_invalid(casted_ptr->value.type)) 20744 return ira->codegen->invalid_instruction; 20745 20746 IrInstruction *cmp_value = instruction->cmp_value->child; 20747 if (type_is_invalid(cmp_value->value.type)) 20748 return ira->codegen->invalid_instruction; 20749 20750 IrInstruction *new_value = instruction->new_value->child; 20751 if (type_is_invalid(new_value->value.type)) 20752 return ira->codegen->invalid_instruction; 20753 20754 IrInstruction *success_order_value = instruction->success_order_value->child; 20755 if (type_is_invalid(success_order_value->value.type)) 20756 return ira->codegen->invalid_instruction; 20757 20758 AtomicOrder success_order; 20759 if (!ir_resolve_atomic_order(ira, success_order_value, &success_order)) 20760 return ira->codegen->invalid_instruction; 20761 20762 IrInstruction *failure_order_value = instruction->failure_order_value->child; 20763 if (type_is_invalid(failure_order_value->value.type)) 20764 return ira->codegen->invalid_instruction; 20765 20766 AtomicOrder failure_order; 20767 if (!ir_resolve_atomic_order(ira, failure_order_value, &failure_order)) 20768 return ira->codegen->invalid_instruction; 20769 20770 IrInstruction *casted_cmp_value = ir_implicit_cast(ira, cmp_value, operand_type); 20771 if (type_is_invalid(casted_cmp_value->value.type)) 20772 return ira->codegen->invalid_instruction; 20773 20774 IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, operand_type); 20775 if (type_is_invalid(casted_new_value->value.type)) 20776 return ira->codegen->invalid_instruction; 20777 20778 if (success_order < AtomicOrderMonotonic) { 20779 ir_add_error(ira, success_order_value, 20780 buf_sprintf("success atomic ordering must be Monotonic or stricter")); 20781 return ira->codegen->invalid_instruction; 20782 } 20783 if (failure_order < AtomicOrderMonotonic) { 20784 ir_add_error(ira, failure_order_value, 20785 buf_sprintf("failure atomic ordering must be Monotonic or stricter")); 20786 return ira->codegen->invalid_instruction; 20787 } 20788 if (failure_order > success_order) { 20789 ir_add_error(ira, failure_order_value, 20790 buf_sprintf("failure atomic ordering must be no stricter than success")); 20791 return ira->codegen->invalid_instruction; 20792 } 20793 if (failure_order == AtomicOrderRelease || failure_order == AtomicOrderAcqRel) { 20794 ir_add_error(ira, failure_order_value, 20795 buf_sprintf("failure atomic ordering must not be Release or AcqRel")); 20796 return ira->codegen->invalid_instruction; 20797 } 20798 20799 if (instr_is_comptime(casted_ptr) && instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) { 20800 zig_panic("TODO compile-time execution of cmpxchg"); 20801 } 20802 20803 ZigType *result_type = get_optional_type(ira->codegen, operand_type); 20804 IrInstruction *result_loc; 20805 if (handle_is_ptr(result_type)) { 20806 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 20807 result_type, nullptr, true, false, true); 20808 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { 20809 return result_loc; 20810 } 20811 } else { 20812 result_loc = nullptr; 20813 } 20814 20815 return ir_build_cmpxchg_gen(ira, &instruction->base, result_type, 20816 casted_ptr, casted_cmp_value, casted_new_value, 20817 success_order, failure_order, instruction->is_weak, result_loc); 20818 } 20819 20820 static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { 20821 IrInstruction *order_value = instruction->order_value->child; 20822 if (type_is_invalid(order_value->value.type)) 20823 return ira->codegen->invalid_instruction; 20824 20825 AtomicOrder order; 20826 if (!ir_resolve_atomic_order(ira, order_value, &order)) 20827 return ira->codegen->invalid_instruction; 20828 20829 IrInstruction *result = ir_build_fence(&ira->new_irb, 20830 instruction->base.scope, instruction->base.source_node, order_value, order); 20831 result->value.type = ira->codegen->builtin_types.entry_void; 20832 return result; 20833 } 20834 20835 static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstructionTruncate *instruction) { 20836 IrInstruction *dest_type_value = instruction->dest_type->child; 20837 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 20838 if (type_is_invalid(dest_type)) 20839 return ira->codegen->invalid_instruction; 20840 20841 if (dest_type->id != ZigTypeIdInt && 20842 dest_type->id != ZigTypeIdComptimeInt) 20843 { 20844 ir_add_error(ira, dest_type_value, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 20845 return ira->codegen->invalid_instruction; 20846 } 20847 20848 IrInstruction *target = instruction->target->child; 20849 ZigType *src_type = target->value.type; 20850 if (type_is_invalid(src_type)) 20851 return ira->codegen->invalid_instruction; 20852 20853 if (src_type->id != ZigTypeIdInt && 20854 src_type->id != ZigTypeIdComptimeInt) 20855 { 20856 ir_add_error(ira, target, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name))); 20857 return ira->codegen->invalid_instruction; 20858 } 20859 20860 if (dest_type->id == ZigTypeIdComptimeInt) { 20861 return ir_implicit_cast(ira, target, dest_type); 20862 } 20863 20864 if (instr_is_comptime(target)) { 20865 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 20866 if (val == nullptr) 20867 return ira->codegen->invalid_instruction; 20868 20869 IrInstruction *result = ir_const(ira, &instruction->base, dest_type); 20870 bigint_truncate(&result->value.data.x_bigint, &val->data.x_bigint, 20871 dest_type->data.integral.bit_count, dest_type->data.integral.is_signed); 20872 return result; 20873 } 20874 20875 if (src_type->data.integral.bit_count == 0 || dest_type->data.integral.bit_count == 0) { 20876 IrInstruction *result = ir_const(ira, &instruction->base, dest_type); 20877 bigint_init_unsigned(&result->value.data.x_bigint, 0); 20878 return result; 20879 } 20880 20881 if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { 20882 const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; 20883 ir_add_error(ira, target, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); 20884 return ira->codegen->invalid_instruction; 20885 } else if (src_type->data.integral.bit_count < dest_type->data.integral.bit_count) { 20886 ir_add_error(ira, target, buf_sprintf("type '%s' has fewer bits than destination type '%s'", 20887 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 20888 return ira->codegen->invalid_instruction; 20889 } 20890 20891 IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope, 20892 instruction->base.source_node, dest_type_value, target); 20893 new_instruction->value.type = dest_type; 20894 return new_instruction; 20895 } 20896 20897 static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstructionIntCast *instruction) { 20898 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 20899 if (type_is_invalid(dest_type)) 20900 return ira->codegen->invalid_instruction; 20901 20902 if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { 20903 ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 20904 return ira->codegen->invalid_instruction; 20905 } 20906 20907 IrInstruction *target = instruction->target->child; 20908 if (type_is_invalid(target->value.type)) 20909 return ira->codegen->invalid_instruction; 20910 20911 if (target->value.type->id != ZigTypeIdInt && target->value.type->id != ZigTypeIdComptimeInt) { 20912 ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", 20913 buf_ptr(&target->value.type->name))); 20914 return ira->codegen->invalid_instruction; 20915 } 20916 20917 if (instr_is_comptime(target)) { 20918 return ir_implicit_cast(ira, target, dest_type); 20919 } 20920 20921 if (dest_type->id == ZigTypeIdComptimeInt) { 20922 ir_add_error(ira, instruction->target, buf_sprintf("attempt to cast runtime value to '%s'", 20923 buf_ptr(&dest_type->name))); 20924 return ira->codegen->invalid_instruction; 20925 } 20926 20927 return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); 20928 } 20929 20930 static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstructionFloatCast *instruction) { 20931 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 20932 if (type_is_invalid(dest_type)) 20933 return ira->codegen->invalid_instruction; 20934 20935 if (dest_type->id != ZigTypeIdFloat) { 20936 ir_add_error(ira, instruction->dest_type, 20937 buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); 20938 return ira->codegen->invalid_instruction; 20939 } 20940 20941 IrInstruction *target = instruction->target->child; 20942 if (type_is_invalid(target->value.type)) 20943 return ira->codegen->invalid_instruction; 20944 20945 if (target->value.type->id == ZigTypeIdComptimeInt || 20946 target->value.type->id == ZigTypeIdComptimeFloat) 20947 { 20948 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { 20949 CastOp op; 20950 if (target->value.type->id == ZigTypeIdComptimeInt) { 20951 op = CastOpIntToFloat; 20952 } else { 20953 op = CastOpNumLitToConcrete; 20954 } 20955 return ir_resolve_cast(ira, &instruction->base, target, dest_type, op); 20956 } else { 20957 return ira->codegen->invalid_instruction; 20958 } 20959 } 20960 20961 if (target->value.type->id != ZigTypeIdFloat) { 20962 ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", 20963 buf_ptr(&target->value.type->name))); 20964 return ira->codegen->invalid_instruction; 20965 } 20966 20967 return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); 20968 } 20969 20970 static IrInstruction *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstructionErrSetCast *instruction) { 20971 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 20972 if (type_is_invalid(dest_type)) 20973 return ira->codegen->invalid_instruction; 20974 20975 if (dest_type->id != ZigTypeIdErrorSet) { 20976 ir_add_error(ira, instruction->dest_type, 20977 buf_sprintf("expected error set type, found '%s'", buf_ptr(&dest_type->name))); 20978 return ira->codegen->invalid_instruction; 20979 } 20980 20981 IrInstruction *target = instruction->target->child; 20982 if (type_is_invalid(target->value.type)) 20983 return ira->codegen->invalid_instruction; 20984 20985 if (target->value.type->id != ZigTypeIdErrorSet) { 20986 ir_add_error(ira, instruction->target, 20987 buf_sprintf("expected error set type, found '%s'", buf_ptr(&target->value.type->name))); 20988 return ira->codegen->invalid_instruction; 20989 } 20990 20991 return ir_analyze_err_set_cast(ira, &instruction->base, target, dest_type); 20992 } 20993 20994 static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstructionFromBytes *instruction) { 20995 Error err; 20996 20997 ZigType *dest_child_type = ir_resolve_type(ira, instruction->dest_child_type->child); 20998 if (type_is_invalid(dest_child_type)) 20999 return ira->codegen->invalid_instruction; 21000 21001 IrInstruction *target = instruction->target->child; 21002 if (type_is_invalid(target->value.type)) 21003 return ira->codegen->invalid_instruction; 21004 21005 bool src_ptr_const; 21006 bool src_ptr_volatile; 21007 uint32_t src_ptr_align; 21008 if (target->value.type->id == ZigTypeIdPointer) { 21009 src_ptr_const = target->value.type->data.pointer.is_const; 21010 src_ptr_volatile = target->value.type->data.pointer.is_volatile; 21011 21012 if ((err = resolve_ptr_align(ira, target->value.type, &src_ptr_align))) 21013 return ira->codegen->invalid_instruction; 21014 } else if (is_slice(target->value.type)) { 21015 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry; 21016 src_ptr_const = src_ptr_type->data.pointer.is_const; 21017 src_ptr_volatile = src_ptr_type->data.pointer.is_volatile; 21018 21019 if ((err = resolve_ptr_align(ira, src_ptr_type, &src_ptr_align))) 21020 return ira->codegen->invalid_instruction; 21021 } else { 21022 src_ptr_const = true; 21023 src_ptr_volatile = false; 21024 21025 if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusAlignmentKnown))) 21026 return ira->codegen->invalid_instruction; 21027 21028 src_ptr_align = get_abi_alignment(ira->codegen, target->value.type); 21029 } 21030 21031 if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusSizeKnown))) 21032 return ira->codegen->invalid_instruction; 21033 21034 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_child_type, 21035 src_ptr_const, src_ptr_volatile, PtrLenUnknown, 21036 src_ptr_align, 0, 0, false); 21037 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); 21038 21039 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 21040 src_ptr_const, src_ptr_volatile, PtrLenUnknown, 21041 src_ptr_align, 0, 0, false); 21042 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 21043 21044 IrInstruction *casted_value = ir_implicit_cast(ira, target, u8_slice); 21045 if (type_is_invalid(casted_value->value.type)) 21046 return ira->codegen->invalid_instruction; 21047 21048 bool have_known_len = false; 21049 uint64_t known_len; 21050 21051 if (instr_is_comptime(casted_value)) { 21052 ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad); 21053 if (!val) 21054 return ira->codegen->invalid_instruction; 21055 21056 ConstExprValue *len_val = &val->data.x_struct.fields[slice_len_index]; 21057 if (value_is_comptime(len_val)) { 21058 known_len = bigint_as_unsigned(&len_val->data.x_bigint); 21059 have_known_len = true; 21060 } 21061 } 21062 21063 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 21064 dest_slice_type, nullptr, true, false, true); 21065 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { 21066 return result_loc; 21067 } 21068 21069 if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) { 21070 known_len = casted_value->value.data.rh_slice.len; 21071 have_known_len = true; 21072 } 21073 21074 if (have_known_len) { 21075 uint64_t child_type_size = type_size(ira->codegen, dest_child_type); 21076 uint64_t remainder = known_len % child_type_size; 21077 if (remainder != 0) { 21078 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 21079 buf_sprintf("unable to convert [%" ZIG_PRI_u64 "]u8 to %s: size mismatch", 21080 known_len, buf_ptr(&dest_slice_type->name))); 21081 add_error_note(ira->codegen, msg, instruction->dest_child_type->source_node, 21082 buf_sprintf("%s has size %" ZIG_PRI_u64 "; remaining bytes: %" ZIG_PRI_u64, 21083 buf_ptr(&dest_child_type->name), child_type_size, remainder)); 21084 return ira->codegen->invalid_instruction; 21085 } 21086 } 21087 21088 return ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type, result_loc); 21089 } 21090 21091 static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { 21092 Error err; 21093 21094 IrInstruction *target = instruction->target->child; 21095 if (type_is_invalid(target->value.type)) 21096 return ira->codegen->invalid_instruction; 21097 21098 if (!is_slice(target->value.type)) { 21099 ir_add_error(ira, instruction->target, 21100 buf_sprintf("expected slice, found '%s'", buf_ptr(&target->value.type->name))); 21101 return ira->codegen->invalid_instruction; 21102 } 21103 21104 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry; 21105 21106 uint32_t alignment; 21107 if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment))) 21108 return ira->codegen->invalid_instruction; 21109 21110 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 21111 src_ptr_type->data.pointer.is_const, src_ptr_type->data.pointer.is_volatile, PtrLenUnknown, 21112 alignment, 0, 0, false); 21113 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); 21114 21115 if (instr_is_comptime(target)) { 21116 ConstExprValue *target_val = ir_resolve_const(ira, target, UndefBad); 21117 if (target_val == nullptr) 21118 return ira->codegen->invalid_instruction; 21119 21120 IrInstruction *result = ir_const(ira, &instruction->base, dest_slice_type); 21121 result->value.data.x_struct.fields = create_const_vals(2); 21122 21123 ConstExprValue *ptr_val = &result->value.data.x_struct.fields[slice_ptr_index]; 21124 ConstExprValue *target_ptr_val = &target_val->data.x_struct.fields[slice_ptr_index]; 21125 copy_const_val(ptr_val, target_ptr_val, false); 21126 ptr_val->type = dest_ptr_type; 21127 21128 ConstExprValue *len_val = &result->value.data.x_struct.fields[slice_len_index]; 21129 len_val->special = ConstValSpecialStatic; 21130 len_val->type = ira->codegen->builtin_types.entry_usize; 21131 ConstExprValue *target_len_val = &target_val->data.x_struct.fields[slice_len_index]; 21132 ZigType *elem_type = src_ptr_type->data.pointer.child_type; 21133 BigInt elem_size_bigint; 21134 bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type)); 21135 bigint_mul(&len_val->data.x_bigint, &target_len_val->data.x_bigint, &elem_size_bigint); 21136 21137 return result; 21138 } 21139 21140 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 21141 dest_slice_type, nullptr, true, false, true); 21142 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { 21143 return result_loc; 21144 } 21145 21146 return ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type, result_loc); 21147 } 21148 21149 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { 21150 Error err; 21151 21152 ZigType *ptr_type = get_src_ptr_type(ty); 21153 assert(ptr_type != nullptr); 21154 if (ptr_type->id == ZigTypeIdPointer) { 21155 if ((err = type_resolve(ira->codegen, ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 21156 return err; 21157 } 21158 21159 *result_align = get_ptr_align(ira->codegen, ty); 21160 return ErrorNone; 21161 } 21162 21163 static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) { 21164 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 21165 if (type_is_invalid(dest_type)) 21166 return ira->codegen->invalid_instruction; 21167 21168 IrInstruction *target = instruction->target->child; 21169 if (type_is_invalid(target->value.type)) 21170 return ira->codegen->invalid_instruction; 21171 21172 if (target->value.type->id != ZigTypeIdInt && target->value.type->id != ZigTypeIdComptimeInt) { 21173 ir_add_error(ira, instruction->target, buf_sprintf("expected int type, found '%s'", 21174 buf_ptr(&target->value.type->name))); 21175 return ira->codegen->invalid_instruction; 21176 } 21177 21178 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat); 21179 } 21180 21181 static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { 21182 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 21183 if (type_is_invalid(dest_type)) 21184 return ira->codegen->invalid_instruction; 21185 21186 IrInstruction *target = instruction->target->child; 21187 if (type_is_invalid(target->value.type)) 21188 return ira->codegen->invalid_instruction; 21189 21190 if (target->value.type->id == ZigTypeIdComptimeInt) { 21191 return ir_implicit_cast(ira, target, dest_type); 21192 } 21193 21194 if (target->value.type->id != ZigTypeIdFloat && target->value.type->id != ZigTypeIdComptimeFloat) { 21195 ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", 21196 buf_ptr(&target->value.type->name))); 21197 return ira->codegen->invalid_instruction; 21198 } 21199 21200 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt); 21201 } 21202 21203 static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { 21204 IrInstruction *target = instruction->target->child; 21205 if (type_is_invalid(target->value.type)) 21206 return ira->codegen->invalid_instruction; 21207 21208 IrInstruction *casted_target; 21209 if (target->value.type->id == ZigTypeIdErrorSet) { 21210 casted_target = target; 21211 } else { 21212 casted_target = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_global_error_set); 21213 if (type_is_invalid(casted_target->value.type)) 21214 return ira->codegen->invalid_instruction; 21215 } 21216 21217 return ir_analyze_err_to_int(ira, &instruction->base, casted_target, ira->codegen->err_tag_type); 21218 } 21219 21220 static IrInstruction *ir_analyze_instruction_int_to_err(IrAnalyze *ira, IrInstructionIntToErr *instruction) { 21221 IrInstruction *target = instruction->target->child; 21222 if (type_is_invalid(target->value.type)) 21223 return ira->codegen->invalid_instruction; 21224 21225 IrInstruction *casted_target = ir_implicit_cast(ira, target, ira->codegen->err_tag_type); 21226 if (type_is_invalid(casted_target->value.type)) 21227 return ira->codegen->invalid_instruction; 21228 21229 return ir_analyze_int_to_err(ira, &instruction->base, casted_target, ira->codegen->builtin_types.entry_global_error_set); 21230 } 21231 21232 static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstructionBoolToInt *instruction) { 21233 IrInstruction *target = instruction->target->child; 21234 if (type_is_invalid(target->value.type)) 21235 return ira->codegen->invalid_instruction; 21236 21237 if (target->value.type->id != ZigTypeIdBool) { 21238 ir_add_error(ira, instruction->target, buf_sprintf("expected bool, found '%s'", 21239 buf_ptr(&target->value.type->name))); 21240 return ira->codegen->invalid_instruction; 21241 } 21242 21243 if (instr_is_comptime(target)) { 21244 bool is_true; 21245 if (!ir_resolve_bool(ira, target, &is_true)) 21246 return ira->codegen->invalid_instruction; 21247 21248 return ir_const_unsigned(ira, &instruction->base, is_true ? 1 : 0); 21249 } 21250 21251 ZigType *u1_type = get_int_type(ira->codegen, false, 1); 21252 return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt); 21253 } 21254 21255 static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { 21256 IrInstruction *is_signed_value = instruction->is_signed->child; 21257 bool is_signed; 21258 if (!ir_resolve_bool(ira, is_signed_value, &is_signed)) 21259 return ira->codegen->invalid_instruction; 21260 21261 IrInstruction *bit_count_value = instruction->bit_count->child; 21262 uint64_t bit_count; 21263 if (!ir_resolve_unsigned(ira, bit_count_value, ira->codegen->builtin_types.entry_u16, &bit_count)) 21264 return ira->codegen->invalid_instruction; 21265 21266 return ir_const_type(ira, &instruction->base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count)); 21267 } 21268 21269 static IrInstruction *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstructionVectorType *instruction) { 21270 uint64_t len; 21271 if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len)) 21272 return ira->codegen->invalid_instruction; 21273 21274 ZigType *elem_type = ir_resolve_type(ira, instruction->elem_type->child); 21275 if (type_is_invalid(elem_type)) 21276 return ira->codegen->invalid_instruction; 21277 21278 if (!is_valid_vector_elem_type(elem_type)) { 21279 ir_add_error(ira, instruction->elem_type, 21280 buf_sprintf("vector element type must be integer, float, or pointer; '%s' is invalid", 21281 buf_ptr(&elem_type->name))); 21282 return ira->codegen->invalid_instruction; 21283 } 21284 21285 ZigType *vector_type = get_vector_type(ira->codegen, len, elem_type); 21286 21287 return ir_const_type(ira, &instruction->base, vector_type); 21288 } 21289 21290 static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { 21291 IrInstruction *value = instruction->value->child; 21292 if (type_is_invalid(value->value.type)) 21293 return ira->codegen->invalid_instruction; 21294 21295 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 21296 21297 IrInstruction *casted_value = ir_implicit_cast(ira, value, bool_type); 21298 if (type_is_invalid(casted_value->value.type)) 21299 return ira->codegen->invalid_instruction; 21300 21301 if (instr_is_comptime(casted_value)) { 21302 ConstExprValue *value = ir_resolve_const(ira, casted_value, UndefBad); 21303 if (value == nullptr) 21304 return ira->codegen->invalid_instruction; 21305 21306 return ir_const_bool(ira, &instruction->base, !value->data.x_bool); 21307 } 21308 21309 IrInstruction *result = ir_build_bool_not(&ira->new_irb, instruction->base.scope, 21310 instruction->base.source_node, casted_value); 21311 result->value.type = bool_type; 21312 return result; 21313 } 21314 21315 static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemset *instruction) { 21316 Error err; 21317 21318 IrInstruction *dest_ptr = instruction->dest_ptr->child; 21319 if (type_is_invalid(dest_ptr->value.type)) 21320 return ira->codegen->invalid_instruction; 21321 21322 IrInstruction *byte_value = instruction->byte->child; 21323 if (type_is_invalid(byte_value->value.type)) 21324 return ira->codegen->invalid_instruction; 21325 21326 IrInstruction *count_value = instruction->count->child; 21327 if (type_is_invalid(count_value->value.type)) 21328 return ira->codegen->invalid_instruction; 21329 21330 ZigType *dest_uncasted_type = dest_ptr->value.type; 21331 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 21332 dest_uncasted_type->data.pointer.is_volatile; 21333 21334 ZigType *usize = ira->codegen->builtin_types.entry_usize; 21335 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 21336 uint32_t dest_align; 21337 if (dest_uncasted_type->id == ZigTypeIdPointer) { 21338 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 21339 return ira->codegen->invalid_instruction; 21340 } else { 21341 dest_align = get_abi_alignment(ira->codegen, u8); 21342 } 21343 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 21344 PtrLenUnknown, dest_align, 0, 0, false); 21345 21346 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr); 21347 if (type_is_invalid(casted_dest_ptr->value.type)) 21348 return ira->codegen->invalid_instruction; 21349 21350 IrInstruction *casted_byte = ir_implicit_cast(ira, byte_value, u8); 21351 if (type_is_invalid(casted_byte->value.type)) 21352 return ira->codegen->invalid_instruction; 21353 21354 IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); 21355 if (type_is_invalid(casted_count->value.type)) 21356 return ira->codegen->invalid_instruction; 21357 21358 // TODO test this at comptime with u8 and non-u8 types 21359 if (casted_dest_ptr->value.special == ConstValSpecialStatic && 21360 casted_byte->value.special == ConstValSpecialStatic && 21361 casted_count->value.special == ConstValSpecialStatic && 21362 casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 21363 casted_dest_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) 21364 { 21365 ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; 21366 21367 ConstExprValue *dest_elements; 21368 size_t start; 21369 size_t bound_end; 21370 switch (dest_ptr_val->data.x_ptr.special) { 21371 case ConstPtrSpecialInvalid: 21372 case ConstPtrSpecialDiscard: 21373 zig_unreachable(); 21374 case ConstPtrSpecialRef: 21375 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 21376 start = 0; 21377 bound_end = 1; 21378 break; 21379 case ConstPtrSpecialBaseArray: 21380 { 21381 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 21382 expand_undef_array(ira->codegen, array_val); 21383 dest_elements = array_val->data.x_array.data.s_none.elements; 21384 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 21385 bound_end = array_val->type->data.array.len; 21386 break; 21387 } 21388 case ConstPtrSpecialBaseStruct: 21389 zig_panic("TODO memset on const inner struct"); 21390 case ConstPtrSpecialBaseErrorUnionCode: 21391 zig_panic("TODO memset on const inner error union code"); 21392 case ConstPtrSpecialBaseErrorUnionPayload: 21393 zig_panic("TODO memset on const inner error union payload"); 21394 case ConstPtrSpecialBaseOptionalPayload: 21395 zig_panic("TODO memset on const inner optional payload"); 21396 case ConstPtrSpecialHardCodedAddr: 21397 zig_unreachable(); 21398 case ConstPtrSpecialFunction: 21399 zig_panic("TODO memset on ptr cast from function"); 21400 case ConstPtrSpecialNull: 21401 zig_panic("TODO memset on null ptr"); 21402 } 21403 21404 size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); 21405 size_t end = start + count; 21406 if (end > bound_end) { 21407 ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); 21408 return ira->codegen->invalid_instruction; 21409 } 21410 21411 ConstExprValue *byte_val = &casted_byte->value; 21412 for (size_t i = start; i < end; i += 1) { 21413 copy_const_val(&dest_elements[i], byte_val, true); 21414 } 21415 21416 return ir_const_void(ira, &instruction->base); 21417 } 21418 21419 IrInstruction *result = ir_build_memset(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 21420 casted_dest_ptr, casted_byte, casted_count); 21421 result->value.type = ira->codegen->builtin_types.entry_void; 21422 return result; 21423 } 21424 21425 static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcpy *instruction) { 21426 Error err; 21427 21428 IrInstruction *dest_ptr = instruction->dest_ptr->child; 21429 if (type_is_invalid(dest_ptr->value.type)) 21430 return ira->codegen->invalid_instruction; 21431 21432 IrInstruction *src_ptr = instruction->src_ptr->child; 21433 if (type_is_invalid(src_ptr->value.type)) 21434 return ira->codegen->invalid_instruction; 21435 21436 IrInstruction *count_value = instruction->count->child; 21437 if (type_is_invalid(count_value->value.type)) 21438 return ira->codegen->invalid_instruction; 21439 21440 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 21441 ZigType *dest_uncasted_type = dest_ptr->value.type; 21442 ZigType *src_uncasted_type = src_ptr->value.type; 21443 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 21444 dest_uncasted_type->data.pointer.is_volatile; 21445 bool src_is_volatile = (src_uncasted_type->id == ZigTypeIdPointer) && 21446 src_uncasted_type->data.pointer.is_volatile; 21447 21448 uint32_t dest_align; 21449 if (dest_uncasted_type->id == ZigTypeIdPointer) { 21450 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 21451 return ira->codegen->invalid_instruction; 21452 } else { 21453 dest_align = get_abi_alignment(ira->codegen, u8); 21454 } 21455 21456 uint32_t src_align; 21457 if (src_uncasted_type->id == ZigTypeIdPointer) { 21458 if ((err = resolve_ptr_align(ira, src_uncasted_type, &src_align))) 21459 return ira->codegen->invalid_instruction; 21460 } else { 21461 src_align = get_abi_alignment(ira->codegen, u8); 21462 } 21463 21464 ZigType *usize = ira->codegen->builtin_types.entry_usize; 21465 ZigType *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 21466 PtrLenUnknown, dest_align, 0, 0, false); 21467 ZigType *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, 21468 PtrLenUnknown, src_align, 0, 0, false); 21469 21470 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut); 21471 if (type_is_invalid(casted_dest_ptr->value.type)) 21472 return ira->codegen->invalid_instruction; 21473 21474 IrInstruction *casted_src_ptr = ir_implicit_cast(ira, src_ptr, u8_ptr_const); 21475 if (type_is_invalid(casted_src_ptr->value.type)) 21476 return ira->codegen->invalid_instruction; 21477 21478 IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); 21479 if (type_is_invalid(casted_count->value.type)) 21480 return ira->codegen->invalid_instruction; 21481 21482 // TODO test this at comptime with u8 and non-u8 types 21483 // TODO test with dest ptr being a global runtime variable 21484 if (casted_dest_ptr->value.special == ConstValSpecialStatic && 21485 casted_src_ptr->value.special == ConstValSpecialStatic && 21486 casted_count->value.special == ConstValSpecialStatic && 21487 casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) 21488 { 21489 size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); 21490 21491 ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; 21492 ConstExprValue *dest_elements; 21493 size_t dest_start; 21494 size_t dest_end; 21495 switch (dest_ptr_val->data.x_ptr.special) { 21496 case ConstPtrSpecialInvalid: 21497 case ConstPtrSpecialDiscard: 21498 zig_unreachable(); 21499 case ConstPtrSpecialRef: 21500 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 21501 dest_start = 0; 21502 dest_end = 1; 21503 break; 21504 case ConstPtrSpecialBaseArray: 21505 { 21506 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 21507 expand_undef_array(ira->codegen, array_val); 21508 dest_elements = array_val->data.x_array.data.s_none.elements; 21509 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 21510 dest_end = array_val->type->data.array.len; 21511 break; 21512 } 21513 case ConstPtrSpecialBaseStruct: 21514 zig_panic("TODO memcpy on const inner struct"); 21515 case ConstPtrSpecialBaseErrorUnionCode: 21516 zig_panic("TODO memcpy on const inner error union code"); 21517 case ConstPtrSpecialBaseErrorUnionPayload: 21518 zig_panic("TODO memcpy on const inner error union payload"); 21519 case ConstPtrSpecialBaseOptionalPayload: 21520 zig_panic("TODO memcpy on const inner optional payload"); 21521 case ConstPtrSpecialHardCodedAddr: 21522 zig_unreachable(); 21523 case ConstPtrSpecialFunction: 21524 zig_panic("TODO memcpy on ptr cast from function"); 21525 case ConstPtrSpecialNull: 21526 zig_panic("TODO memcpy on null ptr"); 21527 } 21528 21529 if (dest_start + count > dest_end) { 21530 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); 21531 return ira->codegen->invalid_instruction; 21532 } 21533 21534 ConstExprValue *src_ptr_val = &casted_src_ptr->value; 21535 ConstExprValue *src_elements; 21536 size_t src_start; 21537 size_t src_end; 21538 21539 switch (src_ptr_val->data.x_ptr.special) { 21540 case ConstPtrSpecialInvalid: 21541 case ConstPtrSpecialDiscard: 21542 zig_unreachable(); 21543 case ConstPtrSpecialRef: 21544 src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; 21545 src_start = 0; 21546 src_end = 1; 21547 break; 21548 case ConstPtrSpecialBaseArray: 21549 { 21550 ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; 21551 expand_undef_array(ira->codegen, array_val); 21552 src_elements = array_val->data.x_array.data.s_none.elements; 21553 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; 21554 src_end = array_val->type->data.array.len; 21555 break; 21556 } 21557 case ConstPtrSpecialBaseStruct: 21558 zig_panic("TODO memcpy on const inner struct"); 21559 case ConstPtrSpecialBaseErrorUnionCode: 21560 zig_panic("TODO memcpy on const inner error union code"); 21561 case ConstPtrSpecialBaseErrorUnionPayload: 21562 zig_panic("TODO memcpy on const inner error union payload"); 21563 case ConstPtrSpecialBaseOptionalPayload: 21564 zig_panic("TODO memcpy on const inner optional payload"); 21565 case ConstPtrSpecialHardCodedAddr: 21566 zig_unreachable(); 21567 case ConstPtrSpecialFunction: 21568 zig_panic("TODO memcpy on ptr cast from function"); 21569 case ConstPtrSpecialNull: 21570 zig_panic("TODO memcpy on null ptr"); 21571 } 21572 21573 if (src_start + count > src_end) { 21574 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); 21575 return ira->codegen->invalid_instruction; 21576 } 21577 21578 // TODO check for noalias violations - this should be generalized to work for any function 21579 21580 for (size_t i = 0; i < count; i += 1) { 21581 copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); 21582 } 21583 21584 return ir_const_void(ira, &instruction->base); 21585 } 21586 21587 IrInstruction *result = ir_build_memcpy(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 21588 casted_dest_ptr, casted_src_ptr, casted_count); 21589 result->value.type = ira->codegen->builtin_types.entry_void; 21590 return result; 21591 } 21592 21593 static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) { 21594 IrInstruction *ptr_ptr = instruction->ptr->child; 21595 if (type_is_invalid(ptr_ptr->value.type)) 21596 return ira->codegen->invalid_instruction; 21597 21598 ZigType *ptr_ptr_type = ptr_ptr->value.type; 21599 assert(ptr_ptr_type->id == ZigTypeIdPointer); 21600 ZigType *array_type = ptr_ptr_type->data.pointer.child_type; 21601 21602 IrInstruction *start = instruction->start->child; 21603 if (type_is_invalid(start->value.type)) 21604 return ira->codegen->invalid_instruction; 21605 21606 ZigType *usize = ira->codegen->builtin_types.entry_usize; 21607 IrInstruction *casted_start = ir_implicit_cast(ira, start, usize); 21608 if (type_is_invalid(casted_start->value.type)) 21609 return ira->codegen->invalid_instruction; 21610 21611 IrInstruction *end; 21612 if (instruction->end) { 21613 end = instruction->end->child; 21614 if (type_is_invalid(end->value.type)) 21615 return ira->codegen->invalid_instruction; 21616 end = ir_implicit_cast(ira, end, usize); 21617 if (type_is_invalid(end->value.type)) 21618 return ira->codegen->invalid_instruction; 21619 } else { 21620 end = nullptr; 21621 } 21622 21623 ZigType *return_type; 21624 21625 if (array_type->id == ZigTypeIdArray) { 21626 bool is_comptime_const = ptr_ptr->value.special == ConstValSpecialStatic && 21627 ptr_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst; 21628 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type, 21629 ptr_ptr_type->data.pointer.is_const || is_comptime_const, 21630 ptr_ptr_type->data.pointer.is_volatile, 21631 PtrLenUnknown, 21632 ptr_ptr_type->data.pointer.explicit_alignment, 0, 0, false); 21633 return_type = get_slice_type(ira->codegen, slice_ptr_type); 21634 } else if (array_type->id == ZigTypeIdPointer) { 21635 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 21636 ZigType *main_type = array_type->data.pointer.child_type; 21637 if (main_type->id == ZigTypeIdArray) { 21638 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, 21639 main_type->data.pointer.child_type, 21640 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile, 21641 PtrLenUnknown, 21642 array_type->data.pointer.explicit_alignment, 0, 0, false); 21643 return_type = get_slice_type(ira->codegen, slice_ptr_type); 21644 } else { 21645 ir_add_error(ira, &instruction->base, buf_sprintf("slice of single-item pointer")); 21646 return ira->codegen->invalid_instruction; 21647 } 21648 } else { 21649 if (array_type->data.pointer.ptr_len == PtrLenC) { 21650 array_type = adjust_ptr_len(ira->codegen, array_type, PtrLenUnknown); 21651 } 21652 return_type = get_slice_type(ira->codegen, array_type); 21653 if (!end) { 21654 ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value")); 21655 return ira->codegen->invalid_instruction; 21656 } 21657 } 21658 } else if (is_slice(array_type)) { 21659 ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index].type_entry; 21660 return_type = get_slice_type(ira->codegen, ptr_type); 21661 } else { 21662 ir_add_error(ira, &instruction->base, 21663 buf_sprintf("slice of non-array type '%s'", buf_ptr(&array_type->name))); 21664 return ira->codegen->invalid_instruction; 21665 } 21666 21667 if (instr_is_comptime(ptr_ptr) && 21668 value_is_comptime(&casted_start->value) && 21669 (!end || value_is_comptime(&end->value))) 21670 { 21671 ConstExprValue *array_val; 21672 ConstExprValue *parent_ptr; 21673 size_t abs_offset; 21674 size_t rel_end; 21675 bool ptr_is_undef = false; 21676 if (array_type->id == ZigTypeIdArray || 21677 (array_type->id == ZigTypeIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) 21678 { 21679 if (array_type->id == ZigTypeIdPointer) { 21680 ZigType *child_array_type = array_type->data.pointer.child_type; 21681 assert(child_array_type->id == ZigTypeIdArray); 21682 parent_ptr = const_ptr_pointee(ira, ira->codegen, &ptr_ptr->value, instruction->base.source_node); 21683 if (parent_ptr == nullptr) 21684 return ira->codegen->invalid_instruction; 21685 21686 array_val = const_ptr_pointee(ira, ira->codegen, parent_ptr, instruction->base.source_node); 21687 if (array_val == nullptr) 21688 return ira->codegen->invalid_instruction; 21689 21690 rel_end = child_array_type->data.array.len; 21691 abs_offset = 0; 21692 } else { 21693 array_val = const_ptr_pointee(ira, ira->codegen, &ptr_ptr->value, instruction->base.source_node); 21694 if (array_val == nullptr) 21695 return ira->codegen->invalid_instruction; 21696 rel_end = array_type->data.array.len; 21697 parent_ptr = nullptr; 21698 abs_offset = 0; 21699 } 21700 } else if (array_type->id == ZigTypeIdPointer) { 21701 assert(array_type->data.pointer.ptr_len == PtrLenUnknown); 21702 parent_ptr = const_ptr_pointee(ira, ira->codegen, &ptr_ptr->value, instruction->base.source_node); 21703 if (parent_ptr == nullptr) 21704 return ira->codegen->invalid_instruction; 21705 21706 if (parent_ptr->special == ConstValSpecialUndef) { 21707 array_val = nullptr; 21708 abs_offset = 0; 21709 rel_end = SIZE_MAX; 21710 ptr_is_undef = true; 21711 } else switch (parent_ptr->data.x_ptr.special) { 21712 case ConstPtrSpecialInvalid: 21713 case ConstPtrSpecialDiscard: 21714 zig_unreachable(); 21715 case ConstPtrSpecialRef: 21716 if (parent_ptr->data.x_ptr.data.ref.pointee->type->id == ZigTypeIdArray) { 21717 array_val = parent_ptr->data.x_ptr.data.ref.pointee; 21718 abs_offset = 0; 21719 rel_end = array_val->type->data.array.len; 21720 } else { 21721 array_val = nullptr; 21722 abs_offset = SIZE_MAX; 21723 rel_end = 1; 21724 } 21725 break; 21726 case ConstPtrSpecialBaseArray: 21727 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 21728 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 21729 rel_end = array_val->type->data.array.len - abs_offset; 21730 break; 21731 case ConstPtrSpecialBaseStruct: 21732 zig_panic("TODO slice const inner struct"); 21733 case ConstPtrSpecialBaseErrorUnionCode: 21734 zig_panic("TODO slice const inner error union code"); 21735 case ConstPtrSpecialBaseErrorUnionPayload: 21736 zig_panic("TODO slice const inner error union payload"); 21737 case ConstPtrSpecialBaseOptionalPayload: 21738 zig_panic("TODO slice const inner optional payload"); 21739 case ConstPtrSpecialHardCodedAddr: 21740 array_val = nullptr; 21741 abs_offset = 0; 21742 rel_end = SIZE_MAX; 21743 break; 21744 case ConstPtrSpecialFunction: 21745 zig_panic("TODO slice of ptr cast from function"); 21746 case ConstPtrSpecialNull: 21747 zig_panic("TODO slice of null ptr"); 21748 } 21749 } else if (is_slice(array_type)) { 21750 ConstExprValue *slice_ptr = const_ptr_pointee(ira, ira->codegen, &ptr_ptr->value, instruction->base.source_node); 21751 if (slice_ptr == nullptr) 21752 return ira->codegen->invalid_instruction; 21753 21754 parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index]; 21755 if (parent_ptr->special == ConstValSpecialUndef) { 21756 ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); 21757 return ira->codegen->invalid_instruction; 21758 } 21759 21760 ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index]; 21761 21762 switch (parent_ptr->data.x_ptr.special) { 21763 case ConstPtrSpecialInvalid: 21764 case ConstPtrSpecialDiscard: 21765 zig_unreachable(); 21766 case ConstPtrSpecialRef: 21767 array_val = nullptr; 21768 abs_offset = SIZE_MAX; 21769 rel_end = 1; 21770 break; 21771 case ConstPtrSpecialBaseArray: 21772 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 21773 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 21774 rel_end = bigint_as_unsigned(&len_val->data.x_bigint); 21775 break; 21776 case ConstPtrSpecialBaseStruct: 21777 zig_panic("TODO slice const inner struct"); 21778 case ConstPtrSpecialBaseErrorUnionCode: 21779 zig_panic("TODO slice const inner error union code"); 21780 case ConstPtrSpecialBaseErrorUnionPayload: 21781 zig_panic("TODO slice const inner error union payload"); 21782 case ConstPtrSpecialBaseOptionalPayload: 21783 zig_panic("TODO slice const inner optional payload"); 21784 case ConstPtrSpecialHardCodedAddr: 21785 array_val = nullptr; 21786 abs_offset = 0; 21787 rel_end = bigint_as_unsigned(&len_val->data.x_bigint); 21788 break; 21789 case ConstPtrSpecialFunction: 21790 zig_panic("TODO slice of slice cast from function"); 21791 case ConstPtrSpecialNull: 21792 zig_panic("TODO slice of null"); 21793 } 21794 } else { 21795 zig_unreachable(); 21796 } 21797 21798 uint64_t start_scalar = bigint_as_unsigned(&casted_start->value.data.x_bigint); 21799 if (!ptr_is_undef && start_scalar > rel_end) { 21800 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); 21801 return ira->codegen->invalid_instruction; 21802 } 21803 21804 uint64_t end_scalar; 21805 if (end) { 21806 end_scalar = bigint_as_unsigned(&end->value.data.x_bigint); 21807 } else { 21808 end_scalar = rel_end; 21809 } 21810 if (!ptr_is_undef) { 21811 if (end_scalar > rel_end) { 21812 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); 21813 return ira->codegen->invalid_instruction; 21814 } 21815 if (start_scalar > end_scalar) { 21816 ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); 21817 return ira->codegen->invalid_instruction; 21818 } 21819 } 21820 if (ptr_is_undef && start_scalar != end_scalar) { 21821 ir_add_error(ira, &instruction->base, buf_sprintf("non-zero length slice of undefined pointer")); 21822 return ira->codegen->invalid_instruction; 21823 } 21824 21825 IrInstruction *result = ir_const(ira, &instruction->base, return_type); 21826 ConstExprValue *out_val = &result->value; 21827 out_val->data.x_struct.fields = create_const_vals(2); 21828 21829 ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; 21830 21831 if (array_val) { 21832 size_t index = abs_offset + start_scalar; 21833 bool is_const = slice_is_const(return_type); 21834 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const, PtrLenUnknown); 21835 if (array_type->id == ZigTypeIdArray) { 21836 ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut; 21837 } else if (is_slice(array_type)) { 21838 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 21839 } else if (array_type->id == ZigTypeIdPointer) { 21840 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 21841 } 21842 } else if (ptr_is_undef) { 21843 ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type, 21844 slice_is_const(return_type)); 21845 ptr_val->special = ConstValSpecialUndef; 21846 } else switch (parent_ptr->data.x_ptr.special) { 21847 case ConstPtrSpecialInvalid: 21848 case ConstPtrSpecialDiscard: 21849 zig_unreachable(); 21850 case ConstPtrSpecialRef: 21851 init_const_ptr_ref(ira->codegen, ptr_val, 21852 parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); 21853 break; 21854 case ConstPtrSpecialBaseArray: 21855 zig_unreachable(); 21856 case ConstPtrSpecialBaseStruct: 21857 zig_panic("TODO"); 21858 case ConstPtrSpecialBaseErrorUnionCode: 21859 zig_panic("TODO"); 21860 case ConstPtrSpecialBaseErrorUnionPayload: 21861 zig_panic("TODO"); 21862 case ConstPtrSpecialBaseOptionalPayload: 21863 zig_panic("TODO"); 21864 case ConstPtrSpecialHardCodedAddr: 21865 init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, 21866 parent_ptr->type->data.pointer.child_type, 21867 parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, 21868 slice_is_const(return_type)); 21869 break; 21870 case ConstPtrSpecialFunction: 21871 zig_panic("TODO"); 21872 case ConstPtrSpecialNull: 21873 zig_panic("TODO"); 21874 } 21875 21876 ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; 21877 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); 21878 21879 return result; 21880 } 21881 21882 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 21883 return_type, nullptr, true, false, true); 21884 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { 21885 return result_loc; 21886 } 21887 return ir_build_slice_gen(ira, &instruction->base, return_type, 21888 ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc); 21889 } 21890 21891 static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { 21892 Error err; 21893 IrInstruction *container = instruction->container->child; 21894 if (type_is_invalid(container->value.type)) 21895 return ira->codegen->invalid_instruction; 21896 ZigType *container_type = ir_resolve_type(ira, container); 21897 21898 if ((err = ensure_complete_type(ira->codegen, container_type))) 21899 return ira->codegen->invalid_instruction; 21900 21901 uint64_t result; 21902 if (type_is_invalid(container_type)) { 21903 return ira->codegen->invalid_instruction; 21904 } else if (container_type->id == ZigTypeIdEnum) { 21905 result = container_type->data.enumeration.src_field_count; 21906 } else if (container_type->id == ZigTypeIdStruct) { 21907 result = container_type->data.structure.src_field_count; 21908 } else if (container_type->id == ZigTypeIdUnion) { 21909 result = container_type->data.unionation.src_field_count; 21910 } else if (container_type->id == ZigTypeIdErrorSet) { 21911 if (!resolve_inferred_error_set(ira->codegen, container_type, instruction->base.source_node)) { 21912 return ira->codegen->invalid_instruction; 21913 } 21914 if (type_is_global_error_set(container_type)) { 21915 ir_add_error(ira, &instruction->base, buf_sprintf("global error set member count not available at comptime")); 21916 return ira->codegen->invalid_instruction; 21917 } 21918 result = container_type->data.error_set.err_count; 21919 } else { 21920 ir_add_error(ira, &instruction->base, buf_sprintf("no value count available for type '%s'", buf_ptr(&container_type->name))); 21921 return ira->codegen->invalid_instruction; 21922 } 21923 21924 return ir_const_unsigned(ira, &instruction->base, result); 21925 } 21926 21927 static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstructionMemberType *instruction) { 21928 Error err; 21929 IrInstruction *container_type_value = instruction->container_type->child; 21930 ZigType *container_type = ir_resolve_type(ira, container_type_value); 21931 if (type_is_invalid(container_type)) 21932 return ira->codegen->invalid_instruction; 21933 21934 if ((err = ensure_complete_type(ira->codegen, container_type))) 21935 return ira->codegen->invalid_instruction; 21936 21937 21938 uint64_t member_index; 21939 IrInstruction *index_value = instruction->member_index->child; 21940 if (!ir_resolve_usize(ira, index_value, &member_index)) 21941 return ira->codegen->invalid_instruction; 21942 21943 if (container_type->id == ZigTypeIdStruct) { 21944 if (member_index >= container_type->data.structure.src_field_count) { 21945 ir_add_error(ira, index_value, 21946 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 21947 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); 21948 return ira->codegen->invalid_instruction; 21949 } 21950 TypeStructField *field = &container_type->data.structure.fields[member_index]; 21951 21952 return ir_const_type(ira, &instruction->base, field->type_entry); 21953 } else if (container_type->id == ZigTypeIdUnion) { 21954 if (member_index >= container_type->data.unionation.src_field_count) { 21955 ir_add_error(ira, index_value, 21956 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 21957 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); 21958 return ira->codegen->invalid_instruction; 21959 } 21960 TypeUnionField *field = &container_type->data.unionation.fields[member_index]; 21961 21962 return ir_const_type(ira, &instruction->base, field->type_entry); 21963 } else { 21964 ir_add_error(ira, container_type_value, 21965 buf_sprintf("type '%s' does not support @memberType", buf_ptr(&container_type->name))); 21966 return ira->codegen->invalid_instruction; 21967 } 21968 } 21969 21970 static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstructionMemberName *instruction) { 21971 Error err; 21972 IrInstruction *container_type_value = instruction->container_type->child; 21973 ZigType *container_type = ir_resolve_type(ira, container_type_value); 21974 if (type_is_invalid(container_type)) 21975 return ira->codegen->invalid_instruction; 21976 21977 if ((err = ensure_complete_type(ira->codegen, container_type))) 21978 return ira->codegen->invalid_instruction; 21979 21980 uint64_t member_index; 21981 IrInstruction *index_value = instruction->member_index->child; 21982 if (!ir_resolve_usize(ira, index_value, &member_index)) 21983 return ira->codegen->invalid_instruction; 21984 21985 if (container_type->id == ZigTypeIdStruct) { 21986 if (member_index >= container_type->data.structure.src_field_count) { 21987 ir_add_error(ira, index_value, 21988 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 21989 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); 21990 return ira->codegen->invalid_instruction; 21991 } 21992 TypeStructField *field = &container_type->data.structure.fields[member_index]; 21993 21994 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 21995 init_const_str_lit(ira->codegen, &result->value, field->name); 21996 return result; 21997 } else if (container_type->id == ZigTypeIdEnum) { 21998 if (member_index >= container_type->data.enumeration.src_field_count) { 21999 ir_add_error(ira, index_value, 22000 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 22001 member_index, buf_ptr(&container_type->name), container_type->data.enumeration.src_field_count)); 22002 return ira->codegen->invalid_instruction; 22003 } 22004 TypeEnumField *field = &container_type->data.enumeration.fields[member_index]; 22005 22006 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 22007 init_const_str_lit(ira->codegen, &result->value, field->name); 22008 return result; 22009 } else if (container_type->id == ZigTypeIdUnion) { 22010 if (member_index >= container_type->data.unionation.src_field_count) { 22011 ir_add_error(ira, index_value, 22012 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 22013 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); 22014 return ira->codegen->invalid_instruction; 22015 } 22016 TypeUnionField *field = &container_type->data.unionation.fields[member_index]; 22017 22018 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 22019 init_const_str_lit(ira->codegen, &result->value, field->name); 22020 return result; 22021 } else { 22022 ir_add_error(ira, container_type_value, 22023 buf_sprintf("type '%s' does not support @memberName", buf_ptr(&container_type->name))); 22024 return ira->codegen->invalid_instruction; 22025 } 22026 } 22027 22028 static IrInstruction *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstructionHasField *instruction) { 22029 Error err; 22030 ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); 22031 if (type_is_invalid(container_type)) 22032 return ira->codegen->invalid_instruction; 22033 22034 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusZeroBitsKnown))) 22035 return ira->codegen->invalid_instruction; 22036 22037 Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); 22038 if (field_name == nullptr) 22039 return ira->codegen->invalid_instruction; 22040 22041 bool result; 22042 if (container_type->id == ZigTypeIdStruct) { 22043 result = find_struct_type_field(container_type, field_name) != nullptr; 22044 } else if (container_type->id == ZigTypeIdEnum) { 22045 result = find_enum_type_field(container_type, field_name) != nullptr; 22046 } else if (container_type->id == ZigTypeIdUnion) { 22047 result = find_union_type_field(container_type, field_name) != nullptr; 22048 } else { 22049 ir_add_error(ira, instruction->container_type, 22050 buf_sprintf("type '%s' does not support @hasField", buf_ptr(&container_type->name))); 22051 return ira->codegen->invalid_instruction; 22052 } 22053 return ir_const_bool(ira, &instruction->base, result); 22054 } 22055 22056 static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) { 22057 IrInstruction *result = ir_build_breakpoint(&ira->new_irb, 22058 instruction->base.scope, instruction->base.source_node); 22059 result->value.type = ira->codegen->builtin_types.entry_void; 22060 return result; 22061 } 22062 22063 static IrInstruction *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstructionReturnAddress *instruction) { 22064 IrInstruction *result = ir_build_return_address(&ira->new_irb, 22065 instruction->base.scope, instruction->base.source_node); 22066 result->value.type = ira->codegen->builtin_types.entry_usize; 22067 return result; 22068 } 22069 22070 static IrInstruction *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstructionFrameAddress *instruction) { 22071 IrInstruction *result = ir_build_frame_address(&ira->new_irb, 22072 instruction->base.scope, instruction->base.source_node); 22073 result->value.type = ira->codegen->builtin_types.entry_usize; 22074 return result; 22075 } 22076 22077 static IrInstruction *ir_analyze_instruction_frame_handle(IrAnalyze *ira, IrInstructionFrameHandle *instruction) { 22078 ZigFn *fn = exec_fn_entry(ira->new_irb.exec); 22079 ir_assert(fn != nullptr, &instruction->base); 22080 22081 ZigType *frame_type = get_fn_frame_type(ira->codegen, fn); 22082 ZigType *ptr_frame_type = get_pointer_to_type(ira->codegen, frame_type, false); 22083 22084 IrInstruction *result = ir_build_handle(&ira->new_irb, instruction->base.scope, instruction->base.source_node); 22085 result->value.type = ptr_frame_type; 22086 return result; 22087 } 22088 22089 static IrInstruction *ir_analyze_instruction_frame_type(IrAnalyze *ira, IrInstructionFrameType *instruction) { 22090 ZigFn *fn = ir_resolve_fn(ira, instruction->fn->child); 22091 if (fn == nullptr) 22092 return ira->codegen->invalid_instruction; 22093 22094 ZigType *ty = get_fn_frame_type(ira->codegen, fn); 22095 return ir_const_type(ira, &instruction->base, ty); 22096 } 22097 22098 static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstructionFrameSizeSrc *instruction) { 22099 IrInstruction *fn = instruction->fn->child; 22100 if (type_is_invalid(fn->value.type)) 22101 return ira->codegen->invalid_instruction; 22102 22103 if (fn->value.type->id != ZigTypeIdFn) { 22104 ir_add_error(ira, fn, 22105 buf_sprintf("expected function, found '%s'", buf_ptr(&fn->value.type->name))); 22106 return ira->codegen->invalid_instruction; 22107 } 22108 22109 IrInstruction *result = ir_build_frame_size_gen(&ira->new_irb, instruction->base.scope, 22110 instruction->base.source_node, fn); 22111 result->value.type = ira->codegen->builtin_types.entry_usize; 22112 return result; 22113 } 22114 22115 static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { 22116 Error err; 22117 IrInstruction *type_value = instruction->type_value->child; 22118 if (type_is_invalid(type_value->value.type)) 22119 return ira->codegen->invalid_instruction; 22120 ZigType *type_entry = ir_resolve_type(ira, type_value); 22121 22122 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusAlignmentKnown))) 22123 return ira->codegen->invalid_instruction; 22124 22125 switch (type_entry->id) { 22126 case ZigTypeIdInvalid: 22127 zig_unreachable(); 22128 case ZigTypeIdMetaType: 22129 case ZigTypeIdUnreachable: 22130 case ZigTypeIdComptimeFloat: 22131 case ZigTypeIdComptimeInt: 22132 case ZigTypeIdEnumLiteral: 22133 case ZigTypeIdUndefined: 22134 case ZigTypeIdNull: 22135 case ZigTypeIdBoundFn: 22136 case ZigTypeIdArgTuple: 22137 case ZigTypeIdVoid: 22138 case ZigTypeIdOpaque: 22139 ir_add_error(ira, instruction->type_value, 22140 buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); 22141 return ira->codegen->invalid_instruction; 22142 case ZigTypeIdBool: 22143 case ZigTypeIdInt: 22144 case ZigTypeIdFloat: 22145 case ZigTypeIdPointer: 22146 case ZigTypeIdArray: 22147 case ZigTypeIdStruct: 22148 case ZigTypeIdOptional: 22149 case ZigTypeIdErrorUnion: 22150 case ZigTypeIdErrorSet: 22151 case ZigTypeIdEnum: 22152 case ZigTypeIdUnion: 22153 case ZigTypeIdFn: 22154 case ZigTypeIdVector: 22155 case ZigTypeIdFnFrame: 22156 case ZigTypeIdAnyFrame: 22157 { 22158 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); 22159 return ir_const_unsigned(ira, &instruction->base, align_in_bytes); 22160 } 22161 } 22162 zig_unreachable(); 22163 } 22164 22165 static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { 22166 Error err; 22167 22168 IrInstruction *type_value = instruction->type_value->child; 22169 if (type_is_invalid(type_value->value.type)) 22170 return ira->codegen->invalid_instruction; 22171 22172 ZigType *dest_type = ir_resolve_type(ira, type_value); 22173 if (type_is_invalid(dest_type)) 22174 return ira->codegen->invalid_instruction; 22175 22176 if (dest_type->id != ZigTypeIdInt) { 22177 ir_add_error(ira, type_value, 22178 buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 22179 return ira->codegen->invalid_instruction; 22180 } 22181 22182 IrInstruction *op1 = instruction->op1->child; 22183 if (type_is_invalid(op1->value.type)) 22184 return ira->codegen->invalid_instruction; 22185 22186 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 22187 if (type_is_invalid(casted_op1->value.type)) 22188 return ira->codegen->invalid_instruction; 22189 22190 IrInstruction *op2 = instruction->op2->child; 22191 if (type_is_invalid(op2->value.type)) 22192 return ira->codegen->invalid_instruction; 22193 22194 IrInstruction *casted_op2; 22195 if (instruction->op == IrOverflowOpShl) { 22196 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 22197 dest_type->data.integral.bit_count - 1); 22198 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 22199 } else { 22200 casted_op2 = ir_implicit_cast(ira, op2, dest_type); 22201 } 22202 if (type_is_invalid(casted_op2->value.type)) 22203 return ira->codegen->invalid_instruction; 22204 22205 IrInstruction *result_ptr = instruction->result_ptr->child; 22206 if (type_is_invalid(result_ptr->value.type)) 22207 return ira->codegen->invalid_instruction; 22208 22209 ZigType *expected_ptr_type; 22210 if (result_ptr->value.type->id == ZigTypeIdPointer) { 22211 uint32_t alignment; 22212 if ((err = resolve_ptr_align(ira, result_ptr->value.type, &alignment))) 22213 return ira->codegen->invalid_instruction; 22214 expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type, 22215 false, result_ptr->value.type->data.pointer.is_volatile, 22216 PtrLenSingle, 22217 alignment, 0, 0, false); 22218 } else { 22219 expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false); 22220 } 22221 22222 IrInstruction *casted_result_ptr = ir_implicit_cast(ira, result_ptr, expected_ptr_type); 22223 if (type_is_invalid(casted_result_ptr->value.type)) 22224 return ira->codegen->invalid_instruction; 22225 22226 if (casted_op1->value.special == ConstValSpecialStatic && 22227 casted_op2->value.special == ConstValSpecialStatic && 22228 casted_result_ptr->value.special == ConstValSpecialStatic) 22229 { 22230 BigInt *op1_bigint = &casted_op1->value.data.x_bigint; 22231 BigInt *op2_bigint = &casted_op2->value.data.x_bigint; 22232 ConstExprValue *pointee_val = const_ptr_pointee(ira, ira->codegen, &casted_result_ptr->value, casted_result_ptr->source_node); 22233 if (pointee_val == nullptr) 22234 return ira->codegen->invalid_instruction; 22235 BigInt *dest_bigint = &pointee_val->data.x_bigint; 22236 switch (instruction->op) { 22237 case IrOverflowOpAdd: 22238 bigint_add(dest_bigint, op1_bigint, op2_bigint); 22239 break; 22240 case IrOverflowOpSub: 22241 bigint_sub(dest_bigint, op1_bigint, op2_bigint); 22242 break; 22243 case IrOverflowOpMul: 22244 bigint_mul(dest_bigint, op1_bigint, op2_bigint); 22245 break; 22246 case IrOverflowOpShl: 22247 bigint_shl(dest_bigint, op1_bigint, op2_bigint); 22248 break; 22249 } 22250 bool result_bool = false; 22251 if (!bigint_fits_in_bits(dest_bigint, dest_type->data.integral.bit_count, 22252 dest_type->data.integral.is_signed)) 22253 { 22254 result_bool = true; 22255 BigInt tmp_bigint; 22256 bigint_init_bigint(&tmp_bigint, dest_bigint); 22257 bigint_truncate(dest_bigint, &tmp_bigint, dest_type->data.integral.bit_count, 22258 dest_type->data.integral.is_signed); 22259 } 22260 pointee_val->special = ConstValSpecialStatic; 22261 return ir_const_bool(ira, &instruction->base, result_bool); 22262 } 22263 22264 IrInstruction *result = ir_build_overflow_op(&ira->new_irb, 22265 instruction->base.scope, instruction->base.source_node, 22266 instruction->op, type_value, casted_op1, casted_op2, casted_result_ptr, dest_type); 22267 result->value.type = ira->codegen->builtin_types.entry_bool; 22268 return result; 22269 } 22270 22271 static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, ZigType *float_type, 22272 ConstExprValue *op1, ConstExprValue *op2, ConstExprValue *op3, ConstExprValue *out_val) { 22273 if (float_type->id == ZigTypeIdComptimeFloat) { 22274 f128M_mulAdd(&out_val->data.x_bigfloat.value, &op1->data.x_bigfloat.value, &op2->data.x_bigfloat.value, 22275 &op3->data.x_bigfloat.value); 22276 } else if (float_type->id == ZigTypeIdFloat) { 22277 switch (float_type->data.floating.bit_count) { 22278 case 16: 22279 out_val->data.x_f16 = f16_mulAdd(op1->data.x_f16, op2->data.x_f16, op3->data.x_f16); 22280 break; 22281 case 32: 22282 out_val->data.x_f32 = fmaf(op1->data.x_f32, op2->data.x_f32, op3->data.x_f32); 22283 break; 22284 case 64: 22285 out_val->data.x_f64 = fma(op1->data.x_f64, op2->data.x_f64, op3->data.x_f64); 22286 break; 22287 case 128: 22288 f128M_mulAdd(&op1->data.x_f128, &op2->data.x_f128, &op3->data.x_f128, &out_val->data.x_f128); 22289 break; 22290 default: 22291 zig_unreachable(); 22292 } 22293 } else { 22294 zig_unreachable(); 22295 } 22296 } 22297 22298 static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructionMulAdd *instruction) { 22299 IrInstruction *type_value = instruction->type_value->child; 22300 if (type_is_invalid(type_value->value.type)) 22301 return ira->codegen->invalid_instruction; 22302 22303 ZigType *expr_type = ir_resolve_type(ira, type_value); 22304 if (type_is_invalid(expr_type)) 22305 return ira->codegen->invalid_instruction; 22306 22307 // Only allow float types, and vectors of floats. 22308 ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 22309 if (float_type->id != ZigTypeIdFloat) { 22310 ir_add_error(ira, type_value, 22311 buf_sprintf("expected float or vector of float type, found '%s'", buf_ptr(&float_type->name))); 22312 return ira->codegen->invalid_instruction; 22313 } 22314 22315 IrInstruction *op1 = instruction->op1->child; 22316 if (type_is_invalid(op1->value.type)) 22317 return ira->codegen->invalid_instruction; 22318 22319 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, expr_type); 22320 if (type_is_invalid(casted_op1->value.type)) 22321 return ira->codegen->invalid_instruction; 22322 22323 IrInstruction *op2 = instruction->op2->child; 22324 if (type_is_invalid(op2->value.type)) 22325 return ira->codegen->invalid_instruction; 22326 22327 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, expr_type); 22328 if (type_is_invalid(casted_op2->value.type)) 22329 return ira->codegen->invalid_instruction; 22330 22331 IrInstruction *op3 = instruction->op3->child; 22332 if (type_is_invalid(op3->value.type)) 22333 return ira->codegen->invalid_instruction; 22334 22335 IrInstruction *casted_op3 = ir_implicit_cast(ira, op3, expr_type); 22336 if (type_is_invalid(casted_op3->value.type)) 22337 return ira->codegen->invalid_instruction; 22338 22339 if (instr_is_comptime(casted_op1) && 22340 instr_is_comptime(casted_op2) && 22341 instr_is_comptime(casted_op3)) { 22342 ConstExprValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); 22343 if (!op1_const) 22344 return ira->codegen->invalid_instruction; 22345 ConstExprValue *op2_const = ir_resolve_const(ira, casted_op2, UndefBad); 22346 if (!op2_const) 22347 return ira->codegen->invalid_instruction; 22348 ConstExprValue *op3_const = ir_resolve_const(ira, casted_op3, UndefBad); 22349 if (!op3_const) 22350 return ira->codegen->invalid_instruction; 22351 22352 IrInstruction *result = ir_const(ira, &instruction->base, expr_type); 22353 ConstExprValue *out_val = &result->value; 22354 22355 if (expr_type->id == ZigTypeIdVector) { 22356 expand_undef_array(ira->codegen, op1_const); 22357 expand_undef_array(ira->codegen, op2_const); 22358 expand_undef_array(ira->codegen, op3_const); 22359 out_val->special = ConstValSpecialUndef; 22360 expand_undef_array(ira->codegen, out_val); 22361 size_t len = expr_type->data.vector.len; 22362 for (size_t i = 0; i < len; i += 1) { 22363 ConstExprValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i]; 22364 ConstExprValue *float_operand_op2 = &op2_const->data.x_array.data.s_none.elements[i]; 22365 ConstExprValue *float_operand_op3 = &op3_const->data.x_array.data.s_none.elements[i]; 22366 ConstExprValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; 22367 assert(float_operand_op1->type == float_type); 22368 assert(float_operand_op2->type == float_type); 22369 assert(float_operand_op3->type == float_type); 22370 assert(float_out_val->type == float_type); 22371 ir_eval_mul_add(ira, instruction, float_type, 22372 op1_const, op2_const, op3_const, float_out_val); 22373 float_out_val->type = float_type; 22374 } 22375 out_val->type = expr_type; 22376 out_val->special = ConstValSpecialStatic; 22377 } else { 22378 ir_eval_mul_add(ira, instruction, float_type, op1_const, op2_const, op3_const, out_val); 22379 } 22380 return result; 22381 } 22382 22383 IrInstruction *result = ir_build_mul_add(&ira->new_irb, 22384 instruction->base.scope, instruction->base.source_node, 22385 type_value, casted_op1, casted_op2, casted_op3); 22386 result->value.type = expr_type; 22387 return result; 22388 } 22389 22390 static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErrSrc *instruction) { 22391 IrInstruction *base_ptr = instruction->base_ptr->child; 22392 if (type_is_invalid(base_ptr->value.type)) 22393 return ira->codegen->invalid_instruction; 22394 22395 IrInstruction *value; 22396 if (instruction->base_ptr_is_payload) { 22397 value = base_ptr; 22398 } else { 22399 value = ir_get_deref(ira, &instruction->base, base_ptr, nullptr); 22400 } 22401 22402 ZigType *type_entry = value->value.type; 22403 if (type_is_invalid(type_entry)) 22404 return ira->codegen->invalid_instruction; 22405 if (type_entry->id == ZigTypeIdErrorUnion) { 22406 if (instr_is_comptime(value)) { 22407 ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); 22408 if (!err_union_val) 22409 return ira->codegen->invalid_instruction; 22410 22411 if (err_union_val->special != ConstValSpecialRuntime) { 22412 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 22413 return ir_const_bool(ira, &instruction->base, (err != nullptr)); 22414 } 22415 } 22416 22417 if (instruction->resolve_err_set) { 22418 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 22419 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { 22420 return ira->codegen->invalid_instruction; 22421 } 22422 if (!type_is_global_error_set(err_set_type) && 22423 err_set_type->data.error_set.err_count == 0) 22424 { 22425 assert(err_set_type->data.error_set.infer_fn == nullptr); 22426 return ir_const_bool(ira, &instruction->base, false); 22427 } 22428 } 22429 22430 return ir_build_test_err_gen(ira, &instruction->base, value); 22431 } else if (type_entry->id == ZigTypeIdErrorSet) { 22432 return ir_const_bool(ira, &instruction->base, true); 22433 } else { 22434 return ir_const_bool(ira, &instruction->base, false); 22435 } 22436 } 22437 22438 static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, 22439 IrInstruction *base_ptr, bool initializing) 22440 { 22441 ZigType *ptr_type = base_ptr->value.type; 22442 22443 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 22444 assert(ptr_type->id == ZigTypeIdPointer); 22445 22446 ZigType *type_entry = ptr_type->data.pointer.child_type; 22447 if (type_is_invalid(type_entry)) 22448 return ira->codegen->invalid_instruction; 22449 22450 if (type_entry->id != ZigTypeIdErrorUnion) { 22451 ir_add_error(ira, base_ptr, 22452 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 22453 return ira->codegen->invalid_instruction; 22454 } 22455 22456 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 22457 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type, 22458 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 22459 ptr_type->data.pointer.explicit_alignment, 0, 0, false); 22460 22461 if (instr_is_comptime(base_ptr)) { 22462 ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 22463 if (!ptr_val) 22464 return ira->codegen->invalid_instruction; 22465 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && 22466 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) 22467 { 22468 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 22469 if (err_union_val == nullptr) 22470 return ira->codegen->invalid_instruction; 22471 22472 if (initializing && err_union_val->special == ConstValSpecialUndef) { 22473 ConstExprValue *vals = create_const_vals(2); 22474 ConstExprValue *err_set_val = &vals[0]; 22475 ConstExprValue *payload_val = &vals[1]; 22476 22477 err_set_val->special = ConstValSpecialUndef; 22478 err_set_val->type = err_set_type; 22479 err_set_val->parent.id = ConstParentIdErrUnionCode; 22480 err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val; 22481 22482 payload_val->special = ConstValSpecialUndef; 22483 payload_val->type = type_entry->data.error_union.payload_type; 22484 payload_val->parent.id = ConstParentIdErrUnionPayload; 22485 payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val; 22486 22487 err_union_val->special = ConstValSpecialStatic; 22488 err_union_val->data.x_err_union.error_set = err_set_val; 22489 err_union_val->data.x_err_union.payload = payload_val; 22490 } 22491 ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr); 22492 22493 IrInstruction *result; 22494 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 22495 result = ir_build_unwrap_err_code(&ira->new_irb, source_instr->scope, 22496 source_instr->source_node, base_ptr); 22497 result->value.type = result_type; 22498 result->value.special = ConstValSpecialStatic; 22499 } else { 22500 result = ir_const(ira, source_instr, result_type); 22501 } 22502 ConstExprValue *const_val = &result->value; 22503 const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode; 22504 const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val; 22505 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 22506 return result; 22507 } 22508 } 22509 22510 IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, 22511 source_instr->scope, source_instr->source_node, base_ptr); 22512 result->value.type = result_type; 22513 return result; 22514 } 22515 22516 static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, 22517 IrInstructionUnwrapErrCode *instruction) 22518 { 22519 IrInstruction *base_ptr = instruction->err_union_ptr->child; 22520 if (type_is_invalid(base_ptr->value.type)) 22521 return ira->codegen->invalid_instruction; 22522 return ir_analyze_unwrap_err_code(ira, &instruction->base, base_ptr, false); 22523 } 22524 22525 static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, 22526 IrInstruction *base_ptr, bool safety_check_on, bool initializing) 22527 { 22528 ZigType *ptr_type = base_ptr->value.type; 22529 22530 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 22531 assert(ptr_type->id == ZigTypeIdPointer); 22532 22533 ZigType *type_entry = ptr_type->data.pointer.child_type; 22534 if (type_is_invalid(type_entry)) 22535 return ira->codegen->invalid_instruction; 22536 22537 if (type_entry->id != ZigTypeIdErrorUnion) { 22538 ir_add_error(ira, base_ptr, 22539 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 22540 return ira->codegen->invalid_instruction; 22541 } 22542 22543 ZigType *payload_type = type_entry->data.error_union.payload_type; 22544 if (type_is_invalid(payload_type)) 22545 return ira->codegen->invalid_instruction; 22546 22547 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, 22548 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 22549 PtrLenSingle, 0, 0, 0, false); 22550 if (instr_is_comptime(base_ptr)) { 22551 ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 22552 if (!ptr_val) 22553 return ira->codegen->invalid_instruction; 22554 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 22555 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 22556 if (err_union_val == nullptr) 22557 return ira->codegen->invalid_instruction; 22558 if (initializing && err_union_val->special == ConstValSpecialUndef) { 22559 ConstExprValue *vals = create_const_vals(2); 22560 ConstExprValue *err_set_val = &vals[0]; 22561 ConstExprValue *payload_val = &vals[1]; 22562 22563 err_set_val->special = ConstValSpecialStatic; 22564 err_set_val->type = type_entry->data.error_union.err_set_type; 22565 err_set_val->data.x_err_set = nullptr; 22566 22567 payload_val->special = ConstValSpecialUndef; 22568 payload_val->type = payload_type; 22569 22570 err_union_val->special = ConstValSpecialStatic; 22571 err_union_val->data.x_err_union.error_set = err_set_val; 22572 err_union_val->data.x_err_union.payload = payload_val; 22573 } 22574 22575 if (err_union_val->special != ConstValSpecialRuntime) { 22576 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 22577 if (err != nullptr) { 22578 ir_add_error(ira, source_instr, 22579 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); 22580 return ira->codegen->invalid_instruction; 22581 } 22582 22583 IrInstruction *result; 22584 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 22585 result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, 22586 source_instr->source_node, base_ptr, safety_check_on, initializing); 22587 result->value.type = result_type; 22588 result->value.special = ConstValSpecialStatic; 22589 } else { 22590 result = ir_const(ira, source_instr, result_type); 22591 } 22592 result->value.data.x_ptr.special = ConstPtrSpecialRef; 22593 result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; 22594 result->value.data.x_ptr.mut = ptr_val->data.x_ptr.mut; 22595 return result; 22596 } 22597 } 22598 } 22599 22600 IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, 22601 source_instr->source_node, base_ptr, safety_check_on, initializing); 22602 result->value.type = result_type; 22603 return result; 22604 } 22605 22606 static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, 22607 IrInstructionUnwrapErrPayload *instruction) 22608 { 22609 assert(instruction->value->child); 22610 IrInstruction *value = instruction->value->child; 22611 if (type_is_invalid(value->value.type)) 22612 return ira->codegen->invalid_instruction; 22613 22614 return ir_analyze_unwrap_error_payload(ira, &instruction->base, value, instruction->safety_check_on, false); 22615 } 22616 22617 static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { 22618 AstNode *proto_node = instruction->base.source_node; 22619 assert(proto_node->type == NodeTypeFnProto); 22620 22621 if (proto_node->data.fn_proto.auto_err_set) { 22622 ir_add_error(ira, &instruction->base, 22623 buf_sprintf("inferring error set of return type valid only for function definitions")); 22624 return ira->codegen->invalid_instruction; 22625 } 22626 22627 FnTypeId fn_type_id = {0}; 22628 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); 22629 22630 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { 22631 AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); 22632 assert(param_node->type == NodeTypeParamDecl); 22633 22634 bool param_is_var_args = param_node->data.param_decl.is_var_args; 22635 if (param_is_var_args) { 22636 if (fn_type_id.cc == CallingConventionC) { 22637 fn_type_id.param_count = fn_type_id.next_param_index; 22638 continue; 22639 } else if (fn_type_id.cc == CallingConventionUnspecified) { 22640 return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); 22641 } else { 22642 zig_unreachable(); 22643 } 22644 } 22645 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; 22646 param_info->is_noalias = param_node->data.param_decl.is_noalias; 22647 22648 if (instruction->param_types[fn_type_id.next_param_index] == nullptr) { 22649 param_info->type = nullptr; 22650 return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); 22651 } else { 22652 IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->child; 22653 if (type_is_invalid(param_type_value->value.type)) 22654 return ira->codegen->invalid_instruction; 22655 ZigType *param_type = ir_resolve_type(ira, param_type_value); 22656 switch (type_requires_comptime(ira->codegen, param_type)) { 22657 case ReqCompTimeYes: 22658 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 22659 ir_add_error(ira, param_type_value, 22660 buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", 22661 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 22662 return ira->codegen->invalid_instruction; 22663 } 22664 param_info->type = param_type; 22665 fn_type_id.next_param_index += 1; 22666 return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); 22667 case ReqCompTimeInvalid: 22668 return ira->codegen->invalid_instruction; 22669 case ReqCompTimeNo: 22670 break; 22671 } 22672 if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { 22673 ir_add_error(ira, param_type_value, 22674 buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", 22675 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 22676 return ira->codegen->invalid_instruction; 22677 } 22678 param_info->type = param_type; 22679 } 22680 22681 } 22682 22683 if (instruction->align_value != nullptr) { 22684 if (!ir_resolve_align(ira, instruction->align_value->child, &fn_type_id.alignment)) 22685 return ira->codegen->invalid_instruction; 22686 } 22687 22688 IrInstruction *return_type_value = instruction->return_type->child; 22689 fn_type_id.return_type = ir_resolve_type(ira, return_type_value); 22690 if (type_is_invalid(fn_type_id.return_type)) 22691 return ira->codegen->invalid_instruction; 22692 if (fn_type_id.return_type->id == ZigTypeIdOpaque) { 22693 ir_add_error(ira, instruction->return_type, 22694 buf_sprintf("return type cannot be opaque")); 22695 return ira->codegen->invalid_instruction; 22696 } 22697 22698 return ir_const_type(ira, &instruction->base, get_fn_type(ira->codegen, &fn_type_id)); 22699 } 22700 22701 static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { 22702 IrInstruction *value = instruction->value->child; 22703 if (type_is_invalid(value->value.type)) 22704 return ira->codegen->invalid_instruction; 22705 22706 return ir_const_bool(ira, &instruction->base, instr_is_comptime(value)); 22707 } 22708 22709 static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, 22710 IrInstructionCheckSwitchProngs *instruction) 22711 { 22712 IrInstruction *target_value = instruction->target_value->child; 22713 ZigType *switch_type = target_value->value.type; 22714 if (type_is_invalid(switch_type)) 22715 return ira->codegen->invalid_instruction; 22716 22717 if (switch_type->id == ZigTypeIdEnum) { 22718 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> field_prev_uses = {}; 22719 field_prev_uses.init(switch_type->data.enumeration.src_field_count); 22720 22721 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 22722 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 22723 22724 IrInstruction *start_value_uncasted = range->start->child; 22725 if (type_is_invalid(start_value_uncasted->value.type)) 22726 return ira->codegen->invalid_instruction; 22727 IrInstruction *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 22728 if (type_is_invalid(start_value->value.type)) 22729 return ira->codegen->invalid_instruction; 22730 22731 IrInstruction *end_value_uncasted = range->end->child; 22732 if (type_is_invalid(end_value_uncasted->value.type)) 22733 return ira->codegen->invalid_instruction; 22734 IrInstruction *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 22735 if (type_is_invalid(end_value->value.type)) 22736 return ira->codegen->invalid_instruction; 22737 22738 BigInt start_index; 22739 bigint_init_bigint(&start_index, &start_value->value.data.x_enum_tag); 22740 22741 assert(end_value->value.type->id == ZigTypeIdEnum); 22742 BigInt end_index; 22743 bigint_init_bigint(&end_index, &end_value->value.data.x_enum_tag); 22744 22745 BigInt field_index; 22746 bigint_init_bigint(&field_index, &start_index); 22747 for (;;) { 22748 Cmp cmp = bigint_cmp(&field_index, &end_index); 22749 if (cmp == CmpGT) { 22750 break; 22751 } 22752 auto entry = field_prev_uses.put_unique(field_index, start_value->source_node); 22753 if (entry) { 22754 AstNode *prev_node = entry->value; 22755 TypeEnumField *enum_field = find_enum_field_by_tag(switch_type, &field_index); 22756 assert(enum_field != nullptr); 22757 ErrorMsg *msg = ir_add_error(ira, start_value, 22758 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), 22759 buf_ptr(enum_field->name))); 22760 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 22761 } 22762 bigint_incr(&field_index); 22763 } 22764 } 22765 if (!instruction->have_else_prong) { 22766 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { 22767 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; 22768 22769 auto entry = field_prev_uses.maybe_get(enum_field->value); 22770 if (!entry) { 22771 ir_add_error(ira, &instruction->base, 22772 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), 22773 buf_ptr(enum_field->name))); 22774 } 22775 } 22776 } 22777 } else if (switch_type->id == ZigTypeIdErrorSet) { 22778 if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->source_node)) { 22779 return ira->codegen->invalid_instruction; 22780 } 22781 22782 AstNode **field_prev_uses = allocate<AstNode *>(ira->codegen->errors_by_index.length); 22783 22784 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 22785 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 22786 22787 IrInstruction *start_value_uncasted = range->start->child; 22788 if (type_is_invalid(start_value_uncasted->value.type)) 22789 return ira->codegen->invalid_instruction; 22790 IrInstruction *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 22791 if (type_is_invalid(start_value->value.type)) 22792 return ira->codegen->invalid_instruction; 22793 22794 IrInstruction *end_value_uncasted = range->end->child; 22795 if (type_is_invalid(end_value_uncasted->value.type)) 22796 return ira->codegen->invalid_instruction; 22797 IrInstruction *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 22798 if (type_is_invalid(end_value->value.type)) 22799 return ira->codegen->invalid_instruction; 22800 22801 ir_assert(start_value->value.type->id == ZigTypeIdErrorSet, &instruction->base); 22802 uint32_t start_index = start_value->value.data.x_err_set->value; 22803 22804 ir_assert(end_value->value.type->id == ZigTypeIdErrorSet, &instruction->base); 22805 uint32_t end_index = end_value->value.data.x_err_set->value; 22806 22807 if (start_index != end_index) { 22808 ir_add_error(ira, end_value, buf_sprintf("ranges not allowed when switching on errors")); 22809 return ira->codegen->invalid_instruction; 22810 } 22811 22812 AstNode *prev_node = field_prev_uses[start_index]; 22813 if (prev_node != nullptr) { 22814 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name; 22815 ErrorMsg *msg = ir_add_error(ira, start_value, 22816 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name))); 22817 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 22818 } 22819 field_prev_uses[start_index] = start_value->source_node; 22820 } 22821 if (!instruction->have_else_prong) { 22822 if (type_is_global_error_set(switch_type)) { 22823 ir_add_error(ira, &instruction->base, 22824 buf_sprintf("else prong required when switching on type 'anyerror'")); 22825 return ira->codegen->invalid_instruction; 22826 } else { 22827 for (uint32_t i = 0; i < switch_type->data.error_set.err_count; i += 1) { 22828 ErrorTableEntry *err_entry = switch_type->data.error_set.errors[i]; 22829 22830 AstNode *prev_node = field_prev_uses[err_entry->value]; 22831 if (prev_node == nullptr) { 22832 ir_add_error(ira, &instruction->base, 22833 buf_sprintf("error.%s not handled in switch", buf_ptr(&err_entry->name))); 22834 } 22835 } 22836 } 22837 } 22838 22839 free(field_prev_uses); 22840 } else if (switch_type->id == ZigTypeIdInt) { 22841 RangeSet rs = {0}; 22842 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 22843 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 22844 22845 IrInstruction *start_value = range->start->child; 22846 if (type_is_invalid(start_value->value.type)) 22847 return ira->codegen->invalid_instruction; 22848 IrInstruction *casted_start_value = ir_implicit_cast(ira, start_value, switch_type); 22849 if (type_is_invalid(casted_start_value->value.type)) 22850 return ira->codegen->invalid_instruction; 22851 22852 IrInstruction *end_value = range->end->child; 22853 if (type_is_invalid(end_value->value.type)) 22854 return ira->codegen->invalid_instruction; 22855 IrInstruction *casted_end_value = ir_implicit_cast(ira, end_value, switch_type); 22856 if (type_is_invalid(casted_end_value->value.type)) 22857 return ira->codegen->invalid_instruction; 22858 22859 ConstExprValue *start_val = ir_resolve_const(ira, casted_start_value, UndefBad); 22860 if (!start_val) 22861 return ira->codegen->invalid_instruction; 22862 22863 ConstExprValue *end_val = ir_resolve_const(ira, casted_end_value, UndefBad); 22864 if (!end_val) 22865 return ira->codegen->invalid_instruction; 22866 22867 assert(start_val->type->id == ZigTypeIdInt || start_val->type->id == ZigTypeIdComptimeInt); 22868 assert(end_val->type->id == ZigTypeIdInt || end_val->type->id == ZigTypeIdComptimeInt); 22869 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint, 22870 start_value->source_node); 22871 if (prev_node != nullptr) { 22872 ErrorMsg *msg = ir_add_error(ira, start_value, buf_sprintf("duplicate switch value")); 22873 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("previous value is here")); 22874 return ira->codegen->invalid_instruction; 22875 } 22876 } 22877 if (!instruction->have_else_prong) { 22878 BigInt min_val; 22879 eval_min_max_value_int(ira->codegen, switch_type, &min_val, false); 22880 BigInt max_val; 22881 eval_min_max_value_int(ira->codegen, switch_type, &max_val, true); 22882 if (!rangeset_spans(&rs, &min_val, &max_val)) { 22883 ir_add_error(ira, &instruction->base, buf_sprintf("switch must handle all possibilities")); 22884 return ira->codegen->invalid_instruction; 22885 } 22886 } 22887 } else if (switch_type->id == ZigTypeIdBool) { 22888 int seenTrue = 0; 22889 int seenFalse = 0; 22890 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 22891 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 22892 22893 IrInstruction *value = range->start->child; 22894 22895 IrInstruction *casted_value = ir_implicit_cast(ira, value, switch_type); 22896 if (type_is_invalid(casted_value->value.type)) 22897 return ira->codegen->invalid_instruction; 22898 22899 ConstExprValue *const_expr_val = ir_resolve_const(ira, casted_value, UndefBad); 22900 if (!const_expr_val) 22901 return ira->codegen->invalid_instruction; 22902 22903 assert(const_expr_val->type->id == ZigTypeIdBool); 22904 22905 if (const_expr_val->data.x_bool == true) { 22906 seenTrue += 1; 22907 } else { 22908 seenFalse += 1; 22909 } 22910 22911 if ((seenTrue > 1) || (seenFalse > 1)) { 22912 ir_add_error(ira, value, buf_sprintf("duplicate switch value")); 22913 return ira->codegen->invalid_instruction; 22914 } 22915 } 22916 if (((seenTrue < 1) || (seenFalse < 1)) && !instruction->have_else_prong) { 22917 ir_add_error(ira, &instruction->base, buf_sprintf("switch must handle all possibilities")); 22918 return ira->codegen->invalid_instruction; 22919 } 22920 } else if (!instruction->have_else_prong) { 22921 ir_add_error(ira, &instruction->base, 22922 buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); 22923 return ira->codegen->invalid_instruction; 22924 } 22925 return ir_const_void(ira, &instruction->base); 22926 } 22927 22928 static IrInstruction *ir_analyze_instruction_check_statement_is_void(IrAnalyze *ira, 22929 IrInstructionCheckStatementIsVoid *instruction) 22930 { 22931 IrInstruction *statement_value = instruction->statement_value->child; 22932 ZigType *statement_type = statement_value->value.type; 22933 if (type_is_invalid(statement_type)) 22934 return ira->codegen->invalid_instruction; 22935 22936 if (statement_type->id != ZigTypeIdVoid && statement_type->id != ZigTypeIdUnreachable) { 22937 ir_add_error(ira, &instruction->base, buf_sprintf("expression value is ignored")); 22938 } 22939 22940 return ir_const_void(ira, &instruction->base); 22941 } 22942 22943 static IrInstruction *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructionPanic *instruction) { 22944 IrInstruction *msg = instruction->msg->child; 22945 if (type_is_invalid(msg->value.type)) 22946 return ir_unreach_error(ira); 22947 22948 if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) { 22949 ir_add_error(ira, &instruction->base, buf_sprintf("encountered @panic at compile-time")); 22950 return ir_unreach_error(ira); 22951 } 22952 22953 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 22954 true, false, PtrLenUnknown, 0, 0, 0, false); 22955 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 22956 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type); 22957 if (type_is_invalid(casted_msg->value.type)) 22958 return ir_unreach_error(ira); 22959 22960 IrInstruction *new_instruction = ir_build_panic(&ira->new_irb, instruction->base.scope, 22961 instruction->base.source_node, casted_msg); 22962 return ir_finish_anal(ira, new_instruction); 22963 } 22964 22965 static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint32_t align_bytes, bool safety_check_on) { 22966 Error err; 22967 22968 ZigType *target_type = target->value.type; 22969 assert(!type_is_invalid(target_type)); 22970 22971 ZigType *result_type; 22972 uint32_t old_align_bytes; 22973 22974 if (target_type->id == ZigTypeIdPointer) { 22975 result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes); 22976 if ((err = resolve_ptr_align(ira, target_type, &old_align_bytes))) 22977 return ira->codegen->invalid_instruction; 22978 } else if (target_type->id == ZigTypeIdFn) { 22979 FnTypeId fn_type_id = target_type->data.fn.fn_type_id; 22980 old_align_bytes = fn_type_id.alignment; 22981 fn_type_id.alignment = align_bytes; 22982 result_type = get_fn_type(ira->codegen, &fn_type_id); 22983 } else if (target_type->id == ZigTypeIdOptional && 22984 target_type->data.maybe.child_type->id == ZigTypeIdPointer) 22985 { 22986 ZigType *ptr_type = target_type->data.maybe.child_type; 22987 if ((err = resolve_ptr_align(ira, ptr_type, &old_align_bytes))) 22988 return ira->codegen->invalid_instruction; 22989 ZigType *better_ptr_type = adjust_ptr_align(ira->codegen, ptr_type, align_bytes); 22990 22991 result_type = get_optional_type(ira->codegen, better_ptr_type); 22992 } else if (target_type->id == ZigTypeIdOptional && 22993 target_type->data.maybe.child_type->id == ZigTypeIdFn) 22994 { 22995 FnTypeId fn_type_id = target_type->data.maybe.child_type->data.fn.fn_type_id; 22996 old_align_bytes = fn_type_id.alignment; 22997 fn_type_id.alignment = align_bytes; 22998 ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id); 22999 result_type = get_optional_type(ira->codegen, fn_type); 23000 } else if (is_slice(target_type)) { 23001 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry; 23002 if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes))) 23003 return ira->codegen->invalid_instruction; 23004 ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes); 23005 result_type = get_slice_type(ira->codegen, result_ptr_type); 23006 } else { 23007 ir_add_error(ira, target, 23008 buf_sprintf("expected pointer or slice, found '%s'", buf_ptr(&target_type->name))); 23009 return ira->codegen->invalid_instruction; 23010 } 23011 23012 if (instr_is_comptime(target)) { 23013 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 23014 if (!val) 23015 return ira->codegen->invalid_instruction; 23016 23017 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 23018 val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0) 23019 { 23020 ir_add_error(ira, target, 23021 buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes", 23022 val->data.x_ptr.data.hard_coded_addr.addr, align_bytes)); 23023 return ira->codegen->invalid_instruction; 23024 } 23025 23026 IrInstruction *result = ir_const(ira, target, result_type); 23027 copy_const_val(&result->value, val, true); 23028 result->value.type = result_type; 23029 return result; 23030 } 23031 23032 IrInstruction *result; 23033 if (safety_check_on && align_bytes > old_align_bytes && align_bytes != 1) { 23034 result = ir_build_align_cast(&ira->new_irb, target->scope, target->source_node, nullptr, target); 23035 } else { 23036 result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, result_type, target, CastOpNoop); 23037 } 23038 result->value.type = result_type; 23039 return result; 23040 } 23041 23042 static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, 23043 ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on) 23044 { 23045 Error err; 23046 23047 ZigType *src_type = ptr->value.type; 23048 assert(!type_is_invalid(src_type)); 23049 23050 // We have a check for zero bits later so we use get_src_ptr_type to 23051 // validate src_type and dest_type. 23052 23053 ZigType *src_ptr_type = get_src_ptr_type(src_type); 23054 if (src_ptr_type == nullptr) { 23055 ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); 23056 return ira->codegen->invalid_instruction; 23057 } 23058 23059 ZigType *dest_ptr_type = get_src_ptr_type(dest_type); 23060 if (dest_ptr_type == nullptr) { 23061 ir_add_error(ira, dest_type_src, 23062 buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 23063 return ira->codegen->invalid_instruction; 23064 } 23065 23066 if (get_ptr_const(src_type) && !get_ptr_const(dest_type)) { 23067 ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); 23068 return ira->codegen->invalid_instruction; 23069 } 23070 uint32_t src_align_bytes; 23071 if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) 23072 return ira->codegen->invalid_instruction; 23073 23074 uint32_t dest_align_bytes; 23075 if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) 23076 return ira->codegen->invalid_instruction; 23077 23078 if (instr_is_comptime(ptr)) { 23079 bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); 23080 UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad; 23081 ConstExprValue *val = ir_resolve_const(ira, ptr, is_undef_allowed); 23082 if (!val) 23083 return ira->codegen->invalid_instruction; 23084 23085 if (val->special == ConstValSpecialStatic) { 23086 bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || 23087 (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 23088 val->data.x_ptr.data.hard_coded_addr.addr == 0); 23089 if (is_addr_zero && !dest_allows_addr_zero) { 23090 ir_add_error(ira, source_instr, 23091 buf_sprintf("null pointer casted to type '%s'", buf_ptr(&dest_type->name))); 23092 return ira->codegen->invalid_instruction; 23093 } 23094 } 23095 23096 IrInstruction *result; 23097 if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) { 23098 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); 23099 } else { 23100 result = ir_const(ira, source_instr, dest_type); 23101 } 23102 copy_const_val(&result->value, val, true); 23103 result->value.type = dest_type; 23104 23105 // Keep the bigger alignment, it can only help- 23106 // unless the target is zero bits. 23107 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { 23108 result = ir_align_cast(ira, result, src_align_bytes, false); 23109 } 23110 23111 return result; 23112 } 23113 23114 if (dest_align_bytes > src_align_bytes) { 23115 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 23116 add_error_note(ira->codegen, msg, ptr->source_node, 23117 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); 23118 add_error_note(ira->codegen, msg, dest_type_src->source_node, 23119 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_type->name), dest_align_bytes)); 23120 return ira->codegen->invalid_instruction; 23121 } 23122 23123 IrInstruction *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); 23124 23125 if (type_has_bits(dest_type) && !type_has_bits(src_type)) { 23126 ErrorMsg *msg = ir_add_error(ira, source_instr, 23127 buf_sprintf("'%s' and '%s' do not have the same in-memory representation", 23128 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 23129 add_error_note(ira->codegen, msg, ptr->source_node, 23130 buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name))); 23131 add_error_note(ira->codegen, msg, dest_type_src->source_node, 23132 buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name))); 23133 return ira->codegen->invalid_instruction; 23134 } 23135 23136 // Keep the bigger alignment, it can only help- 23137 // unless the target is zero bits. 23138 IrInstruction *result; 23139 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { 23140 result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); 23141 if (type_is_invalid(result->value.type)) 23142 return ira->codegen->invalid_instruction; 23143 } else { 23144 result = casted_ptr; 23145 } 23146 return result; 23147 } 23148 23149 static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtrCastSrc *instruction) { 23150 IrInstruction *dest_type_value = instruction->dest_type->child; 23151 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 23152 if (type_is_invalid(dest_type)) 23153 return ira->codegen->invalid_instruction; 23154 23155 IrInstruction *ptr = instruction->ptr->child; 23156 ZigType *src_type = ptr->value.type; 23157 if (type_is_invalid(src_type)) 23158 return ira->codegen->invalid_instruction; 23159 23160 return ir_analyze_ptr_cast(ira, &instruction->base, ptr, dest_type, dest_type_value, 23161 instruction->safety_check_on); 23162 } 23163 23164 static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ConstExprValue *val, size_t len) { 23165 size_t buf_i = 0; 23166 // TODO optimize the buf case 23167 expand_undef_array(codegen, val); 23168 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) { 23169 ConstExprValue *elem = &val->data.x_array.data.s_none.elements[elem_i]; 23170 buf_write_value_bytes(codegen, &buf[buf_i], elem); 23171 buf_i += type_size(codegen, elem->type); 23172 } 23173 } 23174 23175 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) { 23176 if (val->special == ConstValSpecialUndef) 23177 val->special = ConstValSpecialStatic; 23178 assert(val->special == ConstValSpecialStatic); 23179 switch (val->type->id) { 23180 case ZigTypeIdInvalid: 23181 case ZigTypeIdMetaType: 23182 case ZigTypeIdOpaque: 23183 case ZigTypeIdBoundFn: 23184 case ZigTypeIdArgTuple: 23185 case ZigTypeIdUnreachable: 23186 case ZigTypeIdComptimeFloat: 23187 case ZigTypeIdComptimeInt: 23188 case ZigTypeIdEnumLiteral: 23189 case ZigTypeIdUndefined: 23190 case ZigTypeIdNull: 23191 case ZigTypeIdErrorUnion: 23192 case ZigTypeIdErrorSet: 23193 zig_unreachable(); 23194 case ZigTypeIdVoid: 23195 return; 23196 case ZigTypeIdBool: 23197 buf[0] = val->data.x_bool ? 1 : 0; 23198 return; 23199 case ZigTypeIdInt: 23200 bigint_write_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 23201 codegen->is_big_endian); 23202 return; 23203 case ZigTypeIdEnum: 23204 bigint_write_twos_complement(&val->data.x_enum_tag, buf, 23205 val->type->data.enumeration.tag_int_type->data.integral.bit_count, 23206 codegen->is_big_endian); 23207 return; 23208 case ZigTypeIdFloat: 23209 float_write_ieee597(val, buf, codegen->is_big_endian); 23210 return; 23211 case ZigTypeIdPointer: 23212 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 23213 BigInt bn; 23214 bigint_init_unsigned(&bn, val->data.x_ptr.data.hard_coded_addr.addr); 23215 bigint_write_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, codegen->is_big_endian); 23216 return; 23217 } else { 23218 zig_unreachable(); 23219 } 23220 case ZigTypeIdArray: 23221 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.array.len); 23222 case ZigTypeIdVector: 23223 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.vector.len); 23224 case ZigTypeIdStruct: 23225 switch (val->type->data.structure.layout) { 23226 case ContainerLayoutAuto: 23227 zig_unreachable(); 23228 case ContainerLayoutExtern: { 23229 size_t src_field_count = val->type->data.structure.src_field_count; 23230 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 23231 TypeStructField *struct_field = &val->type->data.structure.fields[field_i]; 23232 if (struct_field->gen_index == SIZE_MAX) 23233 continue; 23234 ConstExprValue *field_val = &val->data.x_struct.fields[field_i]; 23235 size_t offset = struct_field->offset; 23236 buf_write_value_bytes(codegen, buf + offset, field_val); 23237 } 23238 return; 23239 } 23240 case ContainerLayoutPacked: { 23241 size_t src_field_count = val->type->data.structure.src_field_count; 23242 size_t gen_field_count = val->type->data.structure.gen_field_count; 23243 size_t gen_i = 0; 23244 size_t src_i = 0; 23245 size_t offset = 0; 23246 bool is_big_endian = codegen->is_big_endian; 23247 uint8_t child_buf_prealloc[16]; 23248 size_t child_buf_len = 16; 23249 uint8_t *child_buf = child_buf_prealloc; 23250 while (gen_i < gen_field_count) { 23251 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 23252 if (big_int_byte_count > child_buf_len) { 23253 child_buf = allocate_nonzero<uint8_t>(big_int_byte_count); 23254 child_buf_len = big_int_byte_count; 23255 } 23256 BigInt big_int; 23257 bigint_init_unsigned(&big_int, 0); 23258 size_t used_bits = 0; 23259 while (src_i < src_field_count) { 23260 TypeStructField *field = &val->type->data.structure.fields[src_i]; 23261 assert(field->gen_index != SIZE_MAX); 23262 if (field->gen_index != gen_i) 23263 break; 23264 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 23265 buf_write_value_bytes(codegen, child_buf, &val->data.x_struct.fields[src_i]); 23266 BigInt child_val; 23267 bigint_read_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian, 23268 false); 23269 if (is_big_endian) { 23270 BigInt shift_amt; 23271 bigint_init_unsigned(&shift_amt, packed_bits_size); 23272 BigInt shifted; 23273 bigint_shl(&shifted, &big_int, &shift_amt); 23274 bigint_or(&big_int, &shifted, &child_val); 23275 } else { 23276 BigInt shift_amt; 23277 bigint_init_unsigned(&shift_amt, used_bits); 23278 BigInt child_val_shifted; 23279 bigint_shl(&child_val_shifted, &child_val, &shift_amt); 23280 BigInt tmp; 23281 bigint_or(&tmp, &big_int, &child_val_shifted); 23282 big_int = tmp; 23283 used_bits += packed_bits_size; 23284 } 23285 src_i += 1; 23286 } 23287 bigint_write_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian); 23288 offset += big_int_byte_count; 23289 gen_i += 1; 23290 } 23291 return; 23292 } 23293 } 23294 case ZigTypeIdOptional: 23295 zig_panic("TODO buf_write_value_bytes maybe type"); 23296 case ZigTypeIdFn: 23297 zig_panic("TODO buf_write_value_bytes fn type"); 23298 case ZigTypeIdUnion: 23299 zig_panic("TODO buf_write_value_bytes union type"); 23300 case ZigTypeIdFnFrame: 23301 zig_panic("TODO buf_write_value_bytes async fn frame type"); 23302 case ZigTypeIdAnyFrame: 23303 zig_panic("TODO buf_write_value_bytes anyframe type"); 23304 } 23305 zig_unreachable(); 23306 } 23307 23308 static Error buf_read_value_bytes_array(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, 23309 ConstExprValue *val, ZigType *elem_type, size_t len) 23310 { 23311 Error err; 23312 uint64_t elem_size = type_size(codegen, elem_type); 23313 23314 switch (val->data.x_array.special) { 23315 case ConstArraySpecialNone: 23316 val->data.x_array.data.s_none.elements = create_const_vals(len); 23317 for (size_t i = 0; i < len; i++) { 23318 ConstExprValue *elem = &val->data.x_array.data.s_none.elements[i]; 23319 elem->special = ConstValSpecialStatic; 23320 elem->type = elem_type; 23321 if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem))) 23322 return err; 23323 } 23324 return ErrorNone; 23325 case ConstArraySpecialUndef: 23326 zig_panic("TODO buf_read_value_bytes ConstArraySpecialUndef array type"); 23327 case ConstArraySpecialBuf: 23328 zig_panic("TODO buf_read_value_bytes ConstArraySpecialBuf array type"); 23329 } 23330 zig_unreachable(); 23331 } 23332 23333 static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val) { 23334 Error err; 23335 src_assert(val->special == ConstValSpecialStatic, source_node); 23336 switch (val->type->id) { 23337 case ZigTypeIdInvalid: 23338 case ZigTypeIdMetaType: 23339 case ZigTypeIdOpaque: 23340 case ZigTypeIdBoundFn: 23341 case ZigTypeIdArgTuple: 23342 case ZigTypeIdUnreachable: 23343 case ZigTypeIdComptimeFloat: 23344 case ZigTypeIdComptimeInt: 23345 case ZigTypeIdEnumLiteral: 23346 case ZigTypeIdUndefined: 23347 case ZigTypeIdNull: 23348 zig_unreachable(); 23349 case ZigTypeIdVoid: 23350 return ErrorNone; 23351 case ZigTypeIdBool: 23352 val->data.x_bool = (buf[0] != 0); 23353 return ErrorNone; 23354 case ZigTypeIdInt: 23355 bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 23356 codegen->is_big_endian, val->type->data.integral.is_signed); 23357 return ErrorNone; 23358 case ZigTypeIdFloat: 23359 float_read_ieee597(val, buf, codegen->is_big_endian); 23360 return ErrorNone; 23361 case ZigTypeIdPointer: 23362 { 23363 val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 23364 BigInt bn; 23365 bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, 23366 codegen->is_big_endian, false); 23367 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn); 23368 return ErrorNone; 23369 } 23370 case ZigTypeIdArray: 23371 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.array.child_type, 23372 val->type->data.array.len); 23373 case ZigTypeIdVector: 23374 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.vector.elem_type, 23375 val->type->data.vector.len); 23376 case ZigTypeIdEnum: 23377 switch (val->type->data.enumeration.layout) { 23378 case ContainerLayoutAuto: 23379 zig_panic("TODO buf_read_value_bytes enum auto"); 23380 case ContainerLayoutPacked: 23381 zig_panic("TODO buf_read_value_bytes enum packed"); 23382 case ContainerLayoutExtern: { 23383 ZigType *tag_int_type = val->type->data.enumeration.tag_int_type; 23384 src_assert(tag_int_type->id == ZigTypeIdInt, source_node); 23385 bigint_read_twos_complement(&val->data.x_enum_tag, buf, tag_int_type->data.integral.bit_count, 23386 codegen->is_big_endian, tag_int_type->data.integral.is_signed); 23387 return ErrorNone; 23388 } 23389 } 23390 zig_unreachable(); 23391 case ZigTypeIdStruct: 23392 switch (val->type->data.structure.layout) { 23393 case ContainerLayoutAuto: { 23394 ErrorMsg *msg = opt_ir_add_error_node(ira, codegen, source_node, 23395 buf_sprintf("non-extern, non-packed struct '%s' cannot have its bytes reinterpreted", 23396 buf_ptr(&val->type->name))); 23397 add_error_note(codegen, msg, val->type->data.structure.decl_node, 23398 buf_sprintf("declared here")); 23399 return ErrorSemanticAnalyzeFail; 23400 } 23401 case ContainerLayoutExtern: { 23402 size_t src_field_count = val->type->data.structure.src_field_count; 23403 val->data.x_struct.fields = create_const_vals(src_field_count); 23404 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 23405 ConstExprValue *field_val = &val->data.x_struct.fields[field_i]; 23406 field_val->special = ConstValSpecialStatic; 23407 TypeStructField *struct_field = &val->type->data.structure.fields[field_i]; 23408 field_val->type = struct_field->type_entry; 23409 if (struct_field->gen_index == SIZE_MAX) 23410 continue; 23411 size_t offset = struct_field->offset; 23412 uint8_t *new_buf = buf + offset; 23413 if ((err = buf_read_value_bytes(ira, codegen, source_node, new_buf, field_val))) 23414 return err; 23415 } 23416 return ErrorNone; 23417 } 23418 case ContainerLayoutPacked: { 23419 size_t src_field_count = val->type->data.structure.src_field_count; 23420 val->data.x_struct.fields = create_const_vals(src_field_count); 23421 size_t gen_field_count = val->type->data.structure.gen_field_count; 23422 size_t gen_i = 0; 23423 size_t src_i = 0; 23424 size_t offset = 0; 23425 bool is_big_endian = codegen->is_big_endian; 23426 uint8_t child_buf_prealloc[16]; 23427 size_t child_buf_len = 16; 23428 uint8_t *child_buf = child_buf_prealloc; 23429 while (gen_i < gen_field_count) { 23430 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 23431 if (big_int_byte_count > child_buf_len) { 23432 child_buf = allocate_nonzero<uint8_t>(big_int_byte_count); 23433 child_buf_len = big_int_byte_count; 23434 } 23435 BigInt big_int; 23436 bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false); 23437 while (src_i < src_field_count) { 23438 TypeStructField *field = &val->type->data.structure.fields[src_i]; 23439 src_assert(field->gen_index != SIZE_MAX, source_node); 23440 if (field->gen_index != gen_i) 23441 break; 23442 ConstExprValue *field_val = &val->data.x_struct.fields[src_i]; 23443 field_val->special = ConstValSpecialStatic; 23444 field_val->type = field->type_entry; 23445 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 23446 23447 BigInt child_val; 23448 if (is_big_endian) { 23449 zig_panic("TODO buf_read_value_bytes packed struct big endian"); 23450 } else { 23451 BigInt packed_bits_size_bi; 23452 bigint_init_unsigned(&packed_bits_size_bi, packed_bits_size); 23453 bigint_truncate(&child_val, &big_int, packed_bits_size, false); 23454 BigInt tmp; 23455 bigint_shr(&tmp, &big_int, &packed_bits_size_bi); 23456 big_int = tmp; 23457 } 23458 23459 bigint_write_twos_complement(&child_val, child_buf, big_int_byte_count * 8, is_big_endian); 23460 if ((err = buf_read_value_bytes(ira, codegen, source_node, child_buf, field_val))) { 23461 return err; 23462 } 23463 23464 src_i += 1; 23465 } 23466 offset += big_int_byte_count; 23467 gen_i += 1; 23468 } 23469 return ErrorNone; 23470 } 23471 } 23472 zig_unreachable(); 23473 case ZigTypeIdOptional: 23474 zig_panic("TODO buf_read_value_bytes maybe type"); 23475 case ZigTypeIdErrorUnion: 23476 zig_panic("TODO buf_read_value_bytes error union"); 23477 case ZigTypeIdErrorSet: 23478 zig_panic("TODO buf_read_value_bytes pure error type"); 23479 case ZigTypeIdFn: 23480 zig_panic("TODO buf_read_value_bytes fn type"); 23481 case ZigTypeIdUnion: 23482 zig_panic("TODO buf_read_value_bytes union type"); 23483 case ZigTypeIdFnFrame: 23484 zig_panic("TODO buf_read_value_bytes async fn frame type"); 23485 case ZigTypeIdAnyFrame: 23486 zig_panic("TODO buf_read_value_bytes anyframe type"); 23487 } 23488 zig_unreachable(); 23489 } 23490 23491 static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 23492 ZigType *dest_type) 23493 { 23494 Error err; 23495 23496 ZigType *src_type = value->value.type; 23497 ir_assert(get_codegen_ptr_type(src_type) == nullptr, source_instr); 23498 ir_assert(type_can_bit_cast(src_type), source_instr); 23499 ir_assert(get_codegen_ptr_type(dest_type) == nullptr, source_instr); 23500 ir_assert(type_can_bit_cast(dest_type), source_instr); 23501 23502 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown))) 23503 return ira->codegen->invalid_instruction; 23504 23505 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown))) 23506 return ira->codegen->invalid_instruction; 23507 23508 23509 uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); 23510 uint64_t src_size_bytes = type_size(ira->codegen, src_type); 23511 if (dest_size_bytes != src_size_bytes) { 23512 ir_add_error(ira, source_instr, 23513 buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64, 23514 buf_ptr(&dest_type->name), dest_size_bytes, 23515 buf_ptr(&src_type->name), src_size_bytes)); 23516 return ira->codegen->invalid_instruction; 23517 } 23518 23519 uint64_t dest_size_bits = type_size_bits(ira->codegen, dest_type); 23520 uint64_t src_size_bits = type_size_bits(ira->codegen, src_type); 23521 if (dest_size_bits != src_size_bits) { 23522 ir_add_error(ira, source_instr, 23523 buf_sprintf("destination type '%s' has %" ZIG_PRI_u64 " bits but source type '%s' has %" ZIG_PRI_u64 " bits", 23524 buf_ptr(&dest_type->name), dest_size_bits, 23525 buf_ptr(&src_type->name), src_size_bits)); 23526 return ira->codegen->invalid_instruction; 23527 } 23528 23529 if (instr_is_comptime(value)) { 23530 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 23531 if (!val) 23532 return ira->codegen->invalid_instruction; 23533 23534 IrInstruction *result = ir_const(ira, source_instr, dest_type); 23535 uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes); 23536 buf_write_value_bytes(ira->codegen, buf, val); 23537 if ((err = buf_read_value_bytes(ira, ira->codegen, source_instr->source_node, buf, &result->value))) 23538 return ira->codegen->invalid_instruction; 23539 return result; 23540 } 23541 23542 return ir_build_bit_cast_gen(ira, source_instr, value, dest_type); 23543 } 23544 23545 static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 23546 ZigType *ptr_type) 23547 { 23548 ir_assert(get_src_ptr_type(ptr_type) != nullptr, source_instr); 23549 ir_assert(type_has_bits(ptr_type), source_instr); 23550 23551 IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); 23552 if (type_is_invalid(casted_int->value.type)) 23553 return ira->codegen->invalid_instruction; 23554 23555 if (instr_is_comptime(casted_int)) { 23556 ConstExprValue *val = ir_resolve_const(ira, casted_int, UndefBad); 23557 if (!val) 23558 return ira->codegen->invalid_instruction; 23559 23560 uint64_t addr = bigint_as_unsigned(&val->data.x_bigint); 23561 if (!ptr_allows_addr_zero(ptr_type) && addr == 0) { 23562 ir_add_error(ira, source_instr, 23563 buf_sprintf("pointer type '%s' does not allow address zero", buf_ptr(&ptr_type->name))); 23564 return ira->codegen->invalid_instruction; 23565 } 23566 23567 IrInstruction *result = ir_const(ira, source_instr, ptr_type); 23568 result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 23569 result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar; 23570 result->value.data.x_ptr.data.hard_coded_addr.addr = addr; 23571 return result; 23572 } 23573 23574 IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, source_instr->scope, 23575 source_instr->source_node, nullptr, casted_int); 23576 result->value.type = ptr_type; 23577 return result; 23578 } 23579 23580 static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) { 23581 Error err; 23582 IrInstruction *dest_type_value = instruction->dest_type->child; 23583 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 23584 if (type_is_invalid(dest_type)) 23585 return ira->codegen->invalid_instruction; 23586 23587 // We explicitly check for the size, so we can use get_src_ptr_type 23588 if (get_src_ptr_type(dest_type) == nullptr) { 23589 ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 23590 return ira->codegen->invalid_instruction; 23591 } 23592 23593 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 23594 return ira->codegen->invalid_instruction; 23595 if (!type_has_bits(dest_type)) { 23596 ir_add_error(ira, dest_type_value, 23597 buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name))); 23598 return ira->codegen->invalid_instruction; 23599 } 23600 23601 23602 IrInstruction *target = instruction->target->child; 23603 if (type_is_invalid(target->value.type)) 23604 return ira->codegen->invalid_instruction; 23605 23606 return ir_analyze_int_to_ptr(ira, &instruction->base, target, dest_type); 23607 } 23608 23609 static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, 23610 IrInstructionDeclRef *instruction) 23611 { 23612 IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld); 23613 if (type_is_invalid(ref_instruction->value.type)) 23614 return ira->codegen->invalid_instruction; 23615 23616 if (instruction->lval == LValPtr) { 23617 return ref_instruction; 23618 } else { 23619 return ir_get_deref(ira, &instruction->base, ref_instruction, nullptr); 23620 } 23621 } 23622 23623 static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { 23624 IrInstruction *target = instruction->target->child; 23625 if (type_is_invalid(target->value.type)) 23626 return ira->codegen->invalid_instruction; 23627 23628 ZigType *usize = ira->codegen->builtin_types.entry_usize; 23629 23630 // We check size explicitly so we can use get_src_ptr_type here. 23631 if (get_src_ptr_type(target->value.type) == nullptr) { 23632 ir_add_error(ira, target, 23633 buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value.type->name))); 23634 return ira->codegen->invalid_instruction; 23635 } 23636 23637 if (!type_has_bits(target->value.type)) { 23638 ir_add_error(ira, target, 23639 buf_sprintf("pointer to size 0 type has no address")); 23640 return ira->codegen->invalid_instruction; 23641 } 23642 23643 if (instr_is_comptime(target)) { 23644 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 23645 if (!val) 23646 return ira->codegen->invalid_instruction; 23647 if (val->type->id == ZigTypeIdPointer && val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 23648 IrInstruction *result = ir_const(ira, &instruction->base, usize); 23649 bigint_init_unsigned(&result->value.data.x_bigint, val->data.x_ptr.data.hard_coded_addr.addr); 23650 result->value.type = usize; 23651 return result; 23652 } 23653 } 23654 23655 IrInstruction *result = ir_build_ptr_to_int(&ira->new_irb, instruction->base.scope, 23656 instruction->base.source_node, target); 23657 result->value.type = usize; 23658 return result; 23659 } 23660 23661 static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) { 23662 Error err; 23663 ZigType *child_type = ir_resolve_type(ira, instruction->child_type->child); 23664 if (type_is_invalid(child_type)) 23665 return ira->codegen->invalid_instruction; 23666 23667 if (child_type->id == ZigTypeIdUnreachable) { 23668 ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed")); 23669 return ira->codegen->invalid_instruction; 23670 } else if (child_type->id == ZigTypeIdOpaque && instruction->ptr_len == PtrLenUnknown) { 23671 ir_add_error(ira, &instruction->base, buf_sprintf("unknown-length pointer to opaque")); 23672 return ira->codegen->invalid_instruction; 23673 } else if (instruction->ptr_len == PtrLenC) { 23674 if (!type_allowed_in_extern(ira->codegen, child_type)) { 23675 ir_add_error(ira, &instruction->base, 23676 buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", buf_ptr(&child_type->name))); 23677 return ira->codegen->invalid_instruction; 23678 } else if (child_type->id == ZigTypeIdOpaque) { 23679 ir_add_error(ira, &instruction->base, buf_sprintf("C pointers cannot point opaque types")); 23680 return ira->codegen->invalid_instruction; 23681 } else if (instruction->is_allow_zero) { 23682 ir_add_error(ira, &instruction->base, buf_sprintf("C pointers always allow address zero")); 23683 return ira->codegen->invalid_instruction; 23684 } 23685 } 23686 23687 uint32_t align_bytes; 23688 if (instruction->align_value != nullptr) { 23689 if (!ir_resolve_align(ira, instruction->align_value->child, &align_bytes)) 23690 return ira->codegen->invalid_instruction; 23691 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown))) 23692 return ira->codegen->invalid_instruction; 23693 if (!type_has_bits(child_type)) { 23694 align_bytes = 0; 23695 } 23696 } else { 23697 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) 23698 return ira->codegen->invalid_instruction; 23699 align_bytes = 0; 23700 } 23701 23702 bool allow_zero = instruction->is_allow_zero || instruction->ptr_len == PtrLenC; 23703 23704 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, 23705 instruction->is_const, instruction->is_volatile, 23706 instruction->ptr_len, align_bytes, 23707 instruction->bit_offset_start, instruction->host_int_bytes, allow_zero); 23708 return ir_const_type(ira, &instruction->base, result_type); 23709 } 23710 23711 static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstructionAlignCast *instruction) { 23712 uint32_t align_bytes; 23713 IrInstruction *align_bytes_inst = instruction->align_bytes->child; 23714 if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes)) 23715 return ira->codegen->invalid_instruction; 23716 23717 IrInstruction *target = instruction->target->child; 23718 if (type_is_invalid(target->value.type)) 23719 return ira->codegen->invalid_instruction; 23720 23721 IrInstruction *result = ir_align_cast(ira, target, align_bytes, true); 23722 if (type_is_invalid(result->value.type)) 23723 return ira->codegen->invalid_instruction; 23724 23725 return result; 23726 } 23727 23728 static IrInstruction *ir_analyze_instruction_opaque_type(IrAnalyze *ira, IrInstructionOpaqueType *instruction) { 23729 Buf *bare_name = buf_alloc(); 23730 Buf *full_name = get_anon_type_name(ira->codegen, ira->new_irb.exec, "opaque", 23731 instruction->base.scope, instruction->base.source_node, bare_name); 23732 ZigType *result_type = get_opaque_type(ira->codegen, instruction->base.scope, instruction->base.source_node, 23733 buf_ptr(full_name), bare_name); 23734 return ir_const_type(ira, &instruction->base, result_type); 23735 } 23736 23737 static IrInstruction *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstructionSetAlignStack *instruction) { 23738 uint32_t align_bytes; 23739 IrInstruction *align_bytes_inst = instruction->align_bytes->child; 23740 if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes)) 23741 return ira->codegen->invalid_instruction; 23742 23743 if (align_bytes > 256) { 23744 ir_add_error(ira, &instruction->base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes)); 23745 return ira->codegen->invalid_instruction; 23746 } 23747 23748 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 23749 if (fn_entry == nullptr) { 23750 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack outside function")); 23751 return ira->codegen->invalid_instruction; 23752 } 23753 if (fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionNaked) { 23754 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in naked function")); 23755 return ira->codegen->invalid_instruction; 23756 } 23757 23758 if (fn_entry->fn_inline == FnInlineAlways) { 23759 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in inline function")); 23760 return ira->codegen->invalid_instruction; 23761 } 23762 23763 if (fn_entry->set_alignstack_node != nullptr) { 23764 ErrorMsg *msg = ir_add_error_node(ira, instruction->base.source_node, 23765 buf_sprintf("alignstack set twice")); 23766 add_error_note(ira->codegen, msg, fn_entry->set_alignstack_node, buf_sprintf("first set here")); 23767 return ira->codegen->invalid_instruction; 23768 } 23769 23770 fn_entry->set_alignstack_node = instruction->base.source_node; 23771 fn_entry->alignstack_value = align_bytes; 23772 23773 return ir_const_void(ira, &instruction->base); 23774 } 23775 23776 static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstructionArgType *instruction) { 23777 IrInstruction *fn_type_inst = instruction->fn_type->child; 23778 ZigType *fn_type = ir_resolve_type(ira, fn_type_inst); 23779 if (type_is_invalid(fn_type)) 23780 return ira->codegen->invalid_instruction; 23781 23782 IrInstruction *arg_index_inst = instruction->arg_index->child; 23783 uint64_t arg_index; 23784 if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) 23785 return ira->codegen->invalid_instruction; 23786 23787 if (fn_type->id != ZigTypeIdFn) { 23788 ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); 23789 return ira->codegen->invalid_instruction; 23790 } 23791 23792 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 23793 if (arg_index >= fn_type_id->param_count) { 23794 ir_add_error(ira, arg_index_inst, 23795 buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", 23796 arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); 23797 return ira->codegen->invalid_instruction; 23798 } 23799 23800 ZigType *result_type = fn_type_id->param_info[arg_index].type; 23801 if (result_type == nullptr) { 23802 // Args are only unresolved if our function is generic. 23803 ir_assert(fn_type->data.fn.is_generic, &instruction->base); 23804 23805 ir_add_error(ira, arg_index_inst, 23806 buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", 23807 arg_index, buf_ptr(&fn_type->name))); 23808 return ira->codegen->invalid_instruction; 23809 } 23810 return ir_const_type(ira, &instruction->base, result_type); 23811 } 23812 23813 static IrInstruction *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstructionTagType *instruction) { 23814 Error err; 23815 IrInstruction *target_inst = instruction->target->child; 23816 ZigType *enum_type = ir_resolve_type(ira, target_inst); 23817 if (type_is_invalid(enum_type)) 23818 return ira->codegen->invalid_instruction; 23819 23820 if (enum_type->id == ZigTypeIdEnum) { 23821 if ((err = ensure_complete_type(ira->codegen, enum_type))) 23822 return ira->codegen->invalid_instruction; 23823 23824 return ir_const_type(ira, &instruction->base, enum_type->data.enumeration.tag_int_type); 23825 } else if (enum_type->id == ZigTypeIdUnion) { 23826 ZigType *tag_type = ir_resolve_union_tag_type(ira, instruction->target, enum_type); 23827 if (type_is_invalid(tag_type)) 23828 return ira->codegen->invalid_instruction; 23829 return ir_const_type(ira, &instruction->base, tag_type); 23830 } else { 23831 ir_add_error(ira, target_inst, buf_sprintf("expected enum or union, found '%s'", 23832 buf_ptr(&enum_type->name))); 23833 return ira->codegen->invalid_instruction; 23834 } 23835 } 23836 23837 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op) { 23838 ZigType *operand_type = ir_resolve_type(ira, op); 23839 if (type_is_invalid(operand_type)) 23840 return ira->codegen->builtin_types.entry_invalid; 23841 23842 if (operand_type->id == ZigTypeIdInt) { 23843 if (operand_type->data.integral.bit_count < 8) { 23844 ir_add_error(ira, op, 23845 buf_sprintf("expected integer type 8 bits or larger, found %" PRIu32 "-bit integer type", 23846 operand_type->data.integral.bit_count)); 23847 return ira->codegen->builtin_types.entry_invalid; 23848 } 23849 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); 23850 if (operand_type->data.integral.bit_count > max_atomic_bits) { 23851 ir_add_error(ira, op, 23852 buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type", 23853 max_atomic_bits, operand_type->data.integral.bit_count)); 23854 return ira->codegen->builtin_types.entry_invalid; 23855 } 23856 if (!is_power_of_2(operand_type->data.integral.bit_count)) { 23857 ir_add_error(ira, op, 23858 buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count)); 23859 return ira->codegen->builtin_types.entry_invalid; 23860 } 23861 } else if (get_codegen_ptr_type(operand_type) == nullptr) { 23862 ir_add_error(ira, op, 23863 buf_sprintf("expected integer or pointer type, found '%s'", buf_ptr(&operand_type->name))); 23864 return ira->codegen->builtin_types.entry_invalid; 23865 } 23866 23867 return operand_type; 23868 } 23869 23870 static IrInstruction *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstructionAtomicRmw *instruction) { 23871 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 23872 if (type_is_invalid(operand_type)) 23873 return ira->codegen->invalid_instruction; 23874 23875 IrInstruction *ptr_inst = instruction->ptr->child; 23876 if (type_is_invalid(ptr_inst->value.type)) 23877 return ira->codegen->invalid_instruction; 23878 23879 // TODO let this be volatile 23880 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 23881 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 23882 if (type_is_invalid(casted_ptr->value.type)) 23883 return ira->codegen->invalid_instruction; 23884 23885 AtomicRmwOp op; 23886 if (instruction->op == nullptr) { 23887 op = instruction->resolved_op; 23888 } else { 23889 if (!ir_resolve_atomic_rmw_op(ira, instruction->op->child, &op)) { 23890 return ira->codegen->invalid_instruction; 23891 } 23892 } 23893 23894 IrInstruction *operand = instruction->operand->child; 23895 if (type_is_invalid(operand->value.type)) 23896 return ira->codegen->invalid_instruction; 23897 23898 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, operand_type); 23899 if (type_is_invalid(casted_operand->value.type)) 23900 return ira->codegen->invalid_instruction; 23901 23902 AtomicOrder ordering; 23903 if (instruction->ordering == nullptr) { 23904 ordering = instruction->resolved_ordering; 23905 } else { 23906 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 23907 return ira->codegen->invalid_instruction; 23908 if (ordering == AtomicOrderUnordered) { 23909 ir_add_error(ira, instruction->ordering, 23910 buf_sprintf("@atomicRmw atomic ordering must not be Unordered")); 23911 return ira->codegen->invalid_instruction; 23912 } 23913 } 23914 23915 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) 23916 { 23917 zig_panic("TODO compile-time execution of atomicRmw"); 23918 } 23919 23920 IrInstruction *result = ir_build_atomic_rmw(&ira->new_irb, instruction->base.scope, 23921 instruction->base.source_node, nullptr, casted_ptr, nullptr, casted_operand, nullptr, 23922 op, ordering); 23923 result->value.type = operand_type; 23924 return result; 23925 } 23926 23927 static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstructionAtomicLoad *instruction) { 23928 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 23929 if (type_is_invalid(operand_type)) 23930 return ira->codegen->invalid_instruction; 23931 23932 IrInstruction *ptr_inst = instruction->ptr->child; 23933 if (type_is_invalid(ptr_inst->value.type)) 23934 return ira->codegen->invalid_instruction; 23935 23936 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true); 23937 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 23938 if (type_is_invalid(casted_ptr->value.type)) 23939 return ira->codegen->invalid_instruction; 23940 23941 AtomicOrder ordering; 23942 if (instruction->ordering == nullptr) { 23943 ordering = instruction->resolved_ordering; 23944 } else { 23945 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 23946 return ira->codegen->invalid_instruction; 23947 } 23948 23949 if (ordering == AtomicOrderRelease || ordering == AtomicOrderAcqRel) { 23950 ir_assert(instruction->ordering != nullptr, &instruction->base); 23951 ir_add_error(ira, instruction->ordering, 23952 buf_sprintf("@atomicLoad atomic ordering must not be Release or AcqRel")); 23953 return ira->codegen->invalid_instruction; 23954 } 23955 23956 if (instr_is_comptime(casted_ptr)) { 23957 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr); 23958 ir_assert(result->value.type != nullptr, &instruction->base); 23959 return result; 23960 } 23961 23962 IrInstruction *result = ir_build_atomic_load(&ira->new_irb, instruction->base.scope, 23963 instruction->base.source_node, nullptr, casted_ptr, nullptr, ordering); 23964 result->value.type = operand_type; 23965 return result; 23966 } 23967 23968 static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) { 23969 IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope, 23970 instruction->base.source_node); 23971 result->value.type = ira->codegen->builtin_types.entry_void; 23972 return result; 23973 } 23974 23975 static void ir_eval_float_op(IrAnalyze *ira, IrInstructionFloatOp *source_instr, ZigType *float_type, 23976 ConstExprValue *op, ConstExprValue *out_val) { 23977 assert(ira && source_instr && float_type && out_val && op); 23978 assert(float_type->id == ZigTypeIdFloat || 23979 float_type->id == ZigTypeIdComptimeFloat); 23980 23981 BuiltinFnId fop = source_instr->op; 23982 unsigned bits; 23983 23984 switch (float_type->id) { 23985 case ZigTypeIdComptimeFloat: 23986 bits = 128; 23987 break; 23988 case ZigTypeIdFloat: 23989 bits = float_type->data.floating.bit_count; 23990 break; 23991 default: 23992 zig_unreachable(); 23993 } 23994 23995 switch (bits) { 23996 case 16: { 23997 switch (fop) { 23998 case BuiltinFnIdSqrt: 23999 out_val->data.x_f16 = f16_sqrt(op->data.x_f16); 24000 break; 24001 case BuiltinFnIdSin: 24002 case BuiltinFnIdCos: 24003 case BuiltinFnIdExp: 24004 case BuiltinFnIdExp2: 24005 case BuiltinFnIdLn: 24006 case BuiltinFnIdLog10: 24007 case BuiltinFnIdLog2: 24008 case BuiltinFnIdFabs: 24009 case BuiltinFnIdFloor: 24010 case BuiltinFnIdCeil: 24011 case BuiltinFnIdTrunc: 24012 case BuiltinFnIdNearbyInt: 24013 case BuiltinFnIdRound: 24014 zig_panic("unimplemented f16 builtin"); 24015 default: 24016 zig_unreachable(); 24017 }; 24018 break; 24019 }; 24020 case 32: { 24021 switch (fop) { 24022 case BuiltinFnIdSqrt: 24023 out_val->data.x_f32 = sqrtf(op->data.x_f32); 24024 break; 24025 case BuiltinFnIdSin: 24026 out_val->data.x_f32 = sinf(op->data.x_f32); 24027 break; 24028 case BuiltinFnIdCos: 24029 out_val->data.x_f32 = cosf(op->data.x_f32); 24030 break; 24031 case BuiltinFnIdExp: 24032 out_val->data.x_f32 = expf(op->data.x_f32); 24033 break; 24034 case BuiltinFnIdExp2: 24035 out_val->data.x_f32 = exp2f(op->data.x_f32); 24036 break; 24037 case BuiltinFnIdLn: 24038 out_val->data.x_f32 = logf(op->data.x_f32); 24039 break; 24040 case BuiltinFnIdLog10: 24041 out_val->data.x_f32 = log10f(op->data.x_f32); 24042 break; 24043 case BuiltinFnIdLog2: 24044 out_val->data.x_f32 = log2f(op->data.x_f32); 24045 break; 24046 case BuiltinFnIdFabs: 24047 out_val->data.x_f32 = fabsf(op->data.x_f32); 24048 break; 24049 case BuiltinFnIdFloor: 24050 out_val->data.x_f32 = floorf(op->data.x_f32); 24051 break; 24052 case BuiltinFnIdCeil: 24053 out_val->data.x_f32 = ceilf(op->data.x_f32); 24054 break; 24055 case BuiltinFnIdTrunc: 24056 out_val->data.x_f32 = truncf(op->data.x_f32); 24057 break; 24058 case BuiltinFnIdNearbyInt: 24059 out_val->data.x_f32 = nearbyintf(op->data.x_f32); 24060 break; 24061 case BuiltinFnIdRound: 24062 out_val->data.x_f32 = roundf(op->data.x_f32); 24063 break; 24064 default: 24065 zig_unreachable(); 24066 }; 24067 break; 24068 }; 24069 case 64: { 24070 switch (fop) { 24071 case BuiltinFnIdSqrt: 24072 out_val->data.x_f64 = sqrt(op->data.x_f64); 24073 break; 24074 case BuiltinFnIdSin: 24075 out_val->data.x_f64 = sin(op->data.x_f64); 24076 break; 24077 case BuiltinFnIdCos: 24078 out_val->data.x_f64 = cos(op->data.x_f64); 24079 break; 24080 case BuiltinFnIdExp: 24081 out_val->data.x_f64 = exp(op->data.x_f64); 24082 break; 24083 case BuiltinFnIdExp2: 24084 out_val->data.x_f64 = exp2(op->data.x_f64); 24085 break; 24086 case BuiltinFnIdLn: 24087 out_val->data.x_f64 = log(op->data.x_f64); 24088 break; 24089 case BuiltinFnIdLog10: 24090 out_val->data.x_f64 = log10(op->data.x_f64); 24091 break; 24092 case BuiltinFnIdLog2: 24093 out_val->data.x_f64 = log2(op->data.x_f64); 24094 break; 24095 case BuiltinFnIdFabs: 24096 out_val->data.x_f64 = fabs(op->data.x_f64); 24097 break; 24098 case BuiltinFnIdFloor: 24099 out_val->data.x_f64 = floor(op->data.x_f64); 24100 break; 24101 case BuiltinFnIdCeil: 24102 out_val->data.x_f64 = ceil(op->data.x_f64); 24103 break; 24104 case BuiltinFnIdTrunc: 24105 out_val->data.x_f64 = trunc(op->data.x_f64); 24106 break; 24107 case BuiltinFnIdNearbyInt: 24108 out_val->data.x_f64 = nearbyint(op->data.x_f64); 24109 break; 24110 case BuiltinFnIdRound: 24111 out_val->data.x_f64 = round(op->data.x_f64); 24112 break; 24113 default: 24114 zig_unreachable(); 24115 } 24116 break; 24117 }; 24118 case 128: { 24119 float128_t *out, *in; 24120 if (float_type->id == ZigTypeIdComptimeFloat) { 24121 out = &out_val->data.x_bigfloat.value; 24122 in = &op->data.x_bigfloat.value; 24123 } else { 24124 out = &out_val->data.x_f128; 24125 in = &op->data.x_f128; 24126 } 24127 switch (fop) { 24128 case BuiltinFnIdSqrt: 24129 f128M_sqrt(in, out); 24130 break; 24131 case BuiltinFnIdNearbyInt: 24132 case BuiltinFnIdSin: 24133 case BuiltinFnIdCos: 24134 case BuiltinFnIdExp: 24135 case BuiltinFnIdExp2: 24136 case BuiltinFnIdLn: 24137 case BuiltinFnIdLog10: 24138 case BuiltinFnIdLog2: 24139 case BuiltinFnIdFabs: 24140 case BuiltinFnIdFloor: 24141 case BuiltinFnIdCeil: 24142 case BuiltinFnIdTrunc: 24143 case BuiltinFnIdRound: 24144 zig_panic("unimplemented f128 builtin"); 24145 default: 24146 zig_unreachable(); 24147 } 24148 break; 24149 }; 24150 default: 24151 zig_unreachable(); 24152 } 24153 } 24154 24155 static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) { 24156 IrInstruction *type = instruction->type->child; 24157 if (type_is_invalid(type->value.type)) 24158 return ira->codegen->invalid_instruction; 24159 24160 ZigType *expr_type = ir_resolve_type(ira, type); 24161 if (type_is_invalid(expr_type)) 24162 return ira->codegen->invalid_instruction; 24163 24164 // Only allow float types, and vectors of floats. 24165 ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 24166 if (float_type->id != ZigTypeIdFloat && float_type->id != ZigTypeIdComptimeFloat) { 24167 ir_add_error(ira, instruction->type, buf_sprintf("@%s does not support type '%s'", float_op_to_name(instruction->op, false), buf_ptr(&float_type->name))); 24168 return ira->codegen->invalid_instruction; 24169 } 24170 24171 IrInstruction *op1 = instruction->op1->child; 24172 if (type_is_invalid(op1->value.type)) 24173 return ira->codegen->invalid_instruction; 24174 24175 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, float_type); 24176 if (type_is_invalid(casted_op1->value.type)) 24177 return ira->codegen->invalid_instruction; 24178 24179 if (instr_is_comptime(casted_op1)) { 24180 // Our comptime 16-bit and 128-bit support is quite limited. 24181 if ((float_type->id == ZigTypeIdComptimeFloat || 24182 float_type->data.floating.bit_count == 16 || 24183 float_type->data.floating.bit_count == 128) && 24184 instruction->op != BuiltinFnIdSqrt) { 24185 ir_add_error(ira, instruction->type, buf_sprintf("@%s does not support type '%s'", float_op_to_name(instruction->op, false), buf_ptr(&float_type->name))); 24186 return ira->codegen->invalid_instruction; 24187 } 24188 24189 ConstExprValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); 24190 if (!op1_const) 24191 return ira->codegen->invalid_instruction; 24192 24193 IrInstruction *result = ir_const(ira, &instruction->base, expr_type); 24194 ConstExprValue *out_val = &result->value; 24195 24196 if (expr_type->id == ZigTypeIdVector) { 24197 expand_undef_array(ira->codegen, op1_const); 24198 out_val->special = ConstValSpecialUndef; 24199 expand_undef_array(ira->codegen, out_val); 24200 size_t len = expr_type->data.vector.len; 24201 for (size_t i = 0; i < len; i += 1) { 24202 ConstExprValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i]; 24203 ConstExprValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; 24204 assert(float_operand_op1->type == float_type); 24205 assert(float_out_val->type == float_type); 24206 ir_eval_float_op(ira, instruction, float_type, 24207 op1_const, float_out_val); 24208 float_out_val->type = float_type; 24209 } 24210 out_val->type = expr_type; 24211 out_val->special = ConstValSpecialStatic; 24212 } else { 24213 ir_eval_float_op(ira, instruction, float_type, op1_const, out_val); 24214 } 24215 return result; 24216 } 24217 24218 ir_assert(float_type->id == ZigTypeIdFloat, &instruction->base); 24219 24220 IrInstruction *result = ir_build_float_op(&ira->new_irb, instruction->base.scope, 24221 instruction->base.source_node, nullptr, casted_op1, instruction->op); 24222 result->value.type = expr_type; 24223 return result; 24224 } 24225 24226 static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstructionBswap *instruction) { 24227 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 24228 if (type_is_invalid(int_type)) 24229 return ira->codegen->invalid_instruction; 24230 24231 IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); 24232 if (type_is_invalid(op->value.type)) 24233 return ira->codegen->invalid_instruction; 24234 24235 if (int_type->data.integral.bit_count == 0) { 24236 IrInstruction *result = ir_const(ira, &instruction->base, int_type); 24237 bigint_init_unsigned(&result->value.data.x_bigint, 0); 24238 return result; 24239 } 24240 24241 if (int_type->data.integral.bit_count == 8) 24242 return op; 24243 24244 if (int_type->data.integral.bit_count % 8 != 0) { 24245 ir_add_error(ira, instruction->op, 24246 buf_sprintf("@byteSwap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", 24247 buf_ptr(&int_type->name), int_type->data.integral.bit_count)); 24248 return ira->codegen->invalid_instruction; 24249 } 24250 24251 if (instr_is_comptime(op)) { 24252 ConstExprValue *val = ir_resolve_const(ira, op, UndefOk); 24253 if (val == nullptr) 24254 return ira->codegen->invalid_instruction; 24255 if (val->special == ConstValSpecialUndef) 24256 return ir_const_undef(ira, &instruction->base, int_type); 24257 24258 IrInstruction *result = ir_const(ira, &instruction->base, int_type); 24259 size_t buf_size = int_type->data.integral.bit_count / 8; 24260 uint8_t *buf = allocate_nonzero<uint8_t>(buf_size); 24261 bigint_write_twos_complement(&val->data.x_bigint, buf, int_type->data.integral.bit_count, true); 24262 bigint_read_twos_complement(&result->value.data.x_bigint, buf, int_type->data.integral.bit_count, false, 24263 int_type->data.integral.is_signed); 24264 return result; 24265 } 24266 24267 IrInstruction *result = ir_build_bswap(&ira->new_irb, instruction->base.scope, 24268 instruction->base.source_node, nullptr, op); 24269 result->value.type = int_type; 24270 return result; 24271 } 24272 24273 static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstructionBitReverse *instruction) { 24274 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 24275 if (type_is_invalid(int_type)) 24276 return ira->codegen->invalid_instruction; 24277 24278 IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); 24279 if (type_is_invalid(op->value.type)) 24280 return ira->codegen->invalid_instruction; 24281 24282 if (int_type->data.integral.bit_count == 0) { 24283 IrInstruction *result = ir_const(ira, &instruction->base, int_type); 24284 bigint_init_unsigned(&result->value.data.x_bigint, 0); 24285 return result; 24286 } 24287 24288 if (instr_is_comptime(op)) { 24289 ConstExprValue *val = ir_resolve_const(ira, op, UndefOk); 24290 if (val == nullptr) 24291 return ira->codegen->invalid_instruction; 24292 if (val->special == ConstValSpecialUndef) 24293 return ir_const_undef(ira, &instruction->base, int_type); 24294 24295 IrInstruction *result = ir_const(ira, &instruction->base, int_type); 24296 size_t num_bits = int_type->data.integral.bit_count; 24297 size_t buf_size = (num_bits + 7) / 8; 24298 uint8_t *comptime_buf = allocate_nonzero<uint8_t>(buf_size); 24299 uint8_t *result_buf = allocate_nonzero<uint8_t>(buf_size); 24300 memset(comptime_buf,0,buf_size); 24301 memset(result_buf,0,buf_size); 24302 24303 bigint_write_twos_complement(&val->data.x_bigint,comptime_buf,num_bits,ira->codegen->is_big_endian); 24304 24305 size_t bit_i = 0; 24306 size_t bit_rev_i = num_bits - 1; 24307 for (; bit_i < num_bits; bit_i++, bit_rev_i--) { 24308 if (comptime_buf[bit_i / 8] & (1 << (bit_i % 8))) { 24309 result_buf[bit_rev_i / 8] |= (1 << (bit_rev_i % 8)); 24310 } 24311 } 24312 24313 bigint_read_twos_complement(&result->value.data.x_bigint, 24314 result_buf, 24315 int_type->data.integral.bit_count, 24316 ira->codegen->is_big_endian, 24317 int_type->data.integral.is_signed); 24318 24319 return result; 24320 } 24321 24322 IrInstruction *result = ir_build_bit_reverse(&ira->new_irb, instruction->base.scope, 24323 instruction->base.source_node, nullptr, op); 24324 result->value.type = int_type; 24325 return result; 24326 } 24327 24328 24329 static IrInstruction *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstructionEnumToInt *instruction) { 24330 IrInstruction *target = instruction->target->child; 24331 if (type_is_invalid(target->value.type)) 24332 return ira->codegen->invalid_instruction; 24333 24334 return ir_analyze_enum_to_int(ira, &instruction->base, target); 24335 } 24336 24337 static IrInstruction *ir_analyze_instruction_int_to_enum(IrAnalyze *ira, IrInstructionIntToEnum *instruction) { 24338 Error err; 24339 IrInstruction *dest_type_value = instruction->dest_type->child; 24340 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 24341 if (type_is_invalid(dest_type)) 24342 return ira->codegen->invalid_instruction; 24343 24344 if (dest_type->id != ZigTypeIdEnum) { 24345 ir_add_error(ira, instruction->dest_type, 24346 buf_sprintf("expected enum, found type '%s'", buf_ptr(&dest_type->name))); 24347 return ira->codegen->invalid_instruction; 24348 } 24349 24350 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 24351 return ira->codegen->invalid_instruction; 24352 24353 ZigType *tag_type = dest_type->data.enumeration.tag_int_type; 24354 24355 IrInstruction *target = instruction->target->child; 24356 if (type_is_invalid(target->value.type)) 24357 return ira->codegen->invalid_instruction; 24358 24359 IrInstruction *casted_target = ir_implicit_cast(ira, target, tag_type); 24360 if (type_is_invalid(casted_target->value.type)) 24361 return ira->codegen->invalid_instruction; 24362 24363 return ir_analyze_int_to_enum(ira, &instruction->base, casted_target, dest_type); 24364 } 24365 24366 static IrInstruction *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, IrInstructionCheckRuntimeScope *instruction) { 24367 IrInstruction *block_comptime_inst = instruction->scope_is_comptime->child; 24368 bool scope_is_comptime; 24369 if (!ir_resolve_bool(ira, block_comptime_inst, &scope_is_comptime)) 24370 return ira->codegen->invalid_instruction; 24371 24372 IrInstruction *is_comptime_inst = instruction->is_comptime->child; 24373 bool is_comptime; 24374 if (!ir_resolve_bool(ira, is_comptime_inst, &is_comptime)) 24375 return ira->codegen->invalid_instruction; 24376 24377 if (!scope_is_comptime && is_comptime) { 24378 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 24379 buf_sprintf("comptime control flow inside runtime block")); 24380 add_error_note(ira->codegen, msg, block_comptime_inst->source_node, 24381 buf_sprintf("runtime block created here")); 24382 return ira->codegen->invalid_instruction; 24383 } 24384 24385 return ir_const_void(ira, &instruction->base); 24386 } 24387 24388 static IrInstruction *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstructionHasDecl *instruction) { 24389 ZigType *container_type = ir_resolve_type(ira, instruction->container->child); 24390 if (type_is_invalid(container_type)) 24391 return ira->codegen->invalid_instruction; 24392 24393 Buf *name = ir_resolve_str(ira, instruction->name->child); 24394 if (name == nullptr) 24395 return ira->codegen->invalid_instruction; 24396 24397 if (!is_container(container_type)) { 24398 ir_add_error(ira, instruction->container, 24399 buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&container_type->name))); 24400 return ira->codegen->invalid_instruction; 24401 } 24402 24403 ScopeDecls *container_scope = get_container_scope(container_type); 24404 Tld *tld = find_container_decl(ira->codegen, container_scope, name); 24405 if (tld == nullptr) 24406 return ir_const_bool(ira, &instruction->base, false); 24407 24408 if (tld->visib_mod == VisibModPrivate && tld->import != get_scope_import(instruction->base.scope)) { 24409 return ir_const_bool(ira, &instruction->base, false); 24410 } 24411 24412 return ir_const_bool(ira, &instruction->base, true); 24413 } 24414 24415 static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstructionUndeclaredIdent *instruction) { 24416 // put a variable of same name with invalid type in global scope 24417 // so that future references to this same name will find a variable with an invalid type 24418 populate_invalid_variable_in_scope(ira->codegen, instruction->base.scope, instruction->base.source_node, 24419 instruction->name); 24420 ir_add_error(ira, &instruction->base, 24421 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(instruction->name))); 24422 return ira->codegen->invalid_instruction; 24423 } 24424 24425 static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstructionEndExpr *instruction) { 24426 IrInstruction *value = instruction->value->child; 24427 if (type_is_invalid(value->value.type)) 24428 return ira->codegen->invalid_instruction; 24429 24430 bool was_written = instruction->result_loc->written; 24431 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 24432 value->value.type, value, false, false, true); 24433 if (result_loc != nullptr) { 24434 if (type_is_invalid(result_loc->value.type)) 24435 return ira->codegen->invalid_instruction; 24436 if (result_loc->value.type->id == ZigTypeIdUnreachable) 24437 return result_loc; 24438 24439 if (!was_written) { 24440 IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value, 24441 instruction->result_loc->allow_write_through_const); 24442 if (type_is_invalid(store_ptr->value.type)) { 24443 return ira->codegen->invalid_instruction; 24444 } 24445 } 24446 24447 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { 24448 if (instr_is_comptime(value)) { 24449 result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; 24450 } else { 24451 result_loc->value.special = ConstValSpecialRuntime; 24452 } 24453 } 24454 } 24455 24456 return ir_const_void(ira, &instruction->base); 24457 } 24458 24459 static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) { 24460 IrInstruction *operand = instruction->operand->child; 24461 if (type_is_invalid(operand->value.type)) 24462 return operand; 24463 24464 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, 24465 &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false, true); 24466 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) 24467 return result_loc; 24468 24469 return instruction->result_loc_bit_cast->parent->gen_instruction; 24470 } 24471 24472 static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *ira, 24473 IrInstructionUnionInitNamedField *instruction) 24474 { 24475 ZigType *union_type = ir_resolve_type(ira, instruction->union_type->child); 24476 if (type_is_invalid(union_type)) 24477 return ira->codegen->invalid_instruction; 24478 24479 if (union_type->id != ZigTypeIdUnion) { 24480 ir_add_error(ira, instruction->union_type, 24481 buf_sprintf("non-union type '%s' passed to @unionInit", buf_ptr(&union_type->name))); 24482 return ira->codegen->invalid_instruction; 24483 } 24484 24485 Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); 24486 if (field_name == nullptr) 24487 return ira->codegen->invalid_instruction; 24488 24489 IrInstruction *field_result_loc = instruction->field_result_loc->child; 24490 if (type_is_invalid(field_result_loc->value.type)) 24491 return ira->codegen->invalid_instruction; 24492 24493 IrInstruction *result_loc = instruction->result_loc->child; 24494 if (type_is_invalid(result_loc->value.type)) 24495 return ira->codegen->invalid_instruction; 24496 24497 return ir_analyze_union_init(ira, &instruction->base, instruction->base.source_node, 24498 union_type, field_name, field_result_loc, result_loc); 24499 } 24500 24501 static IrInstruction *ir_analyze_instruction_suspend_begin(IrAnalyze *ira, IrInstructionSuspendBegin *instruction) { 24502 IrInstructionSuspendBegin *result = ir_build_suspend_begin(&ira->new_irb, instruction->base.scope, 24503 instruction->base.source_node); 24504 return &result->base; 24505 } 24506 24507 static IrInstruction *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, 24508 IrInstructionSuspendFinish *instruction) 24509 { 24510 IrInstruction *begin_base = instruction->begin->base.child; 24511 if (type_is_invalid(begin_base->value.type)) 24512 return ira->codegen->invalid_instruction; 24513 ir_assert(begin_base->id == IrInstructionIdSuspendBegin, &instruction->base); 24514 IrInstructionSuspendBegin *begin = reinterpret_cast<IrInstructionSuspendBegin *>(begin_base); 24515 24516 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 24517 ir_assert(fn_entry != nullptr, &instruction->base); 24518 24519 if (fn_entry->inferred_async_node == nullptr) { 24520 fn_entry->inferred_async_node = instruction->base.source_node; 24521 } 24522 24523 return ir_build_suspend_finish(&ira->new_irb, instruction->base.scope, instruction->base.source_node, begin); 24524 } 24525 24526 static IrInstruction *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInstruction *source_instr, 24527 IrInstruction *frame_ptr) 24528 { 24529 if (type_is_invalid(frame_ptr->value.type)) 24530 return ira->codegen->invalid_instruction; 24531 24532 ZigType *result_type; 24533 IrInstruction *frame; 24534 if (frame_ptr->value.type->id == ZigTypeIdPointer && 24535 frame_ptr->value.type->data.pointer.ptr_len == PtrLenSingle && 24536 frame_ptr->value.type->data.pointer.child_type->id == ZigTypeIdFnFrame) 24537 { 24538 result_type = frame_ptr->value.type->data.pointer.child_type->data.frame.fn->type_entry->data.fn.fn_type_id.return_type; 24539 frame = frame_ptr; 24540 } else { 24541 frame = ir_get_deref(ira, source_instr, frame_ptr, nullptr); 24542 if (frame->value.type->id == ZigTypeIdPointer && 24543 frame->value.type->data.pointer.ptr_len == PtrLenSingle && 24544 frame->value.type->data.pointer.child_type->id == ZigTypeIdFnFrame) 24545 { 24546 result_type = frame->value.type->data.pointer.child_type->data.frame.fn->type_entry->data.fn.fn_type_id.return_type; 24547 } else if (frame->value.type->id != ZigTypeIdAnyFrame || 24548 frame->value.type->data.any_frame.result_type == nullptr) 24549 { 24550 ir_add_error(ira, source_instr, 24551 buf_sprintf("expected anyframe->T, found '%s'", buf_ptr(&frame->value.type->name))); 24552 return ira->codegen->invalid_instruction; 24553 } else { 24554 result_type = frame->value.type->data.any_frame.result_type; 24555 } 24556 } 24557 24558 ZigType *any_frame_type = get_any_frame_type(ira->codegen, result_type); 24559 IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); 24560 if (type_is_invalid(casted_frame->value.type)) 24561 return ira->codegen->invalid_instruction; 24562 24563 return casted_frame; 24564 } 24565 24566 static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstructionAwaitSrc *instruction) { 24567 IrInstruction *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base, instruction->frame->child); 24568 if (type_is_invalid(frame->value.type)) 24569 return ira->codegen->invalid_instruction; 24570 24571 ZigType *result_type = frame->value.type->data.any_frame.result_type; 24572 24573 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 24574 ir_assert(fn_entry != nullptr, &instruction->base); 24575 24576 if (fn_entry->inferred_async_node == nullptr) { 24577 fn_entry->inferred_async_node = instruction->base.source_node; 24578 } 24579 24580 if (type_can_fail(result_type)) { 24581 fn_entry->calls_or_awaits_errorable_fn = true; 24582 } 24583 24584 IrInstruction *result_loc; 24585 if (type_has_bits(result_type)) { 24586 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 24587 result_type, nullptr, true, true, true); 24588 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) 24589 return result_loc; 24590 } else { 24591 result_loc = nullptr; 24592 } 24593 24594 IrInstruction *result = ir_build_await_gen(ira, &instruction->base, frame, result_type, result_loc); 24595 return ir_finish_anal(ira, result); 24596 } 24597 24598 static IrInstruction *ir_analyze_instruction_resume(IrAnalyze *ira, IrInstructionResume *instruction) { 24599 IrInstruction *frame_ptr = instruction->frame->child; 24600 if (type_is_invalid(frame_ptr->value.type)) 24601 return ira->codegen->invalid_instruction; 24602 24603 IrInstruction *frame; 24604 if (frame_ptr->value.type->id == ZigTypeIdPointer && 24605 frame_ptr->value.type->data.pointer.ptr_len == PtrLenSingle && 24606 frame_ptr->value.type->data.pointer.child_type->id == ZigTypeIdFnFrame) 24607 { 24608 frame = frame_ptr; 24609 } else { 24610 frame = ir_get_deref(ira, &instruction->base, frame_ptr, nullptr); 24611 } 24612 24613 ZigType *any_frame_type = get_any_frame_type(ira->codegen, nullptr); 24614 IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); 24615 if (type_is_invalid(casted_frame->value.type)) 24616 return ira->codegen->invalid_instruction; 24617 24618 return ir_build_resume(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_frame); 24619 } 24620 24621 static IrInstruction *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstructionSpillBegin *instruction) { 24622 if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) 24623 return ir_const_void(ira, &instruction->base); 24624 24625 IrInstruction *operand = instruction->operand->child; 24626 if (type_is_invalid(operand->value.type)) 24627 return ira->codegen->invalid_instruction; 24628 24629 if (!type_has_bits(operand->value.type)) 24630 return ir_const_void(ira, &instruction->base); 24631 24632 ir_assert(instruction->spill_id == SpillIdRetErrCode, &instruction->base); 24633 ira->new_irb.exec->need_err_code_spill = true; 24634 24635 IrInstructionSpillBegin *result = ir_build_spill_begin(&ira->new_irb, instruction->base.scope, 24636 instruction->base.source_node, operand, instruction->spill_id); 24637 return &result->base; 24638 } 24639 24640 static IrInstruction *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstructionSpillEnd *instruction) { 24641 IrInstruction *operand = instruction->begin->operand->child; 24642 if (type_is_invalid(operand->value.type)) 24643 return ira->codegen->invalid_instruction; 24644 24645 if (ir_should_inline(ira->new_irb.exec, instruction->base.scope) || !type_has_bits(operand->value.type)) 24646 return operand; 24647 24648 ir_assert(instruction->begin->base.child->id == IrInstructionIdSpillBegin, &instruction->base); 24649 IrInstructionSpillBegin *begin = reinterpret_cast<IrInstructionSpillBegin *>(instruction->begin->base.child); 24650 24651 IrInstruction *result = ir_build_spill_end(&ira->new_irb, instruction->base.scope, 24652 instruction->base.source_node, begin); 24653 result->value.type = operand->value.type; 24654 return result; 24655 } 24656 24657 static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { 24658 switch (instruction->id) { 24659 case IrInstructionIdInvalid: 24660 case IrInstructionIdWidenOrShorten: 24661 case IrInstructionIdStructFieldPtr: 24662 case IrInstructionIdUnionFieldPtr: 24663 case IrInstructionIdOptionalWrap: 24664 case IrInstructionIdErrWrapCode: 24665 case IrInstructionIdErrWrapPayload: 24666 case IrInstructionIdCast: 24667 case IrInstructionIdDeclVarGen: 24668 case IrInstructionIdPtrCastGen: 24669 case IrInstructionIdCmpxchgGen: 24670 case IrInstructionIdArrayToVector: 24671 case IrInstructionIdVectorToArray: 24672 case IrInstructionIdPtrOfArrayToSlice: 24673 case IrInstructionIdAssertZero: 24674 case IrInstructionIdAssertNonNull: 24675 case IrInstructionIdResizeSlice: 24676 case IrInstructionIdLoadPtrGen: 24677 case IrInstructionIdBitCastGen: 24678 case IrInstructionIdCallGen: 24679 case IrInstructionIdReturnPtr: 24680 case IrInstructionIdAllocaGen: 24681 case IrInstructionIdSliceGen: 24682 case IrInstructionIdRefGen: 24683 case IrInstructionIdTestErrGen: 24684 case IrInstructionIdFrameSizeGen: 24685 case IrInstructionIdAwaitGen: 24686 zig_unreachable(); 24687 24688 case IrInstructionIdReturn: 24689 return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction); 24690 case IrInstructionIdConst: 24691 return ir_analyze_instruction_const(ira, (IrInstructionConst *)instruction); 24692 case IrInstructionIdUnOp: 24693 return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction); 24694 case IrInstructionIdBinOp: 24695 return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction); 24696 case IrInstructionIdDeclVarSrc: 24697 return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVarSrc *)instruction); 24698 case IrInstructionIdLoadPtr: 24699 return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction); 24700 case IrInstructionIdStorePtr: 24701 return ir_analyze_instruction_store_ptr(ira, (IrInstructionStorePtr *)instruction); 24702 case IrInstructionIdElemPtr: 24703 return ir_analyze_instruction_elem_ptr(ira, (IrInstructionElemPtr *)instruction); 24704 case IrInstructionIdVarPtr: 24705 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); 24706 case IrInstructionIdFieldPtr: 24707 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); 24708 case IrInstructionIdCallSrc: 24709 return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction); 24710 case IrInstructionIdBr: 24711 return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); 24712 case IrInstructionIdCondBr: 24713 return ir_analyze_instruction_cond_br(ira, (IrInstructionCondBr *)instruction); 24714 case IrInstructionIdUnreachable: 24715 return ir_analyze_instruction_unreachable(ira, (IrInstructionUnreachable *)instruction); 24716 case IrInstructionIdPhi: 24717 return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); 24718 case IrInstructionIdTypeOf: 24719 return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); 24720 case IrInstructionIdSetCold: 24721 return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); 24722 case IrInstructionIdSetRuntimeSafety: 24723 return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction); 24724 case IrInstructionIdSetFloatMode: 24725 return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction); 24726 case IrInstructionIdAnyFrameType: 24727 return ir_analyze_instruction_any_frame_type(ira, (IrInstructionAnyFrameType *)instruction); 24728 case IrInstructionIdSliceType: 24729 return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction); 24730 case IrInstructionIdGlobalAsm: 24731 return ir_analyze_instruction_global_asm(ira, (IrInstructionGlobalAsm *)instruction); 24732 case IrInstructionIdAsm: 24733 return ir_analyze_instruction_asm(ira, (IrInstructionAsm *)instruction); 24734 case IrInstructionIdArrayType: 24735 return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction); 24736 case IrInstructionIdSizeOf: 24737 return ir_analyze_instruction_size_of(ira, (IrInstructionSizeOf *)instruction); 24738 case IrInstructionIdTestNonNull: 24739 return ir_analyze_instruction_test_non_null(ira, (IrInstructionTestNonNull *)instruction); 24740 case IrInstructionIdOptionalUnwrapPtr: 24741 return ir_analyze_instruction_optional_unwrap_ptr(ira, (IrInstructionOptionalUnwrapPtr *)instruction); 24742 case IrInstructionIdClz: 24743 return ir_analyze_instruction_clz(ira, (IrInstructionClz *)instruction); 24744 case IrInstructionIdCtz: 24745 return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction); 24746 case IrInstructionIdPopCount: 24747 return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction); 24748 case IrInstructionIdBswap: 24749 return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction); 24750 case IrInstructionIdBitReverse: 24751 return ir_analyze_instruction_bit_reverse(ira, (IrInstructionBitReverse *)instruction); 24752 case IrInstructionIdSwitchBr: 24753 return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction); 24754 case IrInstructionIdSwitchTarget: 24755 return ir_analyze_instruction_switch_target(ira, (IrInstructionSwitchTarget *)instruction); 24756 case IrInstructionIdSwitchVar: 24757 return ir_analyze_instruction_switch_var(ira, (IrInstructionSwitchVar *)instruction); 24758 case IrInstructionIdSwitchElseVar: 24759 return ir_analyze_instruction_switch_else_var(ira, (IrInstructionSwitchElseVar *)instruction); 24760 case IrInstructionIdUnionTag: 24761 return ir_analyze_instruction_union_tag(ira, (IrInstructionUnionTag *)instruction); 24762 case IrInstructionIdImport: 24763 return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction); 24764 case IrInstructionIdRef: 24765 return ir_analyze_instruction_ref(ira, (IrInstructionRef *)instruction); 24766 case IrInstructionIdContainerInitList: 24767 return ir_analyze_instruction_container_init_list(ira, (IrInstructionContainerInitList *)instruction); 24768 case IrInstructionIdContainerInitFields: 24769 return ir_analyze_instruction_container_init_fields(ira, (IrInstructionContainerInitFields *)instruction); 24770 case IrInstructionIdCompileErr: 24771 return ir_analyze_instruction_compile_err(ira, (IrInstructionCompileErr *)instruction); 24772 case IrInstructionIdCompileLog: 24773 return ir_analyze_instruction_compile_log(ira, (IrInstructionCompileLog *)instruction); 24774 case IrInstructionIdErrName: 24775 return ir_analyze_instruction_err_name(ira, (IrInstructionErrName *)instruction); 24776 case IrInstructionIdTypeName: 24777 return ir_analyze_instruction_type_name(ira, (IrInstructionTypeName *)instruction); 24778 case IrInstructionIdCImport: 24779 return ir_analyze_instruction_c_import(ira, (IrInstructionCImport *)instruction); 24780 case IrInstructionIdCInclude: 24781 return ir_analyze_instruction_c_include(ira, (IrInstructionCInclude *)instruction); 24782 case IrInstructionIdCDefine: 24783 return ir_analyze_instruction_c_define(ira, (IrInstructionCDefine *)instruction); 24784 case IrInstructionIdCUndef: 24785 return ir_analyze_instruction_c_undef(ira, (IrInstructionCUndef *)instruction); 24786 case IrInstructionIdEmbedFile: 24787 return ir_analyze_instruction_embed_file(ira, (IrInstructionEmbedFile *)instruction); 24788 case IrInstructionIdCmpxchgSrc: 24789 return ir_analyze_instruction_cmpxchg(ira, (IrInstructionCmpxchgSrc *)instruction); 24790 case IrInstructionIdFence: 24791 return ir_analyze_instruction_fence(ira, (IrInstructionFence *)instruction); 24792 case IrInstructionIdTruncate: 24793 return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction); 24794 case IrInstructionIdIntCast: 24795 return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction); 24796 case IrInstructionIdFloatCast: 24797 return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction); 24798 case IrInstructionIdErrSetCast: 24799 return ir_analyze_instruction_err_set_cast(ira, (IrInstructionErrSetCast *)instruction); 24800 case IrInstructionIdFromBytes: 24801 return ir_analyze_instruction_from_bytes(ira, (IrInstructionFromBytes *)instruction); 24802 case IrInstructionIdToBytes: 24803 return ir_analyze_instruction_to_bytes(ira, (IrInstructionToBytes *)instruction); 24804 case IrInstructionIdIntToFloat: 24805 return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); 24806 case IrInstructionIdFloatToInt: 24807 return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction); 24808 case IrInstructionIdBoolToInt: 24809 return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction); 24810 case IrInstructionIdIntType: 24811 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); 24812 case IrInstructionIdVectorType: 24813 return ir_analyze_instruction_vector_type(ira, (IrInstructionVectorType *)instruction); 24814 case IrInstructionIdBoolNot: 24815 return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); 24816 case IrInstructionIdMemset: 24817 return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); 24818 case IrInstructionIdMemcpy: 24819 return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); 24820 case IrInstructionIdSliceSrc: 24821 return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction); 24822 case IrInstructionIdMemberCount: 24823 return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); 24824 case IrInstructionIdMemberType: 24825 return ir_analyze_instruction_member_type(ira, (IrInstructionMemberType *)instruction); 24826 case IrInstructionIdMemberName: 24827 return ir_analyze_instruction_member_name(ira, (IrInstructionMemberName *)instruction); 24828 case IrInstructionIdBreakpoint: 24829 return ir_analyze_instruction_breakpoint(ira, (IrInstructionBreakpoint *)instruction); 24830 case IrInstructionIdReturnAddress: 24831 return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction); 24832 case IrInstructionIdFrameAddress: 24833 return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction); 24834 case IrInstructionIdFrameHandle: 24835 return ir_analyze_instruction_frame_handle(ira, (IrInstructionFrameHandle *)instruction); 24836 case IrInstructionIdFrameType: 24837 return ir_analyze_instruction_frame_type(ira, (IrInstructionFrameType *)instruction); 24838 case IrInstructionIdFrameSizeSrc: 24839 return ir_analyze_instruction_frame_size(ira, (IrInstructionFrameSizeSrc *)instruction); 24840 case IrInstructionIdAlignOf: 24841 return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); 24842 case IrInstructionIdOverflowOp: 24843 return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); 24844 case IrInstructionIdTestErrSrc: 24845 return ir_analyze_instruction_test_err(ira, (IrInstructionTestErrSrc *)instruction); 24846 case IrInstructionIdUnwrapErrCode: 24847 return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); 24848 case IrInstructionIdUnwrapErrPayload: 24849 return ir_analyze_instruction_unwrap_err_payload(ira, (IrInstructionUnwrapErrPayload *)instruction); 24850 case IrInstructionIdFnProto: 24851 return ir_analyze_instruction_fn_proto(ira, (IrInstructionFnProto *)instruction); 24852 case IrInstructionIdTestComptime: 24853 return ir_analyze_instruction_test_comptime(ira, (IrInstructionTestComptime *)instruction); 24854 case IrInstructionIdCheckSwitchProngs: 24855 return ir_analyze_instruction_check_switch_prongs(ira, (IrInstructionCheckSwitchProngs *)instruction); 24856 case IrInstructionIdCheckStatementIsVoid: 24857 return ir_analyze_instruction_check_statement_is_void(ira, (IrInstructionCheckStatementIsVoid *)instruction); 24858 case IrInstructionIdDeclRef: 24859 return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction); 24860 case IrInstructionIdPanic: 24861 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); 24862 case IrInstructionIdPtrCastSrc: 24863 return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction); 24864 case IrInstructionIdIntToPtr: 24865 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); 24866 case IrInstructionIdPtrToInt: 24867 return ir_analyze_instruction_ptr_to_int(ira, (IrInstructionPtrToInt *)instruction); 24868 case IrInstructionIdTagName: 24869 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionTagName *)instruction); 24870 case IrInstructionIdFieldParentPtr: 24871 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); 24872 case IrInstructionIdByteOffsetOf: 24873 return ir_analyze_instruction_byte_offset_of(ira, (IrInstructionByteOffsetOf *)instruction); 24874 case IrInstructionIdBitOffsetOf: 24875 return ir_analyze_instruction_bit_offset_of(ira, (IrInstructionBitOffsetOf *)instruction); 24876 case IrInstructionIdTypeInfo: 24877 return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); 24878 case IrInstructionIdHasField: 24879 return ir_analyze_instruction_has_field(ira, (IrInstructionHasField *) instruction); 24880 case IrInstructionIdTypeId: 24881 return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); 24882 case IrInstructionIdSetEvalBranchQuota: 24883 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstructionSetEvalBranchQuota *)instruction); 24884 case IrInstructionIdPtrType: 24885 return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); 24886 case IrInstructionIdAlignCast: 24887 return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); 24888 case IrInstructionIdImplicitCast: 24889 return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction); 24890 case IrInstructionIdResolveResult: 24891 return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction); 24892 case IrInstructionIdResetResult: 24893 return ir_analyze_instruction_reset_result(ira, (IrInstructionResetResult *)instruction); 24894 case IrInstructionIdOpaqueType: 24895 return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); 24896 case IrInstructionIdSetAlignStack: 24897 return ir_analyze_instruction_set_align_stack(ira, (IrInstructionSetAlignStack *)instruction); 24898 case IrInstructionIdArgType: 24899 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction); 24900 case IrInstructionIdTagType: 24901 return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction); 24902 case IrInstructionIdExport: 24903 return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction); 24904 case IrInstructionIdErrorReturnTrace: 24905 return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction); 24906 case IrInstructionIdErrorUnion: 24907 return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction); 24908 case IrInstructionIdAtomicRmw: 24909 return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction); 24910 case IrInstructionIdAtomicLoad: 24911 return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction); 24912 case IrInstructionIdSaveErrRetAddr: 24913 return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction); 24914 case IrInstructionIdAddImplicitReturnType: 24915 return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction); 24916 case IrInstructionIdFloatOp: 24917 return ir_analyze_instruction_float_op(ira, (IrInstructionFloatOp *)instruction); 24918 case IrInstructionIdMulAdd: 24919 return ir_analyze_instruction_mul_add(ira, (IrInstructionMulAdd *)instruction); 24920 case IrInstructionIdIntToErr: 24921 return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); 24922 case IrInstructionIdErrToInt: 24923 return ir_analyze_instruction_err_to_int(ira, (IrInstructionErrToInt *)instruction); 24924 case IrInstructionIdIntToEnum: 24925 return ir_analyze_instruction_int_to_enum(ira, (IrInstructionIntToEnum *)instruction); 24926 case IrInstructionIdEnumToInt: 24927 return ir_analyze_instruction_enum_to_int(ira, (IrInstructionEnumToInt *)instruction); 24928 case IrInstructionIdCheckRuntimeScope: 24929 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction); 24930 case IrInstructionIdHasDecl: 24931 return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction); 24932 case IrInstructionIdUndeclaredIdent: 24933 return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction); 24934 case IrInstructionIdAllocaSrc: 24935 return nullptr; 24936 case IrInstructionIdEndExpr: 24937 return ir_analyze_instruction_end_expr(ira, (IrInstructionEndExpr *)instruction); 24938 case IrInstructionIdBitCastSrc: 24939 return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction); 24940 case IrInstructionIdUnionInitNamedField: 24941 return ir_analyze_instruction_union_init_named_field(ira, (IrInstructionUnionInitNamedField *)instruction); 24942 case IrInstructionIdSuspendBegin: 24943 return ir_analyze_instruction_suspend_begin(ira, (IrInstructionSuspendBegin *)instruction); 24944 case IrInstructionIdSuspendFinish: 24945 return ir_analyze_instruction_suspend_finish(ira, (IrInstructionSuspendFinish *)instruction); 24946 case IrInstructionIdResume: 24947 return ir_analyze_instruction_resume(ira, (IrInstructionResume *)instruction); 24948 case IrInstructionIdAwaitSrc: 24949 return ir_analyze_instruction_await(ira, (IrInstructionAwaitSrc *)instruction); 24950 case IrInstructionIdSpillBegin: 24951 return ir_analyze_instruction_spill_begin(ira, (IrInstructionSpillBegin *)instruction); 24952 case IrInstructionIdSpillEnd: 24953 return ir_analyze_instruction_spill_end(ira, (IrInstructionSpillEnd *)instruction); 24954 } 24955 zig_unreachable(); 24956 } 24957 24958 // This function attempts to evaluate IR code while doing type checking and other analysis. 24959 // It emits a new IrExecutable which is partially evaluated IR code. 24960 ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, 24961 ZigType *expected_type, AstNode *expected_type_source_node) 24962 { 24963 assert(!old_exec->invalid); 24964 assert(expected_type == nullptr || !type_is_invalid(expected_type)); 24965 24966 IrAnalyze *ira = allocate<IrAnalyze>(1); 24967 old_exec->analysis = ira; 24968 ira->codegen = codegen; 24969 24970 ira->explicit_return_type = expected_type; 24971 ira->explicit_return_type_source_node = expected_type_source_node; 24972 24973 ira->old_irb.codegen = codegen; 24974 ira->old_irb.exec = old_exec; 24975 24976 ira->new_irb.codegen = codegen; 24977 ira->new_irb.exec = new_exec; 24978 24979 ConstExprValue *vals = create_const_vals(ira->old_irb.exec->mem_slot_count); 24980 ira->exec_context.mem_slot_list.resize(ira->old_irb.exec->mem_slot_count); 24981 for (size_t i = 0; i < ira->exec_context.mem_slot_list.length; i += 1) { 24982 ira->exec_context.mem_slot_list.items[i] = &vals[i]; 24983 } 24984 24985 IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); 24986 IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); 24987 ir_ref_bb(new_entry_bb); 24988 ira->new_irb.current_basic_block = new_entry_bb; 24989 ira->old_bb_index = 0; 24990 24991 ir_start_bb(ira, old_entry_bb, nullptr); 24992 24993 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 24994 IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 24995 24996 if (old_instruction->ref_count == 0 && !ir_has_side_effects(old_instruction)) { 24997 ira->instruction_index += 1; 24998 continue; 24999 } 25000 25001 if (ira->codegen->verbose_ir) { 25002 fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id); 25003 } 25004 IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); 25005 if (new_instruction != nullptr) { 25006 ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction); 25007 old_instruction->child = new_instruction; 25008 25009 if (type_is_invalid(new_instruction->value.type)) { 25010 return ira->codegen->builtin_types.entry_invalid; 25011 } 25012 25013 // unreachable instructions do their own control flow. 25014 if (new_instruction->value.type->id == ZigTypeIdUnreachable) 25015 continue; 25016 } 25017 25018 ira->instruction_index += 1; 25019 } 25020 25021 if (new_exec->invalid) { 25022 return ira->codegen->builtin_types.entry_invalid; 25023 } else if (ira->src_implicit_return_type_list.length == 0) { 25024 return codegen->builtin_types.entry_unreachable; 25025 } else { 25026 return ir_resolve_peer_types(ira, expected_type_source_node, expected_type, ira->src_implicit_return_type_list.items, 25027 ira->src_implicit_return_type_list.length); 25028 } 25029 } 25030 25031 bool ir_has_side_effects(IrInstruction *instruction) { 25032 switch (instruction->id) { 25033 case IrInstructionIdInvalid: 25034 zig_unreachable(); 25035 case IrInstructionIdBr: 25036 case IrInstructionIdCondBr: 25037 case IrInstructionIdSwitchBr: 25038 case IrInstructionIdDeclVarSrc: 25039 case IrInstructionIdDeclVarGen: 25040 case IrInstructionIdStorePtr: 25041 case IrInstructionIdCallSrc: 25042 case IrInstructionIdCallGen: 25043 case IrInstructionIdReturn: 25044 case IrInstructionIdUnreachable: 25045 case IrInstructionIdSetCold: 25046 case IrInstructionIdSetRuntimeSafety: 25047 case IrInstructionIdSetFloatMode: 25048 case IrInstructionIdImport: 25049 case IrInstructionIdCompileErr: 25050 case IrInstructionIdCompileLog: 25051 case IrInstructionIdCImport: 25052 case IrInstructionIdCInclude: 25053 case IrInstructionIdCDefine: 25054 case IrInstructionIdCUndef: 25055 case IrInstructionIdFence: 25056 case IrInstructionIdMemset: 25057 case IrInstructionIdMemcpy: 25058 case IrInstructionIdBreakpoint: 25059 case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free 25060 case IrInstructionIdCheckSwitchProngs: 25061 case IrInstructionIdCheckStatementIsVoid: 25062 case IrInstructionIdCheckRuntimeScope: 25063 case IrInstructionIdPanic: 25064 case IrInstructionIdSetEvalBranchQuota: 25065 case IrInstructionIdPtrType: 25066 case IrInstructionIdSetAlignStack: 25067 case IrInstructionIdExport: 25068 case IrInstructionIdSaveErrRetAddr: 25069 case IrInstructionIdAddImplicitReturnType: 25070 case IrInstructionIdAtomicRmw: 25071 case IrInstructionIdCmpxchgGen: 25072 case IrInstructionIdCmpxchgSrc: 25073 case IrInstructionIdAssertZero: 25074 case IrInstructionIdAssertNonNull: 25075 case IrInstructionIdResizeSlice: 25076 case IrInstructionIdGlobalAsm: 25077 case IrInstructionIdUndeclaredIdent: 25078 case IrInstructionIdEndExpr: 25079 case IrInstructionIdPtrOfArrayToSlice: 25080 case IrInstructionIdSliceGen: 25081 case IrInstructionIdOptionalWrap: 25082 case IrInstructionIdVectorToArray: 25083 case IrInstructionIdResetResult: 25084 case IrInstructionIdSuspendBegin: 25085 case IrInstructionIdSuspendFinish: 25086 case IrInstructionIdResume: 25087 case IrInstructionIdAwaitSrc: 25088 case IrInstructionIdAwaitGen: 25089 case IrInstructionIdSpillBegin: 25090 return true; 25091 25092 case IrInstructionIdPhi: 25093 case IrInstructionIdUnOp: 25094 case IrInstructionIdBinOp: 25095 case IrInstructionIdLoadPtr: 25096 case IrInstructionIdConst: 25097 case IrInstructionIdCast: 25098 case IrInstructionIdContainerInitList: 25099 case IrInstructionIdContainerInitFields: 25100 case IrInstructionIdUnionInitNamedField: 25101 case IrInstructionIdFieldPtr: 25102 case IrInstructionIdElemPtr: 25103 case IrInstructionIdVarPtr: 25104 case IrInstructionIdReturnPtr: 25105 case IrInstructionIdTypeOf: 25106 case IrInstructionIdStructFieldPtr: 25107 case IrInstructionIdArrayType: 25108 case IrInstructionIdSliceType: 25109 case IrInstructionIdAnyFrameType: 25110 case IrInstructionIdSizeOf: 25111 case IrInstructionIdTestNonNull: 25112 case IrInstructionIdOptionalUnwrapPtr: 25113 case IrInstructionIdClz: 25114 case IrInstructionIdCtz: 25115 case IrInstructionIdPopCount: 25116 case IrInstructionIdBswap: 25117 case IrInstructionIdBitReverse: 25118 case IrInstructionIdSwitchVar: 25119 case IrInstructionIdSwitchElseVar: 25120 case IrInstructionIdSwitchTarget: 25121 case IrInstructionIdUnionTag: 25122 case IrInstructionIdRef: 25123 case IrInstructionIdEmbedFile: 25124 case IrInstructionIdTruncate: 25125 case IrInstructionIdIntType: 25126 case IrInstructionIdVectorType: 25127 case IrInstructionIdBoolNot: 25128 case IrInstructionIdSliceSrc: 25129 case IrInstructionIdMemberCount: 25130 case IrInstructionIdMemberType: 25131 case IrInstructionIdMemberName: 25132 case IrInstructionIdAlignOf: 25133 case IrInstructionIdReturnAddress: 25134 case IrInstructionIdFrameAddress: 25135 case IrInstructionIdFrameHandle: 25136 case IrInstructionIdFrameType: 25137 case IrInstructionIdFrameSizeSrc: 25138 case IrInstructionIdFrameSizeGen: 25139 case IrInstructionIdTestErrSrc: 25140 case IrInstructionIdTestErrGen: 25141 case IrInstructionIdFnProto: 25142 case IrInstructionIdTestComptime: 25143 case IrInstructionIdPtrCastSrc: 25144 case IrInstructionIdPtrCastGen: 25145 case IrInstructionIdBitCastSrc: 25146 case IrInstructionIdBitCastGen: 25147 case IrInstructionIdWidenOrShorten: 25148 case IrInstructionIdPtrToInt: 25149 case IrInstructionIdIntToPtr: 25150 case IrInstructionIdIntToEnum: 25151 case IrInstructionIdIntToErr: 25152 case IrInstructionIdErrToInt: 25153 case IrInstructionIdDeclRef: 25154 case IrInstructionIdErrName: 25155 case IrInstructionIdTypeName: 25156 case IrInstructionIdTagName: 25157 case IrInstructionIdFieldParentPtr: 25158 case IrInstructionIdByteOffsetOf: 25159 case IrInstructionIdBitOffsetOf: 25160 case IrInstructionIdTypeInfo: 25161 case IrInstructionIdHasField: 25162 case IrInstructionIdTypeId: 25163 case IrInstructionIdAlignCast: 25164 case IrInstructionIdImplicitCast: 25165 case IrInstructionIdResolveResult: 25166 case IrInstructionIdOpaqueType: 25167 case IrInstructionIdArgType: 25168 case IrInstructionIdTagType: 25169 case IrInstructionIdErrorReturnTrace: 25170 case IrInstructionIdErrorUnion: 25171 case IrInstructionIdFloatOp: 25172 case IrInstructionIdMulAdd: 25173 case IrInstructionIdAtomicLoad: 25174 case IrInstructionIdIntCast: 25175 case IrInstructionIdFloatCast: 25176 case IrInstructionIdErrSetCast: 25177 case IrInstructionIdIntToFloat: 25178 case IrInstructionIdFloatToInt: 25179 case IrInstructionIdBoolToInt: 25180 case IrInstructionIdFromBytes: 25181 case IrInstructionIdToBytes: 25182 case IrInstructionIdEnumToInt: 25183 case IrInstructionIdArrayToVector: 25184 case IrInstructionIdHasDecl: 25185 case IrInstructionIdAllocaSrc: 25186 case IrInstructionIdAllocaGen: 25187 case IrInstructionIdSpillEnd: 25188 return false; 25189 25190 case IrInstructionIdAsm: 25191 { 25192 IrInstructionAsm *asm_instruction = (IrInstructionAsm *)instruction; 25193 return asm_instruction->has_side_effects; 25194 } 25195 case IrInstructionIdUnwrapErrPayload: 25196 { 25197 IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = 25198 (IrInstructionUnwrapErrPayload *)instruction; 25199 return unwrap_err_payload_instruction->safety_check_on || 25200 unwrap_err_payload_instruction->initializing; 25201 } 25202 case IrInstructionIdUnwrapErrCode: 25203 return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing; 25204 case IrInstructionIdUnionFieldPtr: 25205 return reinterpret_cast<IrInstructionUnionFieldPtr *>(instruction)->initializing; 25206 case IrInstructionIdErrWrapPayload: 25207 return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr; 25208 case IrInstructionIdErrWrapCode: 25209 return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr; 25210 case IrInstructionIdLoadPtrGen: 25211 return reinterpret_cast<IrInstructionLoadPtrGen *>(instruction)->result_loc != nullptr; 25212 case IrInstructionIdRefGen: 25213 return reinterpret_cast<IrInstructionRefGen *>(instruction)->result_loc != nullptr; 25214 } 25215 zig_unreachable(); 25216 }