blob 4cedaf95 (1292259B) - 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<ZigValue *> 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 // For the purpose of using in a debugger 46 void dump(); 47 }; 48 49 enum ConstCastResultId { 50 ConstCastResultIdOk, 51 ConstCastResultIdInvalid, 52 ConstCastResultIdErrSet, 53 ConstCastResultIdErrSetGlobal, 54 ConstCastResultIdPointerChild, 55 ConstCastResultIdSliceChild, 56 ConstCastResultIdOptionalChild, 57 ConstCastResultIdErrorUnionPayload, 58 ConstCastResultIdErrorUnionErrorSet, 59 ConstCastResultIdFnAlign, 60 ConstCastResultIdFnCC, 61 ConstCastResultIdFnVarArgs, 62 ConstCastResultIdFnIsGeneric, 63 ConstCastResultIdFnReturnType, 64 ConstCastResultIdFnArgCount, 65 ConstCastResultIdFnGenericArgCount, 66 ConstCastResultIdFnArg, 67 ConstCastResultIdFnArgNoAlias, 68 ConstCastResultIdType, 69 ConstCastResultIdUnresolvedInferredErrSet, 70 ConstCastResultIdAsyncAllocatorType, 71 ConstCastResultIdBadAllowsZero, 72 ConstCastResultIdArrayChild, 73 ConstCastResultIdSentinelArrays, 74 ConstCastResultIdPtrLens, 75 ConstCastResultIdCV, 76 ConstCastResultIdPtrSentinel, 77 }; 78 79 struct ConstCastOnly; 80 struct ConstCastArg { 81 size_t arg_index; 82 ZigType *actual_param_type; 83 ZigType *expected_param_type; 84 ConstCastOnly *child; 85 }; 86 87 struct ConstCastArgNoAlias { 88 size_t arg_index; 89 }; 90 91 struct ConstCastOptionalMismatch; 92 struct ConstCastPointerMismatch; 93 struct ConstCastSliceMismatch; 94 struct ConstCastErrUnionErrSetMismatch; 95 struct ConstCastErrUnionPayloadMismatch; 96 struct ConstCastErrSetMismatch; 97 struct ConstCastTypeMismatch; 98 struct ConstCastArrayMismatch; 99 struct ConstCastBadAllowsZero; 100 struct ConstCastBadNullTermArrays; 101 struct ConstCastBadCV; 102 struct ConstCastPtrSentinel; 103 104 struct ConstCastOnly { 105 ConstCastResultId id; 106 union { 107 ConstCastErrSetMismatch *error_set_mismatch; 108 ConstCastPointerMismatch *pointer_mismatch; 109 ConstCastSliceMismatch *slice_mismatch; 110 ConstCastOptionalMismatch *optional; 111 ConstCastErrUnionPayloadMismatch *error_union_payload; 112 ConstCastErrUnionErrSetMismatch *error_union_error_set; 113 ConstCastTypeMismatch *type_mismatch; 114 ConstCastArrayMismatch *array_mismatch; 115 ConstCastOnly *return_type; 116 ConstCastOnly *null_wrap_ptr_child; 117 ConstCastArg fn_arg; 118 ConstCastArgNoAlias arg_no_alias; 119 ConstCastBadAllowsZero *bad_allows_zero; 120 ConstCastBadNullTermArrays *sentinel_arrays; 121 ConstCastBadCV *bad_cv; 122 ConstCastPtrSentinel *bad_ptr_sentinel; 123 } data; 124 }; 125 126 struct ConstCastTypeMismatch { 127 ZigType *wanted_type; 128 ZigType *actual_type; 129 }; 130 131 struct ConstCastOptionalMismatch { 132 ConstCastOnly child; 133 ZigType *wanted_child; 134 ZigType *actual_child; 135 }; 136 137 struct ConstCastPointerMismatch { 138 ConstCastOnly child; 139 ZigType *wanted_child; 140 ZigType *actual_child; 141 }; 142 143 struct ConstCastSliceMismatch { 144 ConstCastOnly child; 145 ZigType *wanted_child; 146 ZigType *actual_child; 147 }; 148 149 struct ConstCastArrayMismatch { 150 ConstCastOnly child; 151 ZigType *wanted_child; 152 ZigType *actual_child; 153 }; 154 155 struct ConstCastErrUnionErrSetMismatch { 156 ConstCastOnly child; 157 ZigType *wanted_err_set; 158 ZigType *actual_err_set; 159 }; 160 161 struct ConstCastErrUnionPayloadMismatch { 162 ConstCastOnly child; 163 ZigType *wanted_payload; 164 ZigType *actual_payload; 165 }; 166 167 struct ConstCastErrSetMismatch { 168 ZigList<ErrorTableEntry *> missing_errors; 169 }; 170 171 struct ConstCastBadAllowsZero { 172 ZigType *wanted_type; 173 ZigType *actual_type; 174 }; 175 176 struct ConstCastBadNullTermArrays { 177 ConstCastOnly child; 178 ZigType *wanted_type; 179 ZigType *actual_type; 180 }; 181 182 struct ConstCastBadCV { 183 ZigType *wanted_type; 184 ZigType *actual_type; 185 }; 186 187 struct ConstCastPtrSentinel { 188 ZigType *wanted_type; 189 ZigType *actual_type; 190 }; 191 192 static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); 193 static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, 194 ResultLoc *result_loc); 195 static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type); 196 static IrInstruction *ir_implicit_cast2(IrAnalyze *ira, IrInstruction *value_source_instr, 197 IrInstruction *value, ZigType *expected_type); 198 static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, 199 ResultLoc *result_loc); 200 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg); 201 static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 202 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing); 203 static void ir_assert(bool ok, IrInstruction *source_instruction); 204 static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var); 205 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); 206 static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval, ResultLoc *result_loc); 207 static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc); 208 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); 209 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); 210 static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ZigValue *val); 211 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val); 212 static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 213 ZigValue *out_val, ZigValue *ptr_val); 214 static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, 215 ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on); 216 static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); 217 static void copy_const_val(ZigValue *dest, ZigValue *src, bool same_global_refs); 218 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); 219 static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 220 ZigType *ptr_type); 221 static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 222 ZigType *dest_type); 223 static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, 224 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, 225 bool non_null_comptime, bool allow_discard); 226 static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, 227 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, 228 bool non_null_comptime, bool allow_discard); 229 static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, 230 IrInstruction *base_ptr, bool safety_check_on, bool initializing); 231 static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, 232 IrInstruction *base_ptr, bool safety_check_on, bool initializing); 233 static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, 234 IrInstruction *base_ptr, bool initializing); 235 static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, 236 IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const); 237 static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, 238 IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, 239 LVal lval, ResultLoc *parent_result_loc); 240 static void ir_reset_result(ResultLoc *result_loc); 241 static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, 242 Scope *scope, AstNode *source_node, Buf *out_bare_name); 243 static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type, 244 ResultLoc *parent_result_loc); 245 static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, 246 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing); 247 static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, 248 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type); 249 static ResultLoc *no_result_loc(void); 250 251 static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) { 252 assert(get_src_ptr_type(const_val->type) != nullptr); 253 assert(const_val->special == ConstValSpecialStatic); 254 ZigValue *result; 255 256 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { 257 case OnePossibleValueInvalid: 258 zig_unreachable(); 259 case OnePossibleValueYes: 260 return get_the_one_possible_value(g, const_val->type->data.pointer.child_type); 261 case OnePossibleValueNo: 262 break; 263 } 264 265 switch (const_val->data.x_ptr.special) { 266 case ConstPtrSpecialInvalid: 267 zig_unreachable(); 268 case ConstPtrSpecialRef: 269 result = const_val->data.x_ptr.data.ref.pointee; 270 break; 271 case ConstPtrSpecialBaseArray: { 272 ZigValue *array_val = const_val->data.x_ptr.data.base_array.array_val; 273 if (const_val->data.x_ptr.data.base_array.elem_index == array_val->type->data.array.len) { 274 result = array_val->type->data.array.sentinel; 275 } else { 276 expand_undef_array(g, array_val); 277 result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index]; 278 } 279 break; 280 } 281 case ConstPtrSpecialBaseStruct: { 282 ZigValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val; 283 expand_undef_struct(g, struct_val); 284 result = struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; 285 break; 286 } 287 case ConstPtrSpecialBaseErrorUnionCode: 288 result = const_val->data.x_ptr.data.base_err_union_code.err_union_val->data.x_err_union.error_set; 289 break; 290 case ConstPtrSpecialBaseErrorUnionPayload: 291 result = const_val->data.x_ptr.data.base_err_union_payload.err_union_val->data.x_err_union.payload; 292 break; 293 case ConstPtrSpecialBaseOptionalPayload: 294 result = const_val->data.x_ptr.data.base_optional_payload.optional_val->data.x_optional; 295 break; 296 case ConstPtrSpecialNull: 297 result = const_val; 298 break; 299 case ConstPtrSpecialHardCodedAddr: 300 zig_unreachable(); 301 case ConstPtrSpecialDiscard: 302 zig_unreachable(); 303 case ConstPtrSpecialFunction: 304 zig_unreachable(); 305 } 306 assert(result != nullptr); 307 return result; 308 } 309 310 static bool is_opt_err_set(ZigType *ty) { 311 return ty->id == ZigTypeIdErrorSet || 312 (ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet); 313 } 314 315 static bool is_slice(ZigType *type) { 316 return type->id == ZigTypeIdStruct && type->data.structure.is_slice; 317 } 318 319 static bool slice_is_const(ZigType *type) { 320 assert(is_slice(type)); 321 return type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const; 322 } 323 324 // This function returns true when you can change the type of a ZigValue and the 325 // value remains meaningful. 326 static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expected, ZigType *actual) { 327 if (expected == actual) 328 return true; 329 330 if (get_codegen_ptr_type(expected) != nullptr && get_codegen_ptr_type(actual) != nullptr) 331 return true; 332 333 if (is_opt_err_set(expected) && is_opt_err_set(actual)) 334 return true; 335 336 if (expected->id != actual->id) 337 return false; 338 339 switch (expected->id) { 340 case ZigTypeIdInvalid: 341 case ZigTypeIdUnreachable: 342 zig_unreachable(); 343 case ZigTypeIdMetaType: 344 case ZigTypeIdVoid: 345 case ZigTypeIdBool: 346 case ZigTypeIdComptimeFloat: 347 case ZigTypeIdComptimeInt: 348 case ZigTypeIdEnumLiteral: 349 case ZigTypeIdPointer: 350 case ZigTypeIdUndefined: 351 case ZigTypeIdNull: 352 case ZigTypeIdBoundFn: 353 case ZigTypeIdErrorSet: 354 case ZigTypeIdOpaque: 355 case ZigTypeIdAnyFrame: 356 case ZigTypeIdFn: 357 return true; 358 case ZigTypeIdFloat: 359 return expected->data.floating.bit_count == actual->data.floating.bit_count; 360 case ZigTypeIdInt: 361 return expected->data.integral.is_signed == actual->data.integral.is_signed; 362 case ZigTypeIdStruct: 363 return is_slice(expected) && is_slice(actual); 364 case ZigTypeIdOptional: 365 case ZigTypeIdErrorUnion: 366 case ZigTypeIdEnum: 367 case ZigTypeIdUnion: 368 case ZigTypeIdArgTuple: 369 case ZigTypeIdVector: 370 case ZigTypeIdFnFrame: 371 return false; 372 case ZigTypeIdArray: 373 return expected->data.array.len == actual->data.array.len && 374 expected->data.array.child_type == actual->data.array.child_type && 375 (expected->data.array.sentinel == nullptr || (actual->data.array.sentinel != nullptr && 376 const_values_equal(codegen, expected->data.array.sentinel, actual->data.array.sentinel))); 377 } 378 zig_unreachable(); 379 } 380 381 static bool ir_should_inline(IrExecutable *exec, Scope *scope) { 382 if (exec->is_inline) 383 return true; 384 385 while (scope != nullptr) { 386 if (scope->id == ScopeIdCompTime) 387 return true; 388 if (scope->id == ScopeIdTypeOf) 389 return false; 390 if (scope->id == ScopeIdFnDef) 391 break; 392 scope = scope->parent; 393 } 394 return false; 395 } 396 397 static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) { 398 assert(basic_block); 399 assert(instruction); 400 basic_block->instruction_list.append(instruction); 401 } 402 403 static size_t exec_next_debug_id(IrExecutable *exec) { 404 size_t result = exec->next_debug_id; 405 exec->next_debug_id += 1; 406 return result; 407 } 408 409 static size_t exec_next_mem_slot(IrExecutable *exec) { 410 size_t result = exec->mem_slot_count; 411 exec->mem_slot_count += 1; 412 return result; 413 } 414 415 static ZigFn *exec_fn_entry(IrExecutable *exec) { 416 return exec->fn_entry; 417 } 418 419 static Buf *exec_c_import_buf(IrExecutable *exec) { 420 return exec->c_import_buf; 421 } 422 423 static bool value_is_comptime(ZigValue *const_val) { 424 return const_val->special != ConstValSpecialRuntime; 425 } 426 427 static bool instr_is_comptime(IrInstruction *instruction) { 428 return value_is_comptime(instruction->value); 429 } 430 431 static bool instr_is_unreachable(IrInstruction *instruction) { 432 return instruction->value->type && instruction->value->type->id == ZigTypeIdUnreachable; 433 } 434 435 static void ir_link_new_bb(IrBasicBlock *new_bb, IrBasicBlock *old_bb) { 436 new_bb->other = old_bb; 437 old_bb->other = new_bb; 438 } 439 440 static void ir_ref_bb(IrBasicBlock *bb) { 441 bb->ref_count += 1; 442 } 443 444 static void ir_ref_instruction(IrInstruction *instruction, IrBasicBlock *cur_bb) { 445 assert(instruction->id != IrInstructionIdInvalid); 446 instruction->ref_count += 1; 447 if (instruction->owner_bb != cur_bb && !instr_is_comptime(instruction)) 448 ir_ref_bb(instruction->owner_bb); 449 } 450 451 static void ir_ref_var(ZigVar *var) { 452 var->ref_count += 1; 453 } 454 455 ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { 456 ZigValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type, 457 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr, 458 node, nullptr, ira->new_irb.exec, nullptr, UndefBad); 459 460 if (type_is_invalid(result->type)) 461 return ira->codegen->builtin_types.entry_invalid; 462 463 assert(result->special != ConstValSpecialRuntime); 464 return result->data.x_type; 465 } 466 467 static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const char *name_hint) { 468 IrBasicBlock *result = allocate<IrBasicBlock>(1, "IrBasicBlock"); 469 result->scope = scope; 470 result->name_hint = name_hint; 471 result->debug_id = exec_next_debug_id(irb->exec); 472 result->index = SIZE_MAX; // set later 473 return result; 474 } 475 476 static IrBasicBlock *ir_build_bb_from(IrBuilder *irb, IrBasicBlock *other_bb) { 477 IrBasicBlock *new_bb = ir_create_basic_block(irb, other_bb->scope, other_bb->name_hint); 478 ir_link_new_bb(new_bb, other_bb); 479 return new_bb; 480 } 481 482 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVarSrc *) { 483 return IrInstructionIdDeclVarSrc; 484 } 485 486 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVarGen *) { 487 return IrInstructionIdDeclVarGen; 488 } 489 490 static constexpr IrInstructionId ir_instruction_id(IrInstructionCondBr *) { 491 return IrInstructionIdCondBr; 492 } 493 494 static constexpr IrInstructionId ir_instruction_id(IrInstructionBr *) { 495 return IrInstructionIdBr; 496 } 497 498 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchBr *) { 499 return IrInstructionIdSwitchBr; 500 } 501 502 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchVar *) { 503 return IrInstructionIdSwitchVar; 504 } 505 506 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchElseVar *) { 507 return IrInstructionIdSwitchElseVar; 508 } 509 510 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchTarget *) { 511 return IrInstructionIdSwitchTarget; 512 } 513 514 static constexpr IrInstructionId ir_instruction_id(IrInstructionPhi *) { 515 return IrInstructionIdPhi; 516 } 517 518 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnOp *) { 519 return IrInstructionIdUnOp; 520 } 521 522 static constexpr IrInstructionId ir_instruction_id(IrInstructionBinOp *) { 523 return IrInstructionIdBinOp; 524 } 525 526 static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrSets *) { 527 return IrInstructionIdMergeErrSets; 528 } 529 530 static constexpr IrInstructionId ir_instruction_id(IrInstructionExport *) { 531 return IrInstructionIdExport; 532 } 533 534 static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) { 535 return IrInstructionIdLoadPtr; 536 } 537 538 static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtrGen *) { 539 return IrInstructionIdLoadPtrGen; 540 } 541 542 static constexpr IrInstructionId ir_instruction_id(IrInstructionStorePtr *) { 543 return IrInstructionIdStorePtr; 544 } 545 546 static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorStoreElem *) { 547 return IrInstructionIdVectorStoreElem; 548 } 549 550 static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldPtr *) { 551 return IrInstructionIdFieldPtr; 552 } 553 554 static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *) { 555 return IrInstructionIdStructFieldPtr; 556 } 557 558 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionFieldPtr *) { 559 return IrInstructionIdUnionFieldPtr; 560 } 561 562 static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) { 563 return IrInstructionIdElemPtr; 564 } 565 566 static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) { 567 return IrInstructionIdVarPtr; 568 } 569 570 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnPtr *) { 571 return IrInstructionIdReturnPtr; 572 } 573 574 static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrc *) { 575 return IrInstructionIdCallSrc; 576 } 577 578 static constexpr IrInstructionId ir_instruction_id(IrInstructionCallGen *) { 579 return IrInstructionIdCallGen; 580 } 581 582 static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) { 583 return IrInstructionIdConst; 584 } 585 586 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturn *) { 587 return IrInstructionIdReturn; 588 } 589 590 static constexpr IrInstructionId ir_instruction_id(IrInstructionCast *) { 591 return IrInstructionIdCast; 592 } 593 594 static constexpr IrInstructionId ir_instruction_id(IrInstructionResizeSlice *) { 595 return IrInstructionIdResizeSlice; 596 } 597 598 static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitList *) { 599 return IrInstructionIdContainerInitList; 600 } 601 602 static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitFields *) { 603 return IrInstructionIdContainerInitFields; 604 } 605 606 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnreachable *) { 607 return IrInstructionIdUnreachable; 608 } 609 610 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) { 611 return IrInstructionIdTypeOf; 612 } 613 614 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) { 615 return IrInstructionIdSetCold; 616 } 617 618 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetRuntimeSafety *) { 619 return IrInstructionIdSetRuntimeSafety; 620 } 621 622 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFloatMode *) { 623 return IrInstructionIdSetFloatMode; 624 } 625 626 static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) { 627 return IrInstructionIdArrayType; 628 } 629 630 static constexpr IrInstructionId ir_instruction_id(IrInstructionAnyFrameType *) { 631 return IrInstructionIdAnyFrameType; 632 } 633 634 static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { 635 return IrInstructionIdSliceType; 636 } 637 638 static constexpr IrInstructionId ir_instruction_id(IrInstructionGlobalAsm *) { 639 return IrInstructionIdGlobalAsm; 640 } 641 642 static constexpr IrInstructionId ir_instruction_id(IrInstructionAsm *) { 643 return IrInstructionIdAsm; 644 } 645 646 static constexpr IrInstructionId ir_instruction_id(IrInstructionSizeOf *) { 647 return IrInstructionIdSizeOf; 648 } 649 650 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestNonNull *) { 651 return IrInstructionIdTestNonNull; 652 } 653 654 static constexpr IrInstructionId ir_instruction_id(IrInstructionOptionalUnwrapPtr *) { 655 return IrInstructionIdOptionalUnwrapPtr; 656 } 657 658 static constexpr IrInstructionId ir_instruction_id(IrInstructionClz *) { 659 return IrInstructionIdClz; 660 } 661 662 static constexpr IrInstructionId ir_instruction_id(IrInstructionCtz *) { 663 return IrInstructionIdCtz; 664 } 665 666 static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) { 667 return IrInstructionIdPopCount; 668 } 669 670 static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) { 671 return IrInstructionIdBswap; 672 } 673 674 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) { 675 return IrInstructionIdBitReverse; 676 } 677 678 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) { 679 return IrInstructionIdUnionTag; 680 } 681 682 static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) { 683 return IrInstructionIdImport; 684 } 685 686 static constexpr IrInstructionId ir_instruction_id(IrInstructionCImport *) { 687 return IrInstructionIdCImport; 688 } 689 690 static constexpr IrInstructionId ir_instruction_id(IrInstructionCInclude *) { 691 return IrInstructionIdCInclude; 692 } 693 694 static constexpr IrInstructionId ir_instruction_id(IrInstructionCDefine *) { 695 return IrInstructionIdCDefine; 696 } 697 698 static constexpr IrInstructionId ir_instruction_id(IrInstructionCUndef *) { 699 return IrInstructionIdCUndef; 700 } 701 702 static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) { 703 return IrInstructionIdRef; 704 } 705 706 static constexpr IrInstructionId ir_instruction_id(IrInstructionRefGen *) { 707 return IrInstructionIdRefGen; 708 } 709 710 static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { 711 return IrInstructionIdCompileErr; 712 } 713 714 static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileLog *) { 715 return IrInstructionIdCompileLog; 716 } 717 718 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrName *) { 719 return IrInstructionIdErrName; 720 } 721 722 static constexpr IrInstructionId ir_instruction_id(IrInstructionEmbedFile *) { 723 return IrInstructionIdEmbedFile; 724 } 725 726 static constexpr IrInstructionId ir_instruction_id(IrInstructionCmpxchgSrc *) { 727 return IrInstructionIdCmpxchgSrc; 728 } 729 730 static constexpr IrInstructionId ir_instruction_id(IrInstructionCmpxchgGen *) { 731 return IrInstructionIdCmpxchgGen; 732 } 733 734 static constexpr IrInstructionId ir_instruction_id(IrInstructionFence *) { 735 return IrInstructionIdFence; 736 } 737 738 static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) { 739 return IrInstructionIdTruncate; 740 } 741 742 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntCast *) { 743 return IrInstructionIdIntCast; 744 } 745 746 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) { 747 return IrInstructionIdFloatCast; 748 } 749 750 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrSetCast *) { 751 return IrInstructionIdErrSetCast; 752 } 753 754 static constexpr IrInstructionId ir_instruction_id(IrInstructionToBytes *) { 755 return IrInstructionIdToBytes; 756 } 757 758 static constexpr IrInstructionId ir_instruction_id(IrInstructionFromBytes *) { 759 return IrInstructionIdFromBytes; 760 } 761 762 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) { 763 return IrInstructionIdIntToFloat; 764 } 765 766 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) { 767 return IrInstructionIdFloatToInt; 768 } 769 770 static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) { 771 return IrInstructionIdBoolToInt; 772 } 773 774 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { 775 return IrInstructionIdIntType; 776 } 777 778 static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorType *) { 779 return IrInstructionIdVectorType; 780 } 781 782 static constexpr IrInstructionId ir_instruction_id(IrInstructionShuffleVector *) { 783 return IrInstructionIdShuffleVector; 784 } 785 786 static constexpr IrInstructionId ir_instruction_id(IrInstructionSplatSrc *) { 787 return IrInstructionIdSplatSrc; 788 } 789 790 static constexpr IrInstructionId ir_instruction_id(IrInstructionSplatGen *) { 791 return IrInstructionIdSplatGen; 792 } 793 794 static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { 795 return IrInstructionIdBoolNot; 796 } 797 798 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemset *) { 799 return IrInstructionIdMemset; 800 } 801 802 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) { 803 return IrInstructionIdMemcpy; 804 } 805 806 static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceSrc *) { 807 return IrInstructionIdSliceSrc; 808 } 809 810 static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceGen *) { 811 return IrInstructionIdSliceGen; 812 } 813 814 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) { 815 return IrInstructionIdMemberCount; 816 } 817 818 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberType *) { 819 return IrInstructionIdMemberType; 820 } 821 822 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberName *) { 823 return IrInstructionIdMemberName; 824 } 825 826 static constexpr IrInstructionId ir_instruction_id(IrInstructionBreakpoint *) { 827 return IrInstructionIdBreakpoint; 828 } 829 830 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnAddress *) { 831 return IrInstructionIdReturnAddress; 832 } 833 834 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *) { 835 return IrInstructionIdFrameAddress; 836 } 837 838 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameHandle *) { 839 return IrInstructionIdFrameHandle; 840 } 841 842 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameType *) { 843 return IrInstructionIdFrameType; 844 } 845 846 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameSizeSrc *) { 847 return IrInstructionIdFrameSizeSrc; 848 } 849 850 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameSizeGen *) { 851 return IrInstructionIdFrameSizeGen; 852 } 853 854 static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignOf *) { 855 return IrInstructionIdAlignOf; 856 } 857 858 static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { 859 return IrInstructionIdOverflowOp; 860 } 861 862 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrSrc *) { 863 return IrInstructionIdTestErrSrc; 864 } 865 866 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrGen *) { 867 return IrInstructionIdTestErrGen; 868 } 869 870 static constexpr IrInstructionId ir_instruction_id(IrInstructionMulAdd *) { 871 return IrInstructionIdMulAdd; 872 } 873 874 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrCode *) { 875 return IrInstructionIdUnwrapErrCode; 876 } 877 878 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrPayload *) { 879 return IrInstructionIdUnwrapErrPayload; 880 } 881 882 static constexpr IrInstructionId ir_instruction_id(IrInstructionOptionalWrap *) { 883 return IrInstructionIdOptionalWrap; 884 } 885 886 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapPayload *) { 887 return IrInstructionIdErrWrapPayload; 888 } 889 890 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapCode *) { 891 return IrInstructionIdErrWrapCode; 892 } 893 894 static constexpr IrInstructionId ir_instruction_id(IrInstructionFnProto *) { 895 return IrInstructionIdFnProto; 896 } 897 898 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestComptime *) { 899 return IrInstructionIdTestComptime; 900 } 901 902 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastSrc *) { 903 return IrInstructionIdPtrCastSrc; 904 } 905 906 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) { 907 return IrInstructionIdPtrCastGen; 908 } 909 910 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastSrc *) { 911 return IrInstructionIdBitCastSrc; 912 } 913 914 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) { 915 return IrInstructionIdBitCastGen; 916 } 917 918 static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) { 919 return IrInstructionIdWidenOrShorten; 920 } 921 922 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrToInt *) { 923 return IrInstructionIdPtrToInt; 924 } 925 926 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToPtr *) { 927 return IrInstructionIdIntToPtr; 928 } 929 930 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToEnum *) { 931 return IrInstructionIdIntToEnum; 932 } 933 934 static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumToInt *) { 935 return IrInstructionIdEnumToInt; 936 } 937 938 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToErr *) { 939 return IrInstructionIdIntToErr; 940 } 941 942 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrToInt *) { 943 return IrInstructionIdErrToInt; 944 } 945 946 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckSwitchProngs *) { 947 return IrInstructionIdCheckSwitchProngs; 948 } 949 950 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckStatementIsVoid *) { 951 return IrInstructionIdCheckStatementIsVoid; 952 } 953 954 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeName *) { 955 return IrInstructionIdTypeName; 956 } 957 958 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) { 959 return IrInstructionIdDeclRef; 960 } 961 962 static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) { 963 return IrInstructionIdPanic; 964 } 965 966 static constexpr IrInstructionId ir_instruction_id(IrInstructionTagName *) { 967 return IrInstructionIdTagName; 968 } 969 970 static constexpr IrInstructionId ir_instruction_id(IrInstructionTagType *) { 971 return IrInstructionIdTagType; 972 } 973 974 static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) { 975 return IrInstructionIdFieldParentPtr; 976 } 977 978 static constexpr IrInstructionId ir_instruction_id(IrInstructionByteOffsetOf *) { 979 return IrInstructionIdByteOffsetOf; 980 } 981 982 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitOffsetOf *) { 983 return IrInstructionIdBitOffsetOf; 984 } 985 986 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { 987 return IrInstructionIdTypeInfo; 988 } 989 990 static constexpr IrInstructionId ir_instruction_id(IrInstructionType *) { 991 return IrInstructionIdType; 992 } 993 994 static constexpr IrInstructionId ir_instruction_id(IrInstructionHasField *) { 995 return IrInstructionIdHasField; 996 } 997 998 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { 999 return IrInstructionIdTypeId; 1000 } 1001 1002 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetEvalBranchQuota *) { 1003 return IrInstructionIdSetEvalBranchQuota; 1004 } 1005 1006 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrType *) { 1007 return IrInstructionIdPtrType; 1008 } 1009 1010 static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { 1011 return IrInstructionIdAlignCast; 1012 } 1013 1014 static constexpr IrInstructionId ir_instruction_id(IrInstructionImplicitCast *) { 1015 return IrInstructionIdImplicitCast; 1016 } 1017 1018 static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *) { 1019 return IrInstructionIdResolveResult; 1020 } 1021 1022 static constexpr IrInstructionId ir_instruction_id(IrInstructionResetResult *) { 1023 return IrInstructionIdResetResult; 1024 } 1025 1026 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrOfArrayToSlice *) { 1027 return IrInstructionIdPtrOfArrayToSlice; 1028 } 1029 1030 static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { 1031 return IrInstructionIdOpaqueType; 1032 } 1033 1034 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetAlignStack *) { 1035 return IrInstructionIdSetAlignStack; 1036 } 1037 1038 static constexpr IrInstructionId ir_instruction_id(IrInstructionArgType *) { 1039 return IrInstructionIdArgType; 1040 } 1041 1042 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorReturnTrace *) { 1043 return IrInstructionIdErrorReturnTrace; 1044 } 1045 1046 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorUnion *) { 1047 return IrInstructionIdErrorUnion; 1048 } 1049 1050 static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicRmw *) { 1051 return IrInstructionIdAtomicRmw; 1052 } 1053 1054 static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) { 1055 return IrInstructionIdAtomicLoad; 1056 } 1057 1058 static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicStore *) { 1059 return IrInstructionIdAtomicStore; 1060 } 1061 1062 static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) { 1063 return IrInstructionIdSaveErrRetAddr; 1064 } 1065 1066 static constexpr IrInstructionId ir_instruction_id(IrInstructionAddImplicitReturnType *) { 1067 return IrInstructionIdAddImplicitReturnType; 1068 } 1069 1070 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatOp *) { 1071 return IrInstructionIdFloatOp; 1072 } 1073 1074 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { 1075 return IrInstructionIdCheckRuntimeScope; 1076 } 1077 1078 static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorToArray *) { 1079 return IrInstructionIdVectorToArray; 1080 } 1081 1082 static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayToVector *) { 1083 return IrInstructionIdArrayToVector; 1084 } 1085 1086 static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertZero *) { 1087 return IrInstructionIdAssertZero; 1088 } 1089 1090 static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) { 1091 return IrInstructionIdAssertNonNull; 1092 } 1093 1094 static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) { 1095 return IrInstructionIdHasDecl; 1096 } 1097 1098 static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent *) { 1099 return IrInstructionIdUndeclaredIdent; 1100 } 1101 1102 static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaSrc *) { 1103 return IrInstructionIdAllocaSrc; 1104 } 1105 1106 static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaGen *) { 1107 return IrInstructionIdAllocaGen; 1108 } 1109 1110 static constexpr IrInstructionId ir_instruction_id(IrInstructionEndExpr *) { 1111 return IrInstructionIdEndExpr; 1112 } 1113 1114 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInitNamedField *) { 1115 return IrInstructionIdUnionInitNamedField; 1116 } 1117 1118 static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBegin *) { 1119 return IrInstructionIdSuspendBegin; 1120 } 1121 1122 static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendFinish *) { 1123 return IrInstructionIdSuspendFinish; 1124 } 1125 1126 static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitSrc *) { 1127 return IrInstructionIdAwaitSrc; 1128 } 1129 1130 static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitGen *) { 1131 return IrInstructionIdAwaitGen; 1132 } 1133 1134 static constexpr IrInstructionId ir_instruction_id(IrInstructionResume *) { 1135 return IrInstructionIdResume; 1136 } 1137 1138 static constexpr IrInstructionId ir_instruction_id(IrInstructionSpillBegin *) { 1139 return IrInstructionIdSpillBegin; 1140 } 1141 1142 static constexpr IrInstructionId ir_instruction_id(IrInstructionSpillEnd *) { 1143 return IrInstructionIdSpillEnd; 1144 } 1145 1146 static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorExtractElem *) { 1147 return IrInstructionIdVectorExtractElem; 1148 } 1149 1150 template<typename T> 1151 static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1152 const char *name = nullptr; 1153 #ifdef ZIG_ENABLE_MEM_PROFILE 1154 T *dummy = nullptr; 1155 name = ir_instruction_type_str(ir_instruction_id(dummy)); 1156 #endif 1157 T *special_instruction = allocate<T>(1, name); 1158 special_instruction->base.id = ir_instruction_id(special_instruction); 1159 special_instruction->base.scope = scope; 1160 special_instruction->base.source_node = source_node; 1161 special_instruction->base.debug_id = exec_next_debug_id(irb->exec); 1162 special_instruction->base.owner_bb = irb->current_basic_block; 1163 special_instruction->base.value = allocate<ZigValue>(1, "ZigValue"); 1164 special_instruction->base.value->global_refs = allocate<ConstGlobalRefs>(1, "ConstGlobalRefs"); 1165 return special_instruction; 1166 } 1167 1168 template<typename T> 1169 static T *ir_create_instruction_noval(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1170 const char *name = nullptr; 1171 #ifdef ZIG_ENABLE_MEM_PROFILE 1172 T *dummy = nullptr; 1173 name = ir_instruction_type_str(ir_instruction_id(dummy)); 1174 #endif 1175 T *special_instruction = allocate<T>(1, name); 1176 special_instruction->base.id = ir_instruction_id(special_instruction); 1177 special_instruction->base.scope = scope; 1178 special_instruction->base.source_node = source_node; 1179 special_instruction->base.debug_id = exec_next_debug_id(irb->exec); 1180 special_instruction->base.owner_bb = irb->current_basic_block; 1181 return special_instruction; 1182 } 1183 1184 template<typename T> 1185 static T *ir_build_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1186 T *special_instruction = ir_create_instruction<T>(irb, scope, source_node); 1187 ir_instruction_append(irb->current_basic_block, &special_instruction->base); 1188 return special_instruction; 1189 } 1190 1191 static IrInstruction *ir_build_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *dest_type, 1192 IrInstruction *value, CastOp cast_op) 1193 { 1194 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, scope, source_node); 1195 cast_instruction->dest_type = dest_type; 1196 cast_instruction->value = value; 1197 cast_instruction->cast_op = cast_op; 1198 1199 ir_ref_instruction(value, irb->current_basic_block); 1200 1201 return &cast_instruction->base; 1202 } 1203 1204 static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *condition, 1205 IrBasicBlock *then_block, IrBasicBlock *else_block, IrInstruction *is_comptime) 1206 { 1207 IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, scope, source_node); 1208 cond_br_instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; 1209 cond_br_instruction->base.value->special = ConstValSpecialStatic; 1210 cond_br_instruction->condition = condition; 1211 cond_br_instruction->then_block = then_block; 1212 cond_br_instruction->else_block = else_block; 1213 cond_br_instruction->is_comptime = is_comptime; 1214 1215 ir_ref_instruction(condition, irb->current_basic_block); 1216 ir_ref_bb(then_block); 1217 ir_ref_bb(else_block); 1218 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); 1219 1220 return &cond_br_instruction->base; 1221 } 1222 1223 static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, 1224 IrInstruction *operand) 1225 { 1226 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); 1227 return_instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; 1228 return_instruction->base.value->special = ConstValSpecialStatic; 1229 return_instruction->operand = operand; 1230 1231 if (operand != nullptr) ir_ref_instruction(operand, irb->current_basic_block); 1232 1233 return &return_instruction->base; 1234 } 1235 1236 static IrInstruction *ir_build_const_void(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1237 IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node); 1238 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 1239 const_instruction->base.value = irb->codegen->intern.for_void(); 1240 return &const_instruction->base; 1241 } 1242 1243 static IrInstruction *ir_build_const_undefined(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1244 IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node); 1245 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 1246 const_instruction->base.value = irb->codegen->intern.for_undefined(); 1247 return &const_instruction->base; 1248 } 1249 1250 static IrInstruction *ir_build_const_uint(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { 1251 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1252 const_instruction->base.value->type = irb->codegen->builtin_types.entry_num_lit_int; 1253 const_instruction->base.value->special = ConstValSpecialStatic; 1254 bigint_init_unsigned(&const_instruction->base.value->data.x_bigint, value); 1255 return &const_instruction->base; 1256 } 1257 1258 static IrInstruction *ir_build_const_bigint(IrBuilder *irb, Scope *scope, AstNode *source_node, BigInt *bigint) { 1259 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1260 const_instruction->base.value->type = irb->codegen->builtin_types.entry_num_lit_int; 1261 const_instruction->base.value->special = ConstValSpecialStatic; 1262 bigint_init_bigint(&const_instruction->base.value->data.x_bigint, bigint); 1263 return &const_instruction->base; 1264 } 1265 1266 static IrInstruction *ir_build_const_bigfloat(IrBuilder *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) { 1267 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1268 const_instruction->base.value->type = irb->codegen->builtin_types.entry_num_lit_float; 1269 const_instruction->base.value->special = ConstValSpecialStatic; 1270 bigfloat_init_bigfloat(&const_instruction->base.value->data.x_bigfloat, bigfloat); 1271 return &const_instruction->base; 1272 } 1273 1274 static IrInstruction *ir_build_const_null(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1275 IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node); 1276 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 1277 const_instruction->base.value = irb->codegen->intern.for_null(); 1278 return &const_instruction->base; 1279 } 1280 1281 static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { 1282 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1283 const_instruction->base.value->type = irb->codegen->builtin_types.entry_usize; 1284 const_instruction->base.value->special = ConstValSpecialStatic; 1285 bigint_init_unsigned(&const_instruction->base.value->data.x_bigint, value); 1286 return &const_instruction->base; 1287 } 1288 1289 static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1290 ZigType *type_entry) 1291 { 1292 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1293 const_instruction->base.value->type = irb->codegen->builtin_types.entry_type; 1294 const_instruction->base.value->special = ConstValSpecialStatic; 1295 const_instruction->base.value->data.x_type = type_entry; 1296 return &const_instruction->base; 1297 } 1298 1299 static IrInstruction *ir_build_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1300 ZigType *type_entry) 1301 { 1302 IrInstruction *instruction = ir_create_const_type(irb, scope, source_node, type_entry); 1303 ir_instruction_append(irb->current_basic_block, instruction); 1304 return instruction; 1305 } 1306 1307 static IrInstruction *ir_create_const_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigFn *fn_entry) { 1308 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1309 const_instruction->base.value->type = fn_entry->type_entry; 1310 const_instruction->base.value->special = ConstValSpecialStatic; 1311 const_instruction->base.value->data.x_ptr.data.fn.fn_entry = fn_entry; 1312 const_instruction->base.value->data.x_ptr.mut = ConstPtrMutComptimeConst; 1313 const_instruction->base.value->data.x_ptr.special = ConstPtrSpecialFunction; 1314 return &const_instruction->base; 1315 } 1316 1317 static IrInstruction *ir_build_const_import(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *import) { 1318 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1319 const_instruction->base.value->type = irb->codegen->builtin_types.entry_type; 1320 const_instruction->base.value->special = ConstValSpecialStatic; 1321 const_instruction->base.value->data.x_type = import; 1322 return &const_instruction->base; 1323 } 1324 1325 static IrInstruction *ir_build_const_bool(IrBuilder *irb, Scope *scope, AstNode *source_node, bool value) { 1326 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1327 const_instruction->base.value->type = irb->codegen->builtin_types.entry_bool; 1328 const_instruction->base.value->special = ConstValSpecialStatic; 1329 const_instruction->base.value->data.x_bool = value; 1330 return &const_instruction->base; 1331 } 1332 1333 static IrInstruction *ir_build_const_enum_literal(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *name) { 1334 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1335 const_instruction->base.value->type = irb->codegen->builtin_types.entry_enum_literal; 1336 const_instruction->base.value->special = ConstValSpecialStatic; 1337 const_instruction->base.value->data.x_enum_literal = name; 1338 return &const_instruction->base; 1339 } 1340 1341 static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, 1342 ZigFn *fn_entry, IrInstruction *first_arg) 1343 { 1344 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1345 const_instruction->base.value->type = get_bound_fn_type(irb->codegen, fn_entry); 1346 const_instruction->base.value->special = ConstValSpecialStatic; 1347 const_instruction->base.value->data.x_bound_fn.fn = fn_entry; 1348 const_instruction->base.value->data.x_bound_fn.first_arg = first_arg; 1349 return &const_instruction->base; 1350 } 1351 1352 static IrInstruction *ir_create_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1353 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1354 init_const_str_lit(irb->codegen, const_instruction->base.value, str); 1355 1356 return &const_instruction->base; 1357 } 1358 1359 static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1360 IrInstruction *instruction = ir_create_const_str_lit(irb, scope, source_node, str); 1361 ir_instruction_append(irb->current_basic_block, instruction); 1362 return instruction; 1363 } 1364 1365 static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, 1366 IrInstruction *op1, IrInstruction *op2, bool safety_check_on) 1367 { 1368 IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irb, scope, source_node); 1369 bin_op_instruction->op_id = op_id; 1370 bin_op_instruction->op1 = op1; 1371 bin_op_instruction->op2 = op2; 1372 bin_op_instruction->safety_check_on = safety_check_on; 1373 1374 ir_ref_instruction(op1, irb->current_basic_block); 1375 ir_ref_instruction(op2, irb->current_basic_block); 1376 1377 return &bin_op_instruction->base; 1378 } 1379 1380 static IrInstruction *ir_build_merge_err_sets(IrBuilder *irb, Scope *scope, AstNode *source_node, 1381 IrInstruction *op1, IrInstruction *op2, Buf *type_name) 1382 { 1383 IrInstructionMergeErrSets *merge_err_sets_instruction = ir_build_instruction<IrInstructionMergeErrSets>(irb, scope, source_node); 1384 merge_err_sets_instruction->op1 = op1; 1385 merge_err_sets_instruction->op2 = op2; 1386 merge_err_sets_instruction->type_name = type_name; 1387 1388 ir_ref_instruction(op1, irb->current_basic_block); 1389 ir_ref_instruction(op2, irb->current_basic_block); 1390 1391 return &merge_err_sets_instruction->base; 1392 } 1393 1394 static IrInstruction *ir_build_var_ptr_x(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, 1395 ScopeFnDef *crossed_fndef_scope) 1396 { 1397 IrInstructionVarPtr *instruction = ir_build_instruction<IrInstructionVarPtr>(irb, scope, source_node); 1398 instruction->var = var; 1399 instruction->crossed_fndef_scope = crossed_fndef_scope; 1400 1401 ir_ref_var(var); 1402 1403 return &instruction->base; 1404 } 1405 1406 static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var) { 1407 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); 1408 } 1409 1410 static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { 1411 IrInstructionReturnPtr *instruction = ir_build_instruction<IrInstructionReturnPtr>(&ira->new_irb, 1412 source_instruction->scope, source_instruction->source_node); 1413 instruction->base.value->type = ty; 1414 return &instruction->base; 1415 } 1416 1417 static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1418 IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len, 1419 AstNode *init_array_type_source_node) 1420 { 1421 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); 1422 instruction->array_ptr = array_ptr; 1423 instruction->elem_index = elem_index; 1424 instruction->safety_check_on = safety_check_on; 1425 instruction->ptr_len = ptr_len; 1426 instruction->init_array_type_source_node = init_array_type_source_node; 1427 1428 ir_ref_instruction(array_ptr, irb->current_basic_block); 1429 ir_ref_instruction(elem_index, irb->current_basic_block); 1430 1431 return &instruction->base; 1432 } 1433 1434 static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node, 1435 IrInstruction *container_ptr, IrInstruction *field_name_expr, bool initializing) 1436 { 1437 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); 1438 instruction->container_ptr = container_ptr; 1439 instruction->field_name_buffer = nullptr; 1440 instruction->field_name_expr = field_name_expr; 1441 instruction->initializing = initializing; 1442 1443 ir_ref_instruction(container_ptr, irb->current_basic_block); 1444 ir_ref_instruction(field_name_expr, irb->current_basic_block); 1445 1446 return &instruction->base; 1447 } 1448 1449 static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1450 IrInstruction *container_ptr, Buf *field_name, bool initializing) 1451 { 1452 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); 1453 instruction->container_ptr = container_ptr; 1454 instruction->field_name_buffer = field_name; 1455 instruction->field_name_expr = nullptr; 1456 instruction->initializing = initializing; 1457 1458 ir_ref_instruction(container_ptr, irb->current_basic_block); 1459 1460 return &instruction->base; 1461 } 1462 1463 static IrInstruction *ir_build_has_field(IrBuilder *irb, Scope *scope, AstNode *source_node, 1464 IrInstruction *container_type, IrInstruction *field_name) 1465 { 1466 IrInstructionHasField *instruction = ir_build_instruction<IrInstructionHasField>(irb, scope, source_node); 1467 instruction->container_type = container_type; 1468 instruction->field_name = field_name; 1469 1470 ir_ref_instruction(container_type, irb->current_basic_block); 1471 ir_ref_instruction(field_name, irb->current_basic_block); 1472 1473 return &instruction->base; 1474 } 1475 1476 static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1477 IrInstruction *struct_ptr, TypeStructField *field) 1478 { 1479 IrInstructionStructFieldPtr *instruction = ir_build_instruction<IrInstructionStructFieldPtr>(irb, scope, source_node); 1480 instruction->struct_ptr = struct_ptr; 1481 instruction->field = field; 1482 1483 ir_ref_instruction(struct_ptr, irb->current_basic_block); 1484 1485 return &instruction->base; 1486 } 1487 1488 static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1489 IrInstruction *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing) 1490 { 1491 IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node); 1492 instruction->initializing = initializing; 1493 instruction->safety_check_on = safety_check_on; 1494 instruction->union_ptr = union_ptr; 1495 instruction->field = field; 1496 1497 ir_ref_instruction(union_ptr, irb->current_basic_block); 1498 1499 return &instruction->base; 1500 } 1501 1502 static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 1503 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, 1504 bool is_comptime, FnInline fn_inline, CallModifier modifier, bool is_async_call_builtin, 1505 IrInstruction *new_stack, ResultLoc *result_loc) 1506 { 1507 IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node); 1508 call_instruction->fn_entry = fn_entry; 1509 call_instruction->fn_ref = fn_ref; 1510 call_instruction->is_comptime = is_comptime; 1511 call_instruction->fn_inline = fn_inline; 1512 call_instruction->args = args; 1513 call_instruction->arg_count = arg_count; 1514 call_instruction->modifier = modifier; 1515 call_instruction->is_async_call_builtin = is_async_call_builtin; 1516 call_instruction->new_stack = new_stack; 1517 call_instruction->result_loc = result_loc; 1518 1519 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); 1520 for (size_t i = 0; i < arg_count; i += 1) 1521 ir_ref_instruction(args[i], irb->current_basic_block); 1522 if (modifier == CallModifierAsync && new_stack != nullptr) { 1523 // in this case the arg at the end is the return pointer 1524 ir_ref_instruction(args[arg_count], irb->current_basic_block); 1525 } 1526 if (new_stack != nullptr) ir_ref_instruction(new_stack, irb->current_basic_block); 1527 1528 return &call_instruction->base; 1529 } 1530 1531 static IrInstructionCallGen *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, 1532 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, 1533 FnInline fn_inline, CallModifier modifier, IrInstruction *new_stack, bool is_async_call_builtin, 1534 IrInstruction *result_loc, ZigType *return_type) 1535 { 1536 IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, 1537 source_instruction->scope, source_instruction->source_node); 1538 call_instruction->base.value->type = return_type; 1539 call_instruction->fn_entry = fn_entry; 1540 call_instruction->fn_ref = fn_ref; 1541 call_instruction->fn_inline = fn_inline; 1542 call_instruction->args = args; 1543 call_instruction->arg_count = arg_count; 1544 call_instruction->modifier = modifier; 1545 call_instruction->is_async_call_builtin = is_async_call_builtin; 1546 call_instruction->new_stack = new_stack; 1547 call_instruction->result_loc = result_loc; 1548 1549 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block); 1550 for (size_t i = 0; i < arg_count; i += 1) 1551 ir_ref_instruction(args[i], ira->new_irb.current_basic_block); 1552 if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block); 1553 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 1554 1555 return call_instruction; 1556 } 1557 1558 static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, 1559 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values, 1560 ResultLocPeerParent *peer_parent) 1561 { 1562 assert(incoming_count != 0); 1563 assert(incoming_count != SIZE_MAX); 1564 1565 IrInstructionPhi *phi_instruction = ir_build_instruction<IrInstructionPhi>(irb, scope, source_node); 1566 phi_instruction->incoming_count = incoming_count; 1567 phi_instruction->incoming_blocks = incoming_blocks; 1568 phi_instruction->incoming_values = incoming_values; 1569 phi_instruction->peer_parent = peer_parent; 1570 1571 for (size_t i = 0; i < incoming_count; i += 1) { 1572 ir_ref_bb(incoming_blocks[i]); 1573 ir_ref_instruction(incoming_values[i], irb->current_basic_block); 1574 } 1575 1576 return &phi_instruction->base; 1577 } 1578 1579 static IrInstruction *ir_create_br(IrBuilder *irb, Scope *scope, AstNode *source_node, 1580 IrBasicBlock *dest_block, IrInstruction *is_comptime) 1581 { 1582 IrInstructionBr *br_instruction = ir_create_instruction<IrInstructionBr>(irb, scope, source_node); 1583 br_instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; 1584 br_instruction->base.value->special = ConstValSpecialStatic; 1585 br_instruction->dest_block = dest_block; 1586 br_instruction->is_comptime = is_comptime; 1587 1588 ir_ref_bb(dest_block); 1589 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 1590 1591 return &br_instruction->base; 1592 } 1593 1594 static IrInstruction *ir_build_br(IrBuilder *irb, Scope *scope, AstNode *source_node, 1595 IrBasicBlock *dest_block, IrInstruction *is_comptime) 1596 { 1597 IrInstruction *instruction = ir_create_br(irb, scope, source_node, dest_block, is_comptime); 1598 ir_instruction_append(irb->current_basic_block, instruction); 1599 return instruction; 1600 } 1601 1602 static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1603 IrInstruction *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, 1604 IrInstruction *sentinel, IrInstruction *align_value, 1605 uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero) 1606 { 1607 IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node); 1608 ptr_type_of_instruction->sentinel = sentinel; 1609 ptr_type_of_instruction->align_value = align_value; 1610 ptr_type_of_instruction->child_type = child_type; 1611 ptr_type_of_instruction->is_const = is_const; 1612 ptr_type_of_instruction->is_volatile = is_volatile; 1613 ptr_type_of_instruction->ptr_len = ptr_len; 1614 ptr_type_of_instruction->bit_offset_start = bit_offset_start; 1615 ptr_type_of_instruction->host_int_bytes = host_int_bytes; 1616 ptr_type_of_instruction->is_allow_zero = is_allow_zero; 1617 1618 if (sentinel) ir_ref_instruction(sentinel, irb->current_basic_block); 1619 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 1620 ir_ref_instruction(child_type, irb->current_basic_block); 1621 1622 return &ptr_type_of_instruction->base; 1623 } 1624 1625 static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 1626 IrInstruction *value, LVal lval, ResultLoc *result_loc) 1627 { 1628 IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); 1629 instruction->op_id = op_id; 1630 instruction->value = value; 1631 instruction->lval = lval; 1632 instruction->result_loc = result_loc; 1633 1634 ir_ref_instruction(value, irb->current_basic_block); 1635 1636 return &instruction->base; 1637 } 1638 1639 static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 1640 IrInstruction *value) 1641 { 1642 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr); 1643 } 1644 1645 static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node, 1646 size_t item_count, IrInstruction **elem_result_loc_list, IrInstruction *result_loc, 1647 AstNode *init_array_type_source_node) 1648 { 1649 IrInstructionContainerInitList *container_init_list_instruction = 1650 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); 1651 container_init_list_instruction->item_count = item_count; 1652 container_init_list_instruction->elem_result_loc_list = elem_result_loc_list; 1653 container_init_list_instruction->result_loc = result_loc; 1654 container_init_list_instruction->init_array_type_source_node = init_array_type_source_node; 1655 1656 for (size_t i = 0; i < item_count; i += 1) { 1657 ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block); 1658 } 1659 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 1660 1661 return &container_init_list_instruction->base; 1662 } 1663 1664 static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node, 1665 size_t field_count, IrInstructionContainerInitFieldsField *fields, IrInstruction *result_loc) 1666 { 1667 IrInstructionContainerInitFields *container_init_fields_instruction = 1668 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); 1669 container_init_fields_instruction->field_count = field_count; 1670 container_init_fields_instruction->fields = fields; 1671 container_init_fields_instruction->result_loc = result_loc; 1672 1673 for (size_t i = 0; i < field_count; i += 1) { 1674 ir_ref_instruction(fields[i].result_loc, irb->current_basic_block); 1675 } 1676 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 1677 1678 return &container_init_fields_instruction->base; 1679 } 1680 1681 static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1682 IrInstructionUnreachable *unreachable_instruction = 1683 ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); 1684 unreachable_instruction->base.value->special = ConstValSpecialStatic; 1685 unreachable_instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; 1686 return &unreachable_instruction->base; 1687 } 1688 1689 static IrInstructionStorePtr *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1690 IrInstruction *ptr, IrInstruction *value) 1691 { 1692 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node); 1693 instruction->base.value->special = ConstValSpecialStatic; 1694 instruction->base.value->type = irb->codegen->builtin_types.entry_void; 1695 instruction->ptr = ptr; 1696 instruction->value = value; 1697 1698 ir_ref_instruction(ptr, irb->current_basic_block); 1699 ir_ref_instruction(value, irb->current_basic_block); 1700 1701 return instruction; 1702 } 1703 1704 static IrInstruction *ir_build_vector_store_elem(IrAnalyze *ira, IrInstruction *source_instruction, 1705 IrInstruction *vector_ptr, IrInstruction *index, IrInstruction *value) 1706 { 1707 IrInstructionVectorStoreElem *inst = ir_build_instruction<IrInstructionVectorStoreElem>( 1708 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 1709 inst->base.value->type = ira->codegen->builtin_types.entry_void; 1710 inst->vector_ptr = vector_ptr; 1711 inst->index = index; 1712 inst->value = value; 1713 1714 ir_ref_instruction(vector_ptr, ira->new_irb.current_basic_block); 1715 ir_ref_instruction(index, ira->new_irb.current_basic_block); 1716 ir_ref_instruction(value, ira->new_irb.current_basic_block); 1717 1718 return &inst->base; 1719 } 1720 1721 static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 1722 ZigVar *var, IrInstruction *align_value, IrInstruction *ptr) 1723 { 1724 IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node); 1725 decl_var_instruction->base.value->special = ConstValSpecialStatic; 1726 decl_var_instruction->base.value->type = irb->codegen->builtin_types.entry_void; 1727 decl_var_instruction->var = var; 1728 decl_var_instruction->align_value = align_value; 1729 decl_var_instruction->ptr = ptr; 1730 1731 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 1732 ir_ref_instruction(ptr, irb->current_basic_block); 1733 1734 return &decl_var_instruction->base; 1735 } 1736 1737 static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction, 1738 ZigVar *var, IrInstruction *var_ptr) 1739 { 1740 IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb, 1741 source_instruction->scope, source_instruction->source_node); 1742 decl_var_instruction->base.value->special = ConstValSpecialStatic; 1743 decl_var_instruction->base.value->type = ira->codegen->builtin_types.entry_void; 1744 decl_var_instruction->var = var; 1745 decl_var_instruction->var_ptr = var_ptr; 1746 1747 ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block); 1748 1749 return &decl_var_instruction->base; 1750 } 1751 1752 static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction, 1753 IrInstruction *operand, ZigType *ty, IrInstruction *result_loc) 1754 { 1755 IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb, 1756 source_instruction->scope, source_instruction->source_node); 1757 instruction->base.value->type = ty; 1758 instruction->operand = operand; 1759 instruction->result_loc = result_loc; 1760 1761 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 1762 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 1763 1764 return &instruction->base; 1765 } 1766 1767 static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node, 1768 IrInstruction *name, IrInstruction *target, IrInstruction *linkage) 1769 { 1770 IrInstructionExport *export_instruction = ir_build_instruction<IrInstructionExport>( 1771 irb, scope, source_node); 1772 export_instruction->base.value->special = ConstValSpecialStatic; 1773 export_instruction->base.value->type = irb->codegen->builtin_types.entry_void; 1774 export_instruction->name = name; 1775 export_instruction->target = target; 1776 export_instruction->linkage = linkage; 1777 1778 ir_ref_instruction(name, irb->current_basic_block); 1779 ir_ref_instruction(target, irb->current_basic_block); 1780 if (linkage) ir_ref_instruction(linkage, irb->current_basic_block); 1781 1782 return &export_instruction->base; 1783 } 1784 1785 static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { 1786 IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node); 1787 instruction->ptr = ptr; 1788 1789 ir_ref_instruction(ptr, irb->current_basic_block); 1790 1791 return &instruction->base; 1792 } 1793 1794 static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1795 IrInstructionTypeOf *instruction = ir_build_instruction<IrInstructionTypeOf>(irb, scope, source_node); 1796 instruction->value = value; 1797 1798 ir_ref_instruction(value, irb->current_basic_block); 1799 1800 return &instruction->base; 1801 } 1802 1803 static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) { 1804 IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); 1805 instruction->is_cold = is_cold; 1806 1807 ir_ref_instruction(is_cold, irb->current_basic_block); 1808 1809 return &instruction->base; 1810 } 1811 1812 static IrInstruction *ir_build_set_runtime_safety(IrBuilder *irb, Scope *scope, AstNode *source_node, 1813 IrInstruction *safety_on) 1814 { 1815 IrInstructionSetRuntimeSafety *instruction = ir_build_instruction<IrInstructionSetRuntimeSafety>(irb, scope, source_node); 1816 instruction->safety_on = safety_on; 1817 1818 ir_ref_instruction(safety_on, irb->current_basic_block); 1819 1820 return &instruction->base; 1821 } 1822 1823 static IrInstruction *ir_build_set_float_mode(IrBuilder *irb, Scope *scope, AstNode *source_node, 1824 IrInstruction *mode_value) 1825 { 1826 IrInstructionSetFloatMode *instruction = ir_build_instruction<IrInstructionSetFloatMode>(irb, scope, source_node); 1827 instruction->mode_value = mode_value; 1828 1829 ir_ref_instruction(mode_value, irb->current_basic_block); 1830 1831 return &instruction->base; 1832 } 1833 1834 static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *size, 1835 IrInstruction *sentinel, IrInstruction *child_type) 1836 { 1837 IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, scope, source_node); 1838 instruction->size = size; 1839 instruction->sentinel = sentinel; 1840 instruction->child_type = child_type; 1841 1842 ir_ref_instruction(size, irb->current_basic_block); 1843 if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block); 1844 ir_ref_instruction(child_type, irb->current_basic_block); 1845 1846 return &instruction->base; 1847 } 1848 1849 static IrInstruction *ir_build_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1850 IrInstruction *payload_type) 1851 { 1852 IrInstructionAnyFrameType *instruction = ir_build_instruction<IrInstructionAnyFrameType>(irb, scope, source_node); 1853 instruction->payload_type = payload_type; 1854 1855 if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); 1856 1857 return &instruction->base; 1858 } 1859 1860 static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1861 IrInstruction *child_type, bool is_const, bool is_volatile, 1862 IrInstruction *sentinel, IrInstruction *align_value, bool is_allow_zero) 1863 { 1864 IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, scope, source_node); 1865 instruction->is_const = is_const; 1866 instruction->is_volatile = is_volatile; 1867 instruction->child_type = child_type; 1868 instruction->sentinel = sentinel; 1869 instruction->align_value = align_value; 1870 instruction->is_allow_zero = is_allow_zero; 1871 1872 if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block); 1873 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 1874 ir_ref_instruction(child_type, irb->current_basic_block); 1875 1876 return &instruction->base; 1877 } 1878 1879 static IrInstruction *ir_build_global_asm(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *asm_code) { 1880 IrInstructionGlobalAsm *instruction = ir_build_instruction<IrInstructionGlobalAsm>(irb, scope, source_node); 1881 instruction->asm_code = asm_code; 1882 return &instruction->base; 1883 } 1884 1885 static IrInstruction *ir_build_asm(IrBuilder *irb, Scope *scope, AstNode *source_node, 1886 Buf *asm_template, AsmToken *token_list, size_t token_list_len, 1887 IrInstruction **input_list, IrInstruction **output_types, ZigVar **output_vars, size_t return_count, 1888 bool has_side_effects) 1889 { 1890 IrInstructionAsm *instruction = ir_build_instruction<IrInstructionAsm>(irb, scope, source_node); 1891 instruction->asm_template = asm_template; 1892 instruction->token_list = token_list; 1893 instruction->token_list_len = token_list_len; 1894 instruction->input_list = input_list; 1895 instruction->output_types = output_types; 1896 instruction->output_vars = output_vars; 1897 instruction->return_count = return_count; 1898 instruction->has_side_effects = has_side_effects; 1899 1900 assert(source_node->type == NodeTypeAsmExpr); 1901 for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) { 1902 IrInstruction *output_type = output_types[i]; 1903 if (output_type) ir_ref_instruction(output_type, irb->current_basic_block); 1904 } 1905 1906 for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) { 1907 IrInstruction *input_value = input_list[i]; 1908 ir_ref_instruction(input_value, irb->current_basic_block); 1909 } 1910 1911 return &instruction->base; 1912 } 1913 1914 static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { 1915 IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, scope, source_node); 1916 instruction->type_value = type_value; 1917 1918 ir_ref_instruction(type_value, irb->current_basic_block); 1919 1920 return &instruction->base; 1921 } 1922 1923 static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1924 IrInstructionTestNonNull *instruction = ir_build_instruction<IrInstructionTestNonNull>(irb, scope, source_node); 1925 instruction->value = value; 1926 1927 ir_ref_instruction(value, irb->current_basic_block); 1928 1929 return &instruction->base; 1930 } 1931 1932 static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1933 IrInstruction *base_ptr, bool safety_check_on, bool initializing) 1934 { 1935 IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node); 1936 instruction->base_ptr = base_ptr; 1937 instruction->safety_check_on = safety_check_on; 1938 instruction->initializing = initializing; 1939 1940 ir_ref_instruction(base_ptr, irb->current_basic_block); 1941 1942 return &instruction->base; 1943 } 1944 1945 static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_ty, 1946 IrInstruction *operand, IrInstruction *result_loc) 1947 { 1948 IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>( 1949 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 1950 instruction->base.value->type = result_ty; 1951 instruction->operand = operand; 1952 instruction->result_loc = result_loc; 1953 1954 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 1955 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 1956 1957 return &instruction->base; 1958 } 1959 1960 static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instruction, 1961 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) 1962 { 1963 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>( 1964 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 1965 instruction->base.value->type = result_type; 1966 instruction->operand = operand; 1967 instruction->result_loc = result_loc; 1968 1969 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 1970 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 1971 1972 return &instruction->base; 1973 } 1974 1975 static IrInstruction *ir_build_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instruction, 1976 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) 1977 { 1978 IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>( 1979 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 1980 instruction->base.value->type = result_type; 1981 instruction->operand = operand; 1982 instruction->result_loc = result_loc; 1983 1984 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 1985 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 1986 1987 return &instruction->base; 1988 } 1989 1990 static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 1991 IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node); 1992 instruction->type = type; 1993 instruction->op = op; 1994 1995 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 1996 ir_ref_instruction(op, irb->current_basic_block); 1997 1998 return &instruction->base; 1999 } 2000 2001 static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 2002 IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node); 2003 instruction->type = type; 2004 instruction->op = op; 2005 2006 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 2007 ir_ref_instruction(op, irb->current_basic_block); 2008 2009 return &instruction->base; 2010 } 2011 2012 static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 2013 IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node); 2014 instruction->type = type; 2015 instruction->op = op; 2016 2017 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 2018 ir_ref_instruction(op, irb->current_basic_block); 2019 2020 return &instruction->base; 2021 } 2022 2023 static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 2024 IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node); 2025 instruction->type = type; 2026 instruction->op = op; 2027 2028 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 2029 ir_ref_instruction(op, irb->current_basic_block); 2030 2031 return &instruction->base; 2032 } 2033 2034 static IrInstruction *ir_build_bit_reverse(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 2035 IrInstructionBitReverse *instruction = ir_build_instruction<IrInstructionBitReverse>(irb, scope, source_node); 2036 instruction->type = type; 2037 instruction->op = op; 2038 2039 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 2040 ir_ref_instruction(op, irb->current_basic_block); 2041 2042 return &instruction->base; 2043 } 2044 2045 static IrInstructionSwitchBr *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value, 2046 IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, 2047 IrInstruction *switch_prongs_void) 2048 { 2049 IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node); 2050 instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; 2051 instruction->base.value->special = ConstValSpecialStatic; 2052 instruction->target_value = target_value; 2053 instruction->else_block = else_block; 2054 instruction->case_count = case_count; 2055 instruction->cases = cases; 2056 instruction->is_comptime = is_comptime; 2057 instruction->switch_prongs_void = switch_prongs_void; 2058 2059 ir_ref_instruction(target_value, irb->current_basic_block); 2060 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 2061 ir_ref_bb(else_block); 2062 if (switch_prongs_void) ir_ref_instruction(switch_prongs_void, irb->current_basic_block); 2063 2064 for (size_t i = 0; i < case_count; i += 1) { 2065 ir_ref_instruction(cases[i].value, irb->current_basic_block); 2066 ir_ref_bb(cases[i].block); 2067 } 2068 2069 return instruction; 2070 } 2071 2072 static IrInstruction *ir_build_switch_target(IrBuilder *irb, Scope *scope, AstNode *source_node, 2073 IrInstruction *target_value_ptr) 2074 { 2075 IrInstructionSwitchTarget *instruction = ir_build_instruction<IrInstructionSwitchTarget>(irb, scope, source_node); 2076 instruction->target_value_ptr = target_value_ptr; 2077 2078 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 2079 2080 return &instruction->base; 2081 } 2082 2083 static IrInstruction *ir_build_switch_var(IrBuilder *irb, Scope *scope, AstNode *source_node, 2084 IrInstruction *target_value_ptr, IrInstruction **prongs_ptr, size_t prongs_len) 2085 { 2086 IrInstructionSwitchVar *instruction = ir_build_instruction<IrInstructionSwitchVar>(irb, scope, source_node); 2087 instruction->target_value_ptr = target_value_ptr; 2088 instruction->prongs_ptr = prongs_ptr; 2089 instruction->prongs_len = prongs_len; 2090 2091 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 2092 for (size_t i = 0; i < prongs_len; i += 1) { 2093 ir_ref_instruction(prongs_ptr[i], irb->current_basic_block); 2094 } 2095 2096 return &instruction->base; 2097 } 2098 2099 // For this instruction the switch_br must be set later. 2100 static IrInstructionSwitchElseVar *ir_build_switch_else_var(IrBuilder *irb, Scope *scope, AstNode *source_node, 2101 IrInstruction *target_value_ptr) 2102 { 2103 IrInstructionSwitchElseVar *instruction = ir_build_instruction<IrInstructionSwitchElseVar>(irb, scope, source_node); 2104 instruction->target_value_ptr = target_value_ptr; 2105 2106 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 2107 2108 return instruction; 2109 } 2110 2111 static IrInstruction *ir_build_union_tag(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2112 IrInstructionUnionTag *instruction = ir_build_instruction<IrInstructionUnionTag>(irb, scope, source_node); 2113 instruction->value = value; 2114 2115 ir_ref_instruction(value, irb->current_basic_block); 2116 2117 return &instruction->base; 2118 } 2119 2120 static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 2121 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, scope, source_node); 2122 instruction->name = name; 2123 2124 ir_ref_instruction(name, irb->current_basic_block); 2125 2126 return &instruction->base; 2127 } 2128 2129 static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value, 2130 bool is_const, bool is_volatile) 2131 { 2132 IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, scope, source_node); 2133 instruction->value = value; 2134 instruction->is_const = is_const; 2135 instruction->is_volatile = is_volatile; 2136 2137 ir_ref_instruction(value, irb->current_basic_block); 2138 2139 return &instruction->base; 2140 } 2141 2142 static IrInstruction *ir_build_ref_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, 2143 IrInstruction *operand, IrInstruction *result_loc) 2144 { 2145 IrInstructionRefGen *instruction = ir_build_instruction<IrInstructionRefGen>(&ira->new_irb, 2146 source_instruction->scope, source_instruction->source_node); 2147 instruction->base.value->type = result_type; 2148 instruction->operand = operand; 2149 instruction->result_loc = result_loc; 2150 2151 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 2152 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 2153 2154 return &instruction->base; 2155 } 2156 2157 static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { 2158 IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); 2159 instruction->msg = msg; 2160 2161 ir_ref_instruction(msg, irb->current_basic_block); 2162 2163 return &instruction->base; 2164 } 2165 2166 static IrInstruction *ir_build_compile_log(IrBuilder *irb, Scope *scope, AstNode *source_node, 2167 size_t msg_count, IrInstruction **msg_list) 2168 { 2169 IrInstructionCompileLog *instruction = ir_build_instruction<IrInstructionCompileLog>(irb, scope, source_node); 2170 instruction->msg_count = msg_count; 2171 instruction->msg_list = msg_list; 2172 2173 for (size_t i = 0; i < msg_count; i += 1) { 2174 ir_ref_instruction(msg_list[i], irb->current_basic_block); 2175 } 2176 2177 return &instruction->base; 2178 } 2179 2180 static IrInstruction *ir_build_err_name(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2181 IrInstructionErrName *instruction = ir_build_instruction<IrInstructionErrName>(irb, scope, source_node); 2182 instruction->value = value; 2183 2184 ir_ref_instruction(value, irb->current_basic_block); 2185 2186 return &instruction->base; 2187 } 2188 2189 static IrInstruction *ir_build_c_import(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2190 IrInstructionCImport *instruction = ir_build_instruction<IrInstructionCImport>(irb, scope, source_node); 2191 return &instruction->base; 2192 } 2193 2194 static IrInstruction *ir_build_c_include(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 2195 IrInstructionCInclude *instruction = ir_build_instruction<IrInstructionCInclude>(irb, scope, source_node); 2196 instruction->name = name; 2197 2198 ir_ref_instruction(name, irb->current_basic_block); 2199 2200 return &instruction->base; 2201 } 2202 2203 static IrInstruction *ir_build_c_define(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name, IrInstruction *value) { 2204 IrInstructionCDefine *instruction = ir_build_instruction<IrInstructionCDefine>(irb, scope, source_node); 2205 instruction->name = name; 2206 instruction->value = value; 2207 2208 ir_ref_instruction(name, irb->current_basic_block); 2209 ir_ref_instruction(value, irb->current_basic_block); 2210 2211 return &instruction->base; 2212 } 2213 2214 static IrInstruction *ir_build_c_undef(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 2215 IrInstructionCUndef *instruction = ir_build_instruction<IrInstructionCUndef>(irb, scope, source_node); 2216 instruction->name = name; 2217 2218 ir_ref_instruction(name, irb->current_basic_block); 2219 2220 return &instruction->base; 2221 } 2222 2223 static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 2224 IrInstructionEmbedFile *instruction = ir_build_instruction<IrInstructionEmbedFile>(irb, scope, source_node); 2225 instruction->name = name; 2226 2227 ir_ref_instruction(name, irb->current_basic_block); 2228 2229 return &instruction->base; 2230 } 2231 2232 static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2233 IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, 2234 IrInstruction *success_order_value, IrInstruction *failure_order_value, bool is_weak, ResultLoc *result_loc) 2235 { 2236 IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node); 2237 instruction->type_value = type_value; 2238 instruction->ptr = ptr; 2239 instruction->cmp_value = cmp_value; 2240 instruction->new_value = new_value; 2241 instruction->success_order_value = success_order_value; 2242 instruction->failure_order_value = failure_order_value; 2243 instruction->is_weak = is_weak; 2244 instruction->result_loc = result_loc; 2245 2246 ir_ref_instruction(type_value, irb->current_basic_block); 2247 ir_ref_instruction(ptr, irb->current_basic_block); 2248 ir_ref_instruction(cmp_value, irb->current_basic_block); 2249 ir_ref_instruction(new_value, irb->current_basic_block); 2250 ir_ref_instruction(success_order_value, irb->current_basic_block); 2251 ir_ref_instruction(failure_order_value, irb->current_basic_block); 2252 2253 return &instruction->base; 2254 } 2255 2256 static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, 2257 IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, 2258 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstruction *result_loc) 2259 { 2260 IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb, 2261 source_instruction->scope, source_instruction->source_node); 2262 instruction->base.value->type = result_type; 2263 instruction->ptr = ptr; 2264 instruction->cmp_value = cmp_value; 2265 instruction->new_value = new_value; 2266 instruction->success_order = success_order; 2267 instruction->failure_order = failure_order; 2268 instruction->is_weak = is_weak; 2269 instruction->result_loc = result_loc; 2270 2271 ir_ref_instruction(ptr, ira->new_irb.current_basic_block); 2272 ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block); 2273 ir_ref_instruction(new_value, ira->new_irb.current_basic_block); 2274 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 2275 2276 return &instruction->base; 2277 } 2278 2279 static IrInstruction *ir_build_fence(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *order_value, AtomicOrder order) { 2280 IrInstructionFence *instruction = ir_build_instruction<IrInstructionFence>(irb, scope, source_node); 2281 instruction->order_value = order_value; 2282 instruction->order = order; 2283 2284 ir_ref_instruction(order_value, irb->current_basic_block); 2285 2286 return &instruction->base; 2287 } 2288 2289 static IrInstruction *ir_build_truncate(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2290 IrInstructionTruncate *instruction = ir_build_instruction<IrInstructionTruncate>(irb, scope, source_node); 2291 instruction->dest_type = dest_type; 2292 instruction->target = target; 2293 2294 ir_ref_instruction(dest_type, irb->current_basic_block); 2295 ir_ref_instruction(target, irb->current_basic_block); 2296 2297 return &instruction->base; 2298 } 2299 2300 static IrInstruction *ir_build_int_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2301 IrInstructionIntCast *instruction = ir_build_instruction<IrInstructionIntCast>(irb, scope, source_node); 2302 instruction->dest_type = dest_type; 2303 instruction->target = target; 2304 2305 ir_ref_instruction(dest_type, irb->current_basic_block); 2306 ir_ref_instruction(target, irb->current_basic_block); 2307 2308 return &instruction->base; 2309 } 2310 2311 static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2312 IrInstructionFloatCast *instruction = ir_build_instruction<IrInstructionFloatCast>(irb, scope, source_node); 2313 instruction->dest_type = dest_type; 2314 instruction->target = target; 2315 2316 ir_ref_instruction(dest_type, irb->current_basic_block); 2317 ir_ref_instruction(target, irb->current_basic_block); 2318 2319 return &instruction->base; 2320 } 2321 2322 static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2323 IrInstructionErrSetCast *instruction = ir_build_instruction<IrInstructionErrSetCast>(irb, scope, source_node); 2324 instruction->dest_type = dest_type; 2325 instruction->target = target; 2326 2327 ir_ref_instruction(dest_type, irb->current_basic_block); 2328 ir_ref_instruction(target, irb->current_basic_block); 2329 2330 return &instruction->base; 2331 } 2332 2333 static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target, 2334 ResultLoc *result_loc) 2335 { 2336 IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); 2337 instruction->target = target; 2338 instruction->result_loc = result_loc; 2339 2340 ir_ref_instruction(target, irb->current_basic_block); 2341 2342 return &instruction->base; 2343 } 2344 2345 static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, 2346 IrInstruction *dest_child_type, IrInstruction *target, ResultLoc *result_loc) 2347 { 2348 IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); 2349 instruction->dest_child_type = dest_child_type; 2350 instruction->target = target; 2351 instruction->result_loc = result_loc; 2352 2353 ir_ref_instruction(dest_child_type, irb->current_basic_block); 2354 ir_ref_instruction(target, irb->current_basic_block); 2355 2356 return &instruction->base; 2357 } 2358 2359 static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2360 IrInstructionIntToFloat *instruction = ir_build_instruction<IrInstructionIntToFloat>(irb, scope, source_node); 2361 instruction->dest_type = dest_type; 2362 instruction->target = target; 2363 2364 ir_ref_instruction(dest_type, irb->current_basic_block); 2365 ir_ref_instruction(target, irb->current_basic_block); 2366 2367 return &instruction->base; 2368 } 2369 2370 static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 2371 IrInstructionFloatToInt *instruction = ir_build_instruction<IrInstructionFloatToInt>(irb, scope, source_node); 2372 instruction->dest_type = dest_type; 2373 instruction->target = target; 2374 2375 ir_ref_instruction(dest_type, irb->current_basic_block); 2376 ir_ref_instruction(target, irb->current_basic_block); 2377 2378 return &instruction->base; 2379 } 2380 2381 static IrInstruction *ir_build_bool_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { 2382 IrInstructionBoolToInt *instruction = ir_build_instruction<IrInstructionBoolToInt>(irb, scope, source_node); 2383 instruction->target = target; 2384 2385 ir_ref_instruction(target, irb->current_basic_block); 2386 2387 return &instruction->base; 2388 } 2389 2390 static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) { 2391 IrInstructionIntType *instruction = ir_build_instruction<IrInstructionIntType>(irb, scope, source_node); 2392 instruction->is_signed = is_signed; 2393 instruction->bit_count = bit_count; 2394 2395 ir_ref_instruction(is_signed, irb->current_basic_block); 2396 ir_ref_instruction(bit_count, irb->current_basic_block); 2397 2398 return &instruction->base; 2399 } 2400 2401 static IrInstruction *ir_build_vector_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *len, 2402 IrInstruction *elem_type) 2403 { 2404 IrInstructionVectorType *instruction = ir_build_instruction<IrInstructionVectorType>(irb, scope, source_node); 2405 instruction->len = len; 2406 instruction->elem_type = elem_type; 2407 2408 ir_ref_instruction(len, irb->current_basic_block); 2409 ir_ref_instruction(elem_type, irb->current_basic_block); 2410 2411 return &instruction->base; 2412 } 2413 2414 static IrInstruction *ir_build_shuffle_vector(IrBuilder *irb, Scope *scope, AstNode *source_node, 2415 IrInstruction *scalar_type, IrInstruction *a, IrInstruction *b, IrInstruction *mask) 2416 { 2417 IrInstructionShuffleVector *instruction = ir_build_instruction<IrInstructionShuffleVector>(irb, scope, source_node); 2418 instruction->scalar_type = scalar_type; 2419 instruction->a = a; 2420 instruction->b = b; 2421 instruction->mask = mask; 2422 2423 if (scalar_type != nullptr) { 2424 ir_ref_instruction(scalar_type, irb->current_basic_block); 2425 } 2426 ir_ref_instruction(a, irb->current_basic_block); 2427 ir_ref_instruction(b, irb->current_basic_block); 2428 ir_ref_instruction(mask, irb->current_basic_block); 2429 2430 return &instruction->base; 2431 } 2432 2433 static IrInstruction *ir_build_splat_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2434 IrInstruction *len, IrInstruction *scalar) 2435 { 2436 IrInstructionSplatSrc *instruction = ir_build_instruction<IrInstructionSplatSrc>(irb, scope, source_node); 2437 instruction->len = len; 2438 instruction->scalar = scalar; 2439 2440 ir_ref_instruction(len, irb->current_basic_block); 2441 ir_ref_instruction(scalar, irb->current_basic_block); 2442 2443 return &instruction->base; 2444 } 2445 2446 static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2447 IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node); 2448 instruction->value = value; 2449 2450 ir_ref_instruction(value, irb->current_basic_block); 2451 2452 return &instruction->base; 2453 } 2454 2455 static IrInstruction *ir_build_memset(IrBuilder *irb, Scope *scope, AstNode *source_node, 2456 IrInstruction *dest_ptr, IrInstruction *byte, IrInstruction *count) 2457 { 2458 IrInstructionMemset *instruction = ir_build_instruction<IrInstructionMemset>(irb, scope, source_node); 2459 instruction->dest_ptr = dest_ptr; 2460 instruction->byte = byte; 2461 instruction->count = count; 2462 2463 ir_ref_instruction(dest_ptr, irb->current_basic_block); 2464 ir_ref_instruction(byte, irb->current_basic_block); 2465 ir_ref_instruction(count, irb->current_basic_block); 2466 2467 return &instruction->base; 2468 } 2469 2470 static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *source_node, 2471 IrInstruction *dest_ptr, IrInstruction *src_ptr, IrInstruction *count) 2472 { 2473 IrInstructionMemcpy *instruction = ir_build_instruction<IrInstructionMemcpy>(irb, scope, source_node); 2474 instruction->dest_ptr = dest_ptr; 2475 instruction->src_ptr = src_ptr; 2476 instruction->count = count; 2477 2478 ir_ref_instruction(dest_ptr, irb->current_basic_block); 2479 ir_ref_instruction(src_ptr, irb->current_basic_block); 2480 ir_ref_instruction(count, irb->current_basic_block); 2481 2482 return &instruction->base; 2483 } 2484 2485 static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2486 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, ResultLoc *result_loc) 2487 { 2488 IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node); 2489 instruction->ptr = ptr; 2490 instruction->start = start; 2491 instruction->end = end; 2492 instruction->safety_check_on = safety_check_on; 2493 instruction->result_loc = result_loc; 2494 2495 ir_ref_instruction(ptr, irb->current_basic_block); 2496 ir_ref_instruction(start, irb->current_basic_block); 2497 if (end) ir_ref_instruction(end, irb->current_basic_block); 2498 2499 return &instruction->base; 2500 } 2501 2502 static IrInstruction *ir_build_splat_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, 2503 IrInstruction *scalar) 2504 { 2505 IrInstructionSplatGen *instruction = ir_build_instruction<IrInstructionSplatGen>( 2506 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2507 instruction->base.value->type = result_type; 2508 instruction->scalar = scalar; 2509 2510 ir_ref_instruction(scalar, ira->new_irb.current_basic_block); 2511 2512 return &instruction->base; 2513 } 2514 2515 static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *slice_type, 2516 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, IrInstruction *result_loc) 2517 { 2518 IrInstructionSliceGen *instruction = ir_build_instruction<IrInstructionSliceGen>( 2519 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2520 instruction->base.value->type = slice_type; 2521 instruction->ptr = ptr; 2522 instruction->start = start; 2523 instruction->end = end; 2524 instruction->safety_check_on = safety_check_on; 2525 instruction->result_loc = result_loc; 2526 2527 ir_ref_instruction(ptr, ira->new_irb.current_basic_block); 2528 ir_ref_instruction(start, ira->new_irb.current_basic_block); 2529 if (end) ir_ref_instruction(end, ira->new_irb.current_basic_block); 2530 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 2531 2532 return &instruction->base; 2533 } 2534 2535 static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) { 2536 IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); 2537 instruction->container = container; 2538 2539 ir_ref_instruction(container, irb->current_basic_block); 2540 2541 return &instruction->base; 2542 } 2543 2544 static IrInstruction *ir_build_member_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2545 IrInstruction *container_type, IrInstruction *member_index) 2546 { 2547 IrInstructionMemberType *instruction = ir_build_instruction<IrInstructionMemberType>(irb, scope, source_node); 2548 instruction->container_type = container_type; 2549 instruction->member_index = member_index; 2550 2551 ir_ref_instruction(container_type, irb->current_basic_block); 2552 ir_ref_instruction(member_index, irb->current_basic_block); 2553 2554 return &instruction->base; 2555 } 2556 2557 static IrInstruction *ir_build_member_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2558 IrInstruction *container_type, IrInstruction *member_index) 2559 { 2560 IrInstructionMemberName *instruction = ir_build_instruction<IrInstructionMemberName>(irb, scope, source_node); 2561 instruction->container_type = container_type; 2562 instruction->member_index = member_index; 2563 2564 ir_ref_instruction(container_type, irb->current_basic_block); 2565 ir_ref_instruction(member_index, irb->current_basic_block); 2566 2567 return &instruction->base; 2568 } 2569 2570 static IrInstruction *ir_build_breakpoint(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2571 IrInstructionBreakpoint *instruction = ir_build_instruction<IrInstructionBreakpoint>(irb, scope, source_node); 2572 return &instruction->base; 2573 } 2574 2575 static IrInstruction *ir_build_return_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2576 IrInstructionReturnAddress *instruction = ir_build_instruction<IrInstructionReturnAddress>(irb, scope, source_node); 2577 return &instruction->base; 2578 } 2579 2580 static IrInstruction *ir_build_frame_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2581 IrInstructionFrameAddress *instruction = ir_build_instruction<IrInstructionFrameAddress>(irb, scope, source_node); 2582 return &instruction->base; 2583 } 2584 2585 static IrInstruction *ir_build_handle(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2586 IrInstructionFrameHandle *instruction = ir_build_instruction<IrInstructionFrameHandle>(irb, scope, source_node); 2587 return &instruction->base; 2588 } 2589 2590 static IrInstruction *ir_build_frame_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn) { 2591 IrInstructionFrameType *instruction = ir_build_instruction<IrInstructionFrameType>(irb, scope, source_node); 2592 instruction->fn = fn; 2593 2594 ir_ref_instruction(fn, irb->current_basic_block); 2595 2596 return &instruction->base; 2597 } 2598 2599 static IrInstruction *ir_build_frame_size_src(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn) { 2600 IrInstructionFrameSizeSrc *instruction = ir_build_instruction<IrInstructionFrameSizeSrc>(irb, scope, source_node); 2601 instruction->fn = fn; 2602 2603 ir_ref_instruction(fn, irb->current_basic_block); 2604 2605 return &instruction->base; 2606 } 2607 2608 static IrInstruction *ir_build_frame_size_gen(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn) 2609 { 2610 IrInstructionFrameSizeGen *instruction = ir_build_instruction<IrInstructionFrameSizeGen>(irb, scope, source_node); 2611 instruction->fn = fn; 2612 2613 ir_ref_instruction(fn, irb->current_basic_block); 2614 2615 return &instruction->base; 2616 } 2617 2618 static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode *source_node, 2619 IrOverflowOp op, IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, 2620 IrInstruction *result_ptr, ZigType *result_ptr_type) 2621 { 2622 IrInstructionOverflowOp *instruction = ir_build_instruction<IrInstructionOverflowOp>(irb, scope, source_node); 2623 instruction->op = op; 2624 instruction->type_value = type_value; 2625 instruction->op1 = op1; 2626 instruction->op2 = op2; 2627 instruction->result_ptr = result_ptr; 2628 instruction->result_ptr_type = result_ptr_type; 2629 2630 ir_ref_instruction(type_value, irb->current_basic_block); 2631 ir_ref_instruction(op1, irb->current_basic_block); 2632 ir_ref_instruction(op2, irb->current_basic_block); 2633 ir_ref_instruction(result_ptr, irb->current_basic_block); 2634 2635 return &instruction->base; 2636 } 2637 2638 2639 //TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign, 2640 // lround, llround, lrint, llrint 2641 // So far this is only non-complicated type functions. 2642 const char *float_op_to_name(BuiltinFnId op, bool llvm_name) { 2643 const bool b = llvm_name; 2644 2645 switch (op) { 2646 case BuiltinFnIdSqrt: 2647 return "sqrt"; 2648 case BuiltinFnIdSin: 2649 return "sin"; 2650 case BuiltinFnIdCos: 2651 return "cos"; 2652 case BuiltinFnIdExp: 2653 return "exp"; 2654 case BuiltinFnIdExp2: 2655 return "exp2"; 2656 case BuiltinFnIdLn: 2657 return b ? "log" : "ln"; 2658 case BuiltinFnIdLog10: 2659 return "log10"; 2660 case BuiltinFnIdLog2: 2661 return "log2"; 2662 case BuiltinFnIdFabs: 2663 return "fabs"; 2664 case BuiltinFnIdFloor: 2665 return "floor"; 2666 case BuiltinFnIdCeil: 2667 return "ceil"; 2668 case BuiltinFnIdTrunc: 2669 return "trunc"; 2670 case BuiltinFnIdNearbyInt: 2671 return b ? "nearbyint" : "nearbyInt"; 2672 case BuiltinFnIdRound: 2673 return "round"; 2674 default: 2675 zig_unreachable(); 2676 } 2677 } 2678 2679 static IrInstruction *ir_build_float_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op1, BuiltinFnId op) { 2680 IrInstructionFloatOp *instruction = ir_build_instruction<IrInstructionFloatOp>(irb, scope, source_node); 2681 instruction->type = type; 2682 instruction->op1 = op1; 2683 instruction->op = op; 2684 2685 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 2686 ir_ref_instruction(op1, irb->current_basic_block); 2687 2688 return &instruction->base; 2689 } 2690 2691 static IrInstruction *ir_build_mul_add(IrBuilder *irb, Scope *scope, AstNode *source_node, 2692 IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, IrInstruction *op3) { 2693 IrInstructionMulAdd *instruction = ir_build_instruction<IrInstructionMulAdd>(irb, scope, source_node); 2694 instruction->type_value = type_value; 2695 instruction->op1 = op1; 2696 instruction->op2 = op2; 2697 instruction->op3 = op3; 2698 2699 ir_ref_instruction(type_value, irb->current_basic_block); 2700 ir_ref_instruction(op1, irb->current_basic_block); 2701 ir_ref_instruction(op2, irb->current_basic_block); 2702 ir_ref_instruction(op3, irb->current_basic_block); 2703 2704 return &instruction->base; 2705 } 2706 2707 static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { 2708 IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node); 2709 instruction->type_value = type_value; 2710 2711 ir_ref_instruction(type_value, irb->current_basic_block); 2712 2713 return &instruction->base; 2714 } 2715 2716 static IrInstruction *ir_build_test_err_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2717 IrInstruction *base_ptr, bool resolve_err_set, bool base_ptr_is_payload) 2718 { 2719 IrInstructionTestErrSrc *instruction = ir_build_instruction<IrInstructionTestErrSrc>(irb, scope, source_node); 2720 instruction->base_ptr = base_ptr; 2721 instruction->resolve_err_set = resolve_err_set; 2722 instruction->base_ptr_is_payload = base_ptr_is_payload; 2723 2724 ir_ref_instruction(base_ptr, irb->current_basic_block); 2725 2726 return &instruction->base; 2727 } 2728 2729 static IrInstruction *ir_build_test_err_gen(IrAnalyze *ira, IrInstruction *source_instruction, 2730 IrInstruction *err_union) 2731 { 2732 IrInstructionTestErrGen *instruction = ir_build_instruction<IrInstructionTestErrGen>( 2733 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2734 instruction->base.value->type = ira->codegen->builtin_types.entry_bool; 2735 instruction->err_union = err_union; 2736 2737 ir_ref_instruction(err_union, ira->new_irb.current_basic_block); 2738 2739 return &instruction->base; 2740 } 2741 2742 static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, 2743 IrInstruction *err_union_ptr) 2744 { 2745 IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); 2746 instruction->err_union_ptr = err_union_ptr; 2747 2748 ir_ref_instruction(err_union_ptr, irb->current_basic_block); 2749 2750 return &instruction->base; 2751 } 2752 2753 static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, 2754 IrInstruction *value, bool safety_check_on, bool initializing) 2755 { 2756 IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); 2757 instruction->value = value; 2758 instruction->safety_check_on = safety_check_on; 2759 instruction->initializing = initializing; 2760 2761 ir_ref_instruction(value, irb->current_basic_block); 2762 2763 return &instruction->base; 2764 } 2765 2766 static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node, 2767 IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type, 2768 bool is_var_args) 2769 { 2770 IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node); 2771 instruction->param_types = param_types; 2772 instruction->align_value = align_value; 2773 instruction->return_type = return_type; 2774 instruction->is_var_args = is_var_args; 2775 2776 assert(source_node->type == NodeTypeFnProto); 2777 size_t param_count = source_node->data.fn_proto.params.length; 2778 if (is_var_args) param_count -= 1; 2779 for (size_t i = 0; i < param_count; i += 1) { 2780 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); 2781 } 2782 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 2783 ir_ref_instruction(return_type, irb->current_basic_block); 2784 2785 return &instruction->base; 2786 } 2787 2788 static IrInstruction *ir_build_test_comptime(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2789 IrInstructionTestComptime *instruction = ir_build_instruction<IrInstructionTestComptime>(irb, scope, source_node); 2790 instruction->value = value; 2791 2792 ir_ref_instruction(value, irb->current_basic_block); 2793 2794 return &instruction->base; 2795 } 2796 2797 static IrInstruction *ir_build_ptr_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2798 IrInstruction *dest_type, IrInstruction *ptr, bool safety_check_on) 2799 { 2800 IrInstructionPtrCastSrc *instruction = ir_build_instruction<IrInstructionPtrCastSrc>( 2801 irb, scope, source_node); 2802 instruction->dest_type = dest_type; 2803 instruction->ptr = ptr; 2804 instruction->safety_check_on = safety_check_on; 2805 2806 ir_ref_instruction(dest_type, irb->current_basic_block); 2807 ir_ref_instruction(ptr, irb->current_basic_block); 2808 2809 return &instruction->base; 2810 } 2811 2812 static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *source_instruction, 2813 ZigType *ptr_type, IrInstruction *ptr, bool safety_check_on) 2814 { 2815 IrInstructionPtrCastGen *instruction = ir_build_instruction<IrInstructionPtrCastGen>( 2816 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2817 instruction->base.value->type = ptr_type; 2818 instruction->ptr = ptr; 2819 instruction->safety_check_on = safety_check_on; 2820 2821 ir_ref_instruction(ptr, ira->new_irb.current_basic_block); 2822 2823 return &instruction->base; 2824 } 2825 2826 static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction, 2827 IrInstruction *ptr, ZigType *ty, IrInstruction *result_loc) 2828 { 2829 IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>( 2830 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2831 instruction->base.value->type = ty; 2832 instruction->ptr = ptr; 2833 instruction->result_loc = result_loc; 2834 2835 ir_ref_instruction(ptr, ira->new_irb.current_basic_block); 2836 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 2837 2838 return &instruction->base; 2839 } 2840 2841 static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 2842 IrInstruction *operand, ResultLocCast *result_loc_cast) 2843 { 2844 IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node); 2845 instruction->operand = operand; 2846 instruction->result_loc_cast = result_loc_cast; 2847 2848 ir_ref_instruction(operand, irb->current_basic_block); 2849 2850 return &instruction->base; 2851 } 2852 2853 static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 2854 IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast) 2855 { 2856 IrInstructionBitCastSrc *instruction = ir_build_instruction<IrInstructionBitCastSrc>(irb, scope, source_node); 2857 instruction->operand = operand; 2858 instruction->result_loc_bit_cast = result_loc_bit_cast; 2859 2860 ir_ref_instruction(operand, irb->current_basic_block); 2861 2862 return &instruction->base; 2863 } 2864 2865 static IrInstruction *ir_build_bit_cast_gen(IrAnalyze *ira, IrInstruction *source_instruction, 2866 IrInstruction *operand, ZigType *ty) 2867 { 2868 IrInstructionBitCastGen *instruction = ir_build_instruction<IrInstructionBitCastGen>( 2869 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2870 instruction->base.value->type = ty; 2871 instruction->operand = operand; 2872 2873 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 2874 2875 return &instruction->base; 2876 } 2877 2878 static IrInstruction *ir_build_widen_or_shorten(IrBuilder *irb, Scope *scope, AstNode *source_node, 2879 IrInstruction *target) 2880 { 2881 IrInstructionWidenOrShorten *instruction = ir_build_instruction<IrInstructionWidenOrShorten>( 2882 irb, scope, source_node); 2883 instruction->target = target; 2884 2885 ir_ref_instruction(target, irb->current_basic_block); 2886 2887 return &instruction->base; 2888 } 2889 2890 static IrInstruction *ir_build_int_to_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 2891 IrInstruction *dest_type, IrInstruction *target) 2892 { 2893 IrInstructionIntToPtr *instruction = ir_build_instruction<IrInstructionIntToPtr>( 2894 irb, scope, source_node); 2895 instruction->dest_type = dest_type; 2896 instruction->target = target; 2897 2898 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2899 ir_ref_instruction(target, irb->current_basic_block); 2900 2901 return &instruction->base; 2902 } 2903 2904 static IrInstruction *ir_build_ptr_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2905 IrInstruction *target) 2906 { 2907 IrInstructionPtrToInt *instruction = ir_build_instruction<IrInstructionPtrToInt>( 2908 irb, scope, source_node); 2909 instruction->target = target; 2910 2911 ir_ref_instruction(target, irb->current_basic_block); 2912 2913 return &instruction->base; 2914 } 2915 2916 static IrInstruction *ir_build_int_to_enum(IrBuilder *irb, Scope *scope, AstNode *source_node, 2917 IrInstruction *dest_type, IrInstruction *target) 2918 { 2919 IrInstructionIntToEnum *instruction = ir_build_instruction<IrInstructionIntToEnum>( 2920 irb, scope, source_node); 2921 instruction->dest_type = dest_type; 2922 instruction->target = target; 2923 2924 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2925 ir_ref_instruction(target, irb->current_basic_block); 2926 2927 return &instruction->base; 2928 } 2929 2930 2931 2932 static IrInstruction *ir_build_enum_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2933 IrInstruction *target) 2934 { 2935 IrInstructionEnumToInt *instruction = ir_build_instruction<IrInstructionEnumToInt>( 2936 irb, scope, source_node); 2937 instruction->target = target; 2938 2939 ir_ref_instruction(target, irb->current_basic_block); 2940 2941 return &instruction->base; 2942 } 2943 2944 static IrInstruction *ir_build_int_to_err(IrBuilder *irb, Scope *scope, AstNode *source_node, 2945 IrInstruction *target) 2946 { 2947 IrInstructionIntToErr *instruction = ir_build_instruction<IrInstructionIntToErr>( 2948 irb, scope, source_node); 2949 instruction->target = target; 2950 2951 ir_ref_instruction(target, irb->current_basic_block); 2952 2953 return &instruction->base; 2954 } 2955 2956 static IrInstruction *ir_build_err_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2957 IrInstruction *target) 2958 { 2959 IrInstructionErrToInt *instruction = ir_build_instruction<IrInstructionErrToInt>( 2960 irb, scope, source_node); 2961 instruction->target = target; 2962 2963 ir_ref_instruction(target, irb->current_basic_block); 2964 2965 return &instruction->base; 2966 } 2967 2968 static IrInstruction *ir_build_check_switch_prongs(IrBuilder *irb, Scope *scope, AstNode *source_node, 2969 IrInstruction *target_value, IrInstructionCheckSwitchProngsRange *ranges, size_t range_count, 2970 bool have_else_prong) 2971 { 2972 IrInstructionCheckSwitchProngs *instruction = ir_build_instruction<IrInstructionCheckSwitchProngs>( 2973 irb, scope, source_node); 2974 instruction->target_value = target_value; 2975 instruction->ranges = ranges; 2976 instruction->range_count = range_count; 2977 instruction->have_else_prong = have_else_prong; 2978 2979 ir_ref_instruction(target_value, irb->current_basic_block); 2980 for (size_t i = 0; i < range_count; i += 1) { 2981 ir_ref_instruction(ranges[i].start, irb->current_basic_block); 2982 ir_ref_instruction(ranges[i].end, irb->current_basic_block); 2983 } 2984 2985 return &instruction->base; 2986 } 2987 2988 static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *scope, AstNode *source_node, 2989 IrInstruction* statement_value) 2990 { 2991 IrInstructionCheckStatementIsVoid *instruction = ir_build_instruction<IrInstructionCheckStatementIsVoid>( 2992 irb, scope, source_node); 2993 instruction->statement_value = statement_value; 2994 2995 ir_ref_instruction(statement_value, irb->current_basic_block); 2996 2997 return &instruction->base; 2998 } 2999 3000 static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 3001 IrInstruction *type_value) 3002 { 3003 IrInstructionTypeName *instruction = ir_build_instruction<IrInstructionTypeName>( 3004 irb, scope, source_node); 3005 instruction->type_value = type_value; 3006 3007 ir_ref_instruction(type_value, irb->current_basic_block); 3008 3009 return &instruction->base; 3010 } 3011 3012 static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) { 3013 IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>(irb, scope, source_node); 3014 instruction->tld = tld; 3015 instruction->lval = lval; 3016 3017 return &instruction->base; 3018 } 3019 3020 static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { 3021 IrInstructionPanic *instruction = ir_build_instruction<IrInstructionPanic>(irb, scope, source_node); 3022 instruction->base.value->special = ConstValSpecialStatic; 3023 instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; 3024 instruction->msg = msg; 3025 3026 ir_ref_instruction(msg, irb->current_basic_block); 3027 3028 return &instruction->base; 3029 } 3030 3031 static IrInstruction *ir_build_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 3032 IrInstruction *target) 3033 { 3034 IrInstructionTagName *instruction = ir_build_instruction<IrInstructionTagName>(irb, scope, source_node); 3035 instruction->target = target; 3036 3037 ir_ref_instruction(target, irb->current_basic_block); 3038 3039 return &instruction->base; 3040 } 3041 3042 static IrInstruction *ir_build_tag_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 3043 IrInstruction *target) 3044 { 3045 IrInstructionTagType *instruction = ir_build_instruction<IrInstructionTagType>(irb, scope, source_node); 3046 instruction->target = target; 3047 3048 ir_ref_instruction(target, irb->current_basic_block); 3049 3050 return &instruction->base; 3051 } 3052 3053 static IrInstruction *ir_build_field_parent_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 3054 IrInstruction *type_value, IrInstruction *field_name, IrInstruction *field_ptr, TypeStructField *field) 3055 { 3056 IrInstructionFieldParentPtr *instruction = ir_build_instruction<IrInstructionFieldParentPtr>( 3057 irb, scope, source_node); 3058 instruction->type_value = type_value; 3059 instruction->field_name = field_name; 3060 instruction->field_ptr = field_ptr; 3061 instruction->field = field; 3062 3063 ir_ref_instruction(type_value, irb->current_basic_block); 3064 ir_ref_instruction(field_name, irb->current_basic_block); 3065 ir_ref_instruction(field_ptr, irb->current_basic_block); 3066 3067 return &instruction->base; 3068 } 3069 3070 static IrInstruction *ir_build_byte_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node, 3071 IrInstruction *type_value, IrInstruction *field_name) 3072 { 3073 IrInstructionByteOffsetOf *instruction = ir_build_instruction<IrInstructionByteOffsetOf>(irb, scope, source_node); 3074 instruction->type_value = type_value; 3075 instruction->field_name = field_name; 3076 3077 ir_ref_instruction(type_value, irb->current_basic_block); 3078 ir_ref_instruction(field_name, irb->current_basic_block); 3079 3080 return &instruction->base; 3081 } 3082 3083 static IrInstruction *ir_build_bit_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node, 3084 IrInstruction *type_value, IrInstruction *field_name) 3085 { 3086 IrInstructionBitOffsetOf *instruction = ir_build_instruction<IrInstructionBitOffsetOf>(irb, scope, source_node); 3087 instruction->type_value = type_value; 3088 instruction->field_name = field_name; 3089 3090 ir_ref_instruction(type_value, irb->current_basic_block); 3091 ir_ref_instruction(field_name, irb->current_basic_block); 3092 3093 return &instruction->base; 3094 } 3095 3096 static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *source_node, 3097 IrInstruction *type_value) { 3098 IrInstructionTypeInfo *instruction = ir_build_instruction<IrInstructionTypeInfo>(irb, scope, source_node); 3099 instruction->type_value = type_value; 3100 3101 ir_ref_instruction(type_value, irb->current_basic_block); 3102 3103 return &instruction->base; 3104 } 3105 3106 static IrInstruction *ir_build_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_info) { 3107 IrInstructionType *instruction = ir_build_instruction<IrInstructionType>(irb, scope, source_node); 3108 instruction->type_info = type_info; 3109 3110 ir_ref_instruction(type_info, irb->current_basic_block); 3111 3112 return &instruction->base; 3113 } 3114 3115 static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node, 3116 IrInstruction *type_value) 3117 { 3118 IrInstructionTypeId *instruction = ir_build_instruction<IrInstructionTypeId>(irb, scope, source_node); 3119 instruction->type_value = type_value; 3120 3121 ir_ref_instruction(type_value, irb->current_basic_block); 3122 3123 return &instruction->base; 3124 } 3125 3126 static IrInstruction *ir_build_set_eval_branch_quota(IrBuilder *irb, Scope *scope, AstNode *source_node, 3127 IrInstruction *new_quota) 3128 { 3129 IrInstructionSetEvalBranchQuota *instruction = ir_build_instruction<IrInstructionSetEvalBranchQuota>(irb, scope, source_node); 3130 instruction->new_quota = new_quota; 3131 3132 ir_ref_instruction(new_quota, irb->current_basic_block); 3133 3134 return &instruction->base; 3135 } 3136 3137 static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 3138 IrInstruction *align_bytes, IrInstruction *target) 3139 { 3140 IrInstructionAlignCast *instruction = ir_build_instruction<IrInstructionAlignCast>(irb, scope, source_node); 3141 instruction->align_bytes = align_bytes; 3142 instruction->target = target; 3143 3144 if (align_bytes) ir_ref_instruction(align_bytes, irb->current_basic_block); 3145 ir_ref_instruction(target, irb->current_basic_block); 3146 3147 return &instruction->base; 3148 } 3149 3150 static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node, 3151 ResultLoc *result_loc, IrInstruction *ty) 3152 { 3153 IrInstructionResolveResult *instruction = ir_build_instruction<IrInstructionResolveResult>(irb, scope, source_node); 3154 instruction->result_loc = result_loc; 3155 instruction->ty = ty; 3156 3157 if (ty != nullptr) ir_ref_instruction(ty, irb->current_basic_block); 3158 3159 return &instruction->base; 3160 } 3161 3162 static IrInstruction *ir_build_reset_result(IrBuilder *irb, Scope *scope, AstNode *source_node, 3163 ResultLoc *result_loc) 3164 { 3165 IrInstructionResetResult *instruction = ir_build_instruction<IrInstructionResetResult>(irb, scope, source_node); 3166 instruction->result_loc = result_loc; 3167 3168 return &instruction->base; 3169 } 3170 3171 static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) { 3172 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); 3173 3174 return &instruction->base; 3175 } 3176 3177 static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, AstNode *source_node, 3178 IrInstruction *align_bytes) 3179 { 3180 IrInstructionSetAlignStack *instruction = ir_build_instruction<IrInstructionSetAlignStack>(irb, scope, source_node); 3181 instruction->align_bytes = align_bytes; 3182 3183 ir_ref_instruction(align_bytes, irb->current_basic_block); 3184 3185 return &instruction->base; 3186 } 3187 3188 static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 3189 IrInstruction *fn_type, IrInstruction *arg_index, bool allow_var) 3190 { 3191 IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node); 3192 instruction->fn_type = fn_type; 3193 instruction->arg_index = arg_index; 3194 instruction->allow_var = allow_var; 3195 3196 ir_ref_instruction(fn_type, irb->current_basic_block); 3197 ir_ref_instruction(arg_index, irb->current_basic_block); 3198 3199 return &instruction->base; 3200 } 3201 3202 static IrInstruction *ir_build_error_return_trace(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstructionErrorReturnTrace::Optional optional) { 3203 IrInstructionErrorReturnTrace *instruction = ir_build_instruction<IrInstructionErrorReturnTrace>(irb, scope, source_node); 3204 instruction->optional = optional; 3205 3206 return &instruction->base; 3207 } 3208 3209 static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode *source_node, 3210 IrInstruction *err_set, IrInstruction *payload) 3211 { 3212 IrInstructionErrorUnion *instruction = ir_build_instruction<IrInstructionErrorUnion>(irb, scope, source_node); 3213 instruction->err_set = err_set; 3214 instruction->payload = payload; 3215 3216 ir_ref_instruction(err_set, irb->current_basic_block); 3217 ir_ref_instruction(payload, irb->current_basic_block); 3218 3219 return &instruction->base; 3220 } 3221 3222 static IrInstruction *ir_build_atomic_rmw(IrBuilder *irb, Scope *scope, AstNode *source_node, 3223 IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *op, IrInstruction *operand, 3224 IrInstruction *ordering, AtomicRmwOp resolved_op, AtomicOrder resolved_ordering) 3225 { 3226 IrInstructionAtomicRmw *instruction = ir_build_instruction<IrInstructionAtomicRmw>(irb, scope, source_node); 3227 instruction->operand_type = operand_type; 3228 instruction->ptr = ptr; 3229 instruction->op = op; 3230 instruction->operand = operand; 3231 instruction->ordering = ordering; 3232 instruction->resolved_op = resolved_op; 3233 instruction->resolved_ordering = resolved_ordering; 3234 3235 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); 3236 ir_ref_instruction(ptr, irb->current_basic_block); 3237 if (op != nullptr) ir_ref_instruction(op, irb->current_basic_block); 3238 ir_ref_instruction(operand, irb->current_basic_block); 3239 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); 3240 3241 return &instruction->base; 3242 } 3243 3244 static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode *source_node, 3245 IrInstruction *operand_type, IrInstruction *ptr, 3246 IrInstruction *ordering, AtomicOrder resolved_ordering) 3247 { 3248 IrInstructionAtomicLoad *instruction = ir_build_instruction<IrInstructionAtomicLoad>(irb, scope, source_node); 3249 instruction->operand_type = operand_type; 3250 instruction->ptr = ptr; 3251 instruction->ordering = ordering; 3252 instruction->resolved_ordering = resolved_ordering; 3253 3254 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); 3255 ir_ref_instruction(ptr, irb->current_basic_block); 3256 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); 3257 3258 return &instruction->base; 3259 } 3260 3261 static IrInstruction *ir_build_atomic_store(IrBuilder *irb, Scope *scope, AstNode *source_node, 3262 IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *value, 3263 IrInstruction *ordering, AtomicOrder resolved_ordering) 3264 { 3265 IrInstructionAtomicStore *instruction = ir_build_instruction<IrInstructionAtomicStore>(irb, scope, source_node); 3266 instruction->operand_type = operand_type; 3267 instruction->ptr = ptr; 3268 instruction->value = value; 3269 instruction->ordering = ordering; 3270 instruction->resolved_ordering = resolved_ordering; 3271 3272 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); 3273 ir_ref_instruction(ptr, irb->current_basic_block); 3274 ir_ref_instruction(value, irb->current_basic_block); 3275 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); 3276 3277 return &instruction->base; 3278 } 3279 3280 static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) { 3281 IrInstructionSaveErrRetAddr *instruction = ir_build_instruction<IrInstructionSaveErrRetAddr>(irb, scope, source_node); 3282 return &instruction->base; 3283 } 3284 3285 static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 3286 IrInstruction *value, ResultLocReturn *result_loc_ret) 3287 { 3288 IrInstructionAddImplicitReturnType *instruction = ir_build_instruction<IrInstructionAddImplicitReturnType>(irb, scope, source_node); 3289 instruction->value = value; 3290 instruction->result_loc_ret = result_loc_ret; 3291 3292 ir_ref_instruction(value, irb->current_basic_block); 3293 3294 return &instruction->base; 3295 } 3296 3297 static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *source_node, 3298 IrInstruction *container, IrInstruction *name) 3299 { 3300 IrInstructionHasDecl *instruction = ir_build_instruction<IrInstructionHasDecl>(irb, scope, source_node); 3301 instruction->container = container; 3302 instruction->name = name; 3303 3304 ir_ref_instruction(container, irb->current_basic_block); 3305 ir_ref_instruction(name, irb->current_basic_block); 3306 3307 return &instruction->base; 3308 } 3309 3310 static IrInstruction *ir_build_undeclared_identifier(IrBuilder *irb, Scope *scope, AstNode *source_node, 3311 Buf *name) 3312 { 3313 IrInstructionUndeclaredIdent *instruction = ir_build_instruction<IrInstructionUndeclaredIdent>(irb, scope, source_node); 3314 instruction->name = name; 3315 3316 return &instruction->base; 3317 } 3318 3319 static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { 3320 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node); 3321 instruction->scope_is_comptime = scope_is_comptime; 3322 instruction->is_comptime = is_comptime; 3323 3324 ir_ref_instruction(scope_is_comptime, irb->current_basic_block); 3325 ir_ref_instruction(is_comptime, irb->current_basic_block); 3326 3327 return &instruction->base; 3328 } 3329 3330 static IrInstruction *ir_build_union_init_named_field(IrBuilder *irb, Scope *scope, AstNode *source_node, 3331 IrInstruction *union_type, IrInstruction *field_name, IrInstruction *field_result_loc, IrInstruction *result_loc) 3332 { 3333 IrInstructionUnionInitNamedField *instruction = ir_build_instruction<IrInstructionUnionInitNamedField>(irb, scope, source_node); 3334 instruction->union_type = union_type; 3335 instruction->field_name = field_name; 3336 instruction->field_result_loc = field_result_loc; 3337 instruction->result_loc = result_loc; 3338 3339 ir_ref_instruction(union_type, irb->current_basic_block); 3340 ir_ref_instruction(field_name, irb->current_basic_block); 3341 ir_ref_instruction(field_result_loc, irb->current_basic_block); 3342 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 3343 3344 return &instruction->base; 3345 } 3346 3347 3348 static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction, 3349 ZigType *result_type, IrInstruction *vector, IrInstruction *result_loc) 3350 { 3351 IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb, 3352 source_instruction->scope, source_instruction->source_node); 3353 instruction->base.value->type = result_type; 3354 instruction->vector = vector; 3355 instruction->result_loc = result_loc; 3356 3357 ir_ref_instruction(vector, ira->new_irb.current_basic_block); 3358 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 3359 3360 return &instruction->base; 3361 } 3362 3363 static IrInstruction *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instruction, 3364 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) 3365 { 3366 IrInstructionPtrOfArrayToSlice *instruction = ir_build_instruction<IrInstructionPtrOfArrayToSlice>(&ira->new_irb, 3367 source_instruction->scope, source_instruction->source_node); 3368 instruction->base.value->type = result_type; 3369 instruction->operand = operand; 3370 instruction->result_loc = result_loc; 3371 3372 ir_ref_instruction(operand, ira->new_irb.current_basic_block); 3373 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 3374 3375 return &instruction->base; 3376 } 3377 3378 static IrInstruction *ir_build_array_to_vector(IrAnalyze *ira, IrInstruction *source_instruction, 3379 IrInstruction *array, ZigType *result_type) 3380 { 3381 IrInstructionArrayToVector *instruction = ir_build_instruction<IrInstructionArrayToVector>(&ira->new_irb, 3382 source_instruction->scope, source_instruction->source_node); 3383 instruction->base.value->type = result_type; 3384 instruction->array = array; 3385 3386 ir_ref_instruction(array, ira->new_irb.current_basic_block); 3387 3388 return &instruction->base; 3389 } 3390 3391 static IrInstruction *ir_build_assert_zero(IrAnalyze *ira, IrInstruction *source_instruction, 3392 IrInstruction *target) 3393 { 3394 IrInstructionAssertZero *instruction = ir_build_instruction<IrInstructionAssertZero>(&ira->new_irb, 3395 source_instruction->scope, source_instruction->source_node); 3396 instruction->base.value->type = ira->codegen->builtin_types.entry_void; 3397 instruction->target = target; 3398 3399 ir_ref_instruction(target, ira->new_irb.current_basic_block); 3400 3401 return &instruction->base; 3402 } 3403 3404 static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *source_instruction, 3405 IrInstruction *target) 3406 { 3407 IrInstructionAssertNonNull *instruction = ir_build_instruction<IrInstructionAssertNonNull>(&ira->new_irb, 3408 source_instruction->scope, source_instruction->source_node); 3409 instruction->base.value->type = ira->codegen->builtin_types.entry_void; 3410 instruction->target = target; 3411 3412 ir_ref_instruction(target, ira->new_irb.current_basic_block); 3413 3414 return &instruction->base; 3415 } 3416 3417 static IrInstruction *ir_build_alloca_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 3418 IrInstruction *align, const char *name_hint, IrInstruction *is_comptime) 3419 { 3420 IrInstructionAllocaSrc *instruction = ir_build_instruction<IrInstructionAllocaSrc>(irb, scope, source_node); 3421 instruction->base.is_gen = true; 3422 instruction->align = align; 3423 instruction->name_hint = name_hint; 3424 instruction->is_comptime = is_comptime; 3425 3426 if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block); 3427 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); 3428 3429 return &instruction->base; 3430 } 3431 3432 static IrInstructionAllocaGen *ir_build_alloca_gen(IrAnalyze *ira, IrInstruction *source_instruction, 3433 uint32_t align, const char *name_hint) 3434 { 3435 IrInstructionAllocaGen *instruction = ir_create_instruction<IrInstructionAllocaGen>(&ira->new_irb, 3436 source_instruction->scope, source_instruction->source_node); 3437 instruction->align = align; 3438 instruction->name_hint = name_hint; 3439 3440 return instruction; 3441 } 3442 3443 static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, 3444 IrInstruction *value, ResultLoc *result_loc) 3445 { 3446 IrInstructionEndExpr *instruction = ir_build_instruction<IrInstructionEndExpr>(irb, scope, source_node); 3447 instruction->base.is_gen = true; 3448 instruction->value = value; 3449 instruction->result_loc = result_loc; 3450 3451 ir_ref_instruction(value, irb->current_basic_block); 3452 3453 return &instruction->base; 3454 } 3455 3456 static IrInstructionSuspendBegin *ir_build_suspend_begin(IrBuilder *irb, Scope *scope, AstNode *source_node) { 3457 IrInstructionSuspendBegin *instruction = ir_build_instruction<IrInstructionSuspendBegin>(irb, scope, source_node); 3458 instruction->base.value->type = irb->codegen->builtin_types.entry_void; 3459 3460 return instruction; 3461 } 3462 3463 static IrInstruction *ir_build_suspend_finish(IrBuilder *irb, Scope *scope, AstNode *source_node, 3464 IrInstructionSuspendBegin *begin) 3465 { 3466 IrInstructionSuspendFinish *instruction = ir_build_instruction<IrInstructionSuspendFinish>(irb, scope, source_node); 3467 instruction->base.value->type = irb->codegen->builtin_types.entry_void; 3468 instruction->begin = begin; 3469 3470 ir_ref_instruction(&begin->base, irb->current_basic_block); 3471 3472 return &instruction->base; 3473 } 3474 3475 static IrInstruction *ir_build_await_src(IrBuilder *irb, Scope *scope, AstNode *source_node, 3476 IrInstruction *frame, ResultLoc *result_loc) 3477 { 3478 IrInstructionAwaitSrc *instruction = ir_build_instruction<IrInstructionAwaitSrc>(irb, scope, source_node); 3479 instruction->frame = frame; 3480 instruction->result_loc = result_loc; 3481 3482 ir_ref_instruction(frame, irb->current_basic_block); 3483 3484 return &instruction->base; 3485 } 3486 3487 static IrInstructionAwaitGen *ir_build_await_gen(IrAnalyze *ira, IrInstruction *source_instruction, 3488 IrInstruction *frame, ZigType *result_type, IrInstruction *result_loc) 3489 { 3490 IrInstructionAwaitGen *instruction = ir_build_instruction<IrInstructionAwaitGen>(&ira->new_irb, 3491 source_instruction->scope, source_instruction->source_node); 3492 instruction->base.value->type = result_type; 3493 instruction->frame = frame; 3494 instruction->result_loc = result_loc; 3495 3496 ir_ref_instruction(frame, ira->new_irb.current_basic_block); 3497 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); 3498 3499 return instruction; 3500 } 3501 3502 static IrInstruction *ir_build_resume(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *frame) { 3503 IrInstructionResume *instruction = ir_build_instruction<IrInstructionResume>(irb, scope, source_node); 3504 instruction->base.value->type = irb->codegen->builtin_types.entry_void; 3505 instruction->frame = frame; 3506 3507 ir_ref_instruction(frame, irb->current_basic_block); 3508 3509 return &instruction->base; 3510 } 3511 3512 static IrInstructionSpillBegin *ir_build_spill_begin(IrBuilder *irb, Scope *scope, AstNode *source_node, 3513 IrInstruction *operand, SpillId spill_id) 3514 { 3515 IrInstructionSpillBegin *instruction = ir_build_instruction<IrInstructionSpillBegin>(irb, scope, source_node); 3516 instruction->base.value->special = ConstValSpecialStatic; 3517 instruction->base.value->type = irb->codegen->builtin_types.entry_void; 3518 instruction->operand = operand; 3519 instruction->spill_id = spill_id; 3520 3521 ir_ref_instruction(operand, irb->current_basic_block); 3522 3523 return instruction; 3524 } 3525 3526 static IrInstruction *ir_build_spill_end(IrBuilder *irb, Scope *scope, AstNode *source_node, 3527 IrInstructionSpillBegin *begin) 3528 { 3529 IrInstructionSpillEnd *instruction = ir_build_instruction<IrInstructionSpillEnd>(irb, scope, source_node); 3530 instruction->begin = begin; 3531 3532 ir_ref_instruction(&begin->base, irb->current_basic_block); 3533 3534 return &instruction->base; 3535 } 3536 3537 static IrInstruction *ir_build_vector_extract_elem(IrAnalyze *ira, IrInstruction *source_instruction, 3538 IrInstruction *vector, IrInstruction *index) 3539 { 3540 IrInstructionVectorExtractElem *instruction = ir_build_instruction<IrInstructionVectorExtractElem>( 3541 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3542 instruction->base.value->type = vector->value->type->data.vector.elem_type; 3543 instruction->vector = vector; 3544 instruction->index = index; 3545 3546 ir_ref_instruction(vector, ira->new_irb.current_basic_block); 3547 ir_ref_instruction(index, ira->new_irb.current_basic_block); 3548 3549 return &instruction->base; 3550 } 3551 3552 static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { 3553 results[ReturnKindUnconditional] = 0; 3554 results[ReturnKindError] = 0; 3555 3556 Scope *scope = inner_scope; 3557 3558 while (scope != outer_scope) { 3559 assert(scope); 3560 switch (scope->id) { 3561 case ScopeIdDefer: { 3562 AstNode *defer_node = scope->source_node; 3563 assert(defer_node->type == NodeTypeDefer); 3564 ReturnKind defer_kind = defer_node->data.defer.kind; 3565 results[defer_kind] += 1; 3566 scope = scope->parent; 3567 continue; 3568 } 3569 case ScopeIdDecls: 3570 case ScopeIdFnDef: 3571 return; 3572 case ScopeIdBlock: 3573 case ScopeIdVarDecl: 3574 case ScopeIdLoop: 3575 case ScopeIdSuspend: 3576 case ScopeIdCompTime: 3577 case ScopeIdRuntime: 3578 case ScopeIdTypeOf: 3579 case ScopeIdExpr: 3580 scope = scope->parent; 3581 continue; 3582 case ScopeIdDeferExpr: 3583 case ScopeIdCImport: 3584 zig_unreachable(); 3585 } 3586 } 3587 } 3588 3589 static IrInstruction *ir_mark_gen(IrInstruction *instruction) { 3590 instruction->is_gen = true; 3591 return instruction; 3592 } 3593 3594 static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers) { 3595 Scope *scope = inner_scope; 3596 bool is_noreturn = false; 3597 while (scope != outer_scope) { 3598 if (!scope) 3599 return is_noreturn; 3600 3601 switch (scope->id) { 3602 case ScopeIdDefer: { 3603 AstNode *defer_node = scope->source_node; 3604 assert(defer_node->type == NodeTypeDefer); 3605 ReturnKind defer_kind = defer_node->data.defer.kind; 3606 if (defer_kind == ReturnKindUnconditional || 3607 (gen_error_defers && defer_kind == ReturnKindError)) 3608 { 3609 AstNode *defer_expr_node = defer_node->data.defer.expr; 3610 Scope *defer_expr_scope = defer_node->data.defer.expr_scope; 3611 IrInstruction *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); 3612 if (defer_expr_value != irb->codegen->invalid_instruction) { 3613 if (defer_expr_value->value->type != nullptr && 3614 defer_expr_value->value->type->id == ZigTypeIdUnreachable) 3615 { 3616 is_noreturn = true; 3617 } else { 3618 ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, 3619 defer_expr_value)); 3620 } 3621 } 3622 } 3623 scope = scope->parent; 3624 continue; 3625 } 3626 case ScopeIdDecls: 3627 case ScopeIdFnDef: 3628 return is_noreturn; 3629 case ScopeIdBlock: 3630 case ScopeIdVarDecl: 3631 case ScopeIdLoop: 3632 case ScopeIdSuspend: 3633 case ScopeIdCompTime: 3634 case ScopeIdRuntime: 3635 case ScopeIdTypeOf: 3636 case ScopeIdExpr: 3637 scope = scope->parent; 3638 continue; 3639 case ScopeIdDeferExpr: 3640 case ScopeIdCImport: 3641 zig_unreachable(); 3642 } 3643 } 3644 return is_noreturn; 3645 } 3646 3647 static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { 3648 assert(basic_block); 3649 3650 irb->current_basic_block = basic_block; 3651 } 3652 3653 static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) { 3654 basic_block->index = irb->exec->basic_block_list.length; 3655 irb->exec->basic_block_list.append(basic_block); 3656 ir_set_cursor_at_end(irb, basic_block); 3657 } 3658 3659 static ScopeSuspend *get_scope_suspend(Scope *scope) { 3660 while (scope) { 3661 if (scope->id == ScopeIdSuspend) 3662 return (ScopeSuspend *)scope; 3663 if (scope->id == ScopeIdFnDef) 3664 return nullptr; 3665 3666 scope = scope->parent; 3667 } 3668 return nullptr; 3669 } 3670 3671 static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { 3672 while (scope) { 3673 if (scope->id == ScopeIdDeferExpr) 3674 return (ScopeDeferExpr *)scope; 3675 if (scope->id == ScopeIdFnDef) 3676 return nullptr; 3677 3678 scope = scope->parent; 3679 } 3680 return nullptr; 3681 } 3682 3683 static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 3684 assert(node->type == NodeTypeReturnExpr); 3685 3686 ZigFn *fn_entry = exec_fn_entry(irb->exec); 3687 if (!fn_entry) { 3688 add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition")); 3689 return irb->codegen->invalid_instruction; 3690 } 3691 3692 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); 3693 if (scope_defer_expr) { 3694 if (!scope_defer_expr->reported_err) { 3695 add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression")); 3696 scope_defer_expr->reported_err = true; 3697 } 3698 return irb->codegen->invalid_instruction; 3699 } 3700 3701 Scope *outer_scope = irb->exec->begin_scope; 3702 3703 AstNode *expr_node = node->data.return_expr.expr; 3704 switch (node->data.return_expr.kind) { 3705 case ReturnKindUnconditional: 3706 { 3707 ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1, "ResultLocReturn"); 3708 result_loc_ret->base.id = ResultLocIdReturn; 3709 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 3710 3711 IrInstruction *return_value; 3712 if (expr_node) { 3713 // Temporarily set this so that if we return a type it gets the name of the function 3714 ZigFn *prev_name_fn = irb->exec->name_fn; 3715 irb->exec->name_fn = exec_fn_entry(irb->exec); 3716 return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base); 3717 irb->exec->name_fn = prev_name_fn; 3718 if (return_value == irb->codegen->invalid_instruction) 3719 return irb->codegen->invalid_instruction; 3720 } else { 3721 return_value = ir_build_const_void(irb, scope, node); 3722 } 3723 3724 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value, result_loc_ret)); 3725 3726 size_t defer_counts[2]; 3727 ir_count_defers(irb, scope, outer_scope, defer_counts); 3728 bool have_err_defers = defer_counts[ReturnKindError] > 0; 3729 if (!have_err_defers && !irb->codegen->have_err_ret_tracing) { 3730 // only generate unconditional defers 3731 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3732 IrInstruction *result = ir_build_return(irb, scope, node, return_value); 3733 result_loc_ret->base.source_instruction = result; 3734 return result; 3735 } 3736 bool should_inline = ir_should_inline(irb->exec, scope); 3737 3738 IrBasicBlock *err_block = ir_create_basic_block(irb, scope, "ErrRetErr"); 3739 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk"); 3740 3741 if (!have_err_defers) { 3742 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3743 } 3744 3745 IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, return_value, false, true); 3746 3747 IrInstruction *is_comptime; 3748 if (should_inline) { 3749 is_comptime = ir_build_const_bool(irb, scope, node, should_inline); 3750 } else { 3751 is_comptime = ir_build_test_comptime(irb, scope, node, is_err); 3752 } 3753 3754 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); 3755 IrBasicBlock *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt"); 3756 3757 ir_set_cursor_at_end_and_append_block(irb, err_block); 3758 if (have_err_defers) { 3759 ir_gen_defers_for_block(irb, scope, outer_scope, true); 3760 } 3761 if (irb->codegen->have_err_ret_tracing && !should_inline) { 3762 ir_build_save_err_ret_addr(irb, scope, node); 3763 } 3764 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 3765 3766 ir_set_cursor_at_end_and_append_block(irb, ok_block); 3767 if (have_err_defers) { 3768 ir_gen_defers_for_block(irb, scope, outer_scope, false); 3769 } 3770 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 3771 3772 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); 3773 IrInstruction *result = ir_build_return(irb, scope, node, return_value); 3774 result_loc_ret->base.source_instruction = result; 3775 return result; 3776 } 3777 case ReturnKindError: 3778 { 3779 assert(expr_node); 3780 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 3781 if (err_union_ptr == irb->codegen->invalid_instruction) 3782 return irb->codegen->invalid_instruction; 3783 IrInstruction *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true, false); 3784 3785 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); 3786 IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); 3787 IrInstruction *is_comptime; 3788 bool should_inline = ir_should_inline(irb->exec, scope); 3789 if (should_inline) { 3790 is_comptime = ir_build_const_bool(irb, scope, node, true); 3791 } else { 3792 is_comptime = ir_build_test_comptime(irb, scope, node, is_err_val); 3793 } 3794 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime)); 3795 3796 ir_set_cursor_at_end_and_append_block(irb, return_block); 3797 IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); 3798 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 3799 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val, nullptr)); 3800 IrInstructionSpillBegin *spill_begin = ir_build_spill_begin(irb, scope, node, err_val, 3801 SpillIdRetErrCode); 3802 ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1, "ResultLocReturn"); 3803 result_loc_ret->base.id = ResultLocIdReturn; 3804 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 3805 ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base); 3806 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { 3807 if (irb->codegen->have_err_ret_tracing && !should_inline) { 3808 ir_build_save_err_ret_addr(irb, scope, node); 3809 } 3810 err_val = ir_build_spill_end(irb, scope, node, spill_begin); 3811 IrInstruction *ret_inst = ir_build_return(irb, scope, node, err_val); 3812 result_loc_ret->base.source_instruction = ret_inst; 3813 } 3814 3815 ir_set_cursor_at_end_and_append_block(irb, continue_block); 3816 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false, false); 3817 if (lval == LValPtr) 3818 return unwrapped_ptr; 3819 else 3820 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, unwrapped_ptr), result_loc); 3821 } 3822 } 3823 zig_unreachable(); 3824 } 3825 3826 static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope, 3827 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime, 3828 bool skip_name_check) 3829 { 3830 ZigVar *variable_entry = allocate<ZigVar>(1, "ZigVar"); 3831 variable_entry->parent_scope = parent_scope; 3832 variable_entry->shadowable = is_shadowable; 3833 variable_entry->mem_slot_index = SIZE_MAX; 3834 variable_entry->is_comptime = is_comptime; 3835 variable_entry->src_arg_index = SIZE_MAX; 3836 variable_entry->const_value = create_const_vals(1); 3837 3838 if (is_comptime != nullptr) { 3839 is_comptime->ref_count += 1; 3840 } 3841 3842 if (name) { 3843 variable_entry->name = strdup(buf_ptr(name)); 3844 3845 if (!skip_name_check) { 3846 ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr); 3847 if (existing_var && !existing_var->shadowable) { 3848 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) { 3849 ErrorMsg *msg = add_node_error(codegen, node, 3850 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); 3851 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); 3852 } 3853 variable_entry->var_type = codegen->builtin_types.entry_invalid; 3854 } else { 3855 ZigType *type; 3856 if (get_primitive_type(codegen, name, &type) != ErrorPrimitiveTypeNotFound) { 3857 add_node_error(codegen, node, 3858 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name))); 3859 variable_entry->var_type = codegen->builtin_types.entry_invalid; 3860 } else { 3861 Tld *tld = find_decl(codegen, parent_scope, name); 3862 if (tld != nullptr) { 3863 ErrorMsg *msg = add_node_error(codegen, node, 3864 buf_sprintf("redefinition of '%s'", buf_ptr(name))); 3865 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); 3866 variable_entry->var_type = codegen->builtin_types.entry_invalid; 3867 } 3868 } 3869 } 3870 } 3871 } else { 3872 assert(is_shadowable); 3873 // TODO make this name not actually be in scope. user should be able to make a variable called "_anon" 3874 // might already be solved, let's just make sure it has test coverage 3875 // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables 3876 variable_entry->name = "_anon"; 3877 } 3878 3879 variable_entry->src_is_const = src_is_const; 3880 variable_entry->gen_is_const = gen_is_const; 3881 variable_entry->decl_node = node; 3882 variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry); 3883 3884 return variable_entry; 3885 } 3886 3887 // Set name to nullptr to make the variable anonymous (not visible to programmer). 3888 // After you call this function var->child_scope has the variable in scope 3889 static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name, 3890 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime) 3891 { 3892 bool is_underscored = name ? buf_eql_str(name, "_") : false; 3893 ZigVar *var = create_local_var(irb->codegen, node, scope, 3894 (is_underscored ? nullptr : name), src_is_const, gen_is_const, 3895 (is_underscored ? true : is_shadowable), is_comptime, false); 3896 if (is_comptime != nullptr || gen_is_const) { 3897 var->mem_slot_index = exec_next_mem_slot(irb->exec); 3898 var->owner_exec = irb->exec; 3899 } 3900 assert(var->child_scope); 3901 return var; 3902 } 3903 3904 static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { 3905 ResultLocPeer *result = allocate<ResultLocPeer>(1, "ResultLocPeer"); 3906 result->base.id = ResultLocIdPeer; 3907 result->base.source_instruction = peer_parent->base.source_instruction; 3908 result->parent = peer_parent; 3909 result->base.allow_write_through_const = peer_parent->parent->allow_write_through_const; 3910 return result; 3911 } 3912 3913 static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node, LVal lval, 3914 ResultLoc *result_loc) 3915 { 3916 assert(block_node->type == NodeTypeBlock); 3917 3918 ZigList<IrInstruction *> incoming_values = {0}; 3919 ZigList<IrBasicBlock *> incoming_blocks = {0}; 3920 3921 ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope); 3922 3923 Scope *outer_block_scope = &scope_block->base; 3924 Scope *child_scope = outer_block_scope; 3925 3926 ZigFn *fn_entry = scope_fn_entry(parent_scope); 3927 if (fn_entry && fn_entry->child_scope == parent_scope) { 3928 fn_entry->def_scope = scope_block; 3929 } 3930 3931 if (block_node->data.block.statements.length == 0) { 3932 // {} 3933 return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc); 3934 } 3935 3936 if (block_node->data.block.name != nullptr) { 3937 scope_block->lval = lval; 3938 scope_block->incoming_blocks = &incoming_blocks; 3939 scope_block->incoming_values = &incoming_values; 3940 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); 3941 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, 3942 ir_should_inline(irb->exec, parent_scope)); 3943 3944 scope_block->peer_parent = allocate<ResultLocPeerParent>(1, "ResultLocPeerParent"); 3945 scope_block->peer_parent->base.id = ResultLocIdPeerParent; 3946 scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; 3947 scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; 3948 scope_block->peer_parent->end_bb = scope_block->end_block; 3949 scope_block->peer_parent->is_comptime = scope_block->is_comptime; 3950 scope_block->peer_parent->parent = result_loc; 3951 ir_build_reset_result(irb, parent_scope, block_node, &scope_block->peer_parent->base); 3952 } 3953 3954 bool is_continuation_unreachable = false; 3955 IrInstruction *noreturn_return_value = nullptr; 3956 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { 3957 AstNode *statement_node = block_node->data.block.statements.at(i); 3958 3959 IrInstruction *statement_value = ir_gen_node(irb, statement_node, child_scope); 3960 is_continuation_unreachable = instr_is_unreachable(statement_value); 3961 if (is_continuation_unreachable) { 3962 // keep the last noreturn statement value around in case we need to return it 3963 noreturn_return_value = statement_value; 3964 } 3965 // This logic must be kept in sync with 3966 // [STMT_EXPR_TEST_THING] <--- (search this token) 3967 if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { 3968 // defer starts a new scope 3969 child_scope = statement_node->data.defer.child_scope; 3970 assert(child_scope); 3971 } else if (statement_value->id == IrInstructionIdDeclVarSrc) { 3972 // variable declarations start a new scope 3973 IrInstructionDeclVarSrc *decl_var_instruction = (IrInstructionDeclVarSrc *)statement_value; 3974 child_scope = decl_var_instruction->var->child_scope; 3975 } else if (statement_value != irb->codegen->invalid_instruction && !is_continuation_unreachable) { 3976 // this statement's value must be void 3977 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); 3978 } 3979 } 3980 3981 if (is_continuation_unreachable) { 3982 assert(noreturn_return_value != nullptr); 3983 if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) { 3984 return noreturn_return_value; 3985 } 3986 3987 if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) { 3988 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; 3989 } 3990 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 3991 IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, 3992 incoming_blocks.items, incoming_values.items, scope_block->peer_parent); 3993 return ir_expr_wrap(irb, parent_scope, phi, result_loc); 3994 } else { 3995 incoming_blocks.append(irb->current_basic_block); 3996 IrInstruction *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)); 3997 3998 if (scope_block->peer_parent != nullptr) { 3999 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent); 4000 scope_block->peer_parent->peers.append(peer_result); 4001 ir_build_end_expr(irb, parent_scope, block_node, else_expr_result, &peer_result->base); 4002 4003 if (scope_block->peer_parent->peers.length != 0) { 4004 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; 4005 } 4006 } 4007 4008 incoming_values.append(else_expr_result); 4009 } 4010 4011 bool is_return_from_fn = block_node == irb->main_block_node; 4012 if (!is_return_from_fn) { 4013 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 4014 } 4015 4016 IrInstruction *result; 4017 if (block_node->data.block.name != nullptr) { 4018 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); 4019 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 4020 IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, 4021 incoming_blocks.items, incoming_values.items, scope_block->peer_parent); 4022 result = ir_expr_wrap(irb, parent_scope, phi, result_loc); 4023 } else { 4024 IrInstruction *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); 4025 result = ir_lval_wrap(irb, parent_scope, void_inst, lval, result_loc); 4026 } 4027 if (!is_return_from_fn) 4028 return result; 4029 4030 // no need for save_err_ret_addr because this cannot return error 4031 // only generate unconditional defers 4032 4033 ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result, nullptr)); 4034 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 4035 return ir_mark_gen(ir_build_return(irb, child_scope, result->source_node, result)); 4036 } 4037 4038 static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 4039 Scope *inner_scope = scope; 4040 if (op_id == IrBinOpArrayCat || op_id == IrBinOpArrayMult) { 4041 inner_scope = create_comptime_scope(irb->codegen, node, scope); 4042 } 4043 4044 IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, inner_scope); 4045 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, inner_scope); 4046 4047 if (op1 == irb->codegen->invalid_instruction || op2 == irb->codegen->invalid_instruction) 4048 return irb->codegen->invalid_instruction; 4049 4050 return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 4051 } 4052 4053 static IrInstruction *ir_gen_merge_err_sets(IrBuilder *irb, Scope *scope, AstNode *node) { 4054 IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 4055 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 4056 4057 if (op1 == irb->codegen->invalid_instruction || op2 == irb->codegen->invalid_instruction) 4058 return irb->codegen->invalid_instruction; 4059 4060 // TODO only pass type_name when the || operator is the top level AST node in the var decl expr 4061 Buf bare_name = BUF_INIT; 4062 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", scope, node, &bare_name); 4063 4064 return ir_build_merge_err_sets(irb, scope, node, op1, op2, type_name); 4065 } 4066 4067 static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { 4068 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); 4069 if (lvalue == irb->codegen->invalid_instruction) 4070 return irb->codegen->invalid_instruction; 4071 4072 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1, "ResultLocInstruction"); 4073 result_loc_inst->base.id = ResultLocIdInstruction; 4074 result_loc_inst->base.source_instruction = lvalue; 4075 ir_ref_instruction(lvalue, irb->current_basic_block); 4076 ir_build_reset_result(irb, scope, node, &result_loc_inst->base); 4077 4078 IrInstruction *rvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op2, scope, LValNone, 4079 &result_loc_inst->base); 4080 if (rvalue == irb->codegen->invalid_instruction) 4081 return irb->codegen->invalid_instruction; 4082 4083 return ir_build_const_void(irb, scope, node); 4084 } 4085 4086 static IrInstruction *ir_gen_assign_merge_err_sets(IrBuilder *irb, Scope *scope, AstNode *node) { 4087 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); 4088 if (lvalue == irb->codegen->invalid_instruction) 4089 return lvalue; 4090 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 4091 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 4092 if (op2 == irb->codegen->invalid_instruction) 4093 return op2; 4094 IrInstruction *result = ir_build_merge_err_sets(irb, scope, node, op1, op2, nullptr); 4095 ir_build_store_ptr(irb, scope, node, lvalue, result); 4096 return ir_build_const_void(irb, scope, node); 4097 } 4098 4099 static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 4100 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); 4101 if (lvalue == irb->codegen->invalid_instruction) 4102 return lvalue; 4103 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 4104 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 4105 if (op2 == irb->codegen->invalid_instruction) 4106 return op2; 4107 IrInstruction *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 4108 ir_build_store_ptr(irb, scope, node, lvalue, result); 4109 return ir_build_const_void(irb, scope, node); 4110 } 4111 4112 static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node) { 4113 assert(node->type == NodeTypeBinOpExpr); 4114 4115 IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 4116 if (val1 == irb->codegen->invalid_instruction) 4117 return irb->codegen->invalid_instruction; 4118 IrBasicBlock *post_val1_block = irb->current_basic_block; 4119 4120 IrInstruction *is_comptime; 4121 if (ir_should_inline(irb->exec, scope)) { 4122 is_comptime = ir_build_const_bool(irb, scope, node, true); 4123 } else { 4124 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 4125 } 4126 4127 // block for when val1 == false 4128 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse"); 4129 // block for when val1 == true (don't even evaluate the second part) 4130 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue"); 4131 4132 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 4133 4134 ir_set_cursor_at_end_and_append_block(irb, false_block); 4135 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 4136 if (val2 == irb->codegen->invalid_instruction) 4137 return irb->codegen->invalid_instruction; 4138 IrBasicBlock *post_val2_block = irb->current_basic_block; 4139 4140 ir_build_br(irb, scope, node, true_block, is_comptime); 4141 4142 ir_set_cursor_at_end_and_append_block(irb, true_block); 4143 4144 IrInstruction **incoming_values = allocate<IrInstruction *>(2, "IrInstruction *"); 4145 incoming_values[0] = val1; 4146 incoming_values[1] = val2; 4147 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *"); 4148 incoming_blocks[0] = post_val1_block; 4149 incoming_blocks[1] = post_val2_block; 4150 4151 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); 4152 } 4153 4154 static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { 4155 assert(node->type == NodeTypeBinOpExpr); 4156 4157 IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 4158 if (val1 == irb->codegen->invalid_instruction) 4159 return irb->codegen->invalid_instruction; 4160 IrBasicBlock *post_val1_block = irb->current_basic_block; 4161 4162 IrInstruction *is_comptime; 4163 if (ir_should_inline(irb->exec, scope)) { 4164 is_comptime = ir_build_const_bool(irb, scope, node, true); 4165 } else { 4166 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 4167 } 4168 4169 // block for when val1 == true 4170 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue"); 4171 // block for when val1 == false (don't even evaluate the second part) 4172 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse"); 4173 4174 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 4175 4176 ir_set_cursor_at_end_and_append_block(irb, true_block); 4177 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 4178 if (val2 == irb->codegen->invalid_instruction) 4179 return irb->codegen->invalid_instruction; 4180 IrBasicBlock *post_val2_block = irb->current_basic_block; 4181 4182 ir_build_br(irb, scope, node, false_block, is_comptime); 4183 4184 ir_set_cursor_at_end_and_append_block(irb, false_block); 4185 4186 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 4187 incoming_values[0] = val1; 4188 incoming_values[1] = val2; 4189 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 4190 incoming_blocks[0] = post_val1_block; 4191 incoming_blocks[1] = post_val2_block; 4192 4193 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); 4194 } 4195 4196 static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, 4197 IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) 4198 { 4199 ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); 4200 peer_parent->base.id = ResultLocIdPeerParent; 4201 peer_parent->base.source_instruction = cond_br_inst; 4202 peer_parent->base.allow_write_through_const = parent->allow_write_through_const; 4203 peer_parent->end_bb = end_block; 4204 peer_parent->is_comptime = is_comptime; 4205 peer_parent->parent = parent; 4206 4207 IrInstruction *popped_inst = irb->current_basic_block->instruction_list.pop(); 4208 ir_assert(popped_inst == cond_br_inst, cond_br_inst); 4209 4210 ir_build_reset_result(irb, cond_br_inst->scope, cond_br_inst->source_node, &peer_parent->base); 4211 irb->current_basic_block->instruction_list.append(popped_inst); 4212 4213 return peer_parent; 4214 } 4215 4216 static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, 4217 IrBasicBlock *else_block, IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) 4218 { 4219 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime); 4220 4221 peer_parent->peers.append(create_peer_result(peer_parent)); 4222 peer_parent->peers.last()->next_bb = else_block; 4223 4224 peer_parent->peers.append(create_peer_result(peer_parent)); 4225 peer_parent->peers.last()->next_bb = end_block; 4226 4227 return peer_parent; 4228 } 4229 4230 static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, 4231 ResultLoc *result_loc) 4232 { 4233 assert(node->type == NodeTypeBinOpExpr); 4234 4235 AstNode *op1_node = node->data.bin_op_expr.op1; 4236 AstNode *op2_node = node->data.bin_op_expr.op2; 4237 4238 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); 4239 if (maybe_ptr == irb->codegen->invalid_instruction) 4240 return irb->codegen->invalid_instruction; 4241 4242 IrInstruction *maybe_val = ir_build_load_ptr(irb, parent_scope, node, maybe_ptr); 4243 IrInstruction *is_non_null = ir_build_test_nonnull(irb, parent_scope, node, maybe_val); 4244 4245 IrInstruction *is_comptime; 4246 if (ir_should_inline(irb->exec, parent_scope)) { 4247 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 4248 } else { 4249 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_non_null); 4250 } 4251 4252 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); 4253 IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); 4254 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); 4255 IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); 4256 4257 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, 4258 result_loc, is_comptime); 4259 4260 ir_set_cursor_at_end_and_append_block(irb, null_block); 4261 IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone, 4262 &peer_parent->peers.at(0)->base); 4263 if (null_result == irb->codegen->invalid_instruction) 4264 return irb->codegen->invalid_instruction; 4265 IrBasicBlock *after_null_block = irb->current_basic_block; 4266 if (!instr_is_unreachable(null_result)) 4267 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 4268 4269 ir_set_cursor_at_end_and_append_block(irb, ok_block); 4270 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false); 4271 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 4272 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); 4273 IrBasicBlock *after_ok_block = irb->current_basic_block; 4274 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 4275 4276 ir_set_cursor_at_end_and_append_block(irb, end_block); 4277 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 4278 incoming_values[0] = null_result; 4279 incoming_values[1] = unwrapped_payload; 4280 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 4281 incoming_blocks[0] = after_null_block; 4282 incoming_blocks[1] = after_ok_block; 4283 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); 4284 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 4285 } 4286 4287 static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 4288 assert(node->type == NodeTypeBinOpExpr); 4289 4290 AstNode *op1_node = node->data.bin_op_expr.op1; 4291 AstNode *op2_node = node->data.bin_op_expr.op2; 4292 4293 IrInstruction *err_set = ir_gen_node(irb, op1_node, parent_scope); 4294 if (err_set == irb->codegen->invalid_instruction) 4295 return irb->codegen->invalid_instruction; 4296 4297 IrInstruction *payload = ir_gen_node(irb, op2_node, parent_scope); 4298 if (payload == irb->codegen->invalid_instruction) 4299 return irb->codegen->invalid_instruction; 4300 4301 return ir_build_error_union(irb, parent_scope, node, err_set, payload); 4302 } 4303 4304 static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 4305 assert(node->type == NodeTypeBinOpExpr); 4306 4307 BinOpType bin_op_type = node->data.bin_op_expr.bin_op; 4308 switch (bin_op_type) { 4309 case BinOpTypeInvalid: 4310 zig_unreachable(); 4311 case BinOpTypeAssign: 4312 return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc); 4313 case BinOpTypeAssignTimes: 4314 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc); 4315 case BinOpTypeAssignTimesWrap: 4316 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc); 4317 case BinOpTypeAssignDiv: 4318 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); 4319 case BinOpTypeAssignMod: 4320 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); 4321 case BinOpTypeAssignPlus: 4322 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc); 4323 case BinOpTypeAssignPlusWrap: 4324 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc); 4325 case BinOpTypeAssignMinus: 4326 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc); 4327 case BinOpTypeAssignMinusWrap: 4328 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc); 4329 case BinOpTypeAssignBitShiftLeft: 4330 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); 4331 case BinOpTypeAssignBitShiftRight: 4332 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); 4333 case BinOpTypeAssignBitAnd: 4334 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc); 4335 case BinOpTypeAssignBitXor: 4336 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc); 4337 case BinOpTypeAssignBitOr: 4338 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc); 4339 case BinOpTypeAssignMergeErrorSets: 4340 return ir_lval_wrap(irb, scope, ir_gen_assign_merge_err_sets(irb, scope, node), lval, result_loc); 4341 case BinOpTypeBoolOr: 4342 return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc); 4343 case BinOpTypeBoolAnd: 4344 return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc); 4345 case BinOpTypeCmpEq: 4346 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc); 4347 case BinOpTypeCmpNotEq: 4348 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc); 4349 case BinOpTypeCmpLessThan: 4350 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc); 4351 case BinOpTypeCmpGreaterThan: 4352 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc); 4353 case BinOpTypeCmpLessOrEq: 4354 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc); 4355 case BinOpTypeCmpGreaterOrEq: 4356 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc); 4357 case BinOpTypeBinOr: 4358 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc); 4359 case BinOpTypeBinXor: 4360 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc); 4361 case BinOpTypeBinAnd: 4362 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc); 4363 case BinOpTypeBitShiftLeft: 4364 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); 4365 case BinOpTypeBitShiftRight: 4366 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); 4367 case BinOpTypeAdd: 4368 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc); 4369 case BinOpTypeAddWrap: 4370 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc); 4371 case BinOpTypeSub: 4372 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc); 4373 case BinOpTypeSubWrap: 4374 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc); 4375 case BinOpTypeMult: 4376 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc); 4377 case BinOpTypeMultWrap: 4378 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc); 4379 case BinOpTypeDiv: 4380 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); 4381 case BinOpTypeMod: 4382 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); 4383 case BinOpTypeArrayCat: 4384 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc); 4385 case BinOpTypeArrayMult: 4386 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc); 4387 case BinOpTypeMergeErrorSets: 4388 return ir_lval_wrap(irb, scope, ir_gen_merge_err_sets(irb, scope, node), lval, result_loc); 4389 case BinOpTypeUnwrapOptional: 4390 return ir_gen_orelse(irb, scope, node, lval, result_loc); 4391 case BinOpTypeErrorUnion: 4392 return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc); 4393 } 4394 zig_unreachable(); 4395 } 4396 4397 static IrInstruction *ir_gen_int_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 4398 assert(node->type == NodeTypeIntLiteral); 4399 4400 return ir_build_const_bigint(irb, scope, node, node->data.int_literal.bigint); 4401 } 4402 4403 static IrInstruction *ir_gen_float_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 4404 assert(node->type == NodeTypeFloatLiteral); 4405 4406 if (node->data.float_literal.overflow) { 4407 add_node_error(irb->codegen, node, buf_sprintf("float literal out of range of any type")); 4408 return irb->codegen->invalid_instruction; 4409 } 4410 4411 return ir_build_const_bigfloat(irb, scope, node, node->data.float_literal.bigfloat); 4412 } 4413 4414 static IrInstruction *ir_gen_char_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 4415 assert(node->type == NodeTypeCharLiteral); 4416 4417 return ir_build_const_uint(irb, scope, node, node->data.char_literal.value); 4418 } 4419 4420 static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 4421 assert(node->type == NodeTypeNullLiteral); 4422 4423 return ir_build_const_null(irb, scope, node); 4424 } 4425 4426 static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode *node, Buf *var_name) { 4427 ScopeDecls *scope_decls = nullptr; 4428 while (scope != nullptr) { 4429 if (scope->id == ScopeIdDecls) { 4430 scope_decls = reinterpret_cast<ScopeDecls *>(scope); 4431 } 4432 scope = scope->parent; 4433 } 4434 TldVar *tld_var = allocate<TldVar>(1); 4435 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); 4436 tld_var->base.resolution = TldResolutionInvalid; 4437 tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, 4438 g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid); 4439 scope_decls->decl_table.put(var_name, &tld_var->base); 4440 } 4441 4442 static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 4443 Error err; 4444 assert(node->type == NodeTypeSymbol); 4445 4446 Buf *variable_name = node->data.symbol_expr.symbol; 4447 4448 if (buf_eql_str(variable_name, "_")) { 4449 if (lval == LValPtr) { 4450 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node); 4451 const_instruction->base.value->type = get_pointer_to_type(irb->codegen, 4452 irb->codegen->builtin_types.entry_void, false); 4453 const_instruction->base.value->special = ConstValSpecialStatic; 4454 const_instruction->base.value->data.x_ptr.special = ConstPtrSpecialDiscard; 4455 return &const_instruction->base; 4456 } else { 4457 add_node_error(irb->codegen, node, buf_sprintf("`_` may only be used to assign things to")); 4458 return irb->codegen->invalid_instruction; 4459 } 4460 } 4461 4462 ZigType *primitive_type; 4463 if ((err = get_primitive_type(irb->codegen, variable_name, &primitive_type))) { 4464 if (err == ErrorOverflow) { 4465 add_node_error(irb->codegen, node, 4466 buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535", 4467 buf_ptr(variable_name))); 4468 return irb->codegen->invalid_instruction; 4469 } 4470 assert(err == ErrorPrimitiveTypeNotFound); 4471 } else { 4472 IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_type); 4473 if (lval == LValPtr) { 4474 return ir_build_ref(irb, scope, node, value, false, false); 4475 } else { 4476 return ir_expr_wrap(irb, scope, value, result_loc); 4477 } 4478 } 4479 4480 ScopeFnDef *crossed_fndef_scope; 4481 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); 4482 if (var) { 4483 IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); 4484 if (lval == LValPtr) { 4485 return var_ptr; 4486 } else { 4487 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, var_ptr), result_loc); 4488 } 4489 } 4490 4491 Tld *tld = find_decl(irb->codegen, scope, variable_name); 4492 if (tld) { 4493 IrInstruction *decl_ref = ir_build_decl_ref(irb, scope, node, tld, lval); 4494 if (lval == LValPtr) { 4495 return decl_ref; 4496 } else { 4497 return ir_expr_wrap(irb, scope, decl_ref, result_loc); 4498 } 4499 } 4500 4501 if (get_container_scope(node->owner)->any_imports_failed) { 4502 // skip the error message since we had a failing import in this file 4503 // if an import breaks we don't need redundant undeclared identifier errors 4504 return irb->codegen->invalid_instruction; 4505 } 4506 4507 return ir_build_undeclared_identifier(irb, scope, node, variable_name); 4508 } 4509 4510 static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 4511 ResultLoc *result_loc) 4512 { 4513 assert(node->type == NodeTypeArrayAccessExpr); 4514 4515 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; 4516 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr); 4517 if (array_ref_instruction == irb->codegen->invalid_instruction) 4518 return array_ref_instruction; 4519 4520 AstNode *subscript_node = node->data.array_access_expr.subscript; 4521 IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, scope); 4522 if (subscript_instruction == irb->codegen->invalid_instruction) 4523 return subscript_instruction; 4524 4525 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, 4526 subscript_instruction, true, PtrLenSingle, nullptr); 4527 if (lval == LValPtr) 4528 return ptr_instruction; 4529 4530 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 4531 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 4532 } 4533 4534 static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) { 4535 assert(node->type == NodeTypeFieldAccessExpr); 4536 4537 AstNode *container_ref_node = node->data.field_access_expr.struct_expr; 4538 Buf *field_name = node->data.field_access_expr.field_name; 4539 4540 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr); 4541 if (container_ref_instruction == irb->codegen->invalid_instruction) 4542 return container_ref_instruction; 4543 4544 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name, false); 4545 } 4546 4547 static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) { 4548 assert(node->type == NodeTypeFnCallExpr); 4549 4550 AstNode *type_node = node->data.fn_call_expr.params.at(0); 4551 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 4552 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 4553 AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3); 4554 4555 4556 IrInstruction *type_value = ir_gen_node(irb, type_node, scope); 4557 if (type_value == irb->codegen->invalid_instruction) 4558 return irb->codegen->invalid_instruction; 4559 4560 IrInstruction *op1 = ir_gen_node(irb, op1_node, scope); 4561 if (op1 == irb->codegen->invalid_instruction) 4562 return irb->codegen->invalid_instruction; 4563 4564 IrInstruction *op2 = ir_gen_node(irb, op2_node, scope); 4565 if (op2 == irb->codegen->invalid_instruction) 4566 return irb->codegen->invalid_instruction; 4567 4568 IrInstruction *result_ptr = ir_gen_node(irb, result_ptr_node, scope); 4569 if (result_ptr == irb->codegen->invalid_instruction) 4570 return irb->codegen->invalid_instruction; 4571 4572 return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr); 4573 } 4574 4575 static IrInstruction *ir_gen_mul_add(IrBuilder *irb, Scope *scope, AstNode *node) { 4576 assert(node->type == NodeTypeFnCallExpr); 4577 4578 AstNode *type_node = node->data.fn_call_expr.params.at(0); 4579 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 4580 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 4581 AstNode *op3_node = node->data.fn_call_expr.params.at(3); 4582 4583 IrInstruction *type_value = ir_gen_node(irb, type_node, scope); 4584 if (type_value == irb->codegen->invalid_instruction) 4585 return irb->codegen->invalid_instruction; 4586 4587 IrInstruction *op1 = ir_gen_node(irb, op1_node, scope); 4588 if (op1 == irb->codegen->invalid_instruction) 4589 return irb->codegen->invalid_instruction; 4590 4591 IrInstruction *op2 = ir_gen_node(irb, op2_node, scope); 4592 if (op2 == irb->codegen->invalid_instruction) 4593 return irb->codegen->invalid_instruction; 4594 4595 IrInstruction *op3 = ir_gen_node(irb, op3_node, scope); 4596 if (op3 == irb->codegen->invalid_instruction) 4597 return irb->codegen->invalid_instruction; 4598 4599 return ir_build_mul_add(irb, scope, node, type_value, op1, op2, op3); 4600 } 4601 4602 static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *node) { 4603 for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) { 4604 if (it_scope->id == ScopeIdDecls) { 4605 ScopeDecls *decls_scope = (ScopeDecls *)it_scope; 4606 ZigType *container_type = decls_scope->container_type; 4607 if (container_type != nullptr) { 4608 return ir_build_const_type(irb, orig_scope, node, container_type); 4609 } else { 4610 return ir_build_const_import(irb, orig_scope, node, decls_scope->import); 4611 } 4612 } 4613 } 4614 zig_unreachable(); 4615 } 4616 4617 static IrInstruction *ir_gen_async_call(IrBuilder *irb, Scope *scope, AstNode *await_node, AstNode *call_node, 4618 LVal lval, ResultLoc *result_loc) 4619 { 4620 size_t arg_offset = 3; 4621 if (call_node->data.fn_call_expr.params.length < arg_offset) { 4622 add_node_error(irb->codegen, call_node, 4623 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 4624 arg_offset, call_node->data.fn_call_expr.params.length)); 4625 return irb->codegen->invalid_instruction; 4626 } 4627 4628 AstNode *bytes_node = call_node->data.fn_call_expr.params.at(0); 4629 IrInstruction *bytes = ir_gen_node(irb, bytes_node, scope); 4630 if (bytes == irb->codegen->invalid_instruction) 4631 return bytes; 4632 4633 AstNode *ret_ptr_node = call_node->data.fn_call_expr.params.at(1); 4634 IrInstruction *ret_ptr = ir_gen_node(irb, ret_ptr_node, scope); 4635 if (ret_ptr == irb->codegen->invalid_instruction) 4636 return ret_ptr; 4637 4638 AstNode *fn_ref_node = call_node->data.fn_call_expr.params.at(2); 4639 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 4640 if (fn_ref == irb->codegen->invalid_instruction) 4641 return fn_ref; 4642 4643 size_t arg_count = call_node->data.fn_call_expr.params.length - arg_offset; 4644 4645 // last "arg" is return pointer 4646 IrInstruction **args = allocate<IrInstruction*>(arg_count + 1); 4647 4648 for (size_t i = 0; i < arg_count; i += 1) { 4649 AstNode *arg_node = call_node->data.fn_call_expr.params.at(i + arg_offset); 4650 IrInstruction *arg = ir_gen_node(irb, arg_node, scope); 4651 if (arg == irb->codegen->invalid_instruction) 4652 return arg; 4653 args[i] = arg; 4654 } 4655 4656 args[arg_count] = ret_ptr; 4657 4658 CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone; 4659 bool is_async_call_builtin = true; 4660 IrInstruction *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args, false, 4661 FnInlineAuto, modifier, is_async_call_builtin, bytes, result_loc); 4662 return ir_lval_wrap(irb, scope, call, lval, result_loc); 4663 } 4664 4665 static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 4666 ResultLoc *result_loc) 4667 { 4668 assert(node->type == NodeTypeFnCallExpr); 4669 4670 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; 4671 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 4672 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 4673 4674 if (!entry) { 4675 add_node_error(irb->codegen, node, 4676 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name))); 4677 return irb->codegen->invalid_instruction; 4678 } 4679 4680 BuiltinFnEntry *builtin_fn = entry->value; 4681 size_t actual_param_count = node->data.fn_call_expr.params.length; 4682 4683 if (builtin_fn->param_count != SIZE_MAX && builtin_fn->param_count != actual_param_count) { 4684 add_node_error(irb->codegen, node, 4685 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 4686 builtin_fn->param_count, actual_param_count)); 4687 return irb->codegen->invalid_instruction; 4688 } 4689 4690 switch (builtin_fn->id) { 4691 case BuiltinFnIdInvalid: 4692 zig_unreachable(); 4693 case BuiltinFnIdTypeof: 4694 { 4695 Scope *sub_scope = create_typeof_scope(irb->codegen, node, scope); 4696 4697 AstNode *arg_node = node->data.fn_call_expr.params.at(0); 4698 IrInstruction *arg = ir_gen_node(irb, arg_node, sub_scope); 4699 if (arg == irb->codegen->invalid_instruction) 4700 return arg; 4701 4702 IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); 4703 return ir_lval_wrap(irb, scope, type_of, lval, result_loc); 4704 } 4705 case BuiltinFnIdSetCold: 4706 { 4707 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4708 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4709 if (arg0_value == irb->codegen->invalid_instruction) 4710 return arg0_value; 4711 4712 IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); 4713 return ir_lval_wrap(irb, scope, set_cold, lval, result_loc); 4714 } 4715 case BuiltinFnIdSetRuntimeSafety: 4716 { 4717 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4718 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4719 if (arg0_value == irb->codegen->invalid_instruction) 4720 return arg0_value; 4721 4722 IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); 4723 return ir_lval_wrap(irb, scope, set_safety, lval, result_loc); 4724 } 4725 case BuiltinFnIdSetFloatMode: 4726 { 4727 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4728 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4729 if (arg0_value == irb->codegen->invalid_instruction) 4730 return arg0_value; 4731 4732 IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); 4733 return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc); 4734 } 4735 case BuiltinFnIdSizeof: 4736 { 4737 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4738 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4739 if (arg0_value == irb->codegen->invalid_instruction) 4740 return arg0_value; 4741 4742 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); 4743 return ir_lval_wrap(irb, scope, size_of, lval, result_loc); 4744 } 4745 case BuiltinFnIdImport: 4746 { 4747 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4748 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4749 if (arg0_value == irb->codegen->invalid_instruction) 4750 return arg0_value; 4751 4752 IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); 4753 return ir_lval_wrap(irb, scope, import, lval, result_loc); 4754 } 4755 case BuiltinFnIdCImport: 4756 { 4757 IrInstruction *c_import = ir_build_c_import(irb, scope, node); 4758 return ir_lval_wrap(irb, scope, c_import, lval, result_loc); 4759 } 4760 case BuiltinFnIdCInclude: 4761 { 4762 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4763 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4764 if (arg0_value == irb->codegen->invalid_instruction) 4765 return arg0_value; 4766 4767 if (!exec_c_import_buf(irb->exec)) { 4768 add_node_error(irb->codegen, node, buf_sprintf("C include valid only inside C import block")); 4769 return irb->codegen->invalid_instruction; 4770 } 4771 4772 IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value); 4773 return ir_lval_wrap(irb, scope, c_include, lval, result_loc); 4774 } 4775 case BuiltinFnIdCDefine: 4776 { 4777 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4778 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4779 if (arg0_value == irb->codegen->invalid_instruction) 4780 return arg0_value; 4781 4782 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4783 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4784 if (arg1_value == irb->codegen->invalid_instruction) 4785 return arg1_value; 4786 4787 if (!exec_c_import_buf(irb->exec)) { 4788 add_node_error(irb->codegen, node, buf_sprintf("C define valid only inside C import block")); 4789 return irb->codegen->invalid_instruction; 4790 } 4791 4792 IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); 4793 return ir_lval_wrap(irb, scope, c_define, lval, result_loc); 4794 } 4795 case BuiltinFnIdCUndef: 4796 { 4797 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4798 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4799 if (arg0_value == irb->codegen->invalid_instruction) 4800 return arg0_value; 4801 4802 if (!exec_c_import_buf(irb->exec)) { 4803 add_node_error(irb->codegen, node, buf_sprintf("C undef valid only inside C import block")); 4804 return irb->codegen->invalid_instruction; 4805 } 4806 4807 IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); 4808 return ir_lval_wrap(irb, scope, c_undef, lval, result_loc); 4809 } 4810 case BuiltinFnIdCompileErr: 4811 { 4812 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4813 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4814 if (arg0_value == irb->codegen->invalid_instruction) 4815 return arg0_value; 4816 4817 IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); 4818 return ir_lval_wrap(irb, scope, compile_err, lval, result_loc); 4819 } 4820 case BuiltinFnIdCompileLog: 4821 { 4822 IrInstruction **args = allocate<IrInstruction*>(actual_param_count); 4823 4824 for (size_t i = 0; i < actual_param_count; i += 1) { 4825 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 4826 args[i] = ir_gen_node(irb, arg_node, scope); 4827 if (args[i] == irb->codegen->invalid_instruction) 4828 return irb->codegen->invalid_instruction; 4829 } 4830 4831 IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); 4832 return ir_lval_wrap(irb, scope, compile_log, lval, result_loc); 4833 } 4834 case BuiltinFnIdErrName: 4835 { 4836 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4837 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4838 if (arg0_value == irb->codegen->invalid_instruction) 4839 return arg0_value; 4840 4841 IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value); 4842 return ir_lval_wrap(irb, scope, err_name, lval, result_loc); 4843 } 4844 case BuiltinFnIdEmbedFile: 4845 { 4846 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4847 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4848 if (arg0_value == irb->codegen->invalid_instruction) 4849 return arg0_value; 4850 4851 IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); 4852 return ir_lval_wrap(irb, scope, embed_file, lval, result_loc); 4853 } 4854 case BuiltinFnIdCmpxchgWeak: 4855 case BuiltinFnIdCmpxchgStrong: 4856 { 4857 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4858 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4859 if (arg0_value == irb->codegen->invalid_instruction) 4860 return arg0_value; 4861 4862 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4863 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4864 if (arg1_value == irb->codegen->invalid_instruction) 4865 return arg1_value; 4866 4867 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4868 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4869 if (arg2_value == irb->codegen->invalid_instruction) 4870 return arg2_value; 4871 4872 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 4873 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 4874 if (arg3_value == irb->codegen->invalid_instruction) 4875 return arg3_value; 4876 4877 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 4878 IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); 4879 if (arg4_value == irb->codegen->invalid_instruction) 4880 return arg4_value; 4881 4882 AstNode *arg5_node = node->data.fn_call_expr.params.at(5); 4883 IrInstruction *arg5_value = ir_gen_node(irb, arg5_node, scope); 4884 if (arg5_value == irb->codegen->invalid_instruction) 4885 return arg5_value; 4886 4887 IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, 4888 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak), 4889 result_loc); 4890 return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc); 4891 } 4892 case BuiltinFnIdFence: 4893 { 4894 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4895 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4896 if (arg0_value == irb->codegen->invalid_instruction) 4897 return arg0_value; 4898 4899 IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); 4900 return ir_lval_wrap(irb, scope, fence, lval, result_loc); 4901 } 4902 case BuiltinFnIdDivExact: 4903 { 4904 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4905 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4906 if (arg0_value == irb->codegen->invalid_instruction) 4907 return arg0_value; 4908 4909 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4910 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4911 if (arg1_value == irb->codegen->invalid_instruction) 4912 return arg1_value; 4913 4914 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); 4915 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 4916 } 4917 case BuiltinFnIdDivTrunc: 4918 { 4919 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4920 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4921 if (arg0_value == irb->codegen->invalid_instruction) 4922 return arg0_value; 4923 4924 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4925 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4926 if (arg1_value == irb->codegen->invalid_instruction) 4927 return arg1_value; 4928 4929 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); 4930 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 4931 } 4932 case BuiltinFnIdDivFloor: 4933 { 4934 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4935 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4936 if (arg0_value == irb->codegen->invalid_instruction) 4937 return arg0_value; 4938 4939 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4940 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4941 if (arg1_value == irb->codegen->invalid_instruction) 4942 return arg1_value; 4943 4944 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); 4945 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 4946 } 4947 case BuiltinFnIdRem: 4948 { 4949 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4950 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4951 if (arg0_value == irb->codegen->invalid_instruction) 4952 return arg0_value; 4953 4954 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4955 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4956 if (arg1_value == irb->codegen->invalid_instruction) 4957 return arg1_value; 4958 4959 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); 4960 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 4961 } 4962 case BuiltinFnIdMod: 4963 { 4964 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4965 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4966 if (arg0_value == irb->codegen->invalid_instruction) 4967 return arg0_value; 4968 4969 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4970 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4971 if (arg1_value == irb->codegen->invalid_instruction) 4972 return arg1_value; 4973 4974 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); 4975 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 4976 } 4977 case BuiltinFnIdSqrt: 4978 case BuiltinFnIdSin: 4979 case BuiltinFnIdCos: 4980 case BuiltinFnIdExp: 4981 case BuiltinFnIdExp2: 4982 case BuiltinFnIdLn: 4983 case BuiltinFnIdLog2: 4984 case BuiltinFnIdLog10: 4985 case BuiltinFnIdFabs: 4986 case BuiltinFnIdFloor: 4987 case BuiltinFnIdCeil: 4988 case BuiltinFnIdTrunc: 4989 case BuiltinFnIdNearbyInt: 4990 case BuiltinFnIdRound: 4991 { 4992 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4993 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4994 if (arg0_value == irb->codegen->invalid_instruction) 4995 return arg0_value; 4996 4997 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4998 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4999 if (arg1_value == irb->codegen->invalid_instruction) 5000 return arg1_value; 5001 5002 IrInstruction *ir_sqrt = ir_build_float_op(irb, scope, node, arg0_value, arg1_value, builtin_fn->id); 5003 return ir_lval_wrap(irb, scope, ir_sqrt, lval, result_loc); 5004 } 5005 case BuiltinFnIdTruncate: 5006 { 5007 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5008 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5009 if (arg0_value == irb->codegen->invalid_instruction) 5010 return arg0_value; 5011 5012 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5013 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5014 if (arg1_value == irb->codegen->invalid_instruction) 5015 return arg1_value; 5016 5017 IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); 5018 return ir_lval_wrap(irb, scope, truncate, lval, result_loc); 5019 } 5020 case BuiltinFnIdIntCast: 5021 { 5022 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5023 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5024 if (arg0_value == irb->codegen->invalid_instruction) 5025 return arg0_value; 5026 5027 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5028 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5029 if (arg1_value == irb->codegen->invalid_instruction) 5030 return arg1_value; 5031 5032 IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); 5033 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5034 } 5035 case BuiltinFnIdFloatCast: 5036 { 5037 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5038 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5039 if (arg0_value == irb->codegen->invalid_instruction) 5040 return arg0_value; 5041 5042 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5043 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5044 if (arg1_value == irb->codegen->invalid_instruction) 5045 return arg1_value; 5046 5047 IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); 5048 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5049 } 5050 case BuiltinFnIdErrSetCast: 5051 { 5052 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5053 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5054 if (arg0_value == irb->codegen->invalid_instruction) 5055 return arg0_value; 5056 5057 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5058 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5059 if (arg1_value == irb->codegen->invalid_instruction) 5060 return arg1_value; 5061 5062 IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); 5063 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5064 } 5065 case BuiltinFnIdFromBytes: 5066 { 5067 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5068 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5069 if (arg0_value == irb->codegen->invalid_instruction) 5070 return arg0_value; 5071 5072 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5073 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5074 if (arg1_value == irb->codegen->invalid_instruction) 5075 return arg1_value; 5076 5077 IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc); 5078 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5079 } 5080 case BuiltinFnIdToBytes: 5081 { 5082 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5083 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5084 if (arg0_value == irb->codegen->invalid_instruction) 5085 return arg0_value; 5086 5087 IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc); 5088 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5089 } 5090 case BuiltinFnIdIntToFloat: 5091 { 5092 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5093 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5094 if (arg0_value == irb->codegen->invalid_instruction) 5095 return arg0_value; 5096 5097 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5098 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5099 if (arg1_value == irb->codegen->invalid_instruction) 5100 return arg1_value; 5101 5102 IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); 5103 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5104 } 5105 case BuiltinFnIdFloatToInt: 5106 { 5107 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5108 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5109 if (arg0_value == irb->codegen->invalid_instruction) 5110 return arg0_value; 5111 5112 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5113 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5114 if (arg1_value == irb->codegen->invalid_instruction) 5115 return arg1_value; 5116 5117 IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); 5118 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5119 } 5120 case BuiltinFnIdErrToInt: 5121 { 5122 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5123 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5124 if (arg0_value == irb->codegen->invalid_instruction) 5125 return arg0_value; 5126 5127 IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value); 5128 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5129 } 5130 case BuiltinFnIdIntToErr: 5131 { 5132 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5133 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5134 if (arg0_value == irb->codegen->invalid_instruction) 5135 return arg0_value; 5136 5137 IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value); 5138 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5139 } 5140 case BuiltinFnIdBoolToInt: 5141 { 5142 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5143 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5144 if (arg0_value == irb->codegen->invalid_instruction) 5145 return arg0_value; 5146 5147 IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value); 5148 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5149 } 5150 case BuiltinFnIdIntType: 5151 { 5152 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5153 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5154 if (arg0_value == irb->codegen->invalid_instruction) 5155 return arg0_value; 5156 5157 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5158 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5159 if (arg1_value == irb->codegen->invalid_instruction) 5160 return arg1_value; 5161 5162 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); 5163 return ir_lval_wrap(irb, scope, int_type, lval, result_loc); 5164 } 5165 case BuiltinFnIdVectorType: 5166 { 5167 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5168 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5169 if (arg0_value == irb->codegen->invalid_instruction) 5170 return arg0_value; 5171 5172 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5173 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5174 if (arg1_value == irb->codegen->invalid_instruction) 5175 return arg1_value; 5176 5177 IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); 5178 return ir_lval_wrap(irb, scope, vector_type, lval, result_loc); 5179 } 5180 case BuiltinFnIdShuffle: 5181 { 5182 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5183 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5184 if (arg0_value == irb->codegen->invalid_instruction) 5185 return arg0_value; 5186 5187 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5188 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5189 if (arg1_value == irb->codegen->invalid_instruction) 5190 return arg1_value; 5191 5192 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5193 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5194 if (arg2_value == irb->codegen->invalid_instruction) 5195 return arg2_value; 5196 5197 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 5198 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 5199 if (arg3_value == irb->codegen->invalid_instruction) 5200 return arg3_value; 5201 5202 IrInstruction *shuffle_vector = ir_build_shuffle_vector(irb, scope, node, 5203 arg0_value, arg1_value, arg2_value, arg3_value); 5204 return ir_lval_wrap(irb, scope, shuffle_vector, lval, result_loc); 5205 } 5206 case BuiltinFnIdSplat: 5207 { 5208 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5209 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5210 if (arg0_value == irb->codegen->invalid_instruction) 5211 return arg0_value; 5212 5213 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5214 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5215 if (arg1_value == irb->codegen->invalid_instruction) 5216 return arg1_value; 5217 5218 IrInstruction *splat = ir_build_splat_src(irb, scope, node, 5219 arg0_value, arg1_value); 5220 return ir_lval_wrap(irb, scope, splat, lval, result_loc); 5221 } 5222 case BuiltinFnIdMemcpy: 5223 { 5224 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5225 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5226 if (arg0_value == irb->codegen->invalid_instruction) 5227 return arg0_value; 5228 5229 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5230 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5231 if (arg1_value == irb->codegen->invalid_instruction) 5232 return arg1_value; 5233 5234 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5235 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5236 if (arg2_value == irb->codegen->invalid_instruction) 5237 return arg2_value; 5238 5239 IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value); 5240 return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc); 5241 } 5242 case BuiltinFnIdMemset: 5243 { 5244 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5245 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5246 if (arg0_value == irb->codegen->invalid_instruction) 5247 return arg0_value; 5248 5249 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5250 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5251 if (arg1_value == irb->codegen->invalid_instruction) 5252 return arg1_value; 5253 5254 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5255 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5256 if (arg2_value == irb->codegen->invalid_instruction) 5257 return arg2_value; 5258 5259 IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value); 5260 return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc); 5261 } 5262 case BuiltinFnIdMemberCount: 5263 { 5264 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5265 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5266 if (arg0_value == irb->codegen->invalid_instruction) 5267 return arg0_value; 5268 5269 IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value); 5270 return ir_lval_wrap(irb, scope, member_count, lval, result_loc); 5271 } 5272 case BuiltinFnIdMemberType: 5273 { 5274 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5275 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5276 if (arg0_value == irb->codegen->invalid_instruction) 5277 return arg0_value; 5278 5279 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5280 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5281 if (arg1_value == irb->codegen->invalid_instruction) 5282 return arg1_value; 5283 5284 5285 IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value); 5286 return ir_lval_wrap(irb, scope, member_type, lval, result_loc); 5287 } 5288 case BuiltinFnIdMemberName: 5289 { 5290 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5291 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5292 if (arg0_value == irb->codegen->invalid_instruction) 5293 return arg0_value; 5294 5295 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5296 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5297 if (arg1_value == irb->codegen->invalid_instruction) 5298 return arg1_value; 5299 5300 5301 IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value); 5302 return ir_lval_wrap(irb, scope, member_name, lval, result_loc); 5303 } 5304 case BuiltinFnIdField: 5305 { 5306 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5307 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr); 5308 if (arg0_value == irb->codegen->invalid_instruction) 5309 return arg0_value; 5310 5311 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5312 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5313 if (arg1_value == irb->codegen->invalid_instruction) 5314 return arg1_value; 5315 5316 IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, 5317 arg0_value, arg1_value, false); 5318 5319 if (lval == LValPtr) 5320 return ptr_instruction; 5321 5322 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 5323 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 5324 } 5325 case BuiltinFnIdHasField: 5326 { 5327 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5328 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5329 if (arg0_value == irb->codegen->invalid_instruction) 5330 return arg0_value; 5331 5332 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5333 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5334 if (arg1_value == irb->codegen->invalid_instruction) 5335 return arg1_value; 5336 5337 IrInstruction *type_info = ir_build_has_field(irb, scope, node, arg0_value, arg1_value); 5338 return ir_lval_wrap(irb, scope, type_info, lval, result_loc); 5339 } 5340 case BuiltinFnIdTypeInfo: 5341 { 5342 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5343 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5344 if (arg0_value == irb->codegen->invalid_instruction) 5345 return arg0_value; 5346 5347 IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); 5348 return ir_lval_wrap(irb, scope, type_info, lval, result_loc); 5349 } 5350 case BuiltinFnIdType: 5351 { 5352 AstNode *arg_node = node->data.fn_call_expr.params.at(0); 5353 IrInstruction *arg = ir_gen_node(irb, arg_node, scope); 5354 if (arg == irb->codegen->invalid_instruction) 5355 return arg; 5356 5357 IrInstruction *type = ir_build_type(irb, scope, node, arg); 5358 return ir_lval_wrap(irb, scope, type, lval, result_loc); 5359 } 5360 case BuiltinFnIdBreakpoint: 5361 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc); 5362 case BuiltinFnIdReturnAddress: 5363 return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval, result_loc); 5364 case BuiltinFnIdFrameAddress: 5365 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval, result_loc); 5366 case BuiltinFnIdFrameHandle: 5367 if (!irb->exec->fn_entry) { 5368 add_node_error(irb->codegen, node, buf_sprintf("@frame() called outside of function definition")); 5369 return irb->codegen->invalid_instruction; 5370 } 5371 return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval, result_loc); 5372 case BuiltinFnIdFrameType: { 5373 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5374 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5375 if (arg0_value == irb->codegen->invalid_instruction) 5376 return arg0_value; 5377 5378 IrInstruction *frame_type = ir_build_frame_type(irb, scope, node, arg0_value); 5379 return ir_lval_wrap(irb, scope, frame_type, lval, result_loc); 5380 } 5381 case BuiltinFnIdFrameSize: { 5382 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5383 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5384 if (arg0_value == irb->codegen->invalid_instruction) 5385 return arg0_value; 5386 5387 IrInstruction *frame_size = ir_build_frame_size_src(irb, scope, node, arg0_value); 5388 return ir_lval_wrap(irb, scope, frame_size, lval, result_loc); 5389 } 5390 case BuiltinFnIdAlignOf: 5391 { 5392 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5393 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5394 if (arg0_value == irb->codegen->invalid_instruction) 5395 return arg0_value; 5396 5397 IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value); 5398 return ir_lval_wrap(irb, scope, align_of, lval, result_loc); 5399 } 5400 case BuiltinFnIdAddWithOverflow: 5401 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval, result_loc); 5402 case BuiltinFnIdSubWithOverflow: 5403 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval, result_loc); 5404 case BuiltinFnIdMulWithOverflow: 5405 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval, result_loc); 5406 case BuiltinFnIdShlWithOverflow: 5407 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval, result_loc); 5408 case BuiltinFnIdMulAdd: 5409 return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc); 5410 case BuiltinFnIdTypeName: 5411 { 5412 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5413 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5414 if (arg0_value == irb->codegen->invalid_instruction) 5415 return arg0_value; 5416 5417 IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value); 5418 return ir_lval_wrap(irb, scope, type_name, lval, result_loc); 5419 } 5420 case BuiltinFnIdPanic: 5421 { 5422 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5423 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5424 if (arg0_value == irb->codegen->invalid_instruction) 5425 return arg0_value; 5426 5427 IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); 5428 return ir_lval_wrap(irb, scope, panic, lval, result_loc); 5429 } 5430 case BuiltinFnIdPtrCast: 5431 { 5432 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5433 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5434 if (arg0_value == irb->codegen->invalid_instruction) 5435 return arg0_value; 5436 5437 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5438 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5439 if (arg1_value == irb->codegen->invalid_instruction) 5440 return arg1_value; 5441 5442 IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); 5443 return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc); 5444 } 5445 case BuiltinFnIdBitCast: 5446 { 5447 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); 5448 IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope); 5449 if (dest_type == irb->codegen->invalid_instruction) 5450 return dest_type; 5451 5452 ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1); 5453 result_loc_bit_cast->base.id = ResultLocIdBitCast; 5454 result_loc_bit_cast->base.source_instruction = dest_type; 5455 ir_ref_instruction(dest_type, irb->current_basic_block); 5456 result_loc_bit_cast->parent = result_loc; 5457 5458 ir_build_reset_result(irb, scope, node, &result_loc_bit_cast->base); 5459 5460 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5461 IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, 5462 &result_loc_bit_cast->base); 5463 if (arg1_value == irb->codegen->invalid_instruction) 5464 return arg1_value; 5465 5466 IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast); 5467 return ir_lval_wrap(irb, scope, bitcast, lval, result_loc); 5468 } 5469 case BuiltinFnIdAs: 5470 { 5471 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); 5472 IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope); 5473 if (dest_type == irb->codegen->invalid_instruction) 5474 return dest_type; 5475 5476 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, dest_type, result_loc); 5477 5478 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5479 IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, 5480 &result_loc_cast->base); 5481 if (arg1_value == irb->codegen->invalid_instruction) 5482 return arg1_value; 5483 5484 IrInstruction *result = ir_build_implicit_cast(irb, scope, node, arg1_value, result_loc_cast); 5485 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5486 } 5487 case BuiltinFnIdIntToPtr: 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 *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value); 5500 return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc); 5501 } 5502 case BuiltinFnIdPtrToInt: 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 *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value); 5510 return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc); 5511 } 5512 case BuiltinFnIdTagName: 5513 { 5514 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5515 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5516 if (arg0_value == irb->codegen->invalid_instruction) 5517 return arg0_value; 5518 5519 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value); 5520 IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag); 5521 return ir_lval_wrap(irb, scope, tag_name, lval, result_loc); 5522 } 5523 case BuiltinFnIdTagType: 5524 { 5525 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5526 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5527 if (arg0_value == irb->codegen->invalid_instruction) 5528 return arg0_value; 5529 5530 IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); 5531 return ir_lval_wrap(irb, scope, tag_type, lval, result_loc); 5532 } 5533 case BuiltinFnIdFieldParentPtr: 5534 { 5535 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5536 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5537 if (arg0_value == irb->codegen->invalid_instruction) 5538 return arg0_value; 5539 5540 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5541 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5542 if (arg1_value == irb->codegen->invalid_instruction) 5543 return arg1_value; 5544 5545 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5546 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5547 if (arg2_value == irb->codegen->invalid_instruction) 5548 return arg2_value; 5549 5550 IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr); 5551 return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc); 5552 } 5553 case BuiltinFnIdByteOffsetOf: 5554 { 5555 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5556 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5557 if (arg0_value == irb->codegen->invalid_instruction) 5558 return arg0_value; 5559 5560 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5561 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5562 if (arg1_value == irb->codegen->invalid_instruction) 5563 return arg1_value; 5564 5565 IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); 5566 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); 5567 } 5568 case BuiltinFnIdBitOffsetOf: 5569 { 5570 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5571 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5572 if (arg0_value == irb->codegen->invalid_instruction) 5573 return arg0_value; 5574 5575 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5576 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5577 if (arg1_value == irb->codegen->invalid_instruction) 5578 return arg1_value; 5579 5580 IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); 5581 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); 5582 } 5583 case BuiltinFnIdInlineCall: 5584 case BuiltinFnIdNoInlineCall: 5585 { 5586 if (node->data.fn_call_expr.params.length == 0) { 5587 add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0")); 5588 return irb->codegen->invalid_instruction; 5589 } 5590 5591 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(0); 5592 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 5593 if (fn_ref == irb->codegen->invalid_instruction) 5594 return fn_ref; 5595 5596 size_t arg_count = node->data.fn_call_expr.params.length - 1; 5597 5598 IrInstruction **args = allocate<IrInstruction*>(arg_count); 5599 for (size_t i = 0; i < arg_count; i += 1) { 5600 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 1); 5601 args[i] = ir_gen_node(irb, arg_node, scope); 5602 if (args[i] == irb->codegen->invalid_instruction) 5603 return args[i]; 5604 } 5605 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; 5606 5607 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, 5608 fn_inline, CallModifierNone, false, nullptr, result_loc); 5609 return ir_lval_wrap(irb, scope, call, lval, result_loc); 5610 } 5611 case BuiltinFnIdNewStackCall: 5612 { 5613 if (node->data.fn_call_expr.params.length < 2) { 5614 add_node_error(irb->codegen, node, 5615 buf_sprintf("expected at least 2 arguments, found %" ZIG_PRI_usize, 5616 node->data.fn_call_expr.params.length)); 5617 return irb->codegen->invalid_instruction; 5618 } 5619 5620 AstNode *new_stack_node = node->data.fn_call_expr.params.at(0); 5621 IrInstruction *new_stack = ir_gen_node(irb, new_stack_node, scope); 5622 if (new_stack == irb->codegen->invalid_instruction) 5623 return new_stack; 5624 5625 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); 5626 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 5627 if (fn_ref == irb->codegen->invalid_instruction) 5628 return fn_ref; 5629 5630 size_t arg_count = node->data.fn_call_expr.params.length - 2; 5631 5632 IrInstruction **args = allocate<IrInstruction*>(arg_count); 5633 for (size_t i = 0; i < arg_count; i += 1) { 5634 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 2); 5635 args[i] = ir_gen_node(irb, arg_node, scope); 5636 if (args[i] == irb->codegen->invalid_instruction) 5637 return args[i]; 5638 } 5639 5640 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, 5641 FnInlineAuto, CallModifierNone, false, new_stack, result_loc); 5642 return ir_lval_wrap(irb, scope, call, lval, result_loc); 5643 } 5644 case BuiltinFnIdAsyncCall: 5645 return ir_gen_async_call(irb, scope, nullptr, node, lval, result_loc); 5646 case BuiltinFnIdTypeId: 5647 { 5648 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5649 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5650 if (arg0_value == irb->codegen->invalid_instruction) 5651 return arg0_value; 5652 5653 IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value); 5654 return ir_lval_wrap(irb, scope, type_id, lval, result_loc); 5655 } 5656 case BuiltinFnIdShlExact: 5657 { 5658 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5659 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5660 if (arg0_value == irb->codegen->invalid_instruction) 5661 return arg0_value; 5662 5663 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5664 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5665 if (arg1_value == irb->codegen->invalid_instruction) 5666 return arg1_value; 5667 5668 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); 5669 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 5670 } 5671 case BuiltinFnIdShrExact: 5672 { 5673 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5674 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5675 if (arg0_value == irb->codegen->invalid_instruction) 5676 return arg0_value; 5677 5678 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5679 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5680 if (arg1_value == irb->codegen->invalid_instruction) 5681 return arg1_value; 5682 5683 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); 5684 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 5685 } 5686 case BuiltinFnIdSetEvalBranchQuota: 5687 { 5688 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5689 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5690 if (arg0_value == irb->codegen->invalid_instruction) 5691 return arg0_value; 5692 5693 IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); 5694 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval, result_loc); 5695 } 5696 case BuiltinFnIdAlignCast: 5697 { 5698 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5699 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5700 if (arg0_value == irb->codegen->invalid_instruction) 5701 return arg0_value; 5702 5703 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5704 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5705 if (arg1_value == irb->codegen->invalid_instruction) 5706 return arg1_value; 5707 5708 IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value); 5709 return ir_lval_wrap(irb, scope, align_cast, lval, result_loc); 5710 } 5711 case BuiltinFnIdOpaqueType: 5712 { 5713 IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); 5714 return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc); 5715 } 5716 case BuiltinFnIdThis: 5717 { 5718 IrInstruction *this_inst = ir_gen_this(irb, scope, node); 5719 return ir_lval_wrap(irb, scope, this_inst, lval, result_loc); 5720 } 5721 case BuiltinFnIdSetAlignStack: 5722 { 5723 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5724 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5725 if (arg0_value == irb->codegen->invalid_instruction) 5726 return arg0_value; 5727 5728 IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); 5729 return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc); 5730 } 5731 case BuiltinFnIdArgType: 5732 { 5733 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5734 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5735 if (arg0_value == irb->codegen->invalid_instruction) 5736 return arg0_value; 5737 5738 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5739 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5740 if (arg1_value == irb->codegen->invalid_instruction) 5741 return arg1_value; 5742 5743 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value, false); 5744 return ir_lval_wrap(irb, scope, arg_type, lval, result_loc); 5745 } 5746 case BuiltinFnIdExport: 5747 { 5748 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5749 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5750 if (arg0_value == irb->codegen->invalid_instruction) 5751 return arg0_value; 5752 5753 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5754 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5755 if (arg1_value == irb->codegen->invalid_instruction) 5756 return arg1_value; 5757 5758 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5759 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5760 if (arg2_value == irb->codegen->invalid_instruction) 5761 return arg2_value; 5762 5763 IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); 5764 return ir_lval_wrap(irb, scope, ir_export, lval, result_loc); 5765 } 5766 case BuiltinFnIdErrorReturnTrace: 5767 { 5768 IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null); 5769 return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc); 5770 } 5771 case BuiltinFnIdAtomicRmw: 5772 { 5773 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5774 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5775 if (arg0_value == irb->codegen->invalid_instruction) 5776 return arg0_value; 5777 5778 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5779 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5780 if (arg1_value == irb->codegen->invalid_instruction) 5781 return arg1_value; 5782 5783 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5784 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5785 if (arg2_value == irb->codegen->invalid_instruction) 5786 return arg2_value; 5787 5788 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 5789 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 5790 if (arg3_value == irb->codegen->invalid_instruction) 5791 return arg3_value; 5792 5793 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 5794 IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); 5795 if (arg4_value == irb->codegen->invalid_instruction) 5796 return arg4_value; 5797 5798 IrInstruction *inst = ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, 5799 arg4_value, 5800 // these 2 values don't mean anything since we passed non-null values for other args 5801 AtomicRmwOp_xchg, AtomicOrderMonotonic); 5802 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 5803 } 5804 case BuiltinFnIdAtomicLoad: 5805 { 5806 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5807 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5808 if (arg0_value == irb->codegen->invalid_instruction) 5809 return arg0_value; 5810 5811 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5812 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5813 if (arg1_value == irb->codegen->invalid_instruction) 5814 return arg1_value; 5815 5816 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5817 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5818 if (arg2_value == irb->codegen->invalid_instruction) 5819 return arg2_value; 5820 5821 IrInstruction *inst = ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, 5822 // this value does not mean anything since we passed non-null values for other arg 5823 AtomicOrderMonotonic); 5824 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 5825 } 5826 case BuiltinFnIdAtomicStore: 5827 { 5828 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5829 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5830 if (arg0_value == irb->codegen->invalid_instruction) 5831 return arg0_value; 5832 5833 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5834 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5835 if (arg1_value == irb->codegen->invalid_instruction) 5836 return arg1_value; 5837 5838 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 5839 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 5840 if (arg2_value == irb->codegen->invalid_instruction) 5841 return arg2_value; 5842 5843 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 5844 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 5845 if (arg3_value == irb->codegen->invalid_instruction) 5846 return arg3_value; 5847 5848 IrInstruction *inst = ir_build_atomic_store(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, 5849 // this value does not mean anything since we passed non-null values for other arg 5850 AtomicOrderMonotonic); 5851 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 5852 } 5853 case BuiltinFnIdIntToEnum: 5854 { 5855 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5856 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5857 if (arg0_value == irb->codegen->invalid_instruction) 5858 return arg0_value; 5859 5860 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5861 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5862 if (arg1_value == irb->codegen->invalid_instruction) 5863 return arg1_value; 5864 5865 IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value); 5866 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5867 } 5868 case BuiltinFnIdEnumToInt: 5869 { 5870 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5871 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5872 if (arg0_value == irb->codegen->invalid_instruction) 5873 return arg0_value; 5874 5875 IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); 5876 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5877 } 5878 case BuiltinFnIdCtz: 5879 case BuiltinFnIdPopCount: 5880 case BuiltinFnIdClz: 5881 case BuiltinFnIdBswap: 5882 case BuiltinFnIdBitReverse: 5883 { 5884 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5885 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5886 if (arg0_value == irb->codegen->invalid_instruction) 5887 return arg0_value; 5888 5889 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5890 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5891 if (arg1_value == irb->codegen->invalid_instruction) 5892 return arg1_value; 5893 5894 IrInstruction *result; 5895 switch (builtin_fn->id) { 5896 case BuiltinFnIdCtz: 5897 result = ir_build_ctz(irb, scope, node, arg0_value, arg1_value); 5898 break; 5899 case BuiltinFnIdPopCount: 5900 result = ir_build_pop_count(irb, scope, node, arg0_value, arg1_value); 5901 break; 5902 case BuiltinFnIdClz: 5903 result = ir_build_clz(irb, scope, node, arg0_value, arg1_value); 5904 break; 5905 case BuiltinFnIdBswap: 5906 result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value); 5907 break; 5908 case BuiltinFnIdBitReverse: 5909 result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value); 5910 break; 5911 default: 5912 zig_unreachable(); 5913 } 5914 return ir_lval_wrap(irb, scope, result, lval, result_loc); 5915 } 5916 case BuiltinFnIdHasDecl: 5917 { 5918 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 5919 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 5920 if (arg0_value == irb->codegen->invalid_instruction) 5921 return arg0_value; 5922 5923 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 5924 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 5925 if (arg1_value == irb->codegen->invalid_instruction) 5926 return arg1_value; 5927 5928 IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value); 5929 return ir_lval_wrap(irb, scope, has_decl, lval, result_loc); 5930 } 5931 case BuiltinFnIdUnionInit: 5932 { 5933 AstNode *union_type_node = node->data.fn_call_expr.params.at(0); 5934 IrInstruction *union_type_inst = ir_gen_node(irb, union_type_node, scope); 5935 if (union_type_inst == irb->codegen->invalid_instruction) 5936 return union_type_inst; 5937 5938 AstNode *name_node = node->data.fn_call_expr.params.at(1); 5939 IrInstruction *name_inst = ir_gen_node(irb, name_node, scope); 5940 if (name_inst == irb->codegen->invalid_instruction) 5941 return name_inst; 5942 5943 AstNode *init_node = node->data.fn_call_expr.params.at(2); 5944 5945 return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node, 5946 lval, result_loc); 5947 } 5948 } 5949 zig_unreachable(); 5950 } 5951 5952 static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 5953 ResultLoc *result_loc) 5954 { 5955 assert(node->type == NodeTypeFnCallExpr); 5956 5957 if (node->data.fn_call_expr.modifier == CallModifierBuiltin) 5958 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); 5959 5960 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; 5961 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 5962 if (fn_ref == irb->codegen->invalid_instruction) 5963 return fn_ref; 5964 5965 IrInstruction *fn_type = ir_build_typeof(irb, scope, node, fn_ref); 5966 5967 size_t arg_count = node->data.fn_call_expr.params.length; 5968 IrInstruction **args = allocate<IrInstruction*>(arg_count); 5969 for (size_t i = 0; i < arg_count; i += 1) { 5970 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 5971 5972 IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i); 5973 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, fn_type, arg_index, true); 5974 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result_loc()); 5975 5976 IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); 5977 if (arg == irb->codegen->invalid_instruction) 5978 return arg; 5979 5980 args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast); 5981 } 5982 5983 IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, 5984 FnInlineAuto, node->data.fn_call_expr.modifier, false, nullptr, result_loc); 5985 return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); 5986 } 5987 5988 static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 5989 ResultLoc *result_loc) 5990 { 5991 assert(node->type == NodeTypeIfBoolExpr); 5992 5993 IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); 5994 if (condition == irb->codegen->invalid_instruction) 5995 return irb->codegen->invalid_instruction; 5996 5997 IrInstruction *is_comptime; 5998 if (ir_should_inline(irb->exec, scope)) { 5999 is_comptime = ir_build_const_bool(irb, scope, node, true); 6000 } else { 6001 is_comptime = ir_build_test_comptime(irb, scope, node, condition); 6002 } 6003 6004 AstNode *then_node = node->data.if_bool_expr.then_block; 6005 AstNode *else_node = node->data.if_bool_expr.else_node; 6006 6007 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "Then"); 6008 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); 6009 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); 6010 6011 IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, condition, 6012 then_block, else_block, is_comptime); 6013 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 6014 result_loc, is_comptime); 6015 6016 ir_set_cursor_at_end_and_append_block(irb, then_block); 6017 6018 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6019 IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, 6020 &peer_parent->peers.at(0)->base); 6021 if (then_expr_result == irb->codegen->invalid_instruction) 6022 return irb->codegen->invalid_instruction; 6023 IrBasicBlock *after_then_block = irb->current_basic_block; 6024 if (!instr_is_unreachable(then_expr_result)) 6025 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 6026 6027 ir_set_cursor_at_end_and_append_block(irb, else_block); 6028 IrInstruction *else_expr_result; 6029 if (else_node) { 6030 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); 6031 if (else_expr_result == irb->codegen->invalid_instruction) 6032 return irb->codegen->invalid_instruction; 6033 } else { 6034 else_expr_result = ir_build_const_void(irb, scope, node); 6035 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 6036 } 6037 IrBasicBlock *after_else_block = irb->current_basic_block; 6038 if (!instr_is_unreachable(else_expr_result)) 6039 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 6040 6041 ir_set_cursor_at_end_and_append_block(irb, endif_block); 6042 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 6043 incoming_values[0] = then_expr_result; 6044 incoming_values[1] = else_expr_result; 6045 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 6046 incoming_blocks[0] = after_then_block; 6047 incoming_blocks[1] = after_else_block; 6048 6049 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 6050 return ir_expr_wrap(irb, scope, phi, result_loc); 6051 } 6052 6053 static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { 6054 assert(node->type == NodeTypePrefixOpExpr); 6055 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 6056 6057 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); 6058 if (value == irb->codegen->invalid_instruction) 6059 return value; 6060 6061 return ir_build_un_op(irb, scope, node, op_id, value); 6062 } 6063 6064 static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id) { 6065 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); 6066 } 6067 6068 static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc) { 6069 ir_build_end_expr(irb, scope, inst->source_node, inst, result_loc); 6070 return inst; 6071 } 6072 6073 static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval, 6074 ResultLoc *result_loc) 6075 { 6076 // This logic must be kept in sync with 6077 // [STMT_EXPR_TEST_THING] <--- (search this token) 6078 if (value == irb->codegen->invalid_instruction || 6079 instr_is_unreachable(value) || 6080 value->source_node->type == NodeTypeDefer || 6081 value->id == IrInstructionIdDeclVarSrc) 6082 { 6083 return value; 6084 } 6085 6086 if (lval == LValPtr) { 6087 // We needed a pointer to a value, but we got a value. So we create 6088 // an instruction which just makes a pointer of it. 6089 return ir_build_ref(irb, scope, value->source_node, value, false, false); 6090 } else if (result_loc != nullptr) { 6091 return ir_expr_wrap(irb, scope, value, result_loc); 6092 } else { 6093 return value; 6094 } 6095 6096 } 6097 6098 static PtrLen star_token_to_ptr_len(TokenId token_id) { 6099 switch (token_id) { 6100 case TokenIdStar: 6101 case TokenIdStarStar: 6102 return PtrLenSingle; 6103 case TokenIdLBracket: 6104 return PtrLenUnknown; 6105 case TokenIdSymbol: 6106 return PtrLenC; 6107 default: 6108 zig_unreachable(); 6109 } 6110 } 6111 6112 static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) { 6113 assert(node->type == NodeTypePointerType); 6114 6115 PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id); 6116 6117 bool is_const = node->data.pointer_type.is_const; 6118 bool is_volatile = node->data.pointer_type.is_volatile; 6119 bool is_allow_zero = node->data.pointer_type.allow_zero_token != nullptr; 6120 AstNode *sentinel_expr = node->data.pointer_type.sentinel; 6121 AstNode *expr_node = node->data.pointer_type.op_expr; 6122 AstNode *align_expr = node->data.pointer_type.align_expr; 6123 6124 IrInstruction *sentinel; 6125 if (sentinel_expr != nullptr) { 6126 sentinel = ir_gen_node(irb, sentinel_expr, scope); 6127 if (sentinel == irb->codegen->invalid_instruction) 6128 return sentinel; 6129 } else { 6130 sentinel = nullptr; 6131 } 6132 6133 IrInstruction *align_value; 6134 if (align_expr != nullptr) { 6135 align_value = ir_gen_node(irb, align_expr, scope); 6136 if (align_value == irb->codegen->invalid_instruction) 6137 return align_value; 6138 } else { 6139 align_value = nullptr; 6140 } 6141 6142 IrInstruction *child_type = ir_gen_node(irb, expr_node, scope); 6143 if (child_type == irb->codegen->invalid_instruction) 6144 return child_type; 6145 6146 uint32_t bit_offset_start = 0; 6147 if (node->data.pointer_type.bit_offset_start != nullptr) { 6148 if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_start, 32, false)) { 6149 Buf *val_buf = buf_alloc(); 6150 bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10); 6151 exec_add_error_node(irb->codegen, irb->exec, node, 6152 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); 6153 return irb->codegen->invalid_instruction; 6154 } 6155 bit_offset_start = bigint_as_u32(node->data.pointer_type.bit_offset_start); 6156 } 6157 6158 uint32_t host_int_bytes = 0; 6159 if (node->data.pointer_type.host_int_bytes != nullptr) { 6160 if (!bigint_fits_in_bits(node->data.pointer_type.host_int_bytes, 32, false)) { 6161 Buf *val_buf = buf_alloc(); 6162 bigint_append_buf(val_buf, node->data.pointer_type.host_int_bytes, 10); 6163 exec_add_error_node(irb->codegen, irb->exec, node, 6164 buf_sprintf("value %s too large for u32 byte count", buf_ptr(val_buf))); 6165 return irb->codegen->invalid_instruction; 6166 } 6167 host_int_bytes = bigint_as_u32(node->data.pointer_type.host_int_bytes); 6168 } 6169 6170 if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) { 6171 exec_add_error_node(irb->codegen, irb->exec, node, 6172 buf_sprintf("bit offset starts after end of host integer")); 6173 return irb->codegen->invalid_instruction; 6174 } 6175 6176 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, 6177 ptr_len, sentinel, align_value, bit_offset_start, host_int_bytes, is_allow_zero); 6178 } 6179 6180 static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, 6181 AstNode *expr_node, LVal lval, ResultLoc *result_loc) 6182 { 6183 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 6184 if (err_union_ptr == irb->codegen->invalid_instruction) 6185 return irb->codegen->invalid_instruction; 6186 6187 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true, false); 6188 if (payload_ptr == irb->codegen->invalid_instruction) 6189 return irb->codegen->invalid_instruction; 6190 6191 if (lval == LValPtr) 6192 return payload_ptr; 6193 6194 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr); 6195 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 6196 } 6197 6198 static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) { 6199 assert(node->type == NodeTypePrefixOpExpr); 6200 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 6201 6202 IrInstruction *value = ir_gen_node(irb, expr_node, scope); 6203 if (value == irb->codegen->invalid_instruction) 6204 return irb->codegen->invalid_instruction; 6205 6206 return ir_build_bool_not(irb, scope, node, value); 6207 } 6208 6209 static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 6210 ResultLoc *result_loc) 6211 { 6212 assert(node->type == NodeTypePrefixOpExpr); 6213 6214 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; 6215 6216 switch (prefix_op) { 6217 case PrefixOpInvalid: 6218 zig_unreachable(); 6219 case PrefixOpBoolNot: 6220 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval, result_loc); 6221 case PrefixOpBinNot: 6222 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval, result_loc); 6223 case PrefixOpNegation: 6224 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval, result_loc); 6225 case PrefixOpNegationWrap: 6226 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval, result_loc); 6227 case PrefixOpOptional: 6228 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval, result_loc); 6229 case PrefixOpAddrOf: { 6230 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 6231 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval, result_loc); 6232 } 6233 } 6234 zig_unreachable(); 6235 } 6236 6237 static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, 6238 IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, 6239 LVal lval, ResultLoc *parent_result_loc) 6240 { 6241 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type); 6242 IrInstruction *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr, 6243 field_name, true); 6244 6245 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); 6246 result_loc_inst->base.id = ResultLocIdInstruction; 6247 result_loc_inst->base.source_instruction = field_ptr; 6248 ir_ref_instruction(field_ptr, irb->current_basic_block); 6249 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 6250 6251 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 6252 &result_loc_inst->base); 6253 if (expr_value == irb->codegen->invalid_instruction) 6254 return expr_value; 6255 6256 IrInstruction *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type, 6257 field_name, field_ptr, container_ptr); 6258 6259 return ir_lval_wrap(irb, scope, init_union, lval, parent_result_loc); 6260 } 6261 6262 static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 6263 ResultLoc *parent_result_loc) 6264 { 6265 assert(node->type == NodeTypeContainerInitExpr); 6266 6267 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; 6268 ContainerInitKind kind = container_init_expr->kind; 6269 6270 ResultLocCast *result_loc_cast = nullptr; 6271 ResultLoc *child_result_loc; 6272 AstNode *init_array_type_source_node; 6273 if (container_init_expr->type != nullptr) { 6274 IrInstruction *container_type; 6275 if (container_init_expr->type->type == NodeTypeInferredArrayType) { 6276 if (kind == ContainerInitKindStruct) { 6277 add_node_error(irb->codegen, container_init_expr->type, 6278 buf_sprintf("initializing array with struct syntax")); 6279 return irb->codegen->invalid_instruction; 6280 } 6281 IrInstruction *sentinel; 6282 if (container_init_expr->type->data.inferred_array_type.sentinel != nullptr) { 6283 sentinel = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.sentinel, scope); 6284 if (sentinel == irb->codegen->invalid_instruction) 6285 return sentinel; 6286 } else { 6287 sentinel = nullptr; 6288 } 6289 6290 IrInstruction *elem_type = ir_gen_node(irb, 6291 container_init_expr->type->data.inferred_array_type.child_type, scope); 6292 if (elem_type == irb->codegen->invalid_instruction) 6293 return elem_type; 6294 size_t item_count = container_init_expr->entries.length; 6295 IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); 6296 container_type = ir_build_array_type(irb, scope, node, item_count_inst, sentinel, elem_type); 6297 } else { 6298 container_type = ir_gen_node(irb, container_init_expr->type, scope); 6299 if (container_type == irb->codegen->invalid_instruction) 6300 return container_type; 6301 } 6302 6303 result_loc_cast = ir_build_cast_result_loc(irb, container_type, parent_result_loc); 6304 child_result_loc = &result_loc_cast->base; 6305 init_array_type_source_node = container_type->source_node; 6306 } else { 6307 child_result_loc = parent_result_loc; 6308 if (parent_result_loc->source_instruction != nullptr) { 6309 init_array_type_source_node = parent_result_loc->source_instruction->source_node; 6310 } else { 6311 init_array_type_source_node = node; 6312 } 6313 } 6314 6315 switch (kind) { 6316 case ContainerInitKindStruct: { 6317 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, 6318 nullptr); 6319 6320 size_t field_count = container_init_expr->entries.length; 6321 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); 6322 for (size_t i = 0; i < field_count; i += 1) { 6323 AstNode *entry_node = container_init_expr->entries.at(i); 6324 assert(entry_node->type == NodeTypeStructValueField); 6325 6326 Buf *name = entry_node->data.struct_val_field.name; 6327 AstNode *expr_node = entry_node->data.struct_val_field.expr; 6328 6329 IrInstruction *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true); 6330 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); 6331 result_loc_inst->base.id = ResultLocIdInstruction; 6332 result_loc_inst->base.source_instruction = field_ptr; 6333 result_loc_inst->base.allow_write_through_const = true; 6334 ir_ref_instruction(field_ptr, irb->current_basic_block); 6335 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 6336 6337 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 6338 &result_loc_inst->base); 6339 if (expr_value == irb->codegen->invalid_instruction) 6340 return expr_value; 6341 6342 fields[i].name = name; 6343 fields[i].source_node = entry_node; 6344 fields[i].result_loc = field_ptr; 6345 } 6346 IrInstruction *result = ir_build_container_init_fields(irb, scope, node, field_count, 6347 fields, container_ptr); 6348 6349 if (result_loc_cast != nullptr) { 6350 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast); 6351 } 6352 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc); 6353 } 6354 case ContainerInitKindArray: { 6355 size_t item_count = container_init_expr->entries.length; 6356 6357 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, 6358 nullptr); 6359 6360 IrInstruction **result_locs = allocate<IrInstruction *>(item_count); 6361 for (size_t i = 0; i < item_count; i += 1) { 6362 AstNode *expr_node = container_init_expr->entries.at(i); 6363 6364 IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i); 6365 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, 6366 elem_index, false, PtrLenSingle, init_array_type_source_node); 6367 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); 6368 result_loc_inst->base.id = ResultLocIdInstruction; 6369 result_loc_inst->base.source_instruction = elem_ptr; 6370 result_loc_inst->base.allow_write_through_const = true; 6371 ir_ref_instruction(elem_ptr, irb->current_basic_block); 6372 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 6373 6374 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 6375 &result_loc_inst->base); 6376 if (expr_value == irb->codegen->invalid_instruction) 6377 return expr_value; 6378 6379 result_locs[i] = elem_ptr; 6380 } 6381 IrInstruction *result = ir_build_container_init_list(irb, scope, node, item_count, 6382 result_locs, container_ptr, init_array_type_source_node); 6383 if (result_loc_cast != nullptr) { 6384 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast); 6385 } 6386 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc); 6387 } 6388 } 6389 zig_unreachable(); 6390 } 6391 6392 static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *alloca, ZigVar *var) { 6393 ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); 6394 result_loc_var->base.id = ResultLocIdVar; 6395 result_loc_var->base.source_instruction = alloca; 6396 result_loc_var->base.allow_write_through_const = true; 6397 result_loc_var->var = var; 6398 6399 ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base); 6400 6401 return result_loc_var; 6402 } 6403 6404 static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type, 6405 ResultLoc *parent_result_loc) 6406 { 6407 ResultLocCast *result_loc_cast = allocate<ResultLocCast>(1); 6408 result_loc_cast->base.id = ResultLocIdCast; 6409 result_loc_cast->base.source_instruction = dest_type; 6410 result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const; 6411 ir_ref_instruction(dest_type, irb->current_basic_block); 6412 result_loc_cast->parent = parent_result_loc; 6413 6414 ir_build_reset_result(irb, dest_type->scope, dest_type->source_node, &result_loc_cast->base); 6415 6416 return result_loc_cast; 6417 } 6418 6419 static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, 6420 IrInstruction *init, const char *name_hint, IrInstruction *is_comptime) 6421 { 6422 IrInstruction *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime); 6423 ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var); 6424 ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base); 6425 ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca); 6426 } 6427 6428 static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) { 6429 assert(node->type == NodeTypeVariableDeclaration); 6430 6431 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; 6432 6433 if (buf_eql_str(variable_declaration->symbol, "_")) { 6434 add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol")); 6435 return irb->codegen->invalid_instruction; 6436 } 6437 6438 // Used for the type expr and the align expr 6439 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 6440 6441 IrInstruction *type_instruction; 6442 if (variable_declaration->type != nullptr) { 6443 type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope); 6444 if (type_instruction == irb->codegen->invalid_instruction) 6445 return type_instruction; 6446 } else { 6447 type_instruction = nullptr; 6448 } 6449 6450 bool is_shadowable = false; 6451 bool is_const = variable_declaration->is_const; 6452 bool is_extern = variable_declaration->is_extern; 6453 6454 bool is_comptime_scalar = ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime; 6455 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar); 6456 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, 6457 is_const, is_const, is_shadowable, is_comptime); 6458 // we detect IrInstructionIdDeclVarSrc in gen_block to make sure the next node 6459 // is inside var->child_scope 6460 6461 if (!is_extern && !variable_declaration->expr) { 6462 var->var_type = irb->codegen->builtin_types.entry_invalid; 6463 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); 6464 return irb->codegen->invalid_instruction; 6465 } 6466 6467 IrInstruction *align_value = nullptr; 6468 if (variable_declaration->align_expr != nullptr) { 6469 align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope); 6470 if (align_value == irb->codegen->invalid_instruction) 6471 return align_value; 6472 } 6473 6474 if (variable_declaration->section_expr != nullptr) { 6475 add_node_error(irb->codegen, variable_declaration->section_expr, 6476 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol))); 6477 } 6478 6479 // Parser should ensure that this never happens 6480 assert(variable_declaration->threadlocal_tok == nullptr); 6481 6482 IrInstruction *alloca = ir_build_alloca_src(irb, scope, node, align_value, 6483 buf_ptr(variable_declaration->symbol), is_comptime); 6484 6485 // Create a result location for the initialization expression. 6486 ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var); 6487 ResultLoc *init_result_loc; 6488 ResultLocCast *result_loc_cast; 6489 if (type_instruction != nullptr) { 6490 result_loc_cast = ir_build_cast_result_loc(irb, type_instruction, &result_loc_var->base); 6491 init_result_loc = &result_loc_cast->base; 6492 } else { 6493 result_loc_cast = nullptr; 6494 init_result_loc = &result_loc_var->base; 6495 } 6496 6497 Scope *init_scope = is_comptime_scalar ? 6498 create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope; 6499 6500 // Temporarily set the name of the IrExecutable to the VariableDeclaration 6501 // so that the struct or enum from the init expression inherits the name. 6502 Buf *old_exec_name = irb->exec->name; 6503 irb->exec->name = variable_declaration->symbol; 6504 IrInstruction *init_value = ir_gen_node_extra(irb, variable_declaration->expr, init_scope, 6505 LValNone, init_result_loc); 6506 irb->exec->name = old_exec_name; 6507 6508 if (init_value == irb->codegen->invalid_instruction) 6509 return irb->codegen->invalid_instruction; 6510 6511 if (result_loc_cast != nullptr) { 6512 IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, init_value->source_node, 6513 init_value, result_loc_cast); 6514 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); 6515 } 6516 6517 return ir_build_var_decl_src(irb, scope, node, var, align_value, alloca); 6518 } 6519 6520 static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 6521 ResultLoc *result_loc) 6522 { 6523 assert(node->type == NodeTypeWhileExpr); 6524 6525 AstNode *continue_expr_node = node->data.while_expr.continue_expr; 6526 AstNode *else_node = node->data.while_expr.else_node; 6527 6528 IrBasicBlock *cond_block = ir_create_basic_block(irb, scope, "WhileCond"); 6529 IrBasicBlock *body_block = ir_create_basic_block(irb, scope, "WhileBody"); 6530 IrBasicBlock *continue_block = continue_expr_node ? 6531 ir_create_basic_block(irb, scope, "WhileContinue") : cond_block; 6532 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "WhileEnd"); 6533 IrBasicBlock *else_block = else_node ? 6534 ir_create_basic_block(irb, scope, "WhileElse") : end_block; 6535 6536 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, 6537 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline); 6538 ir_build_br(irb, scope, node, cond_block, is_comptime); 6539 6540 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6541 Buf *var_symbol = node->data.while_expr.var_symbol; 6542 Buf *err_symbol = node->data.while_expr.err_symbol; 6543 if (err_symbol != nullptr) { 6544 ir_set_cursor_at_end_and_append_block(irb, cond_block); 6545 6546 Scope *payload_scope; 6547 AstNode *symbol_node = node; // TODO make more accurate 6548 ZigVar *payload_var; 6549 if (var_symbol) { 6550 // TODO make it an error to write to payload variable 6551 payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 6552 true, false, false, is_comptime); 6553 payload_scope = payload_var->child_scope; 6554 } else { 6555 payload_scope = subexpr_scope; 6556 } 6557 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, 6558 LValPtr, nullptr); 6559 if (err_val_ptr == irb->codegen->invalid_instruction) 6560 return err_val_ptr; 6561 IrInstruction *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, 6562 true, false); 6563 IrBasicBlock *after_cond_block = irb->current_basic_block; 6564 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 6565 IrInstruction *cond_br_inst; 6566 if (!instr_is_unreachable(is_err)) { 6567 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, 6568 else_block, body_block, is_comptime); 6569 cond_br_inst->is_gen = true; 6570 } else { 6571 // for the purposes of the source instruction to ir_build_result_peers 6572 cond_br_inst = irb->current_basic_block->instruction_list.last(); 6573 } 6574 6575 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 6576 is_comptime); 6577 6578 ir_set_cursor_at_end_and_append_block(irb, body_block); 6579 if (var_symbol) { 6580 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, 6581 err_val_ptr, false, false); 6582 IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? 6583 ir_build_ref(irb, payload_scope, symbol_node, payload_ptr, true, false) : payload_ptr; 6584 ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, var_ptr); 6585 } 6586 6587 ZigList<IrInstruction *> incoming_values = {0}; 6588 ZigList<IrBasicBlock *> incoming_blocks = {0}; 6589 6590 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope); 6591 loop_scope->break_block = end_block; 6592 loop_scope->continue_block = continue_block; 6593 loop_scope->is_comptime = is_comptime; 6594 loop_scope->incoming_blocks = &incoming_blocks; 6595 loop_scope->incoming_values = &incoming_values; 6596 loop_scope->lval = lval; 6597 loop_scope->peer_parent = peer_parent; 6598 6599 // Note the body block of the loop is not the place that lval and result_loc are used - 6600 // it's actually in break statements, handled similarly to return statements. 6601 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 6602 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 6603 if (body_result == irb->codegen->invalid_instruction) 6604 return body_result; 6605 6606 if (!instr_is_unreachable(body_result)) { 6607 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result)); 6608 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime)); 6609 } 6610 6611 if (continue_expr_node) { 6612 ir_set_cursor_at_end_and_append_block(irb, continue_block); 6613 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope); 6614 if (expr_result == irb->codegen->invalid_instruction) 6615 return expr_result; 6616 if (!instr_is_unreachable(expr_result)) { 6617 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, continue_expr_node, expr_result)); 6618 ir_mark_gen(ir_build_br(irb, payload_scope, node, cond_block, is_comptime)); 6619 } 6620 } 6621 6622 ir_set_cursor_at_end_and_append_block(irb, else_block); 6623 assert(else_node != nullptr); 6624 6625 // TODO make it an error to write to error variable 6626 AstNode *err_symbol_node = else_node; // TODO make more accurate 6627 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, 6628 true, false, false, is_comptime); 6629 Scope *err_scope = err_var->child_scope; 6630 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); 6631 ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, err_ptr); 6632 6633 if (peer_parent->peers.length != 0) { 6634 peer_parent->peers.last()->next_bb = else_block; 6635 } 6636 ResultLocPeer *peer_result = create_peer_result(peer_parent); 6637 peer_parent->peers.append(peer_result); 6638 IrInstruction *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base); 6639 if (else_result == irb->codegen->invalid_instruction) 6640 return else_result; 6641 if (!instr_is_unreachable(else_result)) 6642 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 6643 IrBasicBlock *after_else_block = irb->current_basic_block; 6644 ir_set_cursor_at_end_and_append_block(irb, end_block); 6645 if (else_result) { 6646 incoming_blocks.append(after_else_block); 6647 incoming_values.append(else_result); 6648 } else { 6649 incoming_blocks.append(after_cond_block); 6650 incoming_values.append(void_else_result); 6651 } 6652 if (peer_parent->peers.length != 0) { 6653 peer_parent->peers.last()->next_bb = end_block; 6654 } 6655 6656 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 6657 incoming_blocks.items, incoming_values.items, peer_parent); 6658 return ir_expr_wrap(irb, scope, phi, result_loc); 6659 } else if (var_symbol != nullptr) { 6660 ir_set_cursor_at_end_and_append_block(irb, cond_block); 6661 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6662 // TODO make it an error to write to payload variable 6663 AstNode *symbol_node = node; // TODO make more accurate 6664 6665 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 6666 true, false, false, is_comptime); 6667 Scope *child_scope = payload_var->child_scope; 6668 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, 6669 LValPtr, nullptr); 6670 if (maybe_val_ptr == irb->codegen->invalid_instruction) 6671 return maybe_val_ptr; 6672 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); 6673 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); 6674 IrBasicBlock *after_cond_block = irb->current_basic_block; 6675 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 6676 IrInstruction *cond_br_inst; 6677 if (!instr_is_unreachable(is_non_null)) { 6678 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, 6679 body_block, else_block, is_comptime); 6680 cond_br_inst->is_gen = true; 6681 } else { 6682 // for the purposes of the source instruction to ir_build_result_peers 6683 cond_br_inst = irb->current_basic_block->instruction_list.last(); 6684 } 6685 6686 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 6687 is_comptime); 6688 6689 ir_set_cursor_at_end_and_append_block(irb, body_block); 6690 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false, false); 6691 IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? 6692 ir_build_ref(irb, child_scope, symbol_node, payload_ptr, true, false) : payload_ptr; 6693 ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, var_ptr); 6694 6695 ZigList<IrInstruction *> incoming_values = {0}; 6696 ZigList<IrBasicBlock *> incoming_blocks = {0}; 6697 6698 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 6699 loop_scope->break_block = end_block; 6700 loop_scope->continue_block = continue_block; 6701 loop_scope->is_comptime = is_comptime; 6702 loop_scope->incoming_blocks = &incoming_blocks; 6703 loop_scope->incoming_values = &incoming_values; 6704 loop_scope->lval = lval; 6705 loop_scope->peer_parent = peer_parent; 6706 6707 // Note the body block of the loop is not the place that lval and result_loc are used - 6708 // it's actually in break statements, handled similarly to return statements. 6709 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 6710 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 6711 if (body_result == irb->codegen->invalid_instruction) 6712 return body_result; 6713 6714 if (!instr_is_unreachable(body_result)) { 6715 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result)); 6716 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 6717 } 6718 6719 if (continue_expr_node) { 6720 ir_set_cursor_at_end_and_append_block(irb, continue_block); 6721 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, child_scope); 6722 if (expr_result == irb->codegen->invalid_instruction) 6723 return expr_result; 6724 if (!instr_is_unreachable(expr_result)) { 6725 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, continue_expr_node, expr_result)); 6726 ir_mark_gen(ir_build_br(irb, child_scope, node, cond_block, is_comptime)); 6727 } 6728 } 6729 6730 IrInstruction *else_result = nullptr; 6731 if (else_node) { 6732 ir_set_cursor_at_end_and_append_block(irb, else_block); 6733 6734 if (peer_parent->peers.length != 0) { 6735 peer_parent->peers.last()->next_bb = else_block; 6736 } 6737 ResultLocPeer *peer_result = create_peer_result(peer_parent); 6738 peer_parent->peers.append(peer_result); 6739 else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base); 6740 if (else_result == irb->codegen->invalid_instruction) 6741 return else_result; 6742 if (!instr_is_unreachable(else_result)) 6743 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 6744 } 6745 IrBasicBlock *after_else_block = irb->current_basic_block; 6746 ir_set_cursor_at_end_and_append_block(irb, end_block); 6747 if (else_result) { 6748 incoming_blocks.append(after_else_block); 6749 incoming_values.append(else_result); 6750 } else { 6751 incoming_blocks.append(after_cond_block); 6752 incoming_values.append(void_else_result); 6753 } 6754 if (peer_parent->peers.length != 0) { 6755 peer_parent->peers.last()->next_bb = end_block; 6756 } 6757 6758 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 6759 incoming_blocks.items, incoming_values.items, peer_parent); 6760 return ir_expr_wrap(irb, scope, phi, result_loc); 6761 } else { 6762 ir_set_cursor_at_end_and_append_block(irb, cond_block); 6763 IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); 6764 if (cond_val == irb->codegen->invalid_instruction) 6765 return cond_val; 6766 IrBasicBlock *after_cond_block = irb->current_basic_block; 6767 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 6768 IrInstruction *cond_br_inst; 6769 if (!instr_is_unreachable(cond_val)) { 6770 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, 6771 body_block, else_block, is_comptime); 6772 cond_br_inst->is_gen = true; 6773 } else { 6774 // for the purposes of the source instruction to ir_build_result_peers 6775 cond_br_inst = irb->current_basic_block->instruction_list.last(); 6776 } 6777 6778 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 6779 is_comptime); 6780 ir_set_cursor_at_end_and_append_block(irb, body_block); 6781 6782 ZigList<IrInstruction *> incoming_values = {0}; 6783 ZigList<IrBasicBlock *> incoming_blocks = {0}; 6784 6785 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 6786 6787 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope); 6788 loop_scope->break_block = end_block; 6789 loop_scope->continue_block = continue_block; 6790 loop_scope->is_comptime = is_comptime; 6791 loop_scope->incoming_blocks = &incoming_blocks; 6792 loop_scope->incoming_values = &incoming_values; 6793 loop_scope->lval = lval; 6794 loop_scope->peer_parent = peer_parent; 6795 6796 // Note the body block of the loop is not the place that lval and result_loc are used - 6797 // it's actually in break statements, handled similarly to return statements. 6798 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 6799 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 6800 if (body_result == irb->codegen->invalid_instruction) 6801 return body_result; 6802 6803 if (!instr_is_unreachable(body_result)) { 6804 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result)); 6805 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime)); 6806 } 6807 6808 if (continue_expr_node) { 6809 ir_set_cursor_at_end_and_append_block(irb, continue_block); 6810 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, subexpr_scope); 6811 if (expr_result == irb->codegen->invalid_instruction) 6812 return expr_result; 6813 if (!instr_is_unreachable(expr_result)) { 6814 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, continue_expr_node, expr_result)); 6815 ir_mark_gen(ir_build_br(irb, scope, node, cond_block, is_comptime)); 6816 } 6817 } 6818 6819 IrInstruction *else_result = nullptr; 6820 if (else_node) { 6821 ir_set_cursor_at_end_and_append_block(irb, else_block); 6822 6823 if (peer_parent->peers.length != 0) { 6824 peer_parent->peers.last()->next_bb = else_block; 6825 } 6826 ResultLocPeer *peer_result = create_peer_result(peer_parent); 6827 peer_parent->peers.append(peer_result); 6828 6829 else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base); 6830 if (else_result == irb->codegen->invalid_instruction) 6831 return else_result; 6832 if (!instr_is_unreachable(else_result)) 6833 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 6834 } 6835 IrBasicBlock *after_else_block = irb->current_basic_block; 6836 ir_set_cursor_at_end_and_append_block(irb, end_block); 6837 if (else_result) { 6838 incoming_blocks.append(after_else_block); 6839 incoming_values.append(else_result); 6840 } else { 6841 incoming_blocks.append(after_cond_block); 6842 incoming_values.append(void_else_result); 6843 } 6844 if (peer_parent->peers.length != 0) { 6845 peer_parent->peers.last()->next_bb = end_block; 6846 } 6847 6848 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 6849 incoming_blocks.items, incoming_values.items, peer_parent); 6850 return ir_expr_wrap(irb, scope, phi, result_loc); 6851 } 6852 } 6853 6854 static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, 6855 ResultLoc *result_loc) 6856 { 6857 assert(node->type == NodeTypeForExpr); 6858 6859 AstNode *array_node = node->data.for_expr.array_expr; 6860 AstNode *elem_node = node->data.for_expr.elem_node; 6861 AstNode *index_node = node->data.for_expr.index_node; 6862 AstNode *body_node = node->data.for_expr.body; 6863 AstNode *else_node = node->data.for_expr.else_node; 6864 6865 if (!elem_node) { 6866 add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter")); 6867 return irb->codegen->invalid_instruction; 6868 } 6869 assert(elem_node->type == NodeTypeSymbol); 6870 6871 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, parent_scope); 6872 6873 IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, &spill_scope->base, LValPtr, nullptr); 6874 if (array_val_ptr == irb->codegen->invalid_instruction) 6875 return array_val_ptr; 6876 6877 IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, 6878 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); 6879 6880 AstNode *index_var_source_node; 6881 ZigVar *index_var; 6882 const char *index_var_name; 6883 if (index_node) { 6884 index_var_source_node = index_node; 6885 Buf *index_var_name_buf = index_node->data.symbol_expr.symbol; 6886 index_var = ir_create_var(irb, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime); 6887 index_var_name = buf_ptr(index_var_name_buf); 6888 } else { 6889 index_var_source_node = node; 6890 index_var = ir_create_var(irb, node, parent_scope, nullptr, true, false, true, is_comptime); 6891 index_var_name = "i"; 6892 } 6893 6894 IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0); 6895 build_decl_var_and_init(irb, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime); 6896 parent_scope = index_var->child_scope; 6897 6898 IrInstruction *one = ir_build_const_usize(irb, parent_scope, node, 1); 6899 IrInstruction *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var); 6900 6901 6902 IrBasicBlock *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond"); 6903 IrBasicBlock *body_block = ir_create_basic_block(irb, parent_scope, "ForBody"); 6904 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd"); 6905 IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block; 6906 IrBasicBlock *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue"); 6907 6908 Buf *len_field_name = buf_create_from_str("len"); 6909 IrInstruction *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false); 6910 IrInstruction *len_val = ir_build_load_ptr(irb, &spill_scope->base, node, len_ref); 6911 ir_build_br(irb, parent_scope, node, cond_block, is_comptime); 6912 6913 ir_set_cursor_at_end_and_append_block(irb, cond_block); 6914 IrInstruction *index_val = ir_build_load_ptr(irb, &spill_scope->base, node, index_ptr); 6915 IrInstruction *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); 6916 IrBasicBlock *after_cond_block = irb->current_basic_block; 6917 IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); 6918 IrInstruction *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, 6919 body_block, else_block, is_comptime)); 6920 6921 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime); 6922 6923 ir_set_cursor_at_end_and_append_block(irb, body_block); 6924 Scope *elem_ptr_scope = node->data.for_expr.elem_is_ptr ? parent_scope : &spill_scope->base; 6925 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, elem_ptr_scope, node, array_val_ptr, index_val, false, 6926 PtrLenSingle, nullptr); 6927 // TODO make it an error to write to element variable or i variable. 6928 Buf *elem_var_name = elem_node->data.symbol_expr.symbol; 6929 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); 6930 Scope *child_scope = elem_var->child_scope; 6931 6932 IrInstruction *var_ptr = node->data.for_expr.elem_is_ptr ? 6933 ir_build_ref(irb, &spill_scope->base, elem_node, elem_ptr, true, false) : elem_ptr; 6934 ir_build_var_decl_src(irb, parent_scope, elem_node, elem_var, nullptr, var_ptr); 6935 6936 ZigList<IrInstruction *> incoming_values = {0}; 6937 ZigList<IrBasicBlock *> incoming_blocks = {0}; 6938 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 6939 loop_scope->break_block = end_block; 6940 loop_scope->continue_block = continue_block; 6941 loop_scope->is_comptime = is_comptime; 6942 loop_scope->incoming_blocks = &incoming_blocks; 6943 loop_scope->incoming_values = &incoming_values; 6944 loop_scope->lval = LValNone; 6945 loop_scope->peer_parent = peer_parent; 6946 loop_scope->spill_scope = spill_scope; 6947 6948 // Note the body block of the loop is not the place that lval and result_loc are used - 6949 // it's actually in break statements, handled similarly to return statements. 6950 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 6951 IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base); 6952 6953 if (!instr_is_unreachable(body_result)) { 6954 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result)); 6955 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 6956 } 6957 6958 ir_set_cursor_at_end_and_append_block(irb, continue_block); 6959 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); 6960 ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true; 6961 ir_build_br(irb, child_scope, node, cond_block, is_comptime); 6962 6963 IrInstruction *else_result = nullptr; 6964 if (else_node) { 6965 ir_set_cursor_at_end_and_append_block(irb, else_block); 6966 6967 if (peer_parent->peers.length != 0) { 6968 peer_parent->peers.last()->next_bb = else_block; 6969 } 6970 ResultLocPeer *peer_result = create_peer_result(peer_parent); 6971 peer_parent->peers.append(peer_result); 6972 else_result = ir_gen_node_extra(irb, else_node, parent_scope, LValNone, &peer_result->base); 6973 if (else_result == irb->codegen->invalid_instruction) 6974 return else_result; 6975 if (!instr_is_unreachable(else_result)) 6976 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 6977 } 6978 IrBasicBlock *after_else_block = irb->current_basic_block; 6979 ir_set_cursor_at_end_and_append_block(irb, end_block); 6980 6981 if (else_result) { 6982 incoming_blocks.append(after_else_block); 6983 incoming_values.append(else_result); 6984 } else { 6985 incoming_blocks.append(after_cond_block); 6986 incoming_values.append(void_else_value); 6987 } 6988 if (peer_parent->peers.length != 0) { 6989 peer_parent->peers.last()->next_bb = end_block; 6990 } 6991 6992 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, 6993 incoming_blocks.items, incoming_values.items, peer_parent); 6994 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 6995 } 6996 6997 static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 6998 assert(node->type == NodeTypeBoolLiteral); 6999 return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value); 7000 } 7001 7002 static IrInstruction *ir_gen_enum_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 7003 assert(node->type == NodeTypeEnumLiteral); 7004 Buf *name = &node->data.enum_literal.identifier->data.str_lit.str; 7005 return ir_build_const_enum_literal(irb, scope, node, name); 7006 } 7007 7008 static IrInstruction *ir_gen_string_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 7009 assert(node->type == NodeTypeStringLiteral); 7010 7011 return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf); 7012 } 7013 7014 static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *node) { 7015 assert(node->type == NodeTypeArrayType); 7016 7017 AstNode *size_node = node->data.array_type.size; 7018 AstNode *child_type_node = node->data.array_type.child_type; 7019 bool is_const = node->data.array_type.is_const; 7020 bool is_volatile = node->data.array_type.is_volatile; 7021 bool is_allow_zero = node->data.array_type.allow_zero_token != nullptr; 7022 AstNode *sentinel_expr = node->data.array_type.sentinel; 7023 AstNode *align_expr = node->data.array_type.align_expr; 7024 7025 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 7026 7027 IrInstruction *sentinel; 7028 if (sentinel_expr != nullptr) { 7029 sentinel = ir_gen_node(irb, sentinel_expr, comptime_scope); 7030 if (sentinel == irb->codegen->invalid_instruction) 7031 return sentinel; 7032 } else { 7033 sentinel = nullptr; 7034 } 7035 7036 if (size_node) { 7037 if (is_const) { 7038 add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); 7039 return irb->codegen->invalid_instruction; 7040 } 7041 if (is_volatile) { 7042 add_node_error(irb->codegen, node, buf_create_from_str("volatile qualifier invalid on array type")); 7043 return irb->codegen->invalid_instruction; 7044 } 7045 if (is_allow_zero) { 7046 add_node_error(irb->codegen, node, buf_create_from_str("allowzero qualifier invalid on array type")); 7047 return irb->codegen->invalid_instruction; 7048 } 7049 if (align_expr != nullptr) { 7050 add_node_error(irb->codegen, node, buf_create_from_str("align qualifier invalid on array type")); 7051 return irb->codegen->invalid_instruction; 7052 } 7053 7054 IrInstruction *size_value = ir_gen_node(irb, size_node, comptime_scope); 7055 if (size_value == irb->codegen->invalid_instruction) 7056 return size_value; 7057 7058 IrInstruction *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 7059 if (child_type == irb->codegen->invalid_instruction) 7060 return child_type; 7061 7062 return ir_build_array_type(irb, scope, node, size_value, sentinel, child_type); 7063 } else { 7064 IrInstruction *align_value; 7065 if (align_expr != nullptr) { 7066 align_value = ir_gen_node(irb, align_expr, comptime_scope); 7067 if (align_value == irb->codegen->invalid_instruction) 7068 return align_value; 7069 } else { 7070 align_value = nullptr; 7071 } 7072 7073 IrInstruction *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 7074 if (child_type == irb->codegen->invalid_instruction) 7075 return child_type; 7076 7077 return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, sentinel, 7078 align_value, is_allow_zero); 7079 } 7080 } 7081 7082 static IrInstruction *ir_gen_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *node) { 7083 assert(node->type == NodeTypeAnyFrameType); 7084 7085 AstNode *payload_type_node = node->data.anyframe_type.payload_type; 7086 IrInstruction *payload_type_value = nullptr; 7087 7088 if (payload_type_node != nullptr) { 7089 payload_type_value = ir_gen_node(irb, payload_type_node, scope); 7090 if (payload_type_value == irb->codegen->invalid_instruction) 7091 return payload_type_value; 7092 7093 } 7094 7095 return ir_build_anyframe_type(irb, scope, node, payload_type_value); 7096 } 7097 7098 static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 7099 assert(node->type == NodeTypeUndefinedLiteral); 7100 return ir_build_const_undefined(irb, scope, node); 7101 } 7102 7103 static Error parse_asm_template(IrBuilder *irb, AstNode *source_node, Buf *asm_template, 7104 ZigList<AsmToken> *tok_list) 7105 { 7106 // TODO Connect the errors in this function back up to the actual source location 7107 // rather than just the token. https://github.com/ziglang/zig/issues/2080 7108 enum State { 7109 StateStart, 7110 StatePercent, 7111 StateTemplate, 7112 StateVar, 7113 }; 7114 7115 assert(tok_list->length == 0); 7116 7117 AsmToken *cur_tok = nullptr; 7118 7119 enum State state = StateStart; 7120 7121 for (size_t i = 0; i < buf_len(asm_template); i += 1) { 7122 uint8_t c = *((uint8_t*)buf_ptr(asm_template) + i); 7123 switch (state) { 7124 case StateStart: 7125 if (c == '%') { 7126 tok_list->add_one(); 7127 cur_tok = &tok_list->last(); 7128 cur_tok->id = AsmTokenIdPercent; 7129 cur_tok->start = i; 7130 state = StatePercent; 7131 } else { 7132 tok_list->add_one(); 7133 cur_tok = &tok_list->last(); 7134 cur_tok->id = AsmTokenIdTemplate; 7135 cur_tok->start = i; 7136 state = StateTemplate; 7137 } 7138 break; 7139 case StatePercent: 7140 if (c == '%') { 7141 cur_tok->end = i; 7142 state = StateStart; 7143 } else if (c == '[') { 7144 cur_tok->id = AsmTokenIdVar; 7145 state = StateVar; 7146 } else if (c == '=') { 7147 cur_tok->id = AsmTokenIdUniqueId; 7148 cur_tok->end = i; 7149 state = StateStart; 7150 } else { 7151 add_node_error(irb->codegen, source_node, 7152 buf_create_from_str("expected a '%' or '['")); 7153 return ErrorSemanticAnalyzeFail; 7154 } 7155 break; 7156 case StateTemplate: 7157 if (c == '%') { 7158 cur_tok->end = i; 7159 i -= 1; 7160 cur_tok = nullptr; 7161 state = StateStart; 7162 } 7163 break; 7164 case StateVar: 7165 if (c == ']') { 7166 cur_tok->end = i; 7167 state = StateStart; 7168 } else if ((c >= 'a' && c <= 'z') || 7169 (c >= '0' && c <= '9') || 7170 (c == '_')) 7171 { 7172 // do nothing 7173 } else { 7174 add_node_error(irb->codegen, source_node, 7175 buf_sprintf("invalid substitution character: '%c'", c)); 7176 return ErrorSemanticAnalyzeFail; 7177 } 7178 break; 7179 } 7180 } 7181 7182 switch (state) { 7183 case StateStart: 7184 break; 7185 case StatePercent: 7186 case StateVar: 7187 add_node_error(irb->codegen, source_node, buf_sprintf("unexpected end of assembly template")); 7188 return ErrorSemanticAnalyzeFail; 7189 case StateTemplate: 7190 cur_tok->end = buf_len(asm_template); 7191 break; 7192 } 7193 return ErrorNone; 7194 } 7195 7196 static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_template) { 7197 const char *ptr = buf_ptr(src_template) + tok->start + 2; 7198 size_t len = tok->end - tok->start - 2; 7199 size_t result = 0; 7200 for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1, result += 1) { 7201 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); 7202 if (buf_eql_mem(asm_output->asm_symbolic_name, ptr, len)) { 7203 return result; 7204 } 7205 } 7206 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1, result += 1) { 7207 AsmInput *asm_input = node->data.asm_expr.input_list.at(i); 7208 if (buf_eql_mem(asm_input->asm_symbolic_name, ptr, len)) { 7209 return result; 7210 } 7211 } 7212 return SIZE_MAX; 7213 } 7214 7215 static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 7216 Error err; 7217 assert(node->type == NodeTypeAsmExpr); 7218 AstNodeAsmExpr *asm_expr = &node->data.asm_expr; 7219 bool is_volatile = asm_expr->volatile_token != nullptr; 7220 bool in_fn_scope = (scope_fn_entry(scope) != nullptr); 7221 7222 Buf *template_buf = &asm_expr->asm_template->data.str_lit.str; 7223 7224 if (!in_fn_scope) { 7225 if (is_volatile) { 7226 add_token_error(irb->codegen, node->owner, asm_expr->volatile_token, 7227 buf_sprintf("volatile is meaningless on global assembly")); 7228 return irb->codegen->invalid_instruction; 7229 } 7230 7231 if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 || 7232 asm_expr->clobber_list.length != 0) 7233 { 7234 add_node_error(irb->codegen, node, 7235 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers")); 7236 return irb->codegen->invalid_instruction; 7237 } 7238 7239 return ir_build_global_asm(irb, scope, node, template_buf); 7240 } 7241 7242 ZigList<AsmToken> tok_list = {}; 7243 if ((err = parse_asm_template(irb, node, template_buf, &tok_list))) { 7244 return irb->codegen->invalid_instruction; 7245 } 7246 7247 IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length); 7248 IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length); 7249 ZigVar **output_vars = allocate<ZigVar *>(asm_expr->output_list.length); 7250 size_t return_count = 0; 7251 if (!is_volatile && asm_expr->output_list.length == 0) { 7252 add_node_error(irb->codegen, node, 7253 buf_sprintf("assembly expression with no output must be marked volatile")); 7254 return irb->codegen->invalid_instruction; 7255 } 7256 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 7257 AsmOutput *asm_output = asm_expr->output_list.at(i); 7258 if (asm_output->return_type) { 7259 return_count += 1; 7260 7261 IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, scope); 7262 if (return_type == irb->codegen->invalid_instruction) 7263 return irb->codegen->invalid_instruction; 7264 if (return_count > 1) { 7265 add_node_error(irb->codegen, node, 7266 buf_sprintf("inline assembly allows up to one output value")); 7267 return irb->codegen->invalid_instruction; 7268 } 7269 output_types[i] = return_type; 7270 } else { 7271 Buf *variable_name = asm_output->variable_name; 7272 // TODO there is some duplication here with ir_gen_symbol. I need to do a full audit of how 7273 // inline assembly works. https://github.com/ziglang/zig/issues/215 7274 ZigVar *var = find_variable(irb->codegen, scope, variable_name, nullptr); 7275 if (var) { 7276 output_vars[i] = var; 7277 } else { 7278 add_node_error(irb->codegen, node, 7279 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); 7280 return irb->codegen->invalid_instruction; 7281 } 7282 } 7283 7284 const char modifier = *buf_ptr(asm_output->constraint); 7285 if (modifier != '=') { 7286 add_node_error(irb->codegen, node, 7287 buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported." 7288 " Compiler TODO: see https://github.com/ziglang/zig/issues/215", 7289 buf_ptr(asm_output->asm_symbolic_name), modifier)); 7290 return irb->codegen->invalid_instruction; 7291 } 7292 } 7293 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 7294 AsmInput *asm_input = asm_expr->input_list.at(i); 7295 IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, scope); 7296 if (input_value == irb->codegen->invalid_instruction) 7297 return irb->codegen->invalid_instruction; 7298 7299 input_list[i] = input_value; 7300 } 7301 7302 for (size_t token_i = 0; token_i < tok_list.length; token_i += 1) { 7303 AsmToken asm_token = tok_list.at(token_i); 7304 if (asm_token.id == AsmTokenIdVar) { 7305 size_t index = find_asm_index(irb->codegen, node, &asm_token, template_buf); 7306 if (index == SIZE_MAX) { 7307 const char *ptr = buf_ptr(template_buf) + asm_token.start + 2; 7308 uint32_t len = asm_token.end - asm_token.start - 2; 7309 7310 add_node_error(irb->codegen, node, 7311 buf_sprintf("could not find '%.*s' in the inputs or outputs", 7312 len, ptr)); 7313 return irb->codegen->invalid_instruction; 7314 } 7315 } 7316 } 7317 7318 return ir_build_asm(irb, scope, node, template_buf, tok_list.items, tok_list.length, 7319 input_list, output_types, output_vars, return_count, is_volatile); 7320 } 7321 7322 static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 7323 ResultLoc *result_loc) 7324 { 7325 assert(node->type == NodeTypeIfOptional); 7326 7327 Buf *var_symbol = node->data.test_expr.var_symbol; 7328 AstNode *expr_node = node->data.test_expr.target_node; 7329 AstNode *then_node = node->data.test_expr.then_node; 7330 AstNode *else_node = node->data.test_expr.else_node; 7331 bool var_is_ptr = node->data.test_expr.var_is_ptr; 7332 7333 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 7334 if (maybe_val_ptr == irb->codegen->invalid_instruction) 7335 return maybe_val_ptr; 7336 7337 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); 7338 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_val); 7339 7340 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "OptionalThen"); 7341 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "OptionalElse"); 7342 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "OptionalEndIf"); 7343 7344 IrInstruction *is_comptime; 7345 if (ir_should_inline(irb->exec, scope)) { 7346 is_comptime = ir_build_const_bool(irb, scope, node, true); 7347 } else { 7348 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); 7349 } 7350 IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null, 7351 then_block, else_block, is_comptime); 7352 7353 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 7354 result_loc, is_comptime); 7355 7356 ir_set_cursor_at_end_and_append_block(irb, then_block); 7357 7358 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 7359 Scope *var_scope; 7360 if (var_symbol) { 7361 bool is_shadowable = false; 7362 bool is_const = true; 7363 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 7364 var_symbol, is_const, is_const, is_shadowable, is_comptime); 7365 7366 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false); 7367 IrInstruction *var_ptr = var_is_ptr ? ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; 7368 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); 7369 var_scope = var->child_scope; 7370 } else { 7371 var_scope = subexpr_scope; 7372 } 7373 IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, 7374 &peer_parent->peers.at(0)->base); 7375 if (then_expr_result == irb->codegen->invalid_instruction) 7376 return then_expr_result; 7377 IrBasicBlock *after_then_block = irb->current_basic_block; 7378 if (!instr_is_unreachable(then_expr_result)) 7379 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 7380 7381 ir_set_cursor_at_end_and_append_block(irb, else_block); 7382 IrInstruction *else_expr_result; 7383 if (else_node) { 7384 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); 7385 if (else_expr_result == irb->codegen->invalid_instruction) 7386 return else_expr_result; 7387 } else { 7388 else_expr_result = ir_build_const_void(irb, scope, node); 7389 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 7390 } 7391 IrBasicBlock *after_else_block = irb->current_basic_block; 7392 if (!instr_is_unreachable(else_expr_result)) 7393 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 7394 7395 ir_set_cursor_at_end_and_append_block(irb, endif_block); 7396 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 7397 incoming_values[0] = then_expr_result; 7398 incoming_values[1] = else_expr_result; 7399 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 7400 incoming_blocks[0] = after_then_block; 7401 incoming_blocks[1] = after_else_block; 7402 7403 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 7404 return ir_expr_wrap(irb, scope, phi, result_loc); 7405 } 7406 7407 static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 7408 ResultLoc *result_loc) 7409 { 7410 assert(node->type == NodeTypeIfErrorExpr); 7411 7412 AstNode *target_node = node->data.if_err_expr.target_node; 7413 AstNode *then_node = node->data.if_err_expr.then_node; 7414 AstNode *else_node = node->data.if_err_expr.else_node; 7415 bool var_is_ptr = node->data.if_err_expr.var_is_ptr; 7416 bool var_is_const = true; 7417 Buf *var_symbol = node->data.if_err_expr.var_symbol; 7418 Buf *err_symbol = node->data.if_err_expr.err_symbol; 7419 7420 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); 7421 if (err_val_ptr == irb->codegen->invalid_instruction) 7422 return err_val_ptr; 7423 7424 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 7425 IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true, false); 7426 7427 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); 7428 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); 7429 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "TryEnd"); 7430 7431 bool force_comptime = ir_should_inline(irb->exec, scope); 7432 IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); 7433 IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); 7434 7435 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 7436 result_loc, is_comptime); 7437 7438 ir_set_cursor_at_end_and_append_block(irb, ok_block); 7439 7440 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 7441 Scope *var_scope; 7442 if (var_symbol) { 7443 bool is_shadowable = false; 7444 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); 7445 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 7446 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); 7447 7448 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false, false); 7449 IrInstruction *var_ptr = var_is_ptr ? 7450 ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; 7451 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); 7452 var_scope = var->child_scope; 7453 } else { 7454 var_scope = subexpr_scope; 7455 } 7456 IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, 7457 &peer_parent->peers.at(0)->base); 7458 if (then_expr_result == irb->codegen->invalid_instruction) 7459 return then_expr_result; 7460 IrBasicBlock *after_then_block = irb->current_basic_block; 7461 if (!instr_is_unreachable(then_expr_result)) 7462 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 7463 7464 ir_set_cursor_at_end_and_append_block(irb, else_block); 7465 7466 IrInstruction *else_expr_result; 7467 if (else_node) { 7468 Scope *err_var_scope; 7469 if (err_symbol) { 7470 bool is_shadowable = false; 7471 bool is_const = true; 7472 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 7473 err_symbol, is_const, is_const, is_shadowable, is_comptime); 7474 7475 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr); 7476 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, err_ptr); 7477 err_var_scope = var->child_scope; 7478 } else { 7479 err_var_scope = subexpr_scope; 7480 } 7481 else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base); 7482 if (else_expr_result == irb->codegen->invalid_instruction) 7483 return else_expr_result; 7484 } else { 7485 else_expr_result = ir_build_const_void(irb, scope, node); 7486 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 7487 } 7488 IrBasicBlock *after_else_block = irb->current_basic_block; 7489 if (!instr_is_unreachable(else_expr_result)) 7490 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 7491 7492 ir_set_cursor_at_end_and_append_block(irb, endif_block); 7493 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 7494 incoming_values[0] = then_expr_result; 7495 incoming_values[1] = else_expr_result; 7496 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 7497 incoming_blocks[0] = after_then_block; 7498 incoming_blocks[1] = after_else_block; 7499 7500 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 7501 return ir_expr_wrap(irb, scope, phi, result_loc); 7502 } 7503 7504 static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, 7505 IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, 7506 IrInstruction *target_value_ptr, IrInstruction **prong_values, size_t prong_values_len, 7507 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values, 7508 IrInstructionSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc) 7509 { 7510 assert(switch_node->type == NodeTypeSwitchExpr); 7511 assert(prong_node->type == NodeTypeSwitchProng); 7512 7513 AstNode *expr_node = prong_node->data.switch_prong.expr; 7514 AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol; 7515 Scope *child_scope; 7516 if (var_symbol_node) { 7517 assert(var_symbol_node->type == NodeTypeSymbol); 7518 Buf *var_name = var_symbol_node->data.symbol_expr.symbol; 7519 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr; 7520 7521 bool is_shadowable = false; 7522 bool is_const = true; 7523 ZigVar *var = ir_create_var(irb, var_symbol_node, scope, 7524 var_name, is_const, is_const, is_shadowable, var_is_comptime); 7525 child_scope = var->child_scope; 7526 IrInstruction *var_ptr; 7527 if (out_switch_else_var != nullptr) { 7528 IrInstructionSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, 7529 target_value_ptr); 7530 *out_switch_else_var = switch_else_var; 7531 IrInstruction *payload_ptr = &switch_else_var->base; 7532 var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; 7533 } else if (prong_values != nullptr) { 7534 IrInstruction *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, 7535 prong_values, prong_values_len); 7536 var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; 7537 } else { 7538 var_ptr = var_is_ptr ? 7539 ir_build_ref(irb, scope, var_symbol_node, target_value_ptr, true, false) : target_value_ptr; 7540 } 7541 ir_build_var_decl_src(irb, scope, var_symbol_node, var, nullptr, var_ptr); 7542 } else { 7543 child_scope = scope; 7544 } 7545 7546 IrInstruction *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc); 7547 if (expr_result == irb->codegen->invalid_instruction) 7548 return false; 7549 if (!instr_is_unreachable(expr_result)) 7550 ir_mark_gen(ir_build_br(irb, scope, switch_node, end_block, is_comptime)); 7551 incoming_blocks->append(irb->current_basic_block); 7552 incoming_values->append(expr_result); 7553 return true; 7554 } 7555 7556 static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 7557 ResultLoc *result_loc) 7558 { 7559 assert(node->type == NodeTypeSwitchExpr); 7560 7561 AstNode *target_node = node->data.switch_expr.expr; 7562 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); 7563 if (target_value_ptr == irb->codegen->invalid_instruction) 7564 return target_value_ptr; 7565 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); 7566 7567 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "SwitchElse"); 7568 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "SwitchEnd"); 7569 7570 size_t prong_count = node->data.switch_expr.prongs.length; 7571 ZigList<IrInstructionSwitchBrCase> cases = {0}; 7572 7573 IrInstruction *is_comptime; 7574 IrInstruction *var_is_comptime; 7575 if (ir_should_inline(irb->exec, scope)) { 7576 is_comptime = ir_build_const_bool(irb, scope, node, true); 7577 var_is_comptime = is_comptime; 7578 } else { 7579 is_comptime = ir_build_test_comptime(irb, scope, node, target_value); 7580 var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr); 7581 } 7582 7583 ZigList<IrInstruction *> incoming_values = {0}; 7584 ZigList<IrBasicBlock *> incoming_blocks = {0}; 7585 ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0}; 7586 7587 IrInstructionSwitchElseVar *switch_else_var = nullptr; 7588 7589 ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); 7590 peer_parent->base.id = ResultLocIdPeerParent; 7591 peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; 7592 peer_parent->end_bb = end_block; 7593 peer_parent->is_comptime = is_comptime; 7594 peer_parent->parent = result_loc; 7595 7596 ir_build_reset_result(irb, scope, node, &peer_parent->base); 7597 7598 // First do the else and the ranges 7599 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 7600 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 7601 AstNode *else_prong = nullptr; 7602 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 7603 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 7604 size_t prong_item_count = prong_node->data.switch_prong.items.length; 7605 if (prong_item_count == 0) { 7606 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 7607 if (else_prong) { 7608 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 7609 buf_sprintf("multiple else prongs in switch expression")); 7610 add_error_note(irb->codegen, msg, else_prong, 7611 buf_sprintf("previous else prong is here")); 7612 return irb->codegen->invalid_instruction; 7613 } 7614 else_prong = prong_node; 7615 7616 IrBasicBlock *prev_block = irb->current_basic_block; 7617 if (peer_parent->peers.length > 0) { 7618 peer_parent->peers.last()->next_bb = else_block; 7619 } 7620 peer_parent->peers.append(this_peer_result_loc); 7621 ir_set_cursor_at_end_and_append_block(irb, else_block); 7622 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 7623 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, 7624 &switch_else_var, LValNone, &this_peer_result_loc->base)) 7625 { 7626 return irb->codegen->invalid_instruction; 7627 } 7628 ir_set_cursor_at_end(irb, prev_block); 7629 } else if (prong_node->data.switch_prong.any_items_are_range) { 7630 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 7631 7632 IrInstruction *ok_bit = nullptr; 7633 AstNode *last_item_node = nullptr; 7634 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 7635 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 7636 last_item_node = item_node; 7637 if (item_node->type == NodeTypeSwitchRange) { 7638 AstNode *start_node = item_node->data.switch_range.start; 7639 AstNode *end_node = item_node->data.switch_range.end; 7640 7641 IrInstruction *start_value = ir_gen_node(irb, start_node, comptime_scope); 7642 if (start_value == irb->codegen->invalid_instruction) 7643 return irb->codegen->invalid_instruction; 7644 7645 IrInstruction *end_value = ir_gen_node(irb, end_node, comptime_scope); 7646 if (end_value == irb->codegen->invalid_instruction) 7647 return irb->codegen->invalid_instruction; 7648 7649 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 7650 check_range->start = start_value; 7651 check_range->end = end_value; 7652 7653 IrInstruction *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq, 7654 target_value, start_value, false); 7655 IrInstruction *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq, 7656 target_value, end_value, false); 7657 IrInstruction *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd, 7658 lower_range_ok, upper_range_ok, false); 7659 if (ok_bit) { 7660 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false); 7661 } else { 7662 ok_bit = both_ok; 7663 } 7664 } else { 7665 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); 7666 if (item_value == irb->codegen->invalid_instruction) 7667 return irb->codegen->invalid_instruction; 7668 7669 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 7670 check_range->start = item_value; 7671 check_range->end = item_value; 7672 7673 IrInstruction *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq, 7674 item_value, target_value, false); 7675 if (ok_bit) { 7676 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false); 7677 } else { 7678 ok_bit = cmp_ok; 7679 } 7680 } 7681 } 7682 7683 IrBasicBlock *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes"); 7684 IrBasicBlock *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo"); 7685 7686 assert(ok_bit); 7687 assert(last_item_node); 7688 IrInstruction *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, 7689 range_block_yes, range_block_no, is_comptime)); 7690 if (peer_parent->base.source_instruction == nullptr) { 7691 peer_parent->base.source_instruction = br_inst; 7692 } 7693 7694 if (peer_parent->peers.length > 0) { 7695 peer_parent->peers.last()->next_bb = range_block_yes; 7696 } 7697 peer_parent->peers.append(this_peer_result_loc); 7698 ir_set_cursor_at_end_and_append_block(irb, range_block_yes); 7699 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 7700 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, 7701 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) 7702 { 7703 return irb->codegen->invalid_instruction; 7704 } 7705 7706 ir_set_cursor_at_end_and_append_block(irb, range_block_no); 7707 } 7708 } 7709 7710 // next do the non-else non-ranges 7711 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 7712 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 7713 size_t prong_item_count = prong_node->data.switch_prong.items.length; 7714 if (prong_item_count == 0) 7715 continue; 7716 if (prong_node->data.switch_prong.any_items_are_range) 7717 continue; 7718 7719 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 7720 7721 IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); 7722 IrInstruction **items = allocate<IrInstruction *>(prong_item_count); 7723 7724 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 7725 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 7726 assert(item_node->type != NodeTypeSwitchRange); 7727 7728 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); 7729 if (item_value == irb->codegen->invalid_instruction) 7730 return irb->codegen->invalid_instruction; 7731 7732 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 7733 check_range->start = item_value; 7734 check_range->end = item_value; 7735 7736 IrInstructionSwitchBrCase *this_case = cases.add_one(); 7737 this_case->value = item_value; 7738 this_case->block = prong_block; 7739 7740 items[item_i] = item_value; 7741 } 7742 7743 IrBasicBlock *prev_block = irb->current_basic_block; 7744 if (peer_parent->peers.length > 0) { 7745 peer_parent->peers.last()->next_bb = prong_block; 7746 } 7747 peer_parent->peers.append(this_peer_result_loc); 7748 ir_set_cursor_at_end_and_append_block(irb, prong_block); 7749 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 7750 is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, 7751 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) 7752 { 7753 return irb->codegen->invalid_instruction; 7754 } 7755 7756 ir_set_cursor_at_end(irb, prev_block); 7757 7758 } 7759 7760 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, 7761 check_ranges.items, check_ranges.length, else_prong != nullptr); 7762 7763 IrInstruction *br_instruction; 7764 if (cases.length == 0) { 7765 br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); 7766 } else { 7767 IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, scope, node, target_value, else_block, 7768 cases.length, cases.items, is_comptime, switch_prongs_void); 7769 if (switch_else_var != nullptr) { 7770 switch_else_var->switch_br = switch_br; 7771 } 7772 br_instruction = &switch_br->base; 7773 } 7774 if (peer_parent->base.source_instruction == nullptr) { 7775 peer_parent->base.source_instruction = br_instruction; 7776 } 7777 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 7778 peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction; 7779 } 7780 7781 if (!else_prong) { 7782 if (peer_parent->peers.length != 0) { 7783 peer_parent->peers.last()->next_bb = else_block; 7784 } 7785 ir_set_cursor_at_end_and_append_block(irb, else_block); 7786 ir_build_unreachable(irb, scope, node); 7787 } else { 7788 if (peer_parent->peers.length != 0) { 7789 peer_parent->peers.last()->next_bb = end_block; 7790 } 7791 } 7792 7793 ir_set_cursor_at_end_and_append_block(irb, end_block); 7794 assert(incoming_blocks.length == incoming_values.length); 7795 IrInstruction *result_instruction; 7796 if (incoming_blocks.length == 0) { 7797 result_instruction = ir_build_const_void(irb, scope, node); 7798 } else { 7799 result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, 7800 incoming_blocks.items, incoming_values.items, peer_parent); 7801 } 7802 return ir_lval_wrap(irb, scope, result_instruction, lval, result_loc); 7803 } 7804 7805 static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { 7806 assert(node->type == NodeTypeCompTime); 7807 7808 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); 7809 // purposefully pass null for result_loc and let EndExpr handle it 7810 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); 7811 } 7812 7813 static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { 7814 IrInstruction *is_comptime; 7815 if (ir_should_inline(irb->exec, break_scope)) { 7816 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 7817 } else { 7818 is_comptime = block_scope->is_comptime; 7819 } 7820 7821 IrInstruction *result_value; 7822 if (node->data.break_expr.expr) { 7823 ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent); 7824 block_scope->peer_parent->peers.append(peer_result); 7825 7826 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, block_scope->lval, 7827 &peer_result->base); 7828 if (result_value == irb->codegen->invalid_instruction) 7829 return irb->codegen->invalid_instruction; 7830 } else { 7831 result_value = ir_build_const_void(irb, break_scope, node); 7832 } 7833 7834 IrBasicBlock *dest_block = block_scope->end_block; 7835 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 7836 7837 block_scope->incoming_blocks->append(irb->current_basic_block); 7838 block_scope->incoming_values->append(result_value); 7839 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 7840 } 7841 7842 static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *node) { 7843 assert(node->type == NodeTypeBreak); 7844 7845 // Search up the scope. We'll find one of these things first: 7846 // * function definition scope or global scope => error, break outside loop 7847 // * defer expression scope => error, cannot break out of defer expression 7848 // * loop scope => OK 7849 // * (if it's a labeled break) labeled block => OK 7850 7851 Scope *search_scope = break_scope; 7852 ScopeLoop *loop_scope; 7853 for (;;) { 7854 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 7855 if (node->data.break_expr.name != nullptr) { 7856 add_node_error(irb->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name))); 7857 return irb->codegen->invalid_instruction; 7858 } else { 7859 add_node_error(irb->codegen, node, buf_sprintf("break expression outside loop")); 7860 return irb->codegen->invalid_instruction; 7861 } 7862 } else if (search_scope->id == ScopeIdDeferExpr) { 7863 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of defer expression")); 7864 return irb->codegen->invalid_instruction; 7865 } else if (search_scope->id == ScopeIdLoop) { 7866 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 7867 if (node->data.break_expr.name == nullptr || 7868 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name))) 7869 { 7870 loop_scope = this_loop_scope; 7871 break; 7872 } 7873 } else if (search_scope->id == ScopeIdBlock) { 7874 ScopeBlock *this_block_scope = (ScopeBlock *)search_scope; 7875 if (node->data.break_expr.name != nullptr && 7876 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name))) 7877 { 7878 assert(this_block_scope->end_block != nullptr); 7879 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope); 7880 } 7881 } else if (search_scope->id == ScopeIdSuspend) { 7882 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of suspend block")); 7883 return irb->codegen->invalid_instruction; 7884 } 7885 search_scope = search_scope->parent; 7886 } 7887 7888 IrInstruction *is_comptime; 7889 if (ir_should_inline(irb->exec, break_scope)) { 7890 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 7891 } else { 7892 is_comptime = loop_scope->is_comptime; 7893 } 7894 7895 IrInstruction *result_value; 7896 if (node->data.break_expr.expr) { 7897 ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent); 7898 loop_scope->peer_parent->peers.append(peer_result); 7899 7900 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, 7901 loop_scope->lval, &peer_result->base); 7902 if (result_value == irb->codegen->invalid_instruction) 7903 return irb->codegen->invalid_instruction; 7904 } else { 7905 result_value = ir_build_const_void(irb, break_scope, node); 7906 } 7907 7908 IrBasicBlock *dest_block = loop_scope->break_block; 7909 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 7910 7911 loop_scope->incoming_blocks->append(irb->current_basic_block); 7912 loop_scope->incoming_values->append(result_value); 7913 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 7914 } 7915 7916 static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, AstNode *node) { 7917 assert(node->type == NodeTypeContinue); 7918 7919 // Search up the scope. We'll find one of these things first: 7920 // * function definition scope or global scope => error, break outside loop 7921 // * defer expression scope => error, cannot break out of defer expression 7922 // * loop scope => OK 7923 7924 ZigList<ScopeRuntime *> runtime_scopes = {}; 7925 7926 Scope *search_scope = continue_scope; 7927 ScopeLoop *loop_scope; 7928 for (;;) { 7929 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 7930 if (node->data.continue_expr.name != nullptr) { 7931 add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name))); 7932 return irb->codegen->invalid_instruction; 7933 } else { 7934 add_node_error(irb->codegen, node, buf_sprintf("continue expression outside loop")); 7935 return irb->codegen->invalid_instruction; 7936 } 7937 } else if (search_scope->id == ScopeIdDeferExpr) { 7938 add_node_error(irb->codegen, node, buf_sprintf("cannot continue out of defer expression")); 7939 return irb->codegen->invalid_instruction; 7940 } else if (search_scope->id == ScopeIdLoop) { 7941 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 7942 if (node->data.continue_expr.name == nullptr || 7943 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name))) 7944 { 7945 loop_scope = this_loop_scope; 7946 break; 7947 } 7948 } else if (search_scope->id == ScopeIdRuntime) { 7949 ScopeRuntime *scope_runtime = (ScopeRuntime *)search_scope; 7950 runtime_scopes.append(scope_runtime); 7951 } 7952 search_scope = search_scope->parent; 7953 } 7954 7955 IrInstruction *is_comptime; 7956 if (ir_should_inline(irb->exec, continue_scope)) { 7957 is_comptime = ir_build_const_bool(irb, continue_scope, node, true); 7958 } else { 7959 is_comptime = loop_scope->is_comptime; 7960 } 7961 7962 for (size_t i = 0; i < runtime_scopes.length; i += 1) { 7963 ScopeRuntime *scope_runtime = runtime_scopes.at(i); 7964 ir_mark_gen(ir_build_check_runtime_scope(irb, continue_scope, node, scope_runtime->is_comptime, is_comptime)); 7965 } 7966 7967 IrBasicBlock *dest_block = loop_scope->continue_block; 7968 ir_gen_defers_for_block(irb, continue_scope, dest_block->scope, false); 7969 return ir_mark_gen(ir_build_br(irb, continue_scope, node, dest_block, is_comptime)); 7970 } 7971 7972 static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) { 7973 assert(node->type == NodeTypeErrorType); 7974 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set); 7975 } 7976 7977 static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 7978 assert(node->type == NodeTypeDefer); 7979 7980 ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope); 7981 node->data.defer.child_scope = &defer_child_scope->base; 7982 7983 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope); 7984 node->data.defer.expr_scope = &defer_expr_scope->base; 7985 7986 return ir_build_const_void(irb, parent_scope, node); 7987 } 7988 7989 static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 7990 assert(node->type == NodeTypeSliceExpr); 7991 7992 AstNodeSliceExpr *slice_expr = &node->data.slice_expr; 7993 AstNode *array_node = slice_expr->array_ref_expr; 7994 AstNode *start_node = slice_expr->start; 7995 AstNode *end_node = slice_expr->end; 7996 7997 IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr); 7998 if (ptr_value == irb->codegen->invalid_instruction) 7999 return irb->codegen->invalid_instruction; 8000 8001 IrInstruction *start_value = ir_gen_node(irb, start_node, scope); 8002 if (start_value == irb->codegen->invalid_instruction) 8003 return irb->codegen->invalid_instruction; 8004 8005 IrInstruction *end_value; 8006 if (end_node) { 8007 end_value = ir_gen_node(irb, end_node, scope); 8008 if (end_value == irb->codegen->invalid_instruction) 8009 return irb->codegen->invalid_instruction; 8010 } else { 8011 end_value = nullptr; 8012 } 8013 8014 IrInstruction *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, true, result_loc); 8015 return ir_lval_wrap(irb, scope, slice, lval, result_loc); 8016 } 8017 8018 static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, 8019 ResultLoc *result_loc) 8020 { 8021 assert(node->type == NodeTypeCatchExpr); 8022 8023 AstNode *op1_node = node->data.unwrap_err_expr.op1; 8024 AstNode *op2_node = node->data.unwrap_err_expr.op2; 8025 AstNode *var_node = node->data.unwrap_err_expr.symbol; 8026 8027 if (op2_node->type == NodeTypeUnreachable) { 8028 if (var_node != nullptr) { 8029 assert(var_node->type == NodeTypeSymbol); 8030 Buf *var_name = var_node->data.symbol_expr.symbol; 8031 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); 8032 return irb->codegen->invalid_instruction; 8033 } 8034 return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc); 8035 } 8036 8037 8038 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); 8039 if (err_union_ptr == irb->codegen->invalid_instruction) 8040 return irb->codegen->invalid_instruction; 8041 8042 IrInstruction *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true, false); 8043 8044 IrInstruction *is_comptime; 8045 if (ir_should_inline(irb->exec, parent_scope)) { 8046 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 8047 } else { 8048 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_err); 8049 } 8050 8051 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); 8052 IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); 8053 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); 8054 IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); 8055 8056 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc, 8057 is_comptime); 8058 8059 ir_set_cursor_at_end_and_append_block(irb, err_block); 8060 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, parent_scope, is_comptime); 8061 Scope *err_scope; 8062 if (var_node) { 8063 assert(var_node->type == NodeTypeSymbol); 8064 Buf *var_name = var_node->data.symbol_expr.symbol; 8065 bool is_const = true; 8066 bool is_shadowable = false; 8067 ZigVar *var = ir_create_var(irb, node, subexpr_scope, var_name, 8068 is_const, is_const, is_shadowable, is_comptime); 8069 err_scope = var->child_scope; 8070 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); 8071 ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, err_ptr); 8072 } else { 8073 err_scope = subexpr_scope; 8074 } 8075 IrInstruction *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base); 8076 if (err_result == irb->codegen->invalid_instruction) 8077 return irb->codegen->invalid_instruction; 8078 IrBasicBlock *after_err_block = irb->current_basic_block; 8079 if (!instr_is_unreachable(err_result)) 8080 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 8081 8082 ir_set_cursor_at_end_and_append_block(irb, ok_block); 8083 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false, false); 8084 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 8085 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); 8086 IrBasicBlock *after_ok_block = irb->current_basic_block; 8087 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 8088 8089 ir_set_cursor_at_end_and_append_block(irb, end_block); 8090 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 8091 incoming_values[0] = err_result; 8092 incoming_values[1] = unwrapped_payload; 8093 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 8094 incoming_blocks[0] = after_err_block; 8095 incoming_blocks[1] = after_ok_block; 8096 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); 8097 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 8098 } 8099 8100 static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { 8101 if (inner_scope == nullptr || inner_scope == outer_scope) return false; 8102 bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent); 8103 if (inner_scope->id != ScopeIdVarDecl) 8104 return need_comma; 8105 8106 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; 8107 if (need_comma) 8108 buf_append_char(name, ','); 8109 // TODO: const ptr reinterpret here to make the var type agree with the value? 8110 render_const_value(codegen, name, var_scope->var->const_value); 8111 return true; 8112 } 8113 8114 static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, 8115 Scope *scope, AstNode *source_node, Buf *out_bare_name) 8116 { 8117 if (exec != nullptr && exec->name) { 8118 ZigType *import = get_scope_import(scope); 8119 Buf *namespace_name = buf_alloc(); 8120 append_namespace_qualification(codegen, namespace_name, import); 8121 buf_append_buf(namespace_name, exec->name); 8122 buf_init_from_buf(out_bare_name, exec->name); 8123 return namespace_name; 8124 } else if (exec != nullptr && exec->name_fn != nullptr) { 8125 Buf *name = buf_alloc(); 8126 buf_append_buf(name, &exec->name_fn->symbol_name); 8127 buf_appendf(name, "("); 8128 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope); 8129 buf_appendf(name, ")"); 8130 buf_init_from_buf(out_bare_name, name); 8131 return name; 8132 } else { 8133 ZigType *import = get_scope_import(scope); 8134 Buf *namespace_name = buf_alloc(); 8135 append_namespace_qualification(codegen, namespace_name, import); 8136 buf_appendf(namespace_name, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, kind_name, 8137 source_node->line + 1, source_node->column + 1); 8138 buf_init_from_buf(out_bare_name, namespace_name); 8139 return namespace_name; 8140 } 8141 } 8142 8143 static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 8144 assert(node->type == NodeTypeContainerDecl); 8145 8146 ContainerKind kind = node->data.container_decl.kind; 8147 Buf *bare_name = buf_alloc(); 8148 Buf *name = get_anon_type_name(irb->codegen, irb->exec, container_string(kind), parent_scope, node, bare_name); 8149 8150 ContainerLayout layout = node->data.container_decl.layout; 8151 ZigType *container_type = get_partial_container_type(irb->codegen, parent_scope, 8152 kind, node, buf_ptr(name), bare_name, layout); 8153 ScopeDecls *child_scope = get_container_scope(container_type); 8154 8155 for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) { 8156 AstNode *child_node = node->data.container_decl.decls.at(i); 8157 scan_decls(irb->codegen, child_scope, child_node); 8158 } 8159 8160 TldContainer *tld_container = allocate<TldContainer>(1); 8161 init_tld(&tld_container->base, TldIdContainer, bare_name, VisibModPub, node, parent_scope); 8162 tld_container->type_entry = container_type; 8163 tld_container->decls_scope = child_scope; 8164 irb->codegen->resolve_queue.append(&tld_container->base); 8165 8166 // Add this to the list to mark as invalid if analyzing this exec fails. 8167 irb->exec->tld_list.append(&tld_container->base); 8168 8169 return ir_build_const_type(irb, parent_scope, node, container_type); 8170 } 8171 8172 // errors should be populated with set1's values 8173 static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigType *set1, ZigType *set2, 8174 Buf *type_name) 8175 { 8176 assert(set1->id == ZigTypeIdErrorSet); 8177 assert(set2->id == ZigTypeIdErrorSet); 8178 8179 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 8180 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 8181 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 8182 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 8183 if (type_name == nullptr) { 8184 buf_resize(&err_set_type->name, 0); 8185 buf_appendf(&err_set_type->name, "error{"); 8186 } else { 8187 buf_init_from_buf(&err_set_type->name, type_name); 8188 } 8189 8190 for (uint32_t i = 0, count = set1->data.error_set.err_count; i < count; i += 1) { 8191 assert(errors[set1->data.error_set.errors[i]->value] == set1->data.error_set.errors[i]); 8192 } 8193 8194 uint32_t count = set1->data.error_set.err_count; 8195 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 8196 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 8197 if (errors[error_entry->value] == nullptr) { 8198 count += 1; 8199 } 8200 } 8201 8202 err_set_type->data.error_set.err_count = count; 8203 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(count); 8204 8205 bool need_comma = false; 8206 for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { 8207 ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; 8208 if (type_name == nullptr) { 8209 const char *comma = need_comma ? "," : ""; 8210 need_comma = true; 8211 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&error_entry->name)); 8212 } 8213 err_set_type->data.error_set.errors[i] = error_entry; 8214 } 8215 8216 uint32_t index = set1->data.error_set.err_count; 8217 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 8218 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 8219 if (errors[error_entry->value] == nullptr) { 8220 errors[error_entry->value] = error_entry; 8221 if (type_name == nullptr) { 8222 const char *comma = need_comma ? "," : ""; 8223 need_comma = true; 8224 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&error_entry->name)); 8225 } 8226 err_set_type->data.error_set.errors[index] = error_entry; 8227 index += 1; 8228 } 8229 } 8230 assert(index == count); 8231 8232 if (type_name == nullptr) { 8233 buf_appendf(&err_set_type->name, "}"); 8234 } 8235 8236 return err_set_type; 8237 8238 } 8239 8240 static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstNode *node, 8241 ErrorTableEntry *err_entry) 8242 { 8243 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 8244 buf_resize(&err_set_type->name, 0); 8245 buf_appendf(&err_set_type->name, "error{%s}", buf_ptr(&err_entry->name)); 8246 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 8247 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 8248 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 8249 err_set_type->data.error_set.err_count = 1; 8250 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1); 8251 8252 err_set_type->data.error_set.errors[0] = err_entry; 8253 8254 return err_set_type; 8255 } 8256 8257 static AstNode *ast_field_to_symbol_node(AstNode *err_set_field_node) { 8258 if (err_set_field_node->type == NodeTypeSymbol) { 8259 return err_set_field_node; 8260 } else if (err_set_field_node->type == NodeTypeErrorSetField) { 8261 assert(err_set_field_node->data.err_set_field.field_name->type == NodeTypeSymbol); 8262 return err_set_field_node->data.err_set_field.field_name; 8263 } else { 8264 return err_set_field_node; 8265 } 8266 } 8267 8268 static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 8269 assert(node->type == NodeTypeErrorSetDecl); 8270 8271 uint32_t err_count = node->data.err_set_decl.decls.length; 8272 8273 Buf bare_name = BUF_INIT; 8274 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", parent_scope, node, &bare_name); 8275 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 8276 buf_init_from_buf(&err_set_type->name, type_name); 8277 err_set_type->data.error_set.err_count = err_count; 8278 err_set_type->size_in_bits = irb->codegen->builtin_types.entry_global_error_set->size_in_bits; 8279 err_set_type->abi_align = irb->codegen->builtin_types.entry_global_error_set->abi_align; 8280 err_set_type->abi_size = irb->codegen->builtin_types.entry_global_error_set->abi_size; 8281 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(err_count); 8282 8283 size_t errors_count = irb->codegen->errors_by_index.length + err_count; 8284 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(errors_count, "ErrorTableEntry *"); 8285 8286 for (uint32_t i = 0; i < err_count; i += 1) { 8287 AstNode *field_node = node->data.err_set_decl.decls.at(i); 8288 AstNode *symbol_node = ast_field_to_symbol_node(field_node); 8289 Buf *err_name = symbol_node->data.symbol_expr.symbol; 8290 ErrorTableEntry *err = allocate<ErrorTableEntry>(1); 8291 err->decl_node = field_node; 8292 buf_init_from_buf(&err->name, err_name); 8293 8294 auto existing_entry = irb->codegen->error_table.put_unique(err_name, err); 8295 if (existing_entry) { 8296 err->value = existing_entry->value->value; 8297 } else { 8298 size_t error_value_count = irb->codegen->errors_by_index.length; 8299 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)irb->codegen->err_tag_type->data.integral.bit_count)); 8300 err->value = error_value_count; 8301 irb->codegen->errors_by_index.append(err); 8302 } 8303 err_set_type->data.error_set.errors[i] = err; 8304 8305 ErrorTableEntry *prev_err = errors[err->value]; 8306 if (prev_err != nullptr) { 8307 ErrorMsg *msg = add_node_error(irb->codegen, ast_field_to_symbol_node(err->decl_node), 8308 buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name))); 8309 add_error_note(irb->codegen, msg, ast_field_to_symbol_node(prev_err->decl_node), 8310 buf_sprintf("other error here")); 8311 return irb->codegen->invalid_instruction; 8312 } 8313 errors[err->value] = err; 8314 } 8315 deallocate(errors, errors_count, "ErrorTableEntry *"); 8316 return ir_build_const_type(irb, parent_scope, node, err_set_type); 8317 } 8318 8319 static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 8320 assert(node->type == NodeTypeFnProto); 8321 8322 size_t param_count = node->data.fn_proto.params.length; 8323 IrInstruction **param_types = allocate<IrInstruction*>(param_count); 8324 8325 bool is_var_args = false; 8326 for (size_t i = 0; i < param_count; i += 1) { 8327 AstNode *param_node = node->data.fn_proto.params.at(i); 8328 if (param_node->data.param_decl.is_var_args) { 8329 is_var_args = true; 8330 break; 8331 } 8332 if (param_node->data.param_decl.var_token == nullptr) { 8333 AstNode *type_node = param_node->data.param_decl.type; 8334 IrInstruction *type_value = ir_gen_node(irb, type_node, parent_scope); 8335 if (type_value == irb->codegen->invalid_instruction) 8336 return irb->codegen->invalid_instruction; 8337 param_types[i] = type_value; 8338 } else { 8339 param_types[i] = nullptr; 8340 } 8341 } 8342 8343 IrInstruction *align_value = nullptr; 8344 if (node->data.fn_proto.align_expr != nullptr) { 8345 align_value = ir_gen_node(irb, node->data.fn_proto.align_expr, parent_scope); 8346 if (align_value == irb->codegen->invalid_instruction) 8347 return irb->codegen->invalid_instruction; 8348 } 8349 8350 IrInstruction *return_type; 8351 if (node->data.fn_proto.return_var_token == nullptr) { 8352 if (node->data.fn_proto.return_type == nullptr) { 8353 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void); 8354 } else { 8355 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope); 8356 if (return_type == irb->codegen->invalid_instruction) 8357 return irb->codegen->invalid_instruction; 8358 } 8359 } else { 8360 add_node_error(irb->codegen, node, 8361 buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); 8362 return irb->codegen->invalid_instruction; 8363 //return_type = nullptr; 8364 } 8365 8366 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args); 8367 } 8368 8369 static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) { 8370 assert(node->type == NodeTypeResume); 8371 8372 IrInstruction *target_inst = ir_gen_node_extra(irb, node->data.resume_expr.expr, scope, LValPtr, nullptr); 8373 if (target_inst == irb->codegen->invalid_instruction) 8374 return irb->codegen->invalid_instruction; 8375 8376 return ir_build_resume(irb, scope, node, target_inst); 8377 } 8378 8379 static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, 8380 ResultLoc *result_loc) 8381 { 8382 assert(node->type == NodeTypeAwaitExpr); 8383 8384 AstNode *expr_node = node->data.await_expr.expr; 8385 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) { 8386 AstNode *fn_ref_expr = expr_node->data.fn_call_expr.fn_ref_expr; 8387 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 8388 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 8389 if (entry != nullptr) { 8390 BuiltinFnEntry *builtin_fn = entry->value; 8391 if (builtin_fn->id == BuiltinFnIdAsyncCall) { 8392 return ir_gen_async_call(irb, scope, node, expr_node, lval, result_loc); 8393 } 8394 } 8395 } 8396 8397 ZigFn *fn_entry = exec_fn_entry(irb->exec); 8398 if (!fn_entry) { 8399 add_node_error(irb->codegen, node, buf_sprintf("await outside function definition")); 8400 return irb->codegen->invalid_instruction; 8401 } 8402 ScopeSuspend *existing_suspend_scope = get_scope_suspend(scope); 8403 if (existing_suspend_scope) { 8404 if (!existing_suspend_scope->reported_err) { 8405 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot await inside suspend block")); 8406 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("suspend block here")); 8407 existing_suspend_scope->reported_err = true; 8408 } 8409 return irb->codegen->invalid_instruction; 8410 } 8411 8412 IrInstruction *target_inst = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 8413 if (target_inst == irb->codegen->invalid_instruction) 8414 return irb->codegen->invalid_instruction; 8415 8416 IrInstruction *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc); 8417 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc); 8418 } 8419 8420 static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 8421 assert(node->type == NodeTypeSuspend); 8422 8423 ZigFn *fn_entry = exec_fn_entry(irb->exec); 8424 if (!fn_entry) { 8425 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition")); 8426 return irb->codegen->invalid_instruction; 8427 } 8428 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope); 8429 if (existing_suspend_scope) { 8430 if (!existing_suspend_scope->reported_err) { 8431 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block")); 8432 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here")); 8433 existing_suspend_scope->reported_err = true; 8434 } 8435 return irb->codegen->invalid_instruction; 8436 } 8437 8438 IrInstructionSuspendBegin *begin = ir_build_suspend_begin(irb, parent_scope, node); 8439 if (node->data.suspend.block != nullptr) { 8440 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); 8441 Scope *child_scope = &suspend_scope->base; 8442 IrInstruction *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); 8443 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res)); 8444 } 8445 8446 return ir_mark_gen(ir_build_suspend_finish(irb, parent_scope, node, begin)); 8447 } 8448 8449 static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, 8450 LVal lval, ResultLoc *result_loc) 8451 { 8452 assert(scope); 8453 switch (node->type) { 8454 case NodeTypeStructValueField: 8455 case NodeTypeParamDecl: 8456 case NodeTypeUsingNamespace: 8457 case NodeTypeSwitchProng: 8458 case NodeTypeSwitchRange: 8459 case NodeTypeStructField: 8460 case NodeTypeErrorSetField: 8461 case NodeTypeFnDef: 8462 case NodeTypeTestDecl: 8463 zig_unreachable(); 8464 case NodeTypeBlock: 8465 return ir_gen_block(irb, scope, node, lval, result_loc); 8466 case NodeTypeGroupedExpr: 8467 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc); 8468 case NodeTypeBinOpExpr: 8469 return ir_gen_bin_op(irb, scope, node, lval, result_loc); 8470 case NodeTypeIntLiteral: 8471 return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc); 8472 case NodeTypeFloatLiteral: 8473 return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval, result_loc); 8474 case NodeTypeCharLiteral: 8475 return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval, result_loc); 8476 case NodeTypeSymbol: 8477 return ir_gen_symbol(irb, scope, node, lval, result_loc); 8478 case NodeTypeFnCallExpr: 8479 return ir_gen_fn_call(irb, scope, node, lval, result_loc); 8480 case NodeTypeIfBoolExpr: 8481 return ir_gen_if_bool_expr(irb, scope, node, lval, result_loc); 8482 case NodeTypePrefixOpExpr: 8483 return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc); 8484 case NodeTypeContainerInitExpr: 8485 return ir_gen_container_init_expr(irb, scope, node, lval, result_loc); 8486 case NodeTypeVariableDeclaration: 8487 return ir_gen_var_decl(irb, scope, node); 8488 case NodeTypeWhileExpr: 8489 return ir_gen_while_expr(irb, scope, node, lval, result_loc); 8490 case NodeTypeForExpr: 8491 return ir_gen_for_expr(irb, scope, node, lval, result_loc); 8492 case NodeTypeArrayAccessExpr: 8493 return ir_gen_array_access(irb, scope, node, lval, result_loc); 8494 case NodeTypeReturnExpr: 8495 return ir_gen_return(irb, scope, node, lval, result_loc); 8496 case NodeTypeFieldAccessExpr: 8497 { 8498 IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); 8499 if (ptr_instruction == irb->codegen->invalid_instruction) 8500 return ptr_instruction; 8501 if (lval == LValPtr) 8502 return ptr_instruction; 8503 8504 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 8505 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 8506 } 8507 case NodeTypePtrDeref: { 8508 AstNode *expr_node = node->data.ptr_deref_expr.target; 8509 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); 8510 if (value == irb->codegen->invalid_instruction) 8511 return value; 8512 8513 // We essentially just converted any lvalue from &(x.*) to (&x).*; 8514 // this inhibits checking that x is a pointer later, so we directly 8515 // record whether the pointer check is needed 8516 IrInstruction *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc); 8517 return ir_expr_wrap(irb, scope, un_op, result_loc); 8518 } 8519 case NodeTypeUnwrapOptional: { 8520 AstNode *expr_node = node->data.unwrap_optional.expr; 8521 8522 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 8523 if (maybe_ptr == irb->codegen->invalid_instruction) 8524 return irb->codegen->invalid_instruction; 8525 8526 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true, false); 8527 if (lval == LValPtr) 8528 return unwrapped_ptr; 8529 8530 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr); 8531 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 8532 } 8533 case NodeTypeBoolLiteral: 8534 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval, result_loc); 8535 case NodeTypeArrayType: 8536 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc); 8537 case NodeTypePointerType: 8538 return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc); 8539 case NodeTypeAnyFrameType: 8540 return ir_lval_wrap(irb, scope, ir_gen_anyframe_type(irb, scope, node), lval, result_loc); 8541 case NodeTypeStringLiteral: 8542 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc); 8543 case NodeTypeUndefinedLiteral: 8544 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval, result_loc); 8545 case NodeTypeAsmExpr: 8546 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval, result_loc); 8547 case NodeTypeNullLiteral: 8548 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc); 8549 case NodeTypeIfErrorExpr: 8550 return ir_gen_if_err_expr(irb, scope, node, lval, result_loc); 8551 case NodeTypeIfOptional: 8552 return ir_gen_if_optional_expr(irb, scope, node, lval, result_loc); 8553 case NodeTypeSwitchExpr: 8554 return ir_gen_switch_expr(irb, scope, node, lval, result_loc); 8555 case NodeTypeCompTime: 8556 return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); 8557 case NodeTypeErrorType: 8558 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc); 8559 case NodeTypeBreak: 8560 return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval, result_loc); 8561 case NodeTypeContinue: 8562 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc); 8563 case NodeTypeUnreachable: 8564 return ir_build_unreachable(irb, scope, node); 8565 case NodeTypeDefer: 8566 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc); 8567 case NodeTypeSliceExpr: 8568 return ir_gen_slice(irb, scope, node, lval, result_loc); 8569 case NodeTypeCatchExpr: 8570 return ir_gen_catch(irb, scope, node, lval, result_loc); 8571 case NodeTypeContainerDecl: 8572 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval, result_loc); 8573 case NodeTypeFnProto: 8574 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval, result_loc); 8575 case NodeTypeErrorSetDecl: 8576 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval, result_loc); 8577 case NodeTypeResume: 8578 return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval, result_loc); 8579 case NodeTypeAwaitExpr: 8580 return ir_gen_await_expr(irb, scope, node, lval, result_loc); 8581 case NodeTypeSuspend: 8582 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval, result_loc); 8583 case NodeTypeEnumLiteral: 8584 return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval, result_loc); 8585 case NodeTypeInferredArrayType: 8586 add_node_error(irb->codegen, node, 8587 buf_sprintf("inferred array size invalid here")); 8588 return irb->codegen->invalid_instruction; 8589 case NodeTypeVarFieldType: 8590 return ir_lval_wrap(irb, scope, 8591 ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_var), lval, result_loc); 8592 } 8593 zig_unreachable(); 8594 } 8595 8596 static ResultLoc *no_result_loc(void) { 8597 ResultLocNone *result_loc_none = allocate<ResultLocNone>(1); 8598 result_loc_none->base.id = ResultLocIdNone; 8599 return &result_loc_none->base; 8600 } 8601 8602 static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, 8603 ResultLoc *result_loc) 8604 { 8605 if (result_loc == nullptr) { 8606 // Create a result location indicating there is none - but if one gets created 8607 // it will be properly distributed. 8608 result_loc = no_result_loc(); 8609 ir_build_reset_result(irb, scope, node, result_loc); 8610 } 8611 Scope *child_scope; 8612 if (irb->exec->is_inline || 8613 (irb->exec->fn_entry != nullptr && irb->exec->fn_entry->child_scope == scope)) 8614 { 8615 child_scope = scope; 8616 } else { 8617 child_scope = &create_expr_scope(irb->codegen, node, scope)->base; 8618 } 8619 IrInstruction *result = ir_gen_node_raw(irb, node, child_scope, lval, result_loc); 8620 if (result == irb->codegen->invalid_instruction) { 8621 if (irb->exec->first_err_trace_msg == nullptr) { 8622 irb->exec->first_err_trace_msg = irb->codegen->trace_err; 8623 } 8624 src_assert(irb->exec->first_err_trace_msg != nullptr, node); 8625 } 8626 return result; 8627 } 8628 8629 static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { 8630 return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); 8631 } 8632 8633 static void invalidate_exec(IrExecutable *exec, ErrorMsg *msg) { 8634 if (exec->first_err_trace_msg != nullptr) 8635 return; 8636 8637 exec->first_err_trace_msg = msg; 8638 8639 for (size_t i = 0; i < exec->tld_list.length; i += 1) { 8640 exec->tld_list.items[i]->resolution = TldResolutionInvalid; 8641 } 8642 8643 if (exec->source_exec != nullptr) 8644 invalidate_exec(exec->source_exec, msg); 8645 } 8646 8647 bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) { 8648 assert(node->owner); 8649 8650 IrBuilder ir_builder = {0}; 8651 IrBuilder *irb = &ir_builder; 8652 8653 irb->codegen = codegen; 8654 irb->exec = ir_executable; 8655 irb->main_block_node = node; 8656 8657 IrBasicBlock *entry_block = ir_create_basic_block(irb, scope, "Entry"); 8658 ir_set_cursor_at_end_and_append_block(irb, entry_block); 8659 // Entry block gets a reference because we enter it to begin. 8660 ir_ref_bb(irb->current_basic_block); 8661 8662 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); 8663 assert(result); 8664 if (irb->exec->first_err_trace_msg != nullptr) { 8665 codegen->trace_err = irb->exec->first_err_trace_msg; 8666 return false; 8667 } 8668 8669 if (!instr_is_unreachable(result)) { 8670 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result, nullptr)); 8671 // no need for save_err_ret_addr because this cannot return error 8672 ir_mark_gen(ir_build_return(irb, scope, result->source_node, result)); 8673 } 8674 8675 return true; 8676 } 8677 8678 bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { 8679 assert(fn_entry); 8680 8681 IrExecutable *ir_executable = &fn_entry->ir_executable; 8682 AstNode *body_node = fn_entry->body_node; 8683 8684 assert(fn_entry->child_scope); 8685 8686 return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); 8687 } 8688 8689 static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) { 8690 if (!exec || !exec->source_node || limit < 0) return; 8691 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); 8692 8693 ir_add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1); 8694 } 8695 8696 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) { 8697 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); 8698 invalidate_exec(exec, err_msg); 8699 if (exec->parent_exec) { 8700 ir_add_call_stack_errors(codegen, exec, err_msg, 10); 8701 } 8702 return err_msg; 8703 } 8704 8705 static ErrorMsg *ir_add_error_node(IrAnalyze *ira, AstNode *source_node, Buf *msg) { 8706 return exec_add_error_node(ira->codegen, ira->new_irb.exec, source_node, msg); 8707 } 8708 8709 static ErrorMsg *opt_ir_add_error_node(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, Buf *msg) { 8710 if (ira != nullptr) 8711 return exec_add_error_node(codegen, ira->new_irb.exec, source_node, msg); 8712 else 8713 return add_node_error(codegen, source_node, msg); 8714 } 8715 8716 static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction, Buf *msg) { 8717 return ir_add_error_node(ira, source_instruction->source_node, msg); 8718 } 8719 8720 static void ir_assert(bool ok, IrInstruction *source_instruction) { 8721 if (ok) return; 8722 src_assert(ok, source_instruction->source_node); 8723 } 8724 8725 // This function takes a comptime ptr and makes the child const value conform to the type 8726 // described by the pointer. 8727 static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 8728 ZigValue *ptr_val) 8729 { 8730 Error err; 8731 assert(ptr_val->type->id == ZigTypeIdPointer); 8732 assert(ptr_val->special == ConstValSpecialStatic); 8733 ZigValue tmp = {}; 8734 tmp.special = ConstValSpecialStatic; 8735 tmp.type = ptr_val->type->data.pointer.child_type; 8736 if ((err = ir_read_const_ptr(ira, codegen, source_node, &tmp, ptr_val))) 8737 return err; 8738 ZigValue *child_val = const_ptr_pointee_unchecked(codegen, ptr_val); 8739 copy_const_val(child_val, &tmp, false); 8740 return ErrorNone; 8741 } 8742 8743 ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val, 8744 AstNode *source_node) 8745 { 8746 Error err; 8747 ZigValue *val = const_ptr_pointee_unchecked(codegen, const_val); 8748 assert(val != nullptr); 8749 assert(const_val->type->id == ZigTypeIdPointer); 8750 ZigType *expected_type = const_val->type->data.pointer.child_type; 8751 if (expected_type == codegen->builtin_types.entry_var) { 8752 return val; 8753 } 8754 switch (type_has_one_possible_value(codegen, expected_type)) { 8755 case OnePossibleValueInvalid: 8756 return nullptr; 8757 case OnePossibleValueNo: 8758 break; 8759 case OnePossibleValueYes: 8760 return get_the_one_possible_value(codegen, expected_type); 8761 } 8762 if (!types_have_same_zig_comptime_repr(codegen, expected_type, val->type)) { 8763 if ((err = eval_comptime_ptr_reinterpret(ira, codegen, source_node, const_val))) 8764 return nullptr; 8765 return const_ptr_pointee_unchecked(codegen, const_val); 8766 } 8767 return val; 8768 } 8769 8770 static ZigValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec) { 8771 IrBasicBlock *bb = exec->basic_block_list.at(0); 8772 for (size_t i = 0; i < bb->instruction_list.length; i += 1) { 8773 IrInstruction *instruction = bb->instruction_list.at(i); 8774 if (instruction->id == IrInstructionIdReturn) { 8775 IrInstructionReturn *ret_inst = (IrInstructionReturn *)instruction; 8776 IrInstruction *operand = ret_inst->operand; 8777 if (operand->value->special == ConstValSpecialRuntime) { 8778 exec_add_error_node(codegen, exec, operand->source_node, 8779 buf_sprintf("unable to evaluate constant expression")); 8780 return codegen->invalid_instruction->value; 8781 } 8782 return operand->value; 8783 } else if (ir_has_side_effects(instruction)) { 8784 if (instr_is_comptime(instruction)) { 8785 switch (instruction->id) { 8786 case IrInstructionIdUnwrapErrPayload: 8787 case IrInstructionIdUnionFieldPtr: 8788 continue; 8789 default: 8790 break; 8791 } 8792 } 8793 if (get_scope_typeof(instruction->scope) != nullptr) { 8794 // doesn't count, it's inside a @typeOf() 8795 continue; 8796 } 8797 exec_add_error_node(codegen, exec, instruction->source_node, 8798 buf_sprintf("unable to evaluate constant expression")); 8799 return codegen->invalid_instruction->value; 8800 } 8801 } 8802 zig_unreachable(); 8803 } 8804 8805 static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) { 8806 if (ir_should_inline(ira->new_irb.exec, source_instruction->scope)) { 8807 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression")); 8808 return false; 8809 } 8810 return true; 8811 } 8812 8813 static bool const_val_fits_in_num_lit(ZigValue *const_val, ZigType *num_lit_type) { 8814 return ((num_lit_type->id == ZigTypeIdComptimeFloat && 8815 (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat)) || 8816 (num_lit_type->id == ZigTypeIdComptimeInt && 8817 (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt))); 8818 } 8819 8820 static bool float_has_fraction(ZigValue *const_val) { 8821 if (const_val->type->id == ZigTypeIdComptimeFloat) { 8822 return bigfloat_has_fraction(&const_val->data.x_bigfloat); 8823 } else if (const_val->type->id == ZigTypeIdFloat) { 8824 switch (const_val->type->data.floating.bit_count) { 8825 case 16: 8826 { 8827 float16_t floored = f16_roundToInt(const_val->data.x_f16, softfloat_round_minMag, false); 8828 return !f16_eq(floored, const_val->data.x_f16); 8829 } 8830 case 32: 8831 return floorf(const_val->data.x_f32) != const_val->data.x_f32; 8832 case 64: 8833 return floor(const_val->data.x_f64) != const_val->data.x_f64; 8834 case 128: 8835 { 8836 float128_t floored; 8837 f128M_roundToInt(&const_val->data.x_f128, softfloat_round_minMag, false, &floored); 8838 return !f128M_eq(&floored, &const_val->data.x_f128); 8839 } 8840 default: 8841 zig_unreachable(); 8842 } 8843 } else { 8844 zig_unreachable(); 8845 } 8846 } 8847 8848 static void float_append_buf(Buf *buf, ZigValue *const_val) { 8849 if (const_val->type->id == ZigTypeIdComptimeFloat) { 8850 bigfloat_append_buf(buf, &const_val->data.x_bigfloat); 8851 } else if (const_val->type->id == ZigTypeIdFloat) { 8852 switch (const_val->type->data.floating.bit_count) { 8853 case 16: 8854 buf_appendf(buf, "%f", zig_f16_to_double(const_val->data.x_f16)); 8855 break; 8856 case 32: 8857 buf_appendf(buf, "%f", const_val->data.x_f32); 8858 break; 8859 case 64: 8860 buf_appendf(buf, "%f", const_val->data.x_f64); 8861 break; 8862 case 128: 8863 { 8864 // TODO actual implementation 8865 const size_t extra_len = 100; 8866 size_t old_len = buf_len(buf); 8867 buf_resize(buf, old_len + extra_len); 8868 8869 float64_t f64_value = f128M_to_f64(&const_val->data.x_f128); 8870 double double_value; 8871 memcpy(&double_value, &f64_value, sizeof(double)); 8872 8873 int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value); 8874 assert(len > 0); 8875 buf_resize(buf, old_len + len); 8876 break; 8877 } 8878 default: 8879 zig_unreachable(); 8880 } 8881 } else { 8882 zig_unreachable(); 8883 } 8884 } 8885 8886 static void float_init_bigint(BigInt *bigint, ZigValue *const_val) { 8887 if (const_val->type->id == ZigTypeIdComptimeFloat) { 8888 bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat); 8889 } else if (const_val->type->id == ZigTypeIdFloat) { 8890 switch (const_val->type->data.floating.bit_count) { 8891 case 16: 8892 { 8893 double x = zig_f16_to_double(const_val->data.x_f16); 8894 if (x >= 0) { 8895 bigint_init_unsigned(bigint, (uint64_t)x); 8896 } else { 8897 bigint_init_unsigned(bigint, (uint64_t)-x); 8898 bigint->is_negative = true; 8899 } 8900 break; 8901 } 8902 case 32: 8903 if (const_val->data.x_f32 >= 0) { 8904 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f32)); 8905 } else { 8906 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f32)); 8907 bigint->is_negative = true; 8908 } 8909 break; 8910 case 64: 8911 if (const_val->data.x_f64 >= 0) { 8912 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f64)); 8913 } else { 8914 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f64)); 8915 bigint->is_negative = true; 8916 } 8917 break; 8918 case 128: 8919 { 8920 BigFloat tmp_float; 8921 bigfloat_init_128(&tmp_float, const_val->data.x_f128); 8922 bigint_init_bigfloat(bigint, &tmp_float); 8923 } 8924 break; 8925 default: 8926 zig_unreachable(); 8927 } 8928 } else { 8929 zig_unreachable(); 8930 } 8931 } 8932 8933 static void float_init_bigfloat(ZigValue *dest_val, BigFloat *bigfloat) { 8934 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8935 bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat); 8936 } else if (dest_val->type->id == ZigTypeIdFloat) { 8937 switch (dest_val->type->data.floating.bit_count) { 8938 case 16: 8939 dest_val->data.x_f16 = bigfloat_to_f16(bigfloat); 8940 break; 8941 case 32: 8942 dest_val->data.x_f32 = bigfloat_to_f32(bigfloat); 8943 break; 8944 case 64: 8945 dest_val->data.x_f64 = bigfloat_to_f64(bigfloat); 8946 break; 8947 case 80: 8948 zig_panic("TODO"); 8949 case 128: 8950 dest_val->data.x_f128 = bigfloat_to_f128(bigfloat); 8951 break; 8952 default: 8953 zig_unreachable(); 8954 } 8955 } else { 8956 zig_unreachable(); 8957 } 8958 } 8959 8960 static void float_init_f16(ZigValue *dest_val, float16_t x) { 8961 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8962 bigfloat_init_16(&dest_val->data.x_bigfloat, x); 8963 } else if (dest_val->type->id == ZigTypeIdFloat) { 8964 switch (dest_val->type->data.floating.bit_count) { 8965 case 16: 8966 dest_val->data.x_f16 = x; 8967 break; 8968 case 32: 8969 dest_val->data.x_f32 = zig_f16_to_double(x); 8970 break; 8971 case 64: 8972 dest_val->data.x_f64 = zig_f16_to_double(x); 8973 break; 8974 case 128: 8975 f16_to_f128M(x, &dest_val->data.x_f128); 8976 break; 8977 default: 8978 zig_unreachable(); 8979 } 8980 } else { 8981 zig_unreachable(); 8982 } 8983 } 8984 8985 static void float_init_f32(ZigValue *dest_val, float x) { 8986 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 8987 bigfloat_init_32(&dest_val->data.x_bigfloat, x); 8988 } else if (dest_val->type->id == ZigTypeIdFloat) { 8989 switch (dest_val->type->data.floating.bit_count) { 8990 case 16: 8991 dest_val->data.x_f16 = zig_double_to_f16(x); 8992 break; 8993 case 32: 8994 dest_val->data.x_f32 = x; 8995 break; 8996 case 64: 8997 dest_val->data.x_f64 = x; 8998 break; 8999 case 128: 9000 { 9001 float32_t x_f32; 9002 memcpy(&x_f32, &x, sizeof(float)); 9003 f32_to_f128M(x_f32, &dest_val->data.x_f128); 9004 break; 9005 } 9006 default: 9007 zig_unreachable(); 9008 } 9009 } else { 9010 zig_unreachable(); 9011 } 9012 } 9013 9014 static void float_init_f64(ZigValue *dest_val, double x) { 9015 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 9016 bigfloat_init_64(&dest_val->data.x_bigfloat, x); 9017 } else if (dest_val->type->id == ZigTypeIdFloat) { 9018 switch (dest_val->type->data.floating.bit_count) { 9019 case 16: 9020 dest_val->data.x_f16 = zig_double_to_f16(x); 9021 break; 9022 case 32: 9023 dest_val->data.x_f32 = x; 9024 break; 9025 case 64: 9026 dest_val->data.x_f64 = x; 9027 break; 9028 case 128: 9029 { 9030 float64_t x_f64; 9031 memcpy(&x_f64, &x, sizeof(double)); 9032 f64_to_f128M(x_f64, &dest_val->data.x_f128); 9033 break; 9034 } 9035 default: 9036 zig_unreachable(); 9037 } 9038 } else { 9039 zig_unreachable(); 9040 } 9041 } 9042 9043 static void float_init_f128(ZigValue *dest_val, float128_t x) { 9044 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 9045 bigfloat_init_128(&dest_val->data.x_bigfloat, x); 9046 } else if (dest_val->type->id == ZigTypeIdFloat) { 9047 switch (dest_val->type->data.floating.bit_count) { 9048 case 16: 9049 dest_val->data.x_f16 = f128M_to_f16(&x); 9050 break; 9051 case 32: 9052 { 9053 float32_t f32_val = f128M_to_f32(&x); 9054 memcpy(&dest_val->data.x_f32, &f32_val, sizeof(float)); 9055 break; 9056 } 9057 case 64: 9058 { 9059 float64_t f64_val = f128M_to_f64(&x); 9060 memcpy(&dest_val->data.x_f64, &f64_val, sizeof(double)); 9061 break; 9062 } 9063 case 128: 9064 { 9065 memcpy(&dest_val->data.x_f128, &x, sizeof(float128_t)); 9066 break; 9067 } 9068 default: 9069 zig_unreachable(); 9070 } 9071 } else { 9072 zig_unreachable(); 9073 } 9074 } 9075 9076 static void float_init_float(ZigValue *dest_val, ZigValue *src_val) { 9077 if (src_val->type->id == ZigTypeIdComptimeFloat) { 9078 float_init_bigfloat(dest_val, &src_val->data.x_bigfloat); 9079 } else if (src_val->type->id == ZigTypeIdFloat) { 9080 switch (src_val->type->data.floating.bit_count) { 9081 case 16: 9082 float_init_f16(dest_val, src_val->data.x_f16); 9083 break; 9084 case 32: 9085 float_init_f32(dest_val, src_val->data.x_f32); 9086 break; 9087 case 64: 9088 float_init_f64(dest_val, src_val->data.x_f64); 9089 break; 9090 case 128: 9091 float_init_f128(dest_val, src_val->data.x_f128); 9092 break; 9093 default: 9094 zig_unreachable(); 9095 } 9096 } else { 9097 zig_unreachable(); 9098 } 9099 } 9100 9101 static bool float_is_nan(ZigValue *op) { 9102 if (op->type->id == ZigTypeIdComptimeFloat) { 9103 return bigfloat_is_nan(&op->data.x_bigfloat); 9104 } else if (op->type->id == ZigTypeIdFloat) { 9105 switch (op->type->data.floating.bit_count) { 9106 case 16: 9107 return f16_isSignalingNaN(op->data.x_f16); 9108 case 32: 9109 return op->data.x_f32 != op->data.x_f32; 9110 case 64: 9111 return op->data.x_f64 != op->data.x_f64; 9112 case 128: 9113 return f128M_isSignalingNaN(&op->data.x_f128); 9114 default: 9115 zig_unreachable(); 9116 } 9117 } else { 9118 zig_unreachable(); 9119 } 9120 } 9121 9122 static Cmp float_cmp(ZigValue *op1, ZigValue *op2) { 9123 assert(op1->type == op2->type); 9124 if (op1->type->id == ZigTypeIdComptimeFloat) { 9125 return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat); 9126 } else if (op1->type->id == ZigTypeIdFloat) { 9127 switch (op1->type->data.floating.bit_count) { 9128 case 16: 9129 if (f16_lt(op1->data.x_f16, op2->data.x_f16)) { 9130 return CmpLT; 9131 } else if (f16_lt(op2->data.x_f16, op1->data.x_f16)) { 9132 return CmpGT; 9133 } else { 9134 return CmpEQ; 9135 } 9136 case 32: 9137 if (op1->data.x_f32 > op2->data.x_f32) { 9138 return CmpGT; 9139 } else if (op1->data.x_f32 < op2->data.x_f32) { 9140 return CmpLT; 9141 } else { 9142 return CmpEQ; 9143 } 9144 case 64: 9145 if (op1->data.x_f64 > op2->data.x_f64) { 9146 return CmpGT; 9147 } else if (op1->data.x_f64 < op2->data.x_f64) { 9148 return CmpLT; 9149 } else { 9150 return CmpEQ; 9151 } 9152 case 128: 9153 if (f128M_lt(&op1->data.x_f128, &op2->data.x_f128)) { 9154 return CmpLT; 9155 } else if (f128M_eq(&op1->data.x_f128, &op2->data.x_f128)) { 9156 return CmpEQ; 9157 } else { 9158 return CmpGT; 9159 } 9160 default: 9161 zig_unreachable(); 9162 } 9163 } else { 9164 zig_unreachable(); 9165 } 9166 } 9167 9168 static Cmp float_cmp_zero(ZigValue *op) { 9169 if (op->type->id == ZigTypeIdComptimeFloat) { 9170 return bigfloat_cmp_zero(&op->data.x_bigfloat); 9171 } else if (op->type->id == ZigTypeIdFloat) { 9172 switch (op->type->data.floating.bit_count) { 9173 case 16: 9174 { 9175 const float16_t zero = zig_double_to_f16(0); 9176 if (f16_lt(op->data.x_f16, zero)) { 9177 return CmpLT; 9178 } else if (f16_lt(zero, op->data.x_f16)) { 9179 return CmpGT; 9180 } else { 9181 return CmpEQ; 9182 } 9183 } 9184 case 32: 9185 if (op->data.x_f32 < 0.0) { 9186 return CmpLT; 9187 } else if (op->data.x_f32 > 0.0) { 9188 return CmpGT; 9189 } else { 9190 return CmpEQ; 9191 } 9192 case 64: 9193 if (op->data.x_f64 < 0.0) { 9194 return CmpLT; 9195 } else if (op->data.x_f64 > 0.0) { 9196 return CmpGT; 9197 } else { 9198 return CmpEQ; 9199 } 9200 case 128: 9201 float128_t zero_float; 9202 ui32_to_f128M(0, &zero_float); 9203 if (f128M_lt(&op->data.x_f128, &zero_float)) { 9204 return CmpLT; 9205 } else if (f128M_eq(&op->data.x_f128, &zero_float)) { 9206 return CmpEQ; 9207 } else { 9208 return CmpGT; 9209 } 9210 default: 9211 zig_unreachable(); 9212 } 9213 } else { 9214 zig_unreachable(); 9215 } 9216 } 9217 9218 static void float_add(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 9219 assert(op1->type == op2->type); 9220 out_val->type = op1->type; 9221 if (op1->type->id == ZigTypeIdComptimeFloat) { 9222 bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 9223 } else if (op1->type->id == ZigTypeIdFloat) { 9224 switch (op1->type->data.floating.bit_count) { 9225 case 16: 9226 out_val->data.x_f16 = f16_add(op1->data.x_f16, op2->data.x_f16); 9227 return; 9228 case 32: 9229 out_val->data.x_f32 = op1->data.x_f32 + op2->data.x_f32; 9230 return; 9231 case 64: 9232 out_val->data.x_f64 = op1->data.x_f64 + op2->data.x_f64; 9233 return; 9234 case 128: 9235 f128M_add(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 9236 return; 9237 default: 9238 zig_unreachable(); 9239 } 9240 } else { 9241 zig_unreachable(); 9242 } 9243 } 9244 9245 static void float_sub(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 9246 assert(op1->type == op2->type); 9247 out_val->type = op1->type; 9248 if (op1->type->id == ZigTypeIdComptimeFloat) { 9249 bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 9250 } else if (op1->type->id == ZigTypeIdFloat) { 9251 switch (op1->type->data.floating.bit_count) { 9252 case 16: 9253 out_val->data.x_f16 = f16_sub(op1->data.x_f16, op2->data.x_f16); 9254 return; 9255 case 32: 9256 out_val->data.x_f32 = op1->data.x_f32 - op2->data.x_f32; 9257 return; 9258 case 64: 9259 out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64; 9260 return; 9261 case 128: 9262 f128M_sub(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 9263 return; 9264 default: 9265 zig_unreachable(); 9266 } 9267 } else { 9268 zig_unreachable(); 9269 } 9270 } 9271 9272 static void float_mul(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 9273 assert(op1->type == op2->type); 9274 out_val->type = op1->type; 9275 if (op1->type->id == ZigTypeIdComptimeFloat) { 9276 bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 9277 } else if (op1->type->id == ZigTypeIdFloat) { 9278 switch (op1->type->data.floating.bit_count) { 9279 case 16: 9280 out_val->data.x_f16 = f16_mul(op1->data.x_f16, op2->data.x_f16); 9281 return; 9282 case 32: 9283 out_val->data.x_f32 = op1->data.x_f32 * op2->data.x_f32; 9284 return; 9285 case 64: 9286 out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64; 9287 return; 9288 case 128: 9289 f128M_mul(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 9290 return; 9291 default: 9292 zig_unreachable(); 9293 } 9294 } else { 9295 zig_unreachable(); 9296 } 9297 } 9298 9299 static void float_div(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 9300 assert(op1->type == op2->type); 9301 out_val->type = op1->type; 9302 if (op1->type->id == ZigTypeIdComptimeFloat) { 9303 bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 9304 } else if (op1->type->id == ZigTypeIdFloat) { 9305 switch (op1->type->data.floating.bit_count) { 9306 case 16: 9307 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 9308 return; 9309 case 32: 9310 out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32; 9311 return; 9312 case 64: 9313 out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64; 9314 return; 9315 case 128: 9316 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 9317 return; 9318 default: 9319 zig_unreachable(); 9320 } 9321 } else { 9322 zig_unreachable(); 9323 } 9324 } 9325 9326 static void float_div_trunc(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 9327 assert(op1->type == op2->type); 9328 out_val->type = op1->type; 9329 if (op1->type->id == ZigTypeIdComptimeFloat) { 9330 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 9331 } else if (op1->type->id == ZigTypeIdFloat) { 9332 switch (op1->type->data.floating.bit_count) { 9333 case 16: 9334 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 9335 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_minMag, false); 9336 return; 9337 case 32: 9338 out_val->data.x_f32 = truncf(op1->data.x_f32 / op2->data.x_f32); 9339 return; 9340 case 64: 9341 out_val->data.x_f64 = trunc(op1->data.x_f64 / op2->data.x_f64); 9342 return; 9343 case 128: 9344 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 9345 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_minMag, false, &out_val->data.x_f128); 9346 return; 9347 default: 9348 zig_unreachable(); 9349 } 9350 } else { 9351 zig_unreachable(); 9352 } 9353 } 9354 9355 static void float_div_floor(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 9356 assert(op1->type == op2->type); 9357 out_val->type = op1->type; 9358 if (op1->type->id == ZigTypeIdComptimeFloat) { 9359 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 9360 } else if (op1->type->id == ZigTypeIdFloat) { 9361 switch (op1->type->data.floating.bit_count) { 9362 case 16: 9363 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 9364 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_min, false); 9365 return; 9366 case 32: 9367 out_val->data.x_f32 = floorf(op1->data.x_f32 / op2->data.x_f32); 9368 return; 9369 case 64: 9370 out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64); 9371 return; 9372 case 128: 9373 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 9374 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_min, false, &out_val->data.x_f128); 9375 return; 9376 default: 9377 zig_unreachable(); 9378 } 9379 } else { 9380 zig_unreachable(); 9381 } 9382 } 9383 9384 static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 9385 assert(op1->type == op2->type); 9386 out_val->type = op1->type; 9387 if (op1->type->id == ZigTypeIdComptimeFloat) { 9388 bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 9389 } else if (op1->type->id == ZigTypeIdFloat) { 9390 switch (op1->type->data.floating.bit_count) { 9391 case 16: 9392 out_val->data.x_f16 = f16_rem(op1->data.x_f16, op2->data.x_f16); 9393 return; 9394 case 32: 9395 out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32); 9396 return; 9397 case 64: 9398 out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64); 9399 return; 9400 case 128: 9401 f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 9402 return; 9403 default: 9404 zig_unreachable(); 9405 } 9406 } else { 9407 zig_unreachable(); 9408 } 9409 } 9410 9411 // c = a - b * trunc(a / b) 9412 static float16_t zig_f16_mod(float16_t a, float16_t b) { 9413 float16_t c; 9414 c = f16_div(a, b); 9415 c = f16_roundToInt(c, softfloat_round_min, true); 9416 c = f16_mul(b, c); 9417 c = f16_sub(a, c); 9418 return c; 9419 } 9420 9421 // c = a - b * trunc(a / b) 9422 static void zig_f128M_mod(const float128_t* a, const float128_t* b, float128_t* c) { 9423 f128M_div(a, b, c); 9424 f128M_roundToInt(c, softfloat_round_min, true, c); 9425 f128M_mul(b, c, c); 9426 f128M_sub(a, c, c); 9427 } 9428 9429 static void float_mod(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 9430 assert(op1->type == op2->type); 9431 out_val->type = op1->type; 9432 if (op1->type->id == ZigTypeIdComptimeFloat) { 9433 bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 9434 } else if (op1->type->id == ZigTypeIdFloat) { 9435 switch (op1->type->data.floating.bit_count) { 9436 case 16: 9437 out_val->data.x_f16 = zig_f16_mod(op1->data.x_f16, op2->data.x_f16); 9438 return; 9439 case 32: 9440 out_val->data.x_f32 = fmodf(fmodf(op1->data.x_f32, op2->data.x_f32) + op2->data.x_f32, op2->data.x_f32); 9441 return; 9442 case 64: 9443 out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64); 9444 return; 9445 case 128: 9446 zig_f128M_mod(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 9447 return; 9448 default: 9449 zig_unreachable(); 9450 } 9451 } else { 9452 zig_unreachable(); 9453 } 9454 } 9455 9456 static void float_negate(ZigValue *out_val, ZigValue *op) { 9457 out_val->type = op->type; 9458 if (op->type->id == ZigTypeIdComptimeFloat) { 9459 bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat); 9460 } else if (op->type->id == ZigTypeIdFloat) { 9461 switch (op->type->data.floating.bit_count) { 9462 case 16: 9463 { 9464 const float16_t zero = zig_double_to_f16(0); 9465 out_val->data.x_f16 = f16_sub(zero, op->data.x_f16); 9466 return; 9467 } 9468 case 32: 9469 out_val->data.x_f32 = -op->data.x_f32; 9470 return; 9471 case 64: 9472 out_val->data.x_f64 = -op->data.x_f64; 9473 return; 9474 case 128: 9475 float128_t zero_f128; 9476 ui32_to_f128M(0, &zero_f128); 9477 f128M_sub(&zero_f128, &op->data.x_f128, &out_val->data.x_f128); 9478 return; 9479 default: 9480 zig_unreachable(); 9481 } 9482 } else { 9483 zig_unreachable(); 9484 } 9485 } 9486 9487 void float_write_ieee597(ZigValue *op, uint8_t *buf, bool is_big_endian) { 9488 if (op->type->id == ZigTypeIdFloat) { 9489 switch (op->type->data.floating.bit_count) { 9490 case 16: 9491 memcpy(buf, &op->data.x_f16, 2); // TODO wrong when compiler is big endian 9492 return; 9493 case 32: 9494 memcpy(buf, &op->data.x_f32, 4); // TODO wrong when compiler is big endian 9495 return; 9496 case 64: 9497 memcpy(buf, &op->data.x_f64, 8); // TODO wrong when compiler is big endian 9498 return; 9499 case 128: 9500 memcpy(buf, &op->data.x_f128, 16); // TODO wrong when compiler is big endian 9501 return; 9502 default: 9503 zig_unreachable(); 9504 } 9505 } else { 9506 zig_unreachable(); 9507 } 9508 } 9509 9510 void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) { 9511 if (val->type->id == ZigTypeIdFloat) { 9512 switch (val->type->data.floating.bit_count) { 9513 case 16: 9514 memcpy(&val->data.x_f16, buf, 2); // TODO wrong when compiler is big endian 9515 return; 9516 case 32: 9517 memcpy(&val->data.x_f32, buf, 4); // TODO wrong when compiler is big endian 9518 return; 9519 case 64: 9520 memcpy(&val->data.x_f64, buf, 8); // TODO wrong when compiler is big endian 9521 return; 9522 case 128: 9523 memcpy(&val->data.x_f128, buf, 16); // TODO wrong when compiler is big endian 9524 return; 9525 default: 9526 zig_unreachable(); 9527 } 9528 } else { 9529 zig_unreachable(); 9530 } 9531 } 9532 9533 static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, ZigType *other_type, 9534 bool explicit_cast) 9535 { 9536 if (type_is_invalid(other_type)) { 9537 return false; 9538 } 9539 9540 ZigValue *const_val = ir_resolve_const(ira, instruction, LazyOkNoUndef); 9541 if (const_val == nullptr) 9542 return false; 9543 9544 if (const_val->special == ConstValSpecialLazy) { 9545 switch (const_val->data.x_lazy->id) { 9546 case LazyValueIdAlignOf: { 9547 // This is guaranteed to fit into a u29 9548 if (other_type->id == ZigTypeIdComptimeInt) 9549 return true; 9550 size_t align_bits = get_align_amt_type(ira->codegen)->data.integral.bit_count; 9551 if (other_type->id == ZigTypeIdInt && !other_type->data.integral.is_signed && 9552 other_type->data.integral.bit_count >= align_bits) 9553 { 9554 return true; 9555 } 9556 break; 9557 } 9558 case LazyValueIdSizeOf: { 9559 // This is guaranteed to fit into a usize 9560 if (other_type->id == ZigTypeIdComptimeInt) 9561 return true; 9562 size_t usize_bits = ira->codegen->builtin_types.entry_usize->data.integral.bit_count; 9563 if (other_type->id == ZigTypeIdInt && !other_type->data.integral.is_signed && 9564 other_type->data.integral.bit_count >= usize_bits) 9565 { 9566 return true; 9567 } 9568 break; 9569 } 9570 default: 9571 break; 9572 } 9573 } 9574 9575 const_val = ir_resolve_const(ira, instruction, UndefBad); 9576 if (const_val == nullptr) 9577 return false; 9578 9579 bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt); 9580 bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); 9581 assert(const_val_is_int || const_val_is_float); 9582 9583 if (const_val_is_int && other_type->id == ZigTypeIdComptimeFloat) { 9584 return true; 9585 } 9586 if (other_type->id == ZigTypeIdFloat) { 9587 if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) { 9588 return true; 9589 } 9590 if (const_val->type->id == ZigTypeIdInt) { 9591 BigFloat tmp_bf; 9592 bigfloat_init_bigint(&tmp_bf, &const_val->data.x_bigint); 9593 BigFloat orig_bf; 9594 switch (other_type->data.floating.bit_count) { 9595 case 16: { 9596 float16_t tmp = bigfloat_to_f16(&tmp_bf); 9597 bigfloat_init_16(&orig_bf, tmp); 9598 break; 9599 } 9600 case 32: { 9601 float tmp = bigfloat_to_f32(&tmp_bf); 9602 bigfloat_init_32(&orig_bf, tmp); 9603 break; 9604 } 9605 case 64: { 9606 double tmp = bigfloat_to_f64(&tmp_bf); 9607 bigfloat_init_64(&orig_bf, tmp); 9608 break; 9609 } 9610 case 80: 9611 zig_panic("TODO"); 9612 case 128: { 9613 float128_t tmp = bigfloat_to_f128(&tmp_bf); 9614 bigfloat_init_128(&orig_bf, tmp); 9615 break; 9616 } 9617 default: 9618 zig_unreachable(); 9619 } 9620 BigInt orig_bi; 9621 bigint_init_bigfloat(&orig_bi, &orig_bf); 9622 if (bigint_cmp(&orig_bi, &const_val->data.x_bigint) == CmpEQ) { 9623 return true; 9624 } 9625 Buf *val_buf = buf_alloc(); 9626 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 9627 ir_add_error(ira, instruction, 9628 buf_sprintf("integer value %s has no representation in type '%s'", 9629 buf_ptr(val_buf), 9630 buf_ptr(&other_type->name))); 9631 return false; 9632 } 9633 if (other_type->data.floating.bit_count >= const_val->type->data.floating.bit_count) { 9634 return true; 9635 } 9636 switch (other_type->data.floating.bit_count) { 9637 case 16: 9638 switch (const_val->type->data.floating.bit_count) { 9639 case 32: { 9640 float16_t tmp = zig_double_to_f16(const_val->data.x_f32); 9641 float orig = zig_f16_to_double(tmp); 9642 if (const_val->data.x_f32 == orig) { 9643 return true; 9644 } 9645 break; 9646 } 9647 case 64: { 9648 float16_t tmp = zig_double_to_f16(const_val->data.x_f64); 9649 double orig = zig_f16_to_double(tmp); 9650 if (const_val->data.x_f64 == orig) { 9651 return true; 9652 } 9653 break; 9654 } 9655 case 80: 9656 zig_panic("TODO"); 9657 case 128: { 9658 float16_t tmp = f128M_to_f16(&const_val->data.x_f128); 9659 float128_t orig; 9660 f16_to_f128M(tmp, &orig); 9661 if (f128M_eq(&orig, &const_val->data.x_f128)) { 9662 return true; 9663 } 9664 break; 9665 } 9666 default: 9667 zig_unreachable(); 9668 } 9669 break; 9670 case 32: 9671 switch (const_val->type->data.floating.bit_count) { 9672 case 64: { 9673 float tmp = const_val->data.x_f64; 9674 double orig = tmp; 9675 if (const_val->data.x_f64 == orig) { 9676 return true; 9677 } 9678 break; 9679 } 9680 case 80: 9681 zig_panic("TODO"); 9682 case 128: { 9683 float32_t tmp = f128M_to_f32(&const_val->data.x_f128); 9684 float128_t orig; 9685 f32_to_f128M(tmp, &orig); 9686 if (f128M_eq(&orig, &const_val->data.x_f128)) { 9687 return true; 9688 } 9689 break; 9690 } 9691 default: 9692 zig_unreachable(); 9693 } 9694 break; 9695 case 64: 9696 switch (const_val->type->data.floating.bit_count) { 9697 case 80: 9698 zig_panic("TODO"); 9699 case 128: { 9700 float64_t tmp = f128M_to_f64(&const_val->data.x_f128); 9701 float128_t orig; 9702 f64_to_f128M(tmp, &orig); 9703 if (f128M_eq(&orig, &const_val->data.x_f128)) { 9704 return true; 9705 } 9706 break; 9707 } 9708 default: 9709 zig_unreachable(); 9710 } 9711 break; 9712 case 80: 9713 assert(const_val->type->data.floating.bit_count == 128); 9714 zig_panic("TODO"); 9715 case 128: 9716 return true; 9717 default: 9718 zig_unreachable(); 9719 } 9720 Buf *val_buf = buf_alloc(); 9721 float_append_buf(val_buf, const_val); 9722 ir_add_error(ira, instruction, 9723 buf_sprintf("cast of value %s to type '%s' loses information", 9724 buf_ptr(val_buf), 9725 buf_ptr(&other_type->name))); 9726 return false; 9727 } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { 9728 if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 9729 Buf *val_buf = buf_alloc(); 9730 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 9731 ir_add_error(ira, instruction, 9732 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 9733 buf_ptr(val_buf), 9734 buf_ptr(&other_type->name))); 9735 return false; 9736 } 9737 if (bigint_fits_in_bits(&const_val->data.x_bigint, other_type->data.integral.bit_count, 9738 other_type->data.integral.is_signed)) 9739 { 9740 return true; 9741 } 9742 } else if (const_val_fits_in_num_lit(const_val, other_type)) { 9743 return true; 9744 } else if (other_type->id == ZigTypeIdOptional) { 9745 ZigType *child_type = other_type->data.maybe.child_type; 9746 if (const_val_fits_in_num_lit(const_val, child_type)) { 9747 return true; 9748 } else if (child_type->id == ZigTypeIdInt && const_val_is_int) { 9749 if (!child_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 9750 Buf *val_buf = buf_alloc(); 9751 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 9752 ir_add_error(ira, instruction, 9753 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 9754 buf_ptr(val_buf), 9755 buf_ptr(&child_type->name))); 9756 return false; 9757 } 9758 if (bigint_fits_in_bits(&const_val->data.x_bigint, 9759 child_type->data.integral.bit_count, 9760 child_type->data.integral.is_signed)) 9761 { 9762 return true; 9763 } 9764 } else if (child_type->id == ZigTypeIdFloat && const_val_is_float) { 9765 return true; 9766 } 9767 } 9768 if (explicit_cast && (other_type->id == ZigTypeIdInt || other_type->id == ZigTypeIdComptimeInt) && 9769 const_val_is_float) 9770 { 9771 if (float_has_fraction(const_val)) { 9772 Buf *val_buf = buf_alloc(); 9773 float_append_buf(val_buf, const_val); 9774 9775 ir_add_error(ira, instruction, 9776 buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", 9777 buf_ptr(val_buf), 9778 buf_ptr(&other_type->name))); 9779 return false; 9780 } else { 9781 if (other_type->id == ZigTypeIdComptimeInt) { 9782 return true; 9783 } else { 9784 BigInt bigint; 9785 float_init_bigint(&bigint, const_val); 9786 if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count, 9787 other_type->data.integral.is_signed)) 9788 { 9789 return true; 9790 } 9791 } 9792 } 9793 } 9794 9795 const char *num_lit_str; 9796 Buf *val_buf = buf_alloc(); 9797 if (const_val_is_float) { 9798 num_lit_str = "float"; 9799 float_append_buf(val_buf, const_val); 9800 } else { 9801 num_lit_str = "integer"; 9802 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 9803 } 9804 9805 ir_add_error(ira, instruction, 9806 buf_sprintf("%s value %s cannot be coerced to type '%s'", 9807 num_lit_str, 9808 buf_ptr(val_buf), 9809 buf_ptr(&other_type->name))); 9810 return false; 9811 } 9812 9813 static bool is_tagged_union(ZigType *type) { 9814 if (type->id != ZigTypeIdUnion) 9815 return false; 9816 return (type->data.unionation.decl_node->data.container_decl.auto_enum || 9817 type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr); 9818 } 9819 9820 static void populate_error_set_table(ErrorTableEntry **errors, ZigType *set) { 9821 assert(set->id == ZigTypeIdErrorSet); 9822 for (uint32_t i = 0; i < set->data.error_set.err_count; i += 1) { 9823 ErrorTableEntry *error_entry = set->data.error_set.errors[i]; 9824 assert(errors[error_entry->value] == nullptr); 9825 errors[error_entry->value] = error_entry; 9826 } 9827 } 9828 9829 static ErrorTableEntry *better_documented_error(ErrorTableEntry *preferred, ErrorTableEntry *other) { 9830 if (preferred->decl_node->type == NodeTypeErrorSetField) 9831 return preferred; 9832 if (other->decl_node->type == NodeTypeErrorSetField) 9833 return other; 9834 return preferred; 9835 } 9836 9837 static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigType *set2, 9838 AstNode *source_node) 9839 { 9840 assert(set1->id == ZigTypeIdErrorSet); 9841 assert(set2->id == ZigTypeIdErrorSet); 9842 9843 if (!resolve_inferred_error_set(ira->codegen, set1, source_node)) { 9844 return ira->codegen->builtin_types.entry_invalid; 9845 } 9846 if (!resolve_inferred_error_set(ira->codegen, set2, source_node)) { 9847 return ira->codegen->builtin_types.entry_invalid; 9848 } 9849 if (type_is_global_error_set(set1)) { 9850 return set2; 9851 } 9852 if (type_is_global_error_set(set2)) { 9853 return set1; 9854 } 9855 size_t errors_count = ira->codegen->errors_by_index.length; 9856 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(errors_count, "ErrorTableEntry *"); 9857 populate_error_set_table(errors, set1); 9858 ZigList<ErrorTableEntry *> intersection_list = {}; 9859 9860 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9861 buf_resize(&err_set_type->name, 0); 9862 buf_appendf(&err_set_type->name, "error{"); 9863 9864 bool need_comma = false; 9865 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 9866 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 9867 ErrorTableEntry *existing_entry = errors[error_entry->value]; 9868 if (existing_entry != nullptr) { 9869 // prefer the one with docs 9870 const char *comma = need_comma ? "," : ""; 9871 need_comma = true; 9872 ErrorTableEntry *existing_entry_with_docs = better_documented_error(existing_entry, error_entry); 9873 intersection_list.append(existing_entry_with_docs); 9874 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&existing_entry_with_docs->name)); 9875 } 9876 } 9877 deallocate(errors, errors_count, "ErrorTableEntry *"); 9878 9879 err_set_type->data.error_set.err_count = intersection_list.length; 9880 err_set_type->data.error_set.errors = intersection_list.items; 9881 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 9882 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 9883 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 9884 9885 buf_appendf(&err_set_type->name, "}"); 9886 9887 return err_set_type; 9888 } 9889 9890 static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted_type, 9891 ZigType *actual_type, AstNode *source_node, bool wanted_is_mutable) 9892 { 9893 CodeGen *g = ira->codegen; 9894 ConstCastOnly result = {}; 9895 result.id = ConstCastResultIdOk; 9896 9897 Error err; 9898 9899 if (wanted_type == actual_type) 9900 return result; 9901 9902 // If pointers have the same representation in memory, they can be "const-casted". 9903 // `const` attribute can be gained 9904 // `volatile` attribute can be gained 9905 // `allowzero` attribute can be gained (whether from explicit attribute, C pointer, or optional pointer) 9906 // but only if !wanted_is_mutable 9907 // alignment can be decreased 9908 // bit offset attributes must match exactly 9909 // PtrLenSingle/PtrLenUnknown must match exactly, but PtrLenC matches either one 9910 // sentinel-terminated pointers can coerce into PtrLenUnknown 9911 ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type); 9912 ZigType *actual_ptr_type = get_src_ptr_type(actual_type); 9913 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 9914 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 9915 bool wanted_is_c_ptr = wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC; 9916 bool actual_is_c_ptr = actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenC; 9917 bool wanted_opt_or_ptr = wanted_ptr_type != nullptr && 9918 (wanted_type->id == ZigTypeIdPointer || wanted_type->id == ZigTypeIdOptional); 9919 bool actual_opt_or_ptr = actual_ptr_type != nullptr && 9920 (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional); 9921 if (wanted_opt_or_ptr && actual_opt_or_ptr) { 9922 bool ok_null_term_ptrs = 9923 wanted_ptr_type->data.pointer.sentinel == nullptr || 9924 (actual_ptr_type->data.pointer.sentinel != nullptr && 9925 const_values_equal(ira->codegen, wanted_ptr_type->data.pointer.sentinel, 9926 actual_ptr_type->data.pointer.sentinel)); 9927 if (!ok_null_term_ptrs) { 9928 result.id = ConstCastResultIdPtrSentinel; 9929 result.data.bad_ptr_sentinel = allocate_nonzero<ConstCastPtrSentinel>(1); 9930 result.data.bad_ptr_sentinel->wanted_type = wanted_ptr_type; 9931 result.data.bad_ptr_sentinel->actual_type = actual_ptr_type; 9932 return result; 9933 } 9934 bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; 9935 if (!(ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr)) { 9936 result.id = ConstCastResultIdPtrLens; 9937 return result; 9938 } 9939 9940 bool ok_cv_qualifiers = 9941 (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 9942 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile); 9943 if (!ok_cv_qualifiers) { 9944 result.id = ConstCastResultIdCV; 9945 result.data.bad_cv = allocate_nonzero<ConstCastBadCV>(1); 9946 result.data.bad_cv->wanted_type = wanted_ptr_type; 9947 result.data.bad_cv->actual_type = actual_ptr_type; 9948 return result; 9949 } 9950 9951 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 9952 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 9953 if (child.id == ConstCastResultIdInvalid) 9954 return child; 9955 if (child.id != ConstCastResultIdOk) { 9956 result.id = ConstCastResultIdPointerChild; 9957 result.data.pointer_mismatch = allocate_nonzero<ConstCastPointerMismatch>(1); 9958 result.data.pointer_mismatch->child = child; 9959 result.data.pointer_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 9960 result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 9961 return result; 9962 } 9963 bool ok_allows_zero = (wanted_allows_zero && 9964 (actual_allows_zero || !wanted_is_mutable)) || 9965 (!wanted_allows_zero && !actual_allows_zero); 9966 if (!ok_allows_zero) { 9967 result.id = ConstCastResultIdBadAllowsZero; 9968 result.data.bad_allows_zero = allocate_nonzero<ConstCastBadAllowsZero>(1); 9969 result.data.bad_allows_zero->wanted_type = wanted_type; 9970 result.data.bad_allows_zero->actual_type = actual_type; 9971 return result; 9972 } 9973 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 9974 result.id = ConstCastResultIdInvalid; 9975 return result; 9976 } 9977 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 9978 result.id = ConstCastResultIdInvalid; 9979 return result; 9980 } 9981 if ((err = type_resolve(g, wanted_type, ResolveStatusZeroBitsKnown))) { 9982 result.id = ConstCastResultIdInvalid; 9983 return result; 9984 } 9985 if ((err = type_resolve(g, actual_type, ResolveStatusZeroBitsKnown))) { 9986 result.id = ConstCastResultIdInvalid; 9987 return result; 9988 } 9989 if (type_has_bits(wanted_type) == type_has_bits(actual_type) && 9990 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 9991 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 9992 get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type)) 9993 { 9994 return result; 9995 } 9996 } 9997 9998 // arrays 9999 if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdArray && 10000 wanted_type->data.array.len == actual_type->data.array.len) 10001 { 10002 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.array.child_type, 10003 actual_type->data.array.child_type, source_node, wanted_is_mutable); 10004 if (child.id == ConstCastResultIdInvalid) 10005 return child; 10006 if (child.id != ConstCastResultIdOk) { 10007 result.id = ConstCastResultIdArrayChild; 10008 result.data.array_mismatch = allocate_nonzero<ConstCastArrayMismatch>(1); 10009 result.data.array_mismatch->child = child; 10010 result.data.array_mismatch->wanted_child = wanted_type->data.array.child_type; 10011 result.data.array_mismatch->actual_child = actual_type->data.array.child_type; 10012 return result; 10013 } 10014 bool ok_null_terminated = (wanted_type->data.array.sentinel == nullptr) || 10015 (actual_type->data.array.sentinel != nullptr && 10016 const_values_equal(ira->codegen, wanted_type->data.array.sentinel, actual_type->data.array.sentinel)); 10017 if (!ok_null_terminated) { 10018 result.id = ConstCastResultIdSentinelArrays; 10019 result.data.sentinel_arrays = allocate_nonzero<ConstCastBadNullTermArrays>(1); 10020 result.data.sentinel_arrays->child = child; 10021 result.data.sentinel_arrays->wanted_type = wanted_type; 10022 result.data.sentinel_arrays->actual_type = actual_type; 10023 return result; 10024 } 10025 return result; 10026 } 10027 10028 // slice const 10029 if (is_slice(wanted_type) && is_slice(actual_type)) { 10030 ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index]->type_entry; 10031 ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry; 10032 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 10033 result.id = ConstCastResultIdInvalid; 10034 return result; 10035 } 10036 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 10037 result.id = ConstCastResultIdInvalid; 10038 return result; 10039 } 10040 if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 10041 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && 10042 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 10043 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 10044 get_ptr_align(g, actual_ptr_type) >= get_ptr_align(g, wanted_ptr_type)) 10045 { 10046 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 10047 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 10048 if (child.id == ConstCastResultIdInvalid) 10049 return child; 10050 if (child.id != ConstCastResultIdOk) { 10051 result.id = ConstCastResultIdSliceChild; 10052 result.data.slice_mismatch = allocate_nonzero<ConstCastSliceMismatch>(1); 10053 result.data.slice_mismatch->child = child; 10054 result.data.slice_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 10055 result.data.slice_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 10056 } 10057 return result; 10058 } 10059 } 10060 10061 // maybe 10062 if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdOptional) { 10063 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, 10064 actual_type->data.maybe.child_type, source_node, wanted_is_mutable); 10065 if (child.id == ConstCastResultIdInvalid) 10066 return child; 10067 if (child.id != ConstCastResultIdOk) { 10068 result.id = ConstCastResultIdOptionalChild; 10069 result.data.optional = allocate_nonzero<ConstCastOptionalMismatch>(1); 10070 result.data.optional->child = child; 10071 result.data.optional->wanted_child = wanted_type->data.maybe.child_type; 10072 result.data.optional->actual_child = actual_type->data.maybe.child_type; 10073 } 10074 return result; 10075 } 10076 10077 // error union 10078 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id == ZigTypeIdErrorUnion) { 10079 ConstCastOnly payload_child = types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, 10080 actual_type->data.error_union.payload_type, source_node, wanted_is_mutable); 10081 if (payload_child.id == ConstCastResultIdInvalid) 10082 return payload_child; 10083 if (payload_child.id != ConstCastResultIdOk) { 10084 result.id = ConstCastResultIdErrorUnionPayload; 10085 result.data.error_union_payload = allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1); 10086 result.data.error_union_payload->child = payload_child; 10087 result.data.error_union_payload->wanted_payload = wanted_type->data.error_union.payload_type; 10088 result.data.error_union_payload->actual_payload = actual_type->data.error_union.payload_type; 10089 return result; 10090 } 10091 ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type, 10092 actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable); 10093 if (error_set_child.id == ConstCastResultIdInvalid) 10094 return error_set_child; 10095 if (error_set_child.id != ConstCastResultIdOk) { 10096 result.id = ConstCastResultIdErrorUnionErrorSet; 10097 result.data.error_union_error_set = allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1); 10098 result.data.error_union_error_set->child = error_set_child; 10099 result.data.error_union_error_set->wanted_err_set = wanted_type->data.error_union.err_set_type; 10100 result.data.error_union_error_set->actual_err_set = actual_type->data.error_union.err_set_type; 10101 return result; 10102 } 10103 return result; 10104 } 10105 10106 // error set 10107 if (wanted_type->id == ZigTypeIdErrorSet && actual_type->id == ZigTypeIdErrorSet) { 10108 ZigType *contained_set = actual_type; 10109 ZigType *container_set = wanted_type; 10110 10111 // if the container set is inferred, then this will always work. 10112 if (container_set->data.error_set.infer_fn != nullptr && container_set->data.error_set.incomplete) { 10113 return result; 10114 } 10115 // if the container set is the global one, it will always work. 10116 if (type_is_global_error_set(container_set)) { 10117 return result; 10118 } 10119 10120 if (!resolve_inferred_error_set(ira->codegen, contained_set, source_node)) { 10121 result.id = ConstCastResultIdUnresolvedInferredErrSet; 10122 return result; 10123 } 10124 10125 if (type_is_global_error_set(contained_set)) { 10126 result.id = ConstCastResultIdErrSetGlobal; 10127 return result; 10128 } 10129 10130 size_t errors_count = g->errors_by_index.length; 10131 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(errors_count, "ErrorTableEntry *"); 10132 for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) { 10133 ErrorTableEntry *error_entry = container_set->data.error_set.errors[i]; 10134 assert(errors[error_entry->value] == nullptr); 10135 errors[error_entry->value] = error_entry; 10136 } 10137 for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) { 10138 ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i]; 10139 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 10140 if (error_entry == nullptr) { 10141 if (result.id == ConstCastResultIdOk) { 10142 result.id = ConstCastResultIdErrSet; 10143 result.data.error_set_mismatch = allocate<ConstCastErrSetMismatch>(1); 10144 } 10145 result.data.error_set_mismatch->missing_errors.append(contained_error_entry); 10146 } 10147 } 10148 deallocate(errors, errors_count, "ErrorTableEntry *"); 10149 return result; 10150 } 10151 10152 // fn 10153 if (wanted_type->id == ZigTypeIdFn && 10154 actual_type->id == ZigTypeIdFn) 10155 { 10156 if (wanted_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) { 10157 result.id = ConstCastResultIdFnAlign; 10158 return result; 10159 } 10160 if (wanted_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) { 10161 result.id = ConstCastResultIdFnVarArgs; 10162 return result; 10163 } 10164 if (wanted_type->data.fn.is_generic != actual_type->data.fn.is_generic) { 10165 result.id = ConstCastResultIdFnIsGeneric; 10166 return result; 10167 } 10168 if (!wanted_type->data.fn.is_generic && 10169 actual_type->data.fn.fn_type_id.return_type->id != ZigTypeIdUnreachable) 10170 { 10171 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.fn.fn_type_id.return_type, 10172 actual_type->data.fn.fn_type_id.return_type, source_node, false); 10173 if (child.id == ConstCastResultIdInvalid) 10174 return child; 10175 if (child.id != ConstCastResultIdOk) { 10176 result.id = ConstCastResultIdFnReturnType; 10177 result.data.return_type = allocate_nonzero<ConstCastOnly>(1); 10178 *result.data.return_type = child; 10179 return result; 10180 } 10181 } 10182 if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { 10183 result.id = ConstCastResultIdFnArgCount; 10184 return result; 10185 } 10186 if (wanted_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) { 10187 result.id = ConstCastResultIdFnGenericArgCount; 10188 return result; 10189 } 10190 assert(wanted_type->data.fn.is_generic || 10191 wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count); 10192 for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.next_param_index; i += 1) { 10193 // note it's reversed for parameters 10194 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i]; 10195 FnTypeParamInfo *expected_param_info = &wanted_type->data.fn.fn_type_id.param_info[i]; 10196 10197 ConstCastOnly arg_child = types_match_const_cast_only(ira, actual_param_info->type, 10198 expected_param_info->type, source_node, false); 10199 if (arg_child.id == ConstCastResultIdInvalid) 10200 return arg_child; 10201 if (arg_child.id != ConstCastResultIdOk) { 10202 result.id = ConstCastResultIdFnArg; 10203 result.data.fn_arg.arg_index = i; 10204 result.data.fn_arg.actual_param_type = actual_param_info->type; 10205 result.data.fn_arg.expected_param_type = expected_param_info->type; 10206 result.data.fn_arg.child = allocate_nonzero<ConstCastOnly>(1); 10207 *result.data.fn_arg.child = arg_child; 10208 return result; 10209 } 10210 10211 if (expected_param_info->is_noalias != actual_param_info->is_noalias) { 10212 result.id = ConstCastResultIdFnArgNoAlias; 10213 result.data.arg_no_alias.arg_index = i; 10214 return result; 10215 } 10216 } 10217 if (wanted_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) { 10218 // ConstCastResultIdFnCC is guaranteed to be the last one reported, meaning everything else is ok. 10219 result.id = ConstCastResultIdFnCC; 10220 return result; 10221 } 10222 return result; 10223 } 10224 10225 result.id = ConstCastResultIdType; 10226 result.data.type_mismatch = allocate_nonzero<ConstCastTypeMismatch>(1); 10227 result.data.type_mismatch->wanted_type = wanted_type; 10228 result.data.type_mismatch->actual_type = actual_type; 10229 return result; 10230 } 10231 10232 static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) { 10233 size_t old_errors_count = *errors_count; 10234 *errors_count = g->errors_by_index.length; 10235 *errors = reallocate(*errors, old_errors_count, *errors_count); 10236 } 10237 10238 static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type, 10239 IrInstruction **instructions, size_t instruction_count) 10240 { 10241 Error err; 10242 assert(instruction_count >= 1); 10243 IrInstruction *prev_inst; 10244 size_t i = 0; 10245 for (;;) { 10246 prev_inst = instructions[i]; 10247 if (type_is_invalid(prev_inst->value->type)) { 10248 return ira->codegen->builtin_types.entry_invalid; 10249 } 10250 if (prev_inst->value->type->id == ZigTypeIdUnreachable) { 10251 i += 1; 10252 if (i == instruction_count) { 10253 return prev_inst->value->type; 10254 } 10255 continue; 10256 } 10257 break; 10258 } 10259 ErrorTableEntry **errors = nullptr; 10260 size_t errors_count = 0; 10261 ZigType *err_set_type = nullptr; 10262 if (prev_inst->value->type->id == ZigTypeIdErrorSet) { 10263 if (!resolve_inferred_error_set(ira->codegen, prev_inst->value->type, prev_inst->source_node)) { 10264 return ira->codegen->builtin_types.entry_invalid; 10265 } 10266 if (type_is_global_error_set(prev_inst->value->type)) { 10267 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 10268 } else { 10269 err_set_type = prev_inst->value->type; 10270 update_errors_helper(ira->codegen, &errors, &errors_count); 10271 10272 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 10273 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 10274 assert(errors[error_entry->value] == nullptr); 10275 errors[error_entry->value] = error_entry; 10276 } 10277 } 10278 } 10279 10280 bool any_are_null = (prev_inst->value->type->id == ZigTypeIdNull); 10281 bool convert_to_const_slice = false; 10282 for (; i < instruction_count; i += 1) { 10283 IrInstruction *cur_inst = instructions[i]; 10284 ZigType *cur_type = cur_inst->value->type; 10285 ZigType *prev_type = prev_inst->value->type; 10286 10287 if (type_is_invalid(cur_type)) { 10288 return cur_type; 10289 } 10290 10291 if (prev_type == cur_type) { 10292 continue; 10293 } 10294 10295 if (prev_type->id == ZigTypeIdUnreachable) { 10296 prev_inst = cur_inst; 10297 continue; 10298 } 10299 10300 if (cur_type->id == ZigTypeIdUnreachable) { 10301 continue; 10302 } 10303 10304 if (prev_type->id == ZigTypeIdErrorSet) { 10305 ir_assert(err_set_type != nullptr, prev_inst); 10306 if (cur_type->id == ZigTypeIdErrorSet) { 10307 if (type_is_global_error_set(err_set_type)) { 10308 continue; 10309 } 10310 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { 10311 return ira->codegen->builtin_types.entry_invalid; 10312 } 10313 if (type_is_global_error_set(cur_type)) { 10314 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 10315 prev_inst = cur_inst; 10316 continue; 10317 } 10318 10319 // number of declared errors might have increased now 10320 update_errors_helper(ira->codegen, &errors, &errors_count); 10321 10322 // if err_set_type is a superset of cur_type, keep err_set_type. 10323 // if cur_type is a superset of err_set_type, switch err_set_type to cur_type 10324 bool prev_is_superset = true; 10325 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 10326 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 10327 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 10328 if (error_entry == nullptr) { 10329 prev_is_superset = false; 10330 break; 10331 } 10332 } 10333 if (prev_is_superset) { 10334 continue; 10335 } 10336 10337 // unset everything in errors 10338 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 10339 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 10340 errors[error_entry->value] = nullptr; 10341 } 10342 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 10343 assert(errors[i] == nullptr); 10344 } 10345 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 10346 ErrorTableEntry *error_entry = cur_type->data.error_set.errors[i]; 10347 assert(errors[error_entry->value] == nullptr); 10348 errors[error_entry->value] = error_entry; 10349 } 10350 bool cur_is_superset = true; 10351 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 10352 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 10353 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 10354 if (error_entry == nullptr) { 10355 cur_is_superset = false; 10356 break; 10357 } 10358 } 10359 if (cur_is_superset) { 10360 err_set_type = cur_type; 10361 prev_inst = cur_inst; 10362 assert(errors != nullptr); 10363 continue; 10364 } 10365 10366 // neither of them are supersets. so we invent a new error set type that is a union of both of them 10367 err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type, nullptr); 10368 assert(errors != nullptr); 10369 continue; 10370 } else if (cur_type->id == ZigTypeIdErrorUnion) { 10371 if (type_is_global_error_set(err_set_type)) { 10372 prev_inst = cur_inst; 10373 continue; 10374 } 10375 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 10376 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 10377 return ira->codegen->builtin_types.entry_invalid; 10378 } 10379 if (type_is_global_error_set(cur_err_set_type)) { 10380 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 10381 prev_inst = cur_inst; 10382 continue; 10383 } 10384 10385 update_errors_helper(ira->codegen, &errors, &errors_count); 10386 10387 // test if err_set_type is a subset of cur_type's error set 10388 // unset everything in errors 10389 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 10390 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 10391 errors[error_entry->value] = nullptr; 10392 } 10393 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 10394 assert(errors[i] == nullptr); 10395 } 10396 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 10397 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 10398 assert(errors[error_entry->value] == nullptr); 10399 errors[error_entry->value] = error_entry; 10400 } 10401 bool cur_is_superset = true; 10402 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 10403 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 10404 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 10405 if (error_entry == nullptr) { 10406 cur_is_superset = false; 10407 break; 10408 } 10409 } 10410 if (cur_is_superset) { 10411 err_set_type = cur_err_set_type; 10412 prev_inst = cur_inst; 10413 assert(errors != nullptr); 10414 continue; 10415 } 10416 10417 // not a subset. invent new error set type, union of both of them 10418 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type, nullptr); 10419 prev_inst = cur_inst; 10420 assert(errors != nullptr); 10421 continue; 10422 } else { 10423 prev_inst = cur_inst; 10424 continue; 10425 } 10426 } 10427 10428 if (cur_type->id == ZigTypeIdErrorSet) { 10429 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { 10430 return ira->codegen->builtin_types.entry_invalid; 10431 } 10432 if (type_is_global_error_set(cur_type)) { 10433 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 10434 continue; 10435 } 10436 if (err_set_type != nullptr && type_is_global_error_set(err_set_type)) { 10437 continue; 10438 } 10439 10440 update_errors_helper(ira->codegen, &errors, &errors_count); 10441 10442 if (err_set_type == nullptr) { 10443 if (prev_type->id == ZigTypeIdErrorUnion) { 10444 err_set_type = prev_type->data.error_union.err_set_type; 10445 } else { 10446 err_set_type = cur_type; 10447 } 10448 10449 if (!resolve_inferred_error_set(ira->codegen, err_set_type, cur_inst->source_node)) { 10450 return ira->codegen->builtin_types.entry_invalid; 10451 } 10452 10453 if (type_is_global_error_set(err_set_type)) { 10454 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 10455 continue; 10456 } 10457 10458 update_errors_helper(ira->codegen, &errors, &errors_count); 10459 10460 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 10461 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 10462 assert(errors[error_entry->value] == nullptr); 10463 errors[error_entry->value] = error_entry; 10464 } 10465 if (err_set_type == cur_type) { 10466 continue; 10467 } 10468 } 10469 // check if the cur type error set is a subset 10470 bool prev_is_superset = true; 10471 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 10472 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 10473 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 10474 if (error_entry == nullptr) { 10475 prev_is_superset = false; 10476 break; 10477 } 10478 } 10479 if (prev_is_superset) { 10480 continue; 10481 } 10482 // not a subset. invent new error set type, union of both of them 10483 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type, nullptr); 10484 assert(errors != nullptr); 10485 continue; 10486 } 10487 10488 if (prev_type->id == ZigTypeIdErrorUnion && cur_type->id == ZigTypeIdErrorUnion) { 10489 ZigType *prev_payload_type = prev_type->data.error_union.payload_type; 10490 ZigType *cur_payload_type = cur_type->data.error_union.payload_type; 10491 10492 bool const_cast_prev = types_match_const_cast_only(ira, prev_payload_type, cur_payload_type, 10493 source_node, false).id == ConstCastResultIdOk; 10494 bool const_cast_cur = types_match_const_cast_only(ira, cur_payload_type, prev_payload_type, 10495 source_node, false).id == ConstCastResultIdOk; 10496 10497 if (const_cast_prev || const_cast_cur) { 10498 if (const_cast_cur) { 10499 prev_inst = cur_inst; 10500 } 10501 10502 ZigType *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type; 10503 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 10504 if (prev_err_set_type == cur_err_set_type) 10505 continue; 10506 10507 if (!resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) { 10508 return ira->codegen->builtin_types.entry_invalid; 10509 } 10510 10511 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 10512 return ira->codegen->builtin_types.entry_invalid; 10513 } 10514 10515 if (type_is_global_error_set(prev_err_set_type) || type_is_global_error_set(cur_err_set_type)) { 10516 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 10517 continue; 10518 } 10519 10520 update_errors_helper(ira->codegen, &errors, &errors_count); 10521 10522 if (err_set_type == nullptr) { 10523 err_set_type = prev_err_set_type; 10524 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 10525 ErrorTableEntry *error_entry = prev_err_set_type->data.error_set.errors[i]; 10526 assert(errors[error_entry->value] == nullptr); 10527 errors[error_entry->value] = error_entry; 10528 } 10529 } 10530 bool prev_is_superset = true; 10531 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 10532 ErrorTableEntry *contained_error_entry = cur_err_set_type->data.error_set.errors[i]; 10533 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 10534 if (error_entry == nullptr) { 10535 prev_is_superset = false; 10536 break; 10537 } 10538 } 10539 if (prev_is_superset) { 10540 continue; 10541 } 10542 // unset all the errors 10543 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 10544 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 10545 errors[error_entry->value] = nullptr; 10546 } 10547 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 10548 assert(errors[i] == nullptr); 10549 } 10550 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 10551 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 10552 assert(errors[error_entry->value] == nullptr); 10553 errors[error_entry->value] = error_entry; 10554 } 10555 bool cur_is_superset = true; 10556 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 10557 ErrorTableEntry *contained_error_entry = prev_err_set_type->data.error_set.errors[i]; 10558 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 10559 if (error_entry == nullptr) { 10560 cur_is_superset = false; 10561 break; 10562 } 10563 } 10564 if (cur_is_superset) { 10565 err_set_type = cur_err_set_type; 10566 continue; 10567 } 10568 10569 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, prev_err_set_type, nullptr); 10570 continue; 10571 } 10572 } 10573 10574 if (prev_type->id == ZigTypeIdNull) { 10575 prev_inst = cur_inst; 10576 any_are_null = true; 10577 continue; 10578 } 10579 10580 if (cur_type->id == ZigTypeIdNull) { 10581 any_are_null = true; 10582 continue; 10583 } 10584 10585 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdEnumLiteral) { 10586 TypeEnumField *field = find_enum_type_field(prev_type, cur_inst->value->data.x_enum_literal); 10587 if (field != nullptr) { 10588 continue; 10589 } 10590 } 10591 if (is_tagged_union(prev_type) && cur_type->id == ZigTypeIdEnumLiteral) { 10592 TypeUnionField *field = find_union_type_field(prev_type, cur_inst->value->data.x_enum_literal); 10593 if (field != nullptr) { 10594 continue; 10595 } 10596 } 10597 10598 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdEnumLiteral) { 10599 TypeEnumField *field = find_enum_type_field(cur_type, prev_inst->value->data.x_enum_literal); 10600 if (field != nullptr) { 10601 prev_inst = cur_inst; 10602 continue; 10603 } 10604 } 10605 10606 if (is_tagged_union(cur_type) && prev_type->id == ZigTypeIdEnumLiteral) { 10607 TypeUnionField *field = find_union_type_field(cur_type, prev_inst->value->data.x_enum_literal); 10608 if (field != nullptr) { 10609 prev_inst = cur_inst; 10610 continue; 10611 } 10612 } 10613 10614 if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenC && 10615 (cur_type->id == ZigTypeIdComptimeInt || cur_type->id == ZigTypeIdInt)) 10616 { 10617 continue; 10618 } 10619 10620 if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenC && 10621 (prev_type->id == ZigTypeIdComptimeInt || prev_type->id == ZigTypeIdInt)) 10622 { 10623 prev_inst = cur_inst; 10624 continue; 10625 } 10626 10627 if (prev_type->id == ZigTypeIdPointer && cur_type->id == ZigTypeIdPointer) { 10628 if (prev_type->data.pointer.ptr_len == PtrLenC && 10629 types_match_const_cast_only(ira, prev_type->data.pointer.child_type, 10630 cur_type->data.pointer.child_type, source_node, 10631 !prev_type->data.pointer.is_const).id == ConstCastResultIdOk) 10632 { 10633 continue; 10634 } 10635 if (cur_type->data.pointer.ptr_len == PtrLenC && 10636 types_match_const_cast_only(ira, cur_type->data.pointer.child_type, 10637 prev_type->data.pointer.child_type, source_node, 10638 !cur_type->data.pointer.is_const).id == ConstCastResultIdOk) 10639 { 10640 prev_inst = cur_inst; 10641 continue; 10642 } 10643 } 10644 10645 if (types_match_const_cast_only(ira, prev_type, cur_type, source_node, false).id == ConstCastResultIdOk) { 10646 continue; 10647 } 10648 10649 if (types_match_const_cast_only(ira, cur_type, prev_type, source_node, false).id == ConstCastResultIdOk) { 10650 prev_inst = cur_inst; 10651 continue; 10652 } 10653 10654 if (prev_type->id == ZigTypeIdInt && 10655 cur_type->id == ZigTypeIdInt && 10656 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed) 10657 { 10658 if (cur_type->data.integral.bit_count > prev_type->data.integral.bit_count) { 10659 prev_inst = cur_inst; 10660 } 10661 continue; 10662 } 10663 10664 if (prev_type->id == ZigTypeIdFloat && cur_type->id == ZigTypeIdFloat) { 10665 if (cur_type->data.floating.bit_count > prev_type->data.floating.bit_count) { 10666 prev_inst = cur_inst; 10667 } 10668 continue; 10669 } 10670 10671 if (prev_type->id == ZigTypeIdErrorUnion && 10672 types_match_const_cast_only(ira, prev_type->data.error_union.payload_type, cur_type, 10673 source_node, false).id == ConstCastResultIdOk) 10674 { 10675 continue; 10676 } 10677 10678 if (cur_type->id == ZigTypeIdErrorUnion && 10679 types_match_const_cast_only(ira, cur_type->data.error_union.payload_type, prev_type, 10680 source_node, false).id == ConstCastResultIdOk) 10681 { 10682 if (err_set_type != nullptr) { 10683 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 10684 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 10685 return ira->codegen->builtin_types.entry_invalid; 10686 } 10687 if (type_is_global_error_set(cur_err_set_type) || type_is_global_error_set(err_set_type)) { 10688 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 10689 prev_inst = cur_inst; 10690 continue; 10691 } 10692 10693 update_errors_helper(ira->codegen, &errors, &errors_count); 10694 10695 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_err_set_type, nullptr); 10696 } 10697 prev_inst = cur_inst; 10698 continue; 10699 } 10700 10701 if (prev_type->id == ZigTypeIdOptional && 10702 types_match_const_cast_only(ira, prev_type->data.maybe.child_type, cur_type, 10703 source_node, false).id == ConstCastResultIdOk) 10704 { 10705 continue; 10706 } 10707 10708 if (cur_type->id == ZigTypeIdOptional && 10709 types_match_const_cast_only(ira, cur_type->data.maybe.child_type, prev_type, 10710 source_node, false).id == ConstCastResultIdOk) 10711 { 10712 prev_inst = cur_inst; 10713 continue; 10714 } 10715 10716 if (prev_type->id == ZigTypeIdOptional && 10717 types_match_const_cast_only(ira, cur_type, prev_type->data.maybe.child_type, 10718 source_node, false).id == ConstCastResultIdOk) 10719 { 10720 prev_inst = cur_inst; 10721 any_are_null = true; 10722 continue; 10723 } 10724 10725 if (cur_type->id == ZigTypeIdOptional && 10726 types_match_const_cast_only(ira, prev_type, cur_type->data.maybe.child_type, 10727 source_node, false).id == ConstCastResultIdOk) 10728 { 10729 any_are_null = true; 10730 continue; 10731 } 10732 10733 if (cur_type->id == ZigTypeIdUndefined) { 10734 continue; 10735 } 10736 10737 if (prev_type->id == ZigTypeIdUndefined) { 10738 prev_inst = cur_inst; 10739 continue; 10740 } 10741 10742 if (prev_type->id == ZigTypeIdComptimeInt || 10743 prev_type->id == ZigTypeIdComptimeFloat) 10744 { 10745 if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) { 10746 prev_inst = cur_inst; 10747 continue; 10748 } else { 10749 return ira->codegen->builtin_types.entry_invalid; 10750 } 10751 } 10752 10753 if (cur_type->id == ZigTypeIdComptimeInt || 10754 cur_type->id == ZigTypeIdComptimeFloat) 10755 { 10756 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) { 10757 continue; 10758 } else { 10759 return ira->codegen->builtin_types.entry_invalid; 10760 } 10761 } 10762 10763 // *[N]T to []T 10764 // *[N]T to E![]T 10765 if (cur_type->id == ZigTypeIdPointer && 10766 cur_type->data.pointer.ptr_len == PtrLenSingle && 10767 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 10768 ((prev_type->id == ZigTypeIdErrorUnion && is_slice(prev_type->data.error_union.payload_type)) || 10769 is_slice(prev_type))) 10770 { 10771 ZigType *array_type = cur_type->data.pointer.child_type; 10772 ZigType *slice_type = (prev_type->id == ZigTypeIdErrorUnion) ? 10773 prev_type->data.error_union.payload_type : prev_type; 10774 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 10775 if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 || 10776 !cur_type->data.pointer.is_const) && 10777 types_match_const_cast_only(ira, 10778 slice_ptr_type->data.pointer.child_type, 10779 array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 10780 { 10781 convert_to_const_slice = false; 10782 continue; 10783 } 10784 } 10785 10786 // *[N]T to []T 10787 // *[N]T to E![]T 10788 if (prev_type->id == ZigTypeIdPointer && 10789 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 10790 prev_type->data.pointer.ptr_len == PtrLenSingle && 10791 ((cur_type->id == ZigTypeIdErrorUnion && is_slice(cur_type->data.error_union.payload_type)) || 10792 is_slice(cur_type))) 10793 { 10794 ZigType *array_type = prev_type->data.pointer.child_type; 10795 ZigType *slice_type = (cur_type->id == ZigTypeIdErrorUnion) ? 10796 cur_type->data.error_union.payload_type : cur_type; 10797 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 10798 if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 || 10799 !prev_type->data.pointer.is_const) && 10800 types_match_const_cast_only(ira, 10801 slice_ptr_type->data.pointer.child_type, 10802 array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 10803 { 10804 prev_inst = cur_inst; 10805 convert_to_const_slice = false; 10806 continue; 10807 } 10808 } 10809 10810 // *[N]T and *[M]T 10811 if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && 10812 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 10813 prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle && 10814 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 10815 (cur_type->data.pointer.is_const || !prev_type->data.pointer.is_const || 10816 prev_type->data.pointer.child_type->data.array.len == 0) && 10817 ( 10818 prev_type->data.pointer.child_type->data.array.sentinel == nullptr || 10819 (cur_type->data.pointer.child_type->data.array.sentinel != nullptr && 10820 const_values_equal(ira->codegen, prev_type->data.pointer.child_type->data.array.sentinel, 10821 cur_type->data.pointer.child_type->data.array.sentinel)) 10822 ) && 10823 types_match_const_cast_only(ira, 10824 cur_type->data.pointer.child_type->data.array.child_type, 10825 prev_type->data.pointer.child_type->data.array.child_type, 10826 source_node, !cur_type->data.pointer.is_const).id == ConstCastResultIdOk) 10827 { 10828 prev_inst = cur_inst; 10829 convert_to_const_slice = true; 10830 continue; 10831 } 10832 if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle && 10833 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 10834 cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && 10835 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 10836 (prev_type->data.pointer.is_const || !cur_type->data.pointer.is_const || 10837 cur_type->data.pointer.child_type->data.array.len == 0) && 10838 ( 10839 cur_type->data.pointer.child_type->data.array.sentinel == nullptr || 10840 (prev_type->data.pointer.child_type->data.array.sentinel != nullptr && 10841 const_values_equal(ira->codegen, cur_type->data.pointer.child_type->data.array.sentinel, 10842 prev_type->data.pointer.child_type->data.array.sentinel)) 10843 ) && 10844 types_match_const_cast_only(ira, 10845 prev_type->data.pointer.child_type->data.array.child_type, 10846 cur_type->data.pointer.child_type->data.array.child_type, 10847 source_node, !prev_type->data.pointer.is_const).id == ConstCastResultIdOk) 10848 { 10849 convert_to_const_slice = true; 10850 continue; 10851 } 10852 10853 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdUnion && 10854 (cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 10855 { 10856 if ((err = type_resolve(ira->codegen, cur_type, ResolveStatusZeroBitsKnown))) 10857 return ira->codegen->builtin_types.entry_invalid; 10858 if (cur_type->data.unionation.tag_type == prev_type) { 10859 continue; 10860 } 10861 } 10862 10863 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdUnion && 10864 (prev_type->data.unionation.decl_node->data.container_decl.auto_enum || prev_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 10865 { 10866 if ((err = type_resolve(ira->codegen, prev_type, ResolveStatusZeroBitsKnown))) 10867 return ira->codegen->builtin_types.entry_invalid; 10868 if (prev_type->data.unionation.tag_type == cur_type) { 10869 prev_inst = cur_inst; 10870 continue; 10871 } 10872 } 10873 10874 ErrorMsg *msg = ir_add_error_node(ira, source_node, 10875 buf_sprintf("incompatible types: '%s' and '%s'", 10876 buf_ptr(&prev_type->name), buf_ptr(&cur_type->name))); 10877 add_error_note(ira->codegen, msg, prev_inst->source_node, 10878 buf_sprintf("type '%s' here", buf_ptr(&prev_type->name))); 10879 add_error_note(ira->codegen, msg, cur_inst->source_node, 10880 buf_sprintf("type '%s' here", buf_ptr(&cur_type->name))); 10881 10882 return ira->codegen->builtin_types.entry_invalid; 10883 } 10884 10885 free(errors); 10886 10887 if (convert_to_const_slice) { 10888 if (prev_inst->value->type->id == ZigTypeIdPointer) { 10889 ZigType *array_type = prev_inst->value->type->data.pointer.child_type; 10890 src_assert(array_type->id == ZigTypeIdArray, source_node); 10891 ZigType *ptr_type = get_pointer_to_type_extra2( 10892 ira->codegen, array_type->data.array.child_type, 10893 prev_inst->value->type->data.pointer.is_const, false, 10894 PtrLenUnknown, 10895 0, 0, 0, false, 10896 VECTOR_INDEX_NONE, nullptr, array_type->data.array.sentinel); 10897 ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); 10898 if (err_set_type != nullptr) { 10899 return get_error_union_type(ira->codegen, err_set_type, slice_type); 10900 } else { 10901 return slice_type; 10902 } 10903 } else { 10904 zig_unreachable(); 10905 } 10906 } else if (err_set_type != nullptr) { 10907 if (prev_inst->value->type->id == ZigTypeIdErrorSet) { 10908 return err_set_type; 10909 } else if (prev_inst->value->type->id == ZigTypeIdErrorUnion) { 10910 ZigType *payload_type = prev_inst->value->type->data.error_union.payload_type; 10911 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 10912 return ira->codegen->builtin_types.entry_invalid; 10913 return get_error_union_type(ira->codegen, err_set_type, payload_type); 10914 } else if (expected_type != nullptr && expected_type->id == ZigTypeIdErrorUnion) { 10915 ZigType *payload_type = expected_type->data.error_union.payload_type; 10916 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 10917 return ira->codegen->builtin_types.entry_invalid; 10918 return get_error_union_type(ira->codegen, err_set_type, payload_type); 10919 } else { 10920 if (prev_inst->value->type->id == ZigTypeIdComptimeInt || 10921 prev_inst->value->type->id == ZigTypeIdComptimeFloat) 10922 { 10923 ir_add_error_node(ira, source_node, 10924 buf_sprintf("unable to make error union out of number literal")); 10925 return ira->codegen->builtin_types.entry_invalid; 10926 } else if (prev_inst->value->type->id == ZigTypeIdNull) { 10927 ir_add_error_node(ira, source_node, 10928 buf_sprintf("unable to make error union out of null literal")); 10929 return ira->codegen->builtin_types.entry_invalid; 10930 } else { 10931 if ((err = type_resolve(ira->codegen, prev_inst->value->type, ResolveStatusSizeKnown))) 10932 return ira->codegen->builtin_types.entry_invalid; 10933 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value->type); 10934 } 10935 } 10936 } else if (any_are_null && prev_inst->value->type->id != ZigTypeIdNull) { 10937 if (prev_inst->value->type->id == ZigTypeIdComptimeInt || 10938 prev_inst->value->type->id == ZigTypeIdComptimeFloat) 10939 { 10940 ir_add_error_node(ira, source_node, 10941 buf_sprintf("unable to make maybe out of number literal")); 10942 return ira->codegen->builtin_types.entry_invalid; 10943 } else if (prev_inst->value->type->id == ZigTypeIdOptional) { 10944 return prev_inst->value->type; 10945 } else { 10946 if ((err = type_resolve(ira->codegen, prev_inst->value->type, ResolveStatusSizeKnown))) 10947 return ira->codegen->builtin_types.entry_invalid; 10948 return get_optional_type(ira->codegen, prev_inst->value->type); 10949 } 10950 } else { 10951 return prev_inst->value->type; 10952 } 10953 } 10954 10955 static void copy_const_val(ZigValue *dest, ZigValue *src, bool same_global_refs) { 10956 ConstGlobalRefs *global_refs = dest->global_refs; 10957 memcpy(dest, src, sizeof(ZigValue)); 10958 if (!same_global_refs) { 10959 dest->global_refs = global_refs; 10960 if (src->special != ConstValSpecialStatic) 10961 return; 10962 if (dest->type->id == ZigTypeIdStruct) { 10963 dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count); 10964 for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { 10965 copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i], false); 10966 } 10967 } 10968 } 10969 } 10970 10971 static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_instr, 10972 CastOp cast_op, 10973 ZigValue *other_val, ZigType *other_type, 10974 ZigValue *const_val, ZigType *new_type) 10975 { 10976 const_val->special = other_val->special; 10977 10978 assert(other_val != const_val); 10979 switch (cast_op) { 10980 case CastOpNoCast: 10981 zig_unreachable(); 10982 case CastOpErrSet: 10983 case CastOpBitCast: 10984 zig_panic("TODO"); 10985 case CastOpNoop: 10986 { 10987 bool same_global_refs = other_val->special == ConstValSpecialStatic; 10988 copy_const_val(const_val, other_val, same_global_refs); 10989 const_val->type = new_type; 10990 break; 10991 } 10992 case CastOpNumLitToConcrete: 10993 if (other_val->type->id == ZigTypeIdComptimeFloat) { 10994 assert(new_type->id == ZigTypeIdFloat); 10995 switch (new_type->data.floating.bit_count) { 10996 case 16: 10997 const_val->data.x_f16 = bigfloat_to_f16(&other_val->data.x_bigfloat); 10998 break; 10999 case 32: 11000 const_val->data.x_f32 = bigfloat_to_f32(&other_val->data.x_bigfloat); 11001 break; 11002 case 64: 11003 const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat); 11004 break; 11005 case 80: 11006 zig_panic("TODO"); 11007 case 128: 11008 const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat); 11009 break; 11010 default: 11011 zig_unreachable(); 11012 } 11013 } else if (other_val->type->id == ZigTypeIdComptimeInt) { 11014 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint); 11015 } else { 11016 zig_unreachable(); 11017 } 11018 const_val->type = new_type; 11019 break; 11020 case CastOpIntToFloat: 11021 { 11022 assert(new_type->id == ZigTypeIdFloat); 11023 11024 BigFloat bigfloat; 11025 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint); 11026 switch (new_type->data.floating.bit_count) { 11027 case 16: 11028 const_val->data.x_f16 = bigfloat_to_f16(&bigfloat); 11029 break; 11030 case 32: 11031 const_val->data.x_f32 = bigfloat_to_f32(&bigfloat); 11032 break; 11033 case 64: 11034 const_val->data.x_f64 = bigfloat_to_f64(&bigfloat); 11035 break; 11036 case 80: 11037 zig_panic("TODO"); 11038 case 128: 11039 const_val->data.x_f128 = bigfloat_to_f128(&bigfloat); 11040 break; 11041 default: 11042 zig_unreachable(); 11043 } 11044 const_val->special = ConstValSpecialStatic; 11045 break; 11046 } 11047 case CastOpFloatToInt: 11048 float_init_bigint(&const_val->data.x_bigint, other_val); 11049 if (new_type->id == ZigTypeIdInt) { 11050 if (!bigint_fits_in_bits(&const_val->data.x_bigint, new_type->data.integral.bit_count, 11051 new_type->data.integral.is_signed)) 11052 { 11053 Buf *int_buf = buf_alloc(); 11054 bigint_append_buf(int_buf, &const_val->data.x_bigint, 10); 11055 11056 ir_add_error(ira, source_instr, 11057 buf_sprintf("integer value '%s' cannot be stored in type '%s'", 11058 buf_ptr(int_buf), buf_ptr(&new_type->name))); 11059 return false; 11060 } 11061 } 11062 11063 const_val->special = ConstValSpecialStatic; 11064 break; 11065 case CastOpBoolToInt: 11066 bigint_init_unsigned(&const_val->data.x_bigint, other_val->data.x_bool ? 1 : 0); 11067 const_val->special = ConstValSpecialStatic; 11068 break; 11069 } 11070 return true; 11071 } 11072 11073 static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, ZigType *ty) { 11074 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 11075 old_instruction->scope, old_instruction->source_node); 11076 IrInstruction *new_instruction = &const_instruction->base; 11077 new_instruction->value->type = ty; 11078 new_instruction->value->special = ConstValSpecialStatic; 11079 return new_instruction; 11080 } 11081 11082 static IrInstruction *ir_const_noval(IrAnalyze *ira, IrInstruction *old_instruction) { 11083 IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(&ira->new_irb, 11084 old_instruction->scope, old_instruction->source_node); 11085 return &const_instruction->base; 11086 } 11087 11088 static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 11089 ZigType *wanted_type, CastOp cast_op) 11090 { 11091 if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { 11092 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11093 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, value->value, value->value->type, 11094 result->value, wanted_type)) 11095 { 11096 return ira->codegen->invalid_instruction; 11097 } 11098 return result; 11099 } else { 11100 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op); 11101 result->value->type = wanted_type; 11102 return result; 11103 } 11104 } 11105 11106 static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrInstruction *source_instr, 11107 IrInstruction *value, ZigType *wanted_type) 11108 { 11109 assert(value->value->type->id == ZigTypeIdPointer); 11110 11111 Error err; 11112 11113 if ((err = type_resolve(ira->codegen, value->value->type->data.pointer.child_type, 11114 ResolveStatusAlignmentKnown))) 11115 { 11116 return ira->codegen->invalid_instruction; 11117 } 11118 11119 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value->type)); 11120 11121 if (instr_is_comptime(value)) { 11122 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, value->value, source_instr->source_node); 11123 if (pointee == nullptr) 11124 return ira->codegen->invalid_instruction; 11125 if (pointee->special != ConstValSpecialRuntime) { 11126 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11127 result->value->data.x_ptr.special = ConstPtrSpecialBaseArray; 11128 result->value->data.x_ptr.mut = value->value->data.x_ptr.mut; 11129 result->value->data.x_ptr.data.base_array.array_val = pointee; 11130 result->value->data.x_ptr.data.base_array.elem_index = 0; 11131 return result; 11132 } 11133 } 11134 11135 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 11136 wanted_type, value, CastOpBitCast); 11137 result->value->type = wanted_type; 11138 return result; 11139 } 11140 11141 static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, 11142 IrInstruction *array_ptr, ZigType *wanted_type, ResultLoc *result_loc) 11143 { 11144 Error err; 11145 11146 if ((err = type_resolve(ira->codegen, array_ptr->value->type->data.pointer.child_type, 11147 ResolveStatusAlignmentKnown))) 11148 { 11149 return ira->codegen->invalid_instruction; 11150 } 11151 11152 wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, array_ptr->value->type)); 11153 11154 if (instr_is_comptime(array_ptr)) { 11155 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, array_ptr->value, source_instr->source_node); 11156 if (pointee == nullptr) 11157 return ira->codegen->invalid_instruction; 11158 if (pointee->special != ConstValSpecialRuntime) { 11159 assert(array_ptr->value->type->id == ZigTypeIdPointer); 11160 ZigType *array_type = array_ptr->value->type->data.pointer.child_type; 11161 assert(is_slice(wanted_type)); 11162 bool is_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const; 11163 11164 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11165 init_const_slice(ira->codegen, result->value, pointee, 0, array_type->data.array.len, is_const); 11166 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr->value->data.x_ptr.mut; 11167 result->value->type = wanted_type; 11168 return result; 11169 } 11170 } 11171 11172 if (result_loc == nullptr) result_loc = no_result_loc(); 11173 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, 11174 false, true); 11175 if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { 11176 return result_loc_inst; 11177 } 11178 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, array_ptr, result_loc_inst); 11179 } 11180 11181 static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { 11182 assert(old_bb); 11183 11184 if (old_bb->other) { 11185 if (ref_old_instruction == nullptr || old_bb->other->ref_instruction != ref_old_instruction) { 11186 return old_bb->other; 11187 } 11188 } 11189 11190 IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb); 11191 new_bb->ref_instruction = ref_old_instruction; 11192 11193 return new_bb; 11194 } 11195 11196 static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { 11197 assert(ref_old_instruction != nullptr); 11198 IrBasicBlock *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction); 11199 if (new_bb->must_be_comptime_source_instr) { 11200 ErrorMsg *msg = ir_add_error(ira, ref_old_instruction, 11201 buf_sprintf("control flow attempts to use compile-time variable at runtime")); 11202 add_error_note(ira->codegen, msg, new_bb->must_be_comptime_source_instr->source_node, 11203 buf_sprintf("compile-time variable assigned here")); 11204 return nullptr; 11205 } 11206 return new_bb; 11207 } 11208 11209 static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { 11210 ir_assert(!old_bb->suspended, (old_bb->instruction_list.length != 0) ? old_bb->instruction_list.at(0) : nullptr); 11211 ira->instruction_index = 0; 11212 ira->old_irb.current_basic_block = old_bb; 11213 ira->const_predecessor_bb = const_predecessor_bb; 11214 ira->old_bb_index = old_bb->index; 11215 } 11216 11217 static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, 11218 IrSuspendPosition *suspend_pos) 11219 { 11220 if (ira->codegen->verbose_ir) { 11221 fprintf(stderr, "suspend %s_%zu %s_%zu #%" PRIu32 " (%zu,%zu)\n", 11222 ira->old_irb.current_basic_block->name_hint, 11223 ira->old_irb.current_basic_block->debug_id, 11224 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint, 11225 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id, 11226 ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id, 11227 ira->old_bb_index, ira->instruction_index); 11228 } 11229 suspend_pos->basic_block_index = ira->old_bb_index; 11230 suspend_pos->instruction_index = ira->instruction_index; 11231 11232 ira->old_irb.current_basic_block->suspended = true; 11233 11234 // null next_bb means that the caller plans to call ira_resume before returning 11235 if (next_bb != nullptr) { 11236 ira->old_bb_index = next_bb->index; 11237 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 11238 assert(ira->old_irb.current_basic_block == next_bb); 11239 ira->instruction_index = 0; 11240 ira->const_predecessor_bb = nullptr; 11241 next_bb->other = ir_get_new_bb_runtime(ira, next_bb, old_instruction); 11242 ira->new_irb.current_basic_block = next_bb->other; 11243 } 11244 return ira->codegen->unreach_instruction; 11245 } 11246 11247 static IrInstruction *ira_resume(IrAnalyze *ira) { 11248 IrSuspendPosition pos = ira->resume_stack.pop(); 11249 if (ira->codegen->verbose_ir) { 11250 fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); 11251 } 11252 ira->old_bb_index = pos.basic_block_index; 11253 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 11254 assert(ira->old_irb.current_basic_block->in_resume_stack); 11255 ira->old_irb.current_basic_block->in_resume_stack = false; 11256 ira->old_irb.current_basic_block->suspended = false; 11257 ira->instruction_index = pos.instruction_index; 11258 assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); 11259 if (ira->codegen->verbose_ir) { 11260 fprintf(stderr, "%s_%zu #%" PRIu32 "\n", ira->old_irb.current_basic_block->name_hint, 11261 ira->old_irb.current_basic_block->debug_id, 11262 ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id); 11263 } 11264 ira->const_predecessor_bb = nullptr; 11265 ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other; 11266 assert(ira->new_irb.current_basic_block != nullptr); 11267 return ira->codegen->unreach_instruction; 11268 } 11269 11270 static void ir_start_next_bb(IrAnalyze *ira) { 11271 ira->old_bb_index += 1; 11272 11273 bool need_repeat = true; 11274 for (;;) { 11275 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 11276 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 11277 if (old_bb->other == nullptr && old_bb->suspend_instruction_ref == nullptr) { 11278 ira->old_bb_index += 1; 11279 continue; 11280 } 11281 // if it's already started, or 11282 // if it's a suspended block, 11283 // then skip it 11284 if (old_bb->suspended || 11285 (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0) || 11286 (old_bb->other != nullptr && old_bb->other->already_appended)) 11287 { 11288 ira->old_bb_index += 1; 11289 continue; 11290 } 11291 11292 // if there is a resume_stack, pop one from there rather than moving on. 11293 // the last item of the resume stack will be a basic block that will 11294 // move on to the next one below 11295 if (ira->resume_stack.length != 0) { 11296 ira_resume(ira); 11297 return; 11298 } 11299 11300 if (old_bb->other == nullptr) { 11301 old_bb->other = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref); 11302 } 11303 ira->new_irb.current_basic_block = old_bb->other; 11304 ir_start_bb(ira, old_bb, nullptr); 11305 return; 11306 } 11307 if (!need_repeat) { 11308 if (ira->resume_stack.length != 0) { 11309 ira_resume(ira); 11310 } 11311 return; 11312 } 11313 need_repeat = false; 11314 ira->old_bb_index = 0; 11315 continue; 11316 } 11317 } 11318 11319 static void ir_finish_bb(IrAnalyze *ira) { 11320 if (!ira->new_irb.current_basic_block->already_appended) { 11321 ira->new_irb.current_basic_block->already_appended = true; 11322 if (ira->codegen->verbose_ir) { 11323 fprintf(stderr, "append new bb %s_%zu\n", ira->new_irb.current_basic_block->name_hint, 11324 ira->new_irb.current_basic_block->debug_id); 11325 } 11326 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); 11327 } 11328 ira->instruction_index += 1; 11329 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { 11330 IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 11331 if (!next_instruction->is_gen) { 11332 ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); 11333 break; 11334 } 11335 ira->instruction_index += 1; 11336 } 11337 11338 ir_start_next_bb(ira); 11339 } 11340 11341 static IrInstruction *ir_unreach_error(IrAnalyze *ira) { 11342 ira->old_bb_index = SIZE_MAX; 11343 if (ira->new_irb.exec->first_err_trace_msg == nullptr) { 11344 ira->new_irb.exec->first_err_trace_msg = ira->codegen->trace_err; 11345 } 11346 return ira->codegen->unreach_instruction; 11347 } 11348 11349 static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instruction) { 11350 size_t *bbc = ira->new_irb.exec->backward_branch_count; 11351 size_t *quota = ira->new_irb.exec->backward_branch_quota; 11352 11353 // If we're already over quota, we've already given an error message for this. 11354 if (*bbc > *quota) { 11355 assert(ira->codegen->errors.length > 0); 11356 return false; 11357 } 11358 11359 *bbc += 1; 11360 if (*bbc > *quota) { 11361 ir_add_error(ira, source_instruction, 11362 buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", *quota)); 11363 return false; 11364 } 11365 return true; 11366 } 11367 11368 static IrInstruction *ir_inline_bb(IrAnalyze *ira, IrInstruction *source_instruction, IrBasicBlock *old_bb) { 11369 if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) { 11370 if (!ir_emit_backward_branch(ira, source_instruction)) 11371 return ir_unreach_error(ira); 11372 } 11373 11374 old_bb->other = ira->old_irb.current_basic_block->other; 11375 ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block); 11376 return ira->codegen->unreach_instruction; 11377 } 11378 11379 static IrInstruction *ir_finish_anal(IrAnalyze *ira, IrInstruction *instruction) { 11380 if (instruction->value->type->id == ZigTypeIdUnreachable) 11381 ir_finish_bb(ira); 11382 return instruction; 11383 } 11384 11385 static IrInstruction *ir_const_type(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { 11386 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_type); 11387 result->value->data.x_type = ty; 11388 return result; 11389 } 11390 11391 static IrInstruction *ir_const_bool(IrAnalyze *ira, IrInstruction *source_instruction, bool value) { 11392 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_bool); 11393 result->value->data.x_bool = value; 11394 return result; 11395 } 11396 11397 static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { 11398 IrInstruction *result = ir_const(ira, source_instruction, ty); 11399 result->value->special = ConstValSpecialUndef; 11400 return result; 11401 } 11402 11403 static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) { 11404 IrInstruction *result = ir_const_noval(ira, source_instruction); 11405 result->value = ira->codegen->intern.for_unreachable(); 11406 return result; 11407 } 11408 11409 static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { 11410 IrInstruction *result = ir_const_noval(ira, source_instruction); 11411 result->value = ira->codegen->intern.for_void(); 11412 return result; 11413 } 11414 11415 static IrInstruction *ir_const_unsigned(IrAnalyze *ira, IrInstruction *source_instruction, uint64_t value) { 11416 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_num_lit_int); 11417 bigint_init_unsigned(&result->value->data.x_bigint, value); 11418 return result; 11419 } 11420 11421 static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instruction, 11422 ZigValue *pointee, ZigType *pointee_type, 11423 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align) 11424 { 11425 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type, 11426 ptr_is_const, ptr_is_volatile, PtrLenSingle, ptr_align, 0, 0, false); 11427 IrInstruction *const_instr = ir_const(ira, instruction, ptr_type); 11428 ZigValue *const_val = const_instr->value; 11429 const_val->data.x_ptr.special = ConstPtrSpecialRef; 11430 const_val->data.x_ptr.mut = ptr_mut; 11431 const_val->data.x_ptr.data.ref.pointee = pointee; 11432 return const_instr; 11433 } 11434 11435 static Error ir_resolve_const_val(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, 11436 ZigValue *val, UndefAllowed undef_allowed) 11437 { 11438 Error err; 11439 for (;;) { 11440 switch (val->special) { 11441 case ConstValSpecialStatic: 11442 return ErrorNone; 11443 case ConstValSpecialRuntime: 11444 if (!type_has_bits(val->type)) 11445 return ErrorNone; 11446 11447 exec_add_error_node(codegen, exec, source_node, 11448 buf_sprintf("unable to evaluate constant expression")); 11449 return ErrorSemanticAnalyzeFail; 11450 case ConstValSpecialUndef: 11451 if (undef_allowed == UndefOk || undef_allowed == LazyOk) 11452 return ErrorNone; 11453 11454 exec_add_error_node(codegen, exec, source_node, 11455 buf_sprintf("use of undefined value here causes undefined behavior")); 11456 return ErrorSemanticAnalyzeFail; 11457 case ConstValSpecialLazy: 11458 if (undef_allowed == LazyOk || undef_allowed == LazyOkNoUndef) 11459 return ErrorNone; 11460 11461 if ((err = ir_resolve_lazy(codegen, source_node, val))) 11462 return err; 11463 11464 continue; 11465 } 11466 } 11467 } 11468 11469 static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { 11470 Error err; 11471 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->source_node, 11472 value->value, undef_allowed))) 11473 { 11474 return nullptr; 11475 } 11476 return value->value; 11477 } 11478 11479 ZigValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, 11480 ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota, 11481 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, 11482 IrExecutable *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef_allowed) 11483 { 11484 Error err; 11485 11486 if (expected_type != nullptr && type_is_invalid(expected_type)) 11487 return codegen->invalid_instruction->value; 11488 11489 IrExecutable *ir_executable = allocate<IrExecutable>(1); 11490 ir_executable->source_node = source_node; 11491 ir_executable->parent_exec = parent_exec; 11492 ir_executable->name = exec_name; 11493 ir_executable->is_inline = true; 11494 ir_executable->fn_entry = fn_entry; 11495 ir_executable->c_import_buf = c_import_buf; 11496 ir_executable->begin_scope = scope; 11497 ir_gen(codegen, node, scope, ir_executable); 11498 11499 if (ir_executable->first_err_trace_msg != nullptr) { 11500 codegen->trace_err = ir_executable->first_err_trace_msg; 11501 return codegen->invalid_instruction->value; 11502 } 11503 11504 if (codegen->verbose_ir) { 11505 fprintf(stderr, "\nSource: "); 11506 ast_render(stderr, node, 4); 11507 fprintf(stderr, "\n{ // (IR)\n"); 11508 ir_print(codegen, stderr, ir_executable, 2, IrPassSrc); 11509 fprintf(stderr, "}\n"); 11510 } 11511 IrExecutable *analyzed_executable = allocate<IrExecutable>(1); 11512 analyzed_executable->source_node = source_node; 11513 analyzed_executable->parent_exec = parent_exec; 11514 analyzed_executable->source_exec = ir_executable; 11515 analyzed_executable->name = exec_name; 11516 analyzed_executable->is_inline = true; 11517 analyzed_executable->fn_entry = fn_entry; 11518 analyzed_executable->c_import_buf = c_import_buf; 11519 analyzed_executable->backward_branch_count = backward_branch_count; 11520 analyzed_executable->backward_branch_quota = backward_branch_quota; 11521 analyzed_executable->begin_scope = scope; 11522 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, expected_type_source_node); 11523 if (type_is_invalid(result_type)) { 11524 return codegen->invalid_instruction->value; 11525 } 11526 11527 if (codegen->verbose_ir) { 11528 fprintf(stderr, "{ // (analyzed)\n"); 11529 ir_print(codegen, stderr, analyzed_executable, 2, IrPassGen); 11530 fprintf(stderr, "}\n"); 11531 } 11532 11533 ZigValue *result = ir_exec_const_result(codegen, analyzed_executable); 11534 if (type_is_invalid(result->type)) 11535 return codegen->invalid_instruction->value; 11536 11537 if ((err = ir_resolve_const_val(codegen, analyzed_executable, node, result, undef_allowed))) 11538 return codegen->invalid_instruction->value; 11539 11540 return result; 11541 } 11542 11543 static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_value) { 11544 if (type_is_invalid(err_value->value->type)) 11545 return nullptr; 11546 11547 if (err_value->value->type->id != ZigTypeIdErrorSet) { 11548 ir_add_error(ira, err_value, 11549 buf_sprintf("expected error, found '%s'", buf_ptr(&err_value->value->type->name))); 11550 return nullptr; 11551 } 11552 11553 ZigValue *const_val = ir_resolve_const(ira, err_value, UndefBad); 11554 if (!const_val) 11555 return nullptr; 11556 11557 assert(const_val->data.x_err_set != nullptr); 11558 return const_val->data.x_err_set; 11559 } 11560 11561 static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, 11562 ZigValue *val) 11563 { 11564 Error err; 11565 if ((err = ir_resolve_const_val(codegen, exec, source_node, val, UndefBad))) 11566 return codegen->builtin_types.entry_invalid; 11567 11568 assert(val->data.x_type != nullptr); 11569 return val->data.x_type; 11570 } 11571 11572 static ZigValue *ir_resolve_type_lazy(IrAnalyze *ira, IrInstruction *type_value) { 11573 if (type_is_invalid(type_value->value->type)) 11574 return nullptr; 11575 11576 if (type_value->value->type->id != ZigTypeIdMetaType) { 11577 ir_add_error(ira, type_value, 11578 buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value->type->name))); 11579 return nullptr; 11580 } 11581 11582 Error err; 11583 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, type_value->source_node, 11584 type_value->value, LazyOk))) 11585 { 11586 return nullptr; 11587 } 11588 11589 return type_value->value; 11590 } 11591 11592 static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { 11593 ZigValue *val = ir_resolve_type_lazy(ira, type_value); 11594 if (val == nullptr) 11595 return ira->codegen->builtin_types.entry_invalid; 11596 11597 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, val); 11598 } 11599 11600 static Error ir_validate_vector_elem_type(IrAnalyze *ira, IrInstruction *source_instr, ZigType *elem_type) { 11601 if (!is_valid_vector_elem_type(elem_type)) { 11602 ir_add_error(ira, source_instr, 11603 buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", 11604 buf_ptr(&elem_type->name))); 11605 return ErrorSemanticAnalyzeFail; 11606 } 11607 return ErrorNone; 11608 } 11609 11610 static ZigType *ir_resolve_vector_elem_type(IrAnalyze *ira, IrInstruction *elem_type_value) { 11611 Error err; 11612 ZigType *elem_type = ir_resolve_type(ira, elem_type_value); 11613 if (type_is_invalid(elem_type)) 11614 return ira->codegen->builtin_types.entry_invalid; 11615 if ((err = ir_validate_vector_elem_type(ira, elem_type_value, elem_type))) 11616 return ira->codegen->builtin_types.entry_invalid; 11617 return elem_type; 11618 } 11619 11620 static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) { 11621 ZigType *ty = ir_resolve_type(ira, type_value); 11622 if (type_is_invalid(ty)) 11623 return ira->codegen->builtin_types.entry_invalid; 11624 11625 if (ty->id != ZigTypeIdInt) { 11626 ErrorMsg *msg = ir_add_error(ira, type_value, 11627 buf_sprintf("expected integer type, found '%s'", buf_ptr(&ty->name))); 11628 if (ty->id == ZigTypeIdVector && 11629 ty->data.vector.elem_type->id == ZigTypeIdInt) 11630 { 11631 add_error_note(ira->codegen, msg, type_value->source_node, 11632 buf_sprintf("represent vectors with their element types, i.e. '%s'", 11633 buf_ptr(&ty->data.vector.elem_type->name))); 11634 } 11635 return ira->codegen->builtin_types.entry_invalid; 11636 } 11637 11638 return ty; 11639 } 11640 11641 static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInstruction *op_source, IrInstruction *type_value) { 11642 if (type_is_invalid(type_value->value->type)) 11643 return ira->codegen->builtin_types.entry_invalid; 11644 11645 if (type_value->value->type->id != ZigTypeIdMetaType) { 11646 ErrorMsg *msg = ir_add_error(ira, type_value, 11647 buf_sprintf("expected error set type, found '%s'", buf_ptr(&type_value->value->type->name))); 11648 add_error_note(ira->codegen, msg, op_source->source_node, 11649 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 11650 return ira->codegen->builtin_types.entry_invalid; 11651 } 11652 11653 ZigValue *const_val = ir_resolve_const(ira, type_value, UndefBad); 11654 if (!const_val) 11655 return ira->codegen->builtin_types.entry_invalid; 11656 11657 assert(const_val->data.x_type != nullptr); 11658 ZigType *result_type = const_val->data.x_type; 11659 if (result_type->id != ZigTypeIdErrorSet) { 11660 ErrorMsg *msg = ir_add_error(ira, type_value, 11661 buf_sprintf("expected error set type, found type '%s'", buf_ptr(&result_type->name))); 11662 add_error_note(ira->codegen, msg, op_source->source_node, 11663 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 11664 return ira->codegen->builtin_types.entry_invalid; 11665 } 11666 return result_type; 11667 } 11668 11669 static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { 11670 if (fn_value == ira->codegen->invalid_instruction) 11671 return nullptr; 11672 11673 if (type_is_invalid(fn_value->value->type)) 11674 return nullptr; 11675 11676 if (fn_value->value->type->id != ZigTypeIdFn) { 11677 ir_add_error_node(ira, fn_value->source_node, 11678 buf_sprintf("expected function type, found '%s'", buf_ptr(&fn_value->value->type->name))); 11679 return nullptr; 11680 } 11681 11682 ZigValue *const_val = ir_resolve_const(ira, fn_value, UndefBad); 11683 if (!const_val) 11684 return nullptr; 11685 11686 // May be a ConstPtrSpecialHardCodedAddr 11687 if (const_val->data.x_ptr.special != ConstPtrSpecialFunction) 11688 return nullptr; 11689 11690 return const_val->data.x_ptr.data.fn.fn_entry; 11691 } 11692 11693 static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 11694 ZigType *wanted_type, ResultLoc *result_loc) 11695 { 11696 assert(wanted_type->id == ZigTypeIdOptional); 11697 11698 if (instr_is_comptime(value)) { 11699 ZigType *payload_type = wanted_type->data.maybe.child_type; 11700 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); 11701 if (type_is_invalid(casted_payload->value->type)) 11702 return ira->codegen->invalid_instruction; 11703 11704 ZigValue *val = ir_resolve_const(ira, casted_payload, UndefOk); 11705 if (!val) 11706 return ira->codegen->invalid_instruction; 11707 11708 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 11709 source_instr->scope, source_instr->source_node); 11710 const_instruction->base.value->special = ConstValSpecialStatic; 11711 if (types_have_same_zig_comptime_repr(ira->codegen, wanted_type, payload_type)) { 11712 copy_const_val(const_instruction->base.value, val, val->data.x_ptr.mut == ConstPtrMutComptimeConst); 11713 } else { 11714 const_instruction->base.value->data.x_optional = val; 11715 } 11716 const_instruction->base.value->type = wanted_type; 11717 return &const_instruction->base; 11718 } 11719 11720 if (result_loc == nullptr && handle_is_ptr(wanted_type)) { 11721 result_loc = no_result_loc(); 11722 } 11723 IrInstruction *result_loc_inst = nullptr; 11724 if (result_loc != nullptr) { 11725 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); 11726 if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { 11727 return result_loc_inst; 11728 } 11729 } 11730 IrInstruction *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst); 11731 result->value->data.rh_maybe = RuntimeHintOptionalNonNull; 11732 return result; 11733 } 11734 11735 static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, 11736 IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) 11737 { 11738 assert(wanted_type->id == ZigTypeIdErrorUnion); 11739 11740 ZigType *payload_type = wanted_type->data.error_union.payload_type; 11741 ZigType *err_set_type = wanted_type->data.error_union.err_set_type; 11742 if (instr_is_comptime(value)) { 11743 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); 11744 if (type_is_invalid(casted_payload->value->type)) 11745 return ira->codegen->invalid_instruction; 11746 11747 ZigValue *val = ir_resolve_const(ira, casted_payload, UndefBad); 11748 if (!val) 11749 return ira->codegen->invalid_instruction; 11750 11751 ZigValue *err_set_val = create_const_vals(1); 11752 err_set_val->type = err_set_type; 11753 err_set_val->special = ConstValSpecialStatic; 11754 err_set_val->data.x_err_set = nullptr; 11755 11756 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 11757 source_instr->scope, source_instr->source_node); 11758 const_instruction->base.value->type = wanted_type; 11759 const_instruction->base.value->special = ConstValSpecialStatic; 11760 const_instruction->base.value->data.x_err_union.error_set = err_set_val; 11761 const_instruction->base.value->data.x_err_union.payload = val; 11762 return &const_instruction->base; 11763 } 11764 11765 IrInstruction *result_loc_inst; 11766 if (handle_is_ptr(wanted_type)) { 11767 if (result_loc == nullptr) result_loc = no_result_loc(); 11768 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); 11769 if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { 11770 return result_loc_inst; 11771 } 11772 } else { 11773 result_loc_inst = nullptr; 11774 } 11775 11776 IrInstruction *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst); 11777 result->value->data.rh_error_union = RuntimeHintErrorUnionNonError; 11778 return result; 11779 } 11780 11781 static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 11782 ZigType *wanted_type) 11783 { 11784 assert(value->value->type->id == ZigTypeIdErrorSet); 11785 assert(wanted_type->id == ZigTypeIdErrorSet); 11786 11787 if (instr_is_comptime(value)) { 11788 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 11789 if (!val) 11790 return ira->codegen->invalid_instruction; 11791 11792 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 11793 return ira->codegen->invalid_instruction; 11794 } 11795 if (!type_is_global_error_set(wanted_type)) { 11796 bool subset = false; 11797 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 11798 if (wanted_type->data.error_set.errors[i]->value == val->data.x_err_set->value) { 11799 subset = true; 11800 break; 11801 } 11802 } 11803 if (!subset) { 11804 ir_add_error(ira, source_instr, 11805 buf_sprintf("error.%s not a member of error set '%s'", 11806 buf_ptr(&val->data.x_err_set->name), buf_ptr(&wanted_type->name))); 11807 return ira->codegen->invalid_instruction; 11808 } 11809 } 11810 11811 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 11812 source_instr->scope, source_instr->source_node); 11813 const_instruction->base.value->type = wanted_type; 11814 const_instruction->base.value->special = ConstValSpecialStatic; 11815 const_instruction->base.value->data.x_err_set = val->data.x_err_set; 11816 return &const_instruction->base; 11817 } 11818 11819 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, CastOpErrSet); 11820 result->value->type = wanted_type; 11821 return result; 11822 } 11823 11824 static IrInstruction *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInstruction *source_instr, 11825 IrInstruction *frame_ptr, ZigType *wanted_type) 11826 { 11827 if (instr_is_comptime(frame_ptr)) { 11828 ZigValue *ptr_val = ir_resolve_const(ira, frame_ptr, UndefBad); 11829 if (ptr_val == nullptr) 11830 return ira->codegen->invalid_instruction; 11831 11832 ir_assert(ptr_val->type->id == ZigTypeIdPointer, source_instr); 11833 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 11834 zig_panic("TODO comptime frame pointer"); 11835 } 11836 } 11837 11838 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 11839 wanted_type, frame_ptr, CastOpBitCast); 11840 result->value->type = wanted_type; 11841 return result; 11842 } 11843 11844 static IrInstruction *ir_analyze_anyframe_to_anyframe(IrAnalyze *ira, IrInstruction *source_instr, 11845 IrInstruction *value, ZigType *wanted_type) 11846 { 11847 if (instr_is_comptime(value)) { 11848 zig_panic("TODO comptime anyframe->T to anyframe"); 11849 } 11850 11851 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 11852 wanted_type, value, CastOpBitCast); 11853 result->value->type = wanted_type; 11854 return result; 11855 } 11856 11857 11858 static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 11859 ZigType *wanted_type, ResultLoc *result_loc) 11860 { 11861 assert(wanted_type->id == ZigTypeIdErrorUnion); 11862 11863 IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); 11864 11865 if (instr_is_comptime(casted_value)) { 11866 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); 11867 if (!val) 11868 return ira->codegen->invalid_instruction; 11869 11870 ZigValue *err_set_val = create_const_vals(1); 11871 err_set_val->special = ConstValSpecialStatic; 11872 err_set_val->type = wanted_type->data.error_union.err_set_type; 11873 err_set_val->data.x_err_set = val->data.x_err_set; 11874 11875 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 11876 source_instr->scope, source_instr->source_node); 11877 const_instruction->base.value->type = wanted_type; 11878 const_instruction->base.value->special = ConstValSpecialStatic; 11879 const_instruction->base.value->data.x_err_union.error_set = err_set_val; 11880 const_instruction->base.value->data.x_err_union.payload = nullptr; 11881 return &const_instruction->base; 11882 } 11883 11884 IrInstruction *result_loc_inst; 11885 if (handle_is_ptr(wanted_type)) { 11886 if (result_loc == nullptr) result_loc = no_result_loc(); 11887 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); 11888 if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { 11889 return result_loc_inst; 11890 } 11891 } else { 11892 result_loc_inst = nullptr; 11893 } 11894 11895 11896 IrInstruction *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst); 11897 result->value->data.rh_error_union = RuntimeHintErrorUnionError; 11898 return result; 11899 } 11900 11901 static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { 11902 assert(wanted_type->id == ZigTypeIdOptional); 11903 assert(instr_is_comptime(value)); 11904 11905 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 11906 assert(val != nullptr); 11907 11908 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11909 result->value->special = ConstValSpecialStatic; 11910 if (get_codegen_ptr_type(wanted_type) != nullptr) { 11911 result->value->data.x_ptr.special = ConstPtrSpecialNull; 11912 } else if (is_opt_err_set(wanted_type)) { 11913 result->value->data.x_err_set = nullptr; 11914 } else { 11915 result->value->data.x_optional = nullptr; 11916 } 11917 return result; 11918 } 11919 11920 static IrInstruction *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInstruction *source_instr, 11921 IrInstruction *value, ZigType *wanted_type) 11922 { 11923 assert(wanted_type->id == ZigTypeIdPointer); 11924 assert(wanted_type->data.pointer.ptr_len == PtrLenC); 11925 assert(instr_is_comptime(value)); 11926 11927 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 11928 assert(val != nullptr); 11929 11930 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 11931 result->value->data.x_ptr.special = ConstPtrSpecialNull; 11932 result->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 11933 return result; 11934 } 11935 11936 static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value, 11937 bool is_const, bool is_volatile) 11938 { 11939 Error err; 11940 11941 if (type_is_invalid(value->value->type)) 11942 return ira->codegen->invalid_instruction; 11943 11944 if ((err = type_resolve(ira->codegen, value->value->type, ResolveStatusZeroBitsKnown))) 11945 return ira->codegen->invalid_instruction; 11946 11947 if (instr_is_comptime(value)) { 11948 ZigValue *val = ir_resolve_const(ira, value, LazyOk); 11949 if (!val) 11950 return ira->codegen->invalid_instruction; 11951 return ir_get_const_ptr(ira, source_instruction, val, value->value->type, 11952 ConstPtrMutComptimeConst, is_const, is_volatile, 0); 11953 } 11954 11955 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value->type, 11956 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 11957 11958 if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown))) 11959 return ira->codegen->invalid_instruction; 11960 11961 IrInstruction *result_loc; 11962 if (type_has_bits(ptr_type) && !handle_is_ptr(value->value->type)) { 11963 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value->type, nullptr, true, 11964 false, true); 11965 } else { 11966 result_loc = nullptr; 11967 } 11968 11969 IrInstruction *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc); 11970 new_instruction->value->data.rh_ptr = RuntimeHintPtrStack; 11971 return new_instruction; 11972 } 11973 11974 static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, IrInstruction *source_instr, ZigType *union_type) { 11975 assert(union_type->id == ZigTypeIdUnion); 11976 11977 Error err; 11978 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) 11979 return ira->codegen->builtin_types.entry_invalid; 11980 11981 AstNode *decl_node = union_type->data.unionation.decl_node; 11982 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) { 11983 assert(union_type->data.unionation.tag_type != nullptr); 11984 return union_type->data.unionation.tag_type; 11985 } else { 11986 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union '%s' has no tag", 11987 buf_ptr(&union_type->name))); 11988 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here")); 11989 return ira->codegen->builtin_types.entry_invalid; 11990 } 11991 } 11992 11993 static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target) { 11994 Error err; 11995 11996 IrInstruction *enum_target; 11997 ZigType *enum_type; 11998 if (target->value->type->id == ZigTypeIdUnion) { 11999 enum_type = ir_resolve_union_tag_type(ira, target, target->value->type); 12000 if (type_is_invalid(enum_type)) 12001 return ira->codegen->invalid_instruction; 12002 enum_target = ir_implicit_cast(ira, target, enum_type); 12003 if (type_is_invalid(enum_target->value->type)) 12004 return ira->codegen->invalid_instruction; 12005 } else if (target->value->type->id == ZigTypeIdEnum) { 12006 enum_target = target; 12007 enum_type = target->value->type; 12008 } else { 12009 ir_add_error(ira, target, 12010 buf_sprintf("expected enum, found type '%s'", buf_ptr(&target->value->type->name))); 12011 return ira->codegen->invalid_instruction; 12012 } 12013 12014 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) 12015 return ira->codegen->invalid_instruction; 12016 12017 ZigType *tag_type = enum_type->data.enumeration.tag_int_type; 12018 assert(tag_type->id == ZigTypeIdInt || tag_type->id == ZigTypeIdComptimeInt); 12019 12020 // If there is only one possible tag, then we know at comptime what it is. 12021 if (enum_type->data.enumeration.layout == ContainerLayoutAuto && 12022 enum_type->data.enumeration.src_field_count == 1) 12023 { 12024 IrInstruction *result = ir_const(ira, source_instr, tag_type); 12025 init_const_bigint(result->value, tag_type, 12026 &enum_type->data.enumeration.fields[0].value); 12027 return result; 12028 } 12029 12030 if (instr_is_comptime(enum_target)) { 12031 ZigValue *val = ir_resolve_const(ira, enum_target, UndefBad); 12032 if (!val) 12033 return ira->codegen->invalid_instruction; 12034 IrInstruction *result = ir_const(ira, source_instr, tag_type); 12035 init_const_bigint(result->value, tag_type, &val->data.x_enum_tag); 12036 return result; 12037 } 12038 12039 IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, 12040 source_instr->source_node, enum_target); 12041 result->value->type = tag_type; 12042 return result; 12043 } 12044 12045 static IrInstruction *ir_analyze_union_to_tag(IrAnalyze *ira, IrInstruction *source_instr, 12046 IrInstruction *target, ZigType *wanted_type) 12047 { 12048 assert(target->value->type->id == ZigTypeIdUnion); 12049 assert(wanted_type->id == ZigTypeIdEnum); 12050 assert(wanted_type == target->value->type->data.unionation.tag_type); 12051 12052 if (instr_is_comptime(target)) { 12053 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 12054 if (!val) 12055 return ira->codegen->invalid_instruction; 12056 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12057 result->value->special = ConstValSpecialStatic; 12058 result->value->type = wanted_type; 12059 bigint_init_bigint(&result->value->data.x_enum_tag, &val->data.x_union.tag); 12060 return result; 12061 } 12062 12063 // If there is only 1 possible tag, then we know at comptime what it is. 12064 if (wanted_type->data.enumeration.layout == ContainerLayoutAuto && 12065 wanted_type->data.enumeration.src_field_count == 1) 12066 { 12067 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12068 result->value->special = ConstValSpecialStatic; 12069 result->value->type = wanted_type; 12070 TypeEnumField *enum_field = target->value->type->data.unionation.fields[0].enum_field; 12071 bigint_init_bigint(&result->value->data.x_enum_tag, &enum_field->value); 12072 return result; 12073 } 12074 12075 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, 12076 source_instr->source_node, target); 12077 result->value->type = wanted_type; 12078 return result; 12079 } 12080 12081 static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruction *source_instr, 12082 IrInstruction *target, ZigType *wanted_type) 12083 { 12084 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12085 result->value->special = ConstValSpecialUndef; 12086 return result; 12087 } 12088 12089 static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *source_instr, 12090 IrInstruction *uncasted_target, ZigType *wanted_type) 12091 { 12092 Error err; 12093 assert(wanted_type->id == ZigTypeIdUnion); 12094 12095 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) 12096 return ira->codegen->invalid_instruction; 12097 12098 IrInstruction *target = ir_implicit_cast(ira, uncasted_target, wanted_type->data.unionation.tag_type); 12099 if (type_is_invalid(target->value->type)) 12100 return ira->codegen->invalid_instruction; 12101 12102 if (instr_is_comptime(target)) { 12103 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 12104 if (!val) 12105 return ira->codegen->invalid_instruction; 12106 TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); 12107 assert(union_field != nullptr); 12108 ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); 12109 if (field_type == nullptr) 12110 return ira->codegen->invalid_instruction; 12111 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) 12112 return ira->codegen->invalid_instruction; 12113 12114 switch (type_has_one_possible_value(ira->codegen, field_type)) { 12115 case OnePossibleValueInvalid: 12116 return ira->codegen->invalid_instruction; 12117 case OnePossibleValueNo: { 12118 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at( 12119 union_field->enum_field->decl_index); 12120 ErrorMsg *msg = ir_add_error(ira, source_instr, 12121 buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", 12122 buf_ptr(&wanted_type->name), 12123 buf_ptr(&field_type->name), 12124 buf_ptr(union_field->name))); 12125 add_error_note(ira->codegen, msg, field_node, 12126 buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); 12127 return ira->codegen->invalid_instruction; 12128 } 12129 case OnePossibleValueYes: 12130 break; 12131 } 12132 12133 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12134 result->value->special = ConstValSpecialStatic; 12135 result->value->type = wanted_type; 12136 bigint_init_bigint(&result->value->data.x_union.tag, &val->data.x_enum_tag); 12137 result->value->data.x_union.payload = create_const_vals(1); 12138 result->value->data.x_union.payload->special = ConstValSpecialStatic; 12139 result->value->data.x_union.payload->type = field_type; 12140 return result; 12141 } 12142 12143 // if the union has all fields 0 bits, we can do it 12144 // and in fact it's a noop cast because the union value is just the enum value 12145 if (wanted_type->data.unionation.gen_field_count == 0) { 12146 IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, wanted_type, target, CastOpNoop); 12147 result->value->type = wanted_type; 12148 return result; 12149 } 12150 12151 ErrorMsg *msg = ir_add_error(ira, source_instr, 12152 buf_sprintf("runtime cast to union '%s' which has non-void fields", 12153 buf_ptr(&wanted_type->name))); 12154 for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { 12155 TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; 12156 ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); 12157 if (field_type == nullptr) 12158 return ira->codegen->invalid_instruction; 12159 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) 12160 return ira->codegen->invalid_instruction; 12161 if (type_has_bits(field_type)) { 12162 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); 12163 add_error_note(ira->codegen, msg, field_node, 12164 buf_sprintf("field '%s' has type '%s'", 12165 buf_ptr(union_field->name), 12166 buf_ptr(&field_type->name))); 12167 } 12168 } 12169 return ira->codegen->invalid_instruction; 12170 } 12171 12172 static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction *source_instr, 12173 IrInstruction *target, ZigType *wanted_type) 12174 { 12175 assert(wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdFloat); 12176 12177 if (instr_is_comptime(target)) { 12178 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 12179 if (!val) 12180 return ira->codegen->invalid_instruction; 12181 if (wanted_type->id == ZigTypeIdInt) { 12182 if (bigint_cmp_zero(&val->data.x_bigint) == CmpLT && !wanted_type->data.integral.is_signed) { 12183 ir_add_error(ira, source_instr, 12184 buf_sprintf("attempt to cast negative value to unsigned integer")); 12185 return ira->codegen->invalid_instruction; 12186 } 12187 if (!bigint_fits_in_bits(&val->data.x_bigint, wanted_type->data.integral.bit_count, 12188 wanted_type->data.integral.is_signed)) 12189 { 12190 ir_add_error(ira, source_instr, 12191 buf_sprintf("cast from '%s' to '%s' truncates bits", 12192 buf_ptr(&target->value->type->name), buf_ptr(&wanted_type->name))); 12193 return ira->codegen->invalid_instruction; 12194 } 12195 } 12196 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12197 result->value->type = wanted_type; 12198 if (wanted_type->id == ZigTypeIdInt) { 12199 bigint_init_bigint(&result->value->data.x_bigint, &val->data.x_bigint); 12200 } else { 12201 float_init_float(result->value, val); 12202 } 12203 return result; 12204 } 12205 12206 // If the destination integer type has no bits, then we can emit a comptime 12207 // zero. However, we still want to emit a runtime safety check to make sure 12208 // the target is zero. 12209 if (!type_has_bits(wanted_type)) { 12210 assert(wanted_type->id == ZigTypeIdInt); 12211 assert(type_has_bits(target->value->type)); 12212 ir_build_assert_zero(ira, source_instr, target); 12213 IrInstruction *result = ir_const_unsigned(ira, source_instr, 0); 12214 result->value->type = wanted_type; 12215 return result; 12216 } 12217 12218 IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, 12219 source_instr->source_node, target); 12220 result->value->type = wanted_type; 12221 return result; 12222 } 12223 12224 static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *source_instr, 12225 IrInstruction *target, ZigType *wanted_type) 12226 { 12227 Error err; 12228 assert(wanted_type->id == ZigTypeIdEnum); 12229 12230 ZigType *actual_type = target->value->type; 12231 12232 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown))) 12233 return ira->codegen->invalid_instruction; 12234 12235 if (actual_type != wanted_type->data.enumeration.tag_int_type) { 12236 ir_add_error(ira, source_instr, 12237 buf_sprintf("integer to enum cast from '%s' instead of its tag type, '%s'", 12238 buf_ptr(&actual_type->name), 12239 buf_ptr(&wanted_type->data.enumeration.tag_int_type->name))); 12240 return ira->codegen->invalid_instruction; 12241 } 12242 12243 assert(actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt); 12244 12245 if (instr_is_comptime(target)) { 12246 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 12247 if (!val) 12248 return ira->codegen->invalid_instruction; 12249 12250 TypeEnumField *field = find_enum_field_by_tag(wanted_type, &val->data.x_bigint); 12251 if (field == nullptr) { 12252 Buf *val_buf = buf_alloc(); 12253 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 12254 ErrorMsg *msg = ir_add_error(ira, source_instr, 12255 buf_sprintf("enum '%s' has no tag matching integer value %s", 12256 buf_ptr(&wanted_type->name), buf_ptr(val_buf))); 12257 add_error_note(ira->codegen, msg, wanted_type->data.enumeration.decl_node, 12258 buf_sprintf("'%s' declared here", buf_ptr(&wanted_type->name))); 12259 return ira->codegen->invalid_instruction; 12260 } 12261 12262 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12263 bigint_init_bigint(&result->value->data.x_enum_tag, &val->data.x_bigint); 12264 return result; 12265 } 12266 12267 IrInstruction *result = ir_build_int_to_enum(&ira->new_irb, source_instr->scope, 12268 source_instr->source_node, nullptr, target); 12269 result->value->type = wanted_type; 12270 return result; 12271 } 12272 12273 static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction *source_instr, 12274 IrInstruction *target, ZigType *wanted_type) 12275 { 12276 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 12277 if (!val) 12278 return ira->codegen->invalid_instruction; 12279 12280 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12281 if (wanted_type->id == ZigTypeIdComptimeFloat) { 12282 float_init_float(result->value, val); 12283 } else if (wanted_type->id == ZigTypeIdComptimeInt) { 12284 bigint_init_bigint(&result->value->data.x_bigint, &val->data.x_bigint); 12285 } else { 12286 zig_unreachable(); 12287 } 12288 return result; 12289 } 12290 12291 static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 12292 ZigType *wanted_type) 12293 { 12294 assert(target->value->type->id == ZigTypeIdInt); 12295 assert(!target->value->type->data.integral.is_signed); 12296 assert(wanted_type->id == ZigTypeIdErrorSet); 12297 12298 if (instr_is_comptime(target)) { 12299 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 12300 if (!val) 12301 return ira->codegen->invalid_instruction; 12302 12303 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12304 12305 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 12306 return ira->codegen->invalid_instruction; 12307 } 12308 12309 if (type_is_global_error_set(wanted_type)) { 12310 BigInt err_count; 12311 bigint_init_unsigned(&err_count, ira->codegen->errors_by_index.length); 12312 12313 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) { 12314 Buf *val_buf = buf_alloc(); 12315 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 12316 ir_add_error(ira, source_instr, 12317 buf_sprintf("integer value %s represents no error", buf_ptr(val_buf))); 12318 return ira->codegen->invalid_instruction; 12319 } 12320 12321 size_t index = bigint_as_usize(&val->data.x_bigint); 12322 result->value->data.x_err_set = ira->codegen->errors_by_index.at(index); 12323 return result; 12324 } else { 12325 ErrorTableEntry *err = nullptr; 12326 BigInt err_int; 12327 12328 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 12329 ErrorTableEntry *this_err = wanted_type->data.error_set.errors[i]; 12330 bigint_init_unsigned(&err_int, this_err->value); 12331 if (bigint_cmp(&val->data.x_bigint, &err_int) == CmpEQ) { 12332 err = this_err; 12333 break; 12334 } 12335 } 12336 12337 if (err == nullptr) { 12338 Buf *val_buf = buf_alloc(); 12339 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 12340 ir_add_error(ira, source_instr, 12341 buf_sprintf("integer value %s represents no error in '%s'", buf_ptr(val_buf), buf_ptr(&wanted_type->name))); 12342 return ira->codegen->invalid_instruction; 12343 } 12344 12345 result->value->data.x_err_set = err; 12346 return result; 12347 } 12348 } 12349 12350 IrInstruction *result = ir_build_int_to_err(&ira->new_irb, source_instr->scope, source_instr->source_node, target); 12351 result->value->type = wanted_type; 12352 return result; 12353 } 12354 12355 static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 12356 ZigType *wanted_type) 12357 { 12358 assert(wanted_type->id == ZigTypeIdInt); 12359 12360 ZigType *err_type = target->value->type; 12361 12362 if (instr_is_comptime(target)) { 12363 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 12364 if (!val) 12365 return ira->codegen->invalid_instruction; 12366 12367 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12368 12369 ErrorTableEntry *err; 12370 if (err_type->id == ZigTypeIdErrorUnion) { 12371 err = val->data.x_err_union.error_set->data.x_err_set; 12372 } else if (err_type->id == ZigTypeIdErrorSet) { 12373 err = val->data.x_err_set; 12374 } else { 12375 zig_unreachable(); 12376 } 12377 result->value->type = wanted_type; 12378 uint64_t err_value = err ? err->value : 0; 12379 bigint_init_unsigned(&result->value->data.x_bigint, err_value); 12380 12381 if (!bigint_fits_in_bits(&result->value->data.x_bigint, 12382 wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) 12383 { 12384 ir_add_error_node(ira, source_instr->source_node, 12385 buf_sprintf("error code '%s' does not fit in '%s'", 12386 buf_ptr(&err->name), buf_ptr(&wanted_type->name))); 12387 return ira->codegen->invalid_instruction; 12388 } 12389 12390 return result; 12391 } 12392 12393 ZigType *err_set_type; 12394 if (err_type->id == ZigTypeIdErrorUnion) { 12395 err_set_type = err_type->data.error_union.err_set_type; 12396 } else if (err_type->id == ZigTypeIdErrorSet) { 12397 err_set_type = err_type; 12398 } else { 12399 zig_unreachable(); 12400 } 12401 if (!type_is_global_error_set(err_set_type)) { 12402 if (!resolve_inferred_error_set(ira->codegen, err_set_type, source_instr->source_node)) { 12403 return ira->codegen->invalid_instruction; 12404 } 12405 if (err_set_type->data.error_set.err_count == 0) { 12406 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12407 bigint_init_unsigned(&result->value->data.x_bigint, 0); 12408 return result; 12409 } else if (err_set_type->data.error_set.err_count == 1) { 12410 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12411 ErrorTableEntry *err = err_set_type->data.error_set.errors[0]; 12412 bigint_init_unsigned(&result->value->data.x_bigint, err->value); 12413 return result; 12414 } 12415 } 12416 12417 BigInt bn; 12418 bigint_init_unsigned(&bn, ira->codegen->errors_by_index.length); 12419 if (!bigint_fits_in_bits(&bn, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) { 12420 ir_add_error_node(ira, source_instr->source_node, 12421 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name))); 12422 return ira->codegen->invalid_instruction; 12423 } 12424 12425 IrInstruction *result = ir_build_err_to_int(&ira->new_irb, source_instr->scope, source_instr->source_node, target); 12426 result->value->type = wanted_type; 12427 return result; 12428 } 12429 12430 static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 12431 ZigType *wanted_type) 12432 { 12433 assert(wanted_type->id == ZigTypeIdPointer); 12434 Error err; 12435 if ((err = type_resolve(ira->codegen, target->value->type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 12436 return ira->codegen->invalid_instruction; 12437 assert((wanted_type->data.pointer.is_const && target->value->type->data.pointer.is_const) || !target->value->type->data.pointer.is_const); 12438 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, target->value->type)); 12439 ZigType *array_type = wanted_type->data.pointer.child_type; 12440 assert(array_type->id == ZigTypeIdArray); 12441 assert(array_type->data.array.len == 1); 12442 12443 if (instr_is_comptime(target)) { 12444 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 12445 if (!val) 12446 return ira->codegen->invalid_instruction; 12447 12448 assert(val->type->id == ZigTypeIdPointer); 12449 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 12450 if (pointee == nullptr) 12451 return ira->codegen->invalid_instruction; 12452 if (pointee->special != ConstValSpecialRuntime) { 12453 ZigValue *array_val = create_const_vals(1); 12454 array_val->special = ConstValSpecialStatic; 12455 array_val->type = array_type; 12456 array_val->data.x_array.special = ConstArraySpecialNone; 12457 array_val->data.x_array.data.s_none.elements = pointee; 12458 array_val->parent.id = ConstParentIdScalar; 12459 array_val->parent.data.p_scalar.scalar_val = pointee; 12460 12461 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 12462 source_instr->scope, source_instr->source_node); 12463 const_instruction->base.value->type = wanted_type; 12464 const_instruction->base.value->special = ConstValSpecialStatic; 12465 const_instruction->base.value->data.x_ptr.special = ConstPtrSpecialRef; 12466 const_instruction->base.value->data.x_ptr.data.ref.pointee = array_val; 12467 const_instruction->base.value->data.x_ptr.mut = val->data.x_ptr.mut; 12468 return &const_instruction->base; 12469 } 12470 } 12471 12472 // pointer to array and pointer to single item are represented the same way at runtime 12473 IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, 12474 wanted_type, target, CastOpBitCast); 12475 result->value->type = wanted_type; 12476 return result; 12477 } 12478 12479 static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCastOnly *cast_result, 12480 ErrorMsg *parent_msg) 12481 { 12482 switch (cast_result->id) { 12483 case ConstCastResultIdOk: 12484 zig_unreachable(); 12485 case ConstCastResultIdInvalid: 12486 zig_unreachable(); 12487 case ConstCastResultIdOptionalChild: { 12488 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 12489 buf_sprintf("optional type child '%s' cannot cast into optional type child '%s'", 12490 buf_ptr(&cast_result->data.optional->actual_child->name), 12491 buf_ptr(&cast_result->data.optional->wanted_child->name))); 12492 report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg); 12493 break; 12494 } 12495 case ConstCastResultIdErrorUnionErrorSet: { 12496 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 12497 buf_sprintf("error set '%s' cannot cast into error set '%s'", 12498 buf_ptr(&cast_result->data.error_union_error_set->actual_err_set->name), 12499 buf_ptr(&cast_result->data.error_union_error_set->wanted_err_set->name))); 12500 report_recursive_error(ira, source_node, &cast_result->data.error_union_error_set->child, msg); 12501 break; 12502 } 12503 case ConstCastResultIdErrSet: { 12504 ZigList<ErrorTableEntry *> *missing_errors = &cast_result->data.error_set_mismatch->missing_errors; 12505 for (size_t i = 0; i < missing_errors->length; i += 1) { 12506 ErrorTableEntry *error_entry = missing_errors->at(i); 12507 add_error_note(ira->codegen, parent_msg, ast_field_to_symbol_node(error_entry->decl_node), 12508 buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name))); 12509 } 12510 break; 12511 } 12512 case ConstCastResultIdErrSetGlobal: { 12513 add_error_note(ira->codegen, parent_msg, source_node, 12514 buf_sprintf("cannot cast global error set into smaller set")); 12515 break; 12516 } 12517 case ConstCastResultIdPointerChild: { 12518 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 12519 buf_sprintf("pointer type child '%s' cannot cast into pointer type child '%s'", 12520 buf_ptr(&cast_result->data.pointer_mismatch->actual_child->name), 12521 buf_ptr(&cast_result->data.pointer_mismatch->wanted_child->name))); 12522 report_recursive_error(ira, source_node, &cast_result->data.pointer_mismatch->child, msg); 12523 break; 12524 } 12525 case ConstCastResultIdSliceChild: { 12526 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 12527 buf_sprintf("slice type child '%s' cannot cast into slice type child '%s'", 12528 buf_ptr(&cast_result->data.slice_mismatch->actual_child->name), 12529 buf_ptr(&cast_result->data.slice_mismatch->wanted_child->name))); 12530 report_recursive_error(ira, source_node, &cast_result->data.slice_mismatch->child, msg); 12531 break; 12532 } 12533 case ConstCastResultIdErrorUnionPayload: { 12534 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 12535 buf_sprintf("error union payload '%s' cannot cast into error union payload '%s'", 12536 buf_ptr(&cast_result->data.error_union_payload->actual_payload->name), 12537 buf_ptr(&cast_result->data.error_union_payload->wanted_payload->name))); 12538 report_recursive_error(ira, source_node, &cast_result->data.error_union_payload->child, msg); 12539 break; 12540 } 12541 case ConstCastResultIdType: { 12542 AstNode *wanted_decl_node = type_decl_node(cast_result->data.type_mismatch->wanted_type); 12543 AstNode *actual_decl_node = type_decl_node(cast_result->data.type_mismatch->actual_type); 12544 if (wanted_decl_node != nullptr) { 12545 add_error_note(ira->codegen, parent_msg, wanted_decl_node, 12546 buf_sprintf("%s declared here", 12547 buf_ptr(&cast_result->data.type_mismatch->wanted_type->name))); 12548 } 12549 if (actual_decl_node != nullptr) { 12550 add_error_note(ira->codegen, parent_msg, actual_decl_node, 12551 buf_sprintf("%s declared here", 12552 buf_ptr(&cast_result->data.type_mismatch->actual_type->name))); 12553 } 12554 break; 12555 } 12556 case ConstCastResultIdFnArg: { 12557 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 12558 buf_sprintf("parameter %" ZIG_PRI_usize ": '%s' cannot cast into '%s'", 12559 cast_result->data.fn_arg.arg_index, 12560 buf_ptr(&cast_result->data.fn_arg.actual_param_type->name), 12561 buf_ptr(&cast_result->data.fn_arg.expected_param_type->name))); 12562 report_recursive_error(ira, source_node, cast_result->data.fn_arg.child, msg); 12563 break; 12564 } 12565 case ConstCastResultIdBadAllowsZero: { 12566 ZigType *wanted_type = cast_result->data.bad_allows_zero->wanted_type; 12567 ZigType *actual_type = cast_result->data.bad_allows_zero->actual_type; 12568 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 12569 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 12570 if (actual_allows_zero && !wanted_allows_zero) { 12571 add_error_note(ira->codegen, parent_msg, source_node, 12572 buf_sprintf("'%s' could have null values which are illegal in type '%s'", 12573 buf_ptr(&actual_type->name), 12574 buf_ptr(&wanted_type->name))); 12575 } else { 12576 add_error_note(ira->codegen, parent_msg, source_node, 12577 buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'", 12578 buf_ptr(&wanted_type->name), 12579 buf_ptr(&actual_type->name))); 12580 } 12581 break; 12582 } 12583 case ConstCastResultIdPtrLens: { 12584 add_error_note(ira->codegen, parent_msg, source_node, 12585 buf_sprintf("pointer length mismatch")); 12586 break; 12587 } 12588 case ConstCastResultIdPtrSentinel: { 12589 ZigType *actual_type = cast_result->data.bad_ptr_sentinel->actual_type; 12590 ZigType *wanted_type = cast_result->data.bad_ptr_sentinel->wanted_type; 12591 { 12592 Buf *txt_msg = buf_sprintf("destination pointer requires a terminating '"); 12593 render_const_value(ira->codegen, txt_msg, wanted_type->data.pointer.sentinel); 12594 buf_appendf(txt_msg, "' sentinel"); 12595 if (actual_type->data.pointer.sentinel != nullptr) { 12596 buf_appendf(txt_msg, ", but source pointer has a terminating '"); 12597 render_const_value(ira->codegen, txt_msg, actual_type->data.pointer.sentinel); 12598 buf_appendf(txt_msg, "' sentinel"); 12599 } 12600 add_error_note(ira->codegen, parent_msg, source_node, txt_msg); 12601 } 12602 break; 12603 } 12604 case ConstCastResultIdSentinelArrays: { 12605 ZigType *actual_type = cast_result->data.sentinel_arrays->actual_type; 12606 ZigType *wanted_type = cast_result->data.sentinel_arrays->wanted_type; 12607 Buf *txt_msg = buf_sprintf("destination array requires a terminating '"); 12608 render_const_value(ira->codegen, txt_msg, wanted_type->data.array.sentinel); 12609 buf_appendf(txt_msg, "' sentinel"); 12610 if (actual_type->data.array.sentinel != nullptr) { 12611 buf_appendf(txt_msg, ", but source array has a terminating '"); 12612 render_const_value(ira->codegen, txt_msg, actual_type->data.array.sentinel); 12613 buf_appendf(txt_msg, "' sentinel"); 12614 } 12615 add_error_note(ira->codegen, parent_msg, source_node, txt_msg); 12616 break; 12617 } 12618 case ConstCastResultIdCV: { 12619 ZigType *wanted_type = cast_result->data.bad_cv->wanted_type; 12620 ZigType *actual_type = cast_result->data.bad_cv->actual_type; 12621 bool ok_const = !actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const; 12622 bool ok_volatile = !actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile; 12623 if (!ok_const) { 12624 add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards const qualifier")); 12625 } else if (!ok_volatile) { 12626 add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards volatile qualifier")); 12627 } else { 12628 zig_unreachable(); 12629 } 12630 break; 12631 } 12632 case ConstCastResultIdFnIsGeneric: 12633 add_error_note(ira->codegen, parent_msg, source_node, 12634 buf_sprintf("only one of the functions is generic")); 12635 break; 12636 case ConstCastResultIdFnCC: 12637 add_error_note(ira->codegen, parent_msg, source_node, 12638 buf_sprintf("calling convention mismatch")); 12639 break; 12640 case ConstCastResultIdFnAlign: // TODO 12641 case ConstCastResultIdFnVarArgs: // TODO 12642 case ConstCastResultIdFnReturnType: // TODO 12643 case ConstCastResultIdFnArgCount: // TODO 12644 case ConstCastResultIdFnGenericArgCount: // TODO 12645 case ConstCastResultIdFnArgNoAlias: // TODO 12646 case ConstCastResultIdUnresolvedInferredErrSet: // TODO 12647 case ConstCastResultIdAsyncAllocatorType: // TODO 12648 case ConstCastResultIdArrayChild: // TODO 12649 break; 12650 } 12651 } 12652 12653 static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction *source_instr, 12654 IrInstruction *array, ZigType *vector_type) 12655 { 12656 if (instr_is_comptime(array)) { 12657 // arrays and vectors have the same ZigValue representation 12658 IrInstruction *result = ir_const(ira, source_instr, vector_type); 12659 copy_const_val(result->value, array->value, false); 12660 result->value->type = vector_type; 12661 return result; 12662 } 12663 return ir_build_array_to_vector(ira, source_instr, array, vector_type); 12664 } 12665 12666 static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr, 12667 IrInstruction *vector, ZigType *array_type, ResultLoc *result_loc) 12668 { 12669 if (instr_is_comptime(vector)) { 12670 // arrays and vectors have the same ZigValue representation 12671 IrInstruction *result = ir_const(ira, source_instr, array_type); 12672 copy_const_val(result->value, vector->value, false); 12673 result->value->type = array_type; 12674 return result; 12675 } 12676 if (result_loc == nullptr) { 12677 result_loc = no_result_loc(); 12678 } 12679 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, 12680 true, false, true); 12681 if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { 12682 return result_loc_inst; 12683 } 12684 return ir_build_vector_to_array(ira, source_instr, array_type, vector, result_loc_inst); 12685 } 12686 12687 static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr, 12688 IrInstruction *integer, ZigType *dest_type) 12689 { 12690 IrInstruction *unsigned_integer; 12691 if (instr_is_comptime(integer)) { 12692 unsigned_integer = integer; 12693 } else { 12694 assert(integer->value->type->id == ZigTypeIdInt); 12695 12696 if (integer->value->type->data.integral.bit_count > 12697 ira->codegen->builtin_types.entry_usize->data.integral.bit_count) 12698 { 12699 ir_add_error(ira, source_instr, 12700 buf_sprintf("integer type '%s' too big for implicit @intToPtr to type '%s'", 12701 buf_ptr(&integer->value->type->name), 12702 buf_ptr(&dest_type->name))); 12703 return ira->codegen->invalid_instruction; 12704 } 12705 12706 if (integer->value->type->data.integral.is_signed) { 12707 ZigType *unsigned_int_type = get_int_type(ira->codegen, false, 12708 integer->value->type->data.integral.bit_count); 12709 unsigned_integer = ir_analyze_bit_cast(ira, source_instr, integer, unsigned_int_type); 12710 if (type_is_invalid(unsigned_integer->value->type)) 12711 return ira->codegen->invalid_instruction; 12712 } else { 12713 unsigned_integer = integer; 12714 } 12715 } 12716 12717 return ir_analyze_int_to_ptr(ira, source_instr, unsigned_integer, dest_type); 12718 } 12719 12720 static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { 12721 if (ty->id == ZigTypeIdPointer) return ty->data.pointer.child_type->id != ZigTypeIdPointer; 12722 if (ty->id == ZigTypeIdFn) return true; 12723 if (ty->id == ZigTypeIdOptional) { 12724 ZigType *ptr_ty = ty->data.maybe.child_type; 12725 if (ptr_ty->id == ZigTypeIdPointer) return ptr_ty->data.pointer.child_type->id != ZigTypeIdPointer; 12726 if (ptr_ty->id == ZigTypeIdFn) return true; 12727 } 12728 return false; 12729 } 12730 12731 static IrInstruction *ir_analyze_enum_literal(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 12732 ZigType *enum_type) 12733 { 12734 assert(enum_type->id == ZigTypeIdEnum); 12735 12736 Error err; 12737 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusZeroBitsKnown))) 12738 return ira->codegen->invalid_instruction; 12739 12740 TypeEnumField *field = find_enum_type_field(enum_type, value->value->data.x_enum_literal); 12741 if (field == nullptr) { 12742 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("enum '%s' has no field named '%s'", 12743 buf_ptr(&enum_type->name), buf_ptr(value->value->data.x_enum_literal))); 12744 add_error_note(ira->codegen, msg, enum_type->data.enumeration.decl_node, 12745 buf_sprintf("'%s' declared here", buf_ptr(&enum_type->name))); 12746 return ira->codegen->invalid_instruction; 12747 } 12748 IrInstruction *result = ir_const(ira, source_instr, enum_type); 12749 bigint_init_bigint(&result->value->data.x_enum_tag, &field->value); 12750 12751 return result; 12752 } 12753 12754 static IrInstruction *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInstruction *source_instr, 12755 IrInstruction *value, ZigType *wanted_type) 12756 { 12757 ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array")); 12758 return ira->codegen->invalid_instruction; 12759 } 12760 12761 static IrInstruction *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInstruction *source_instr, 12762 IrInstruction *value, ZigType *wanted_type) 12763 { 12764 ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to struct")); 12765 return ira->codegen->invalid_instruction; 12766 } 12767 12768 static IrInstruction *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInstruction *source_instr, 12769 IrInstruction *value, ZigType *wanted_type) 12770 { 12771 ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to union")); 12772 return ira->codegen->invalid_instruction; 12773 } 12774 12775 // Add a compile error and return ErrorSemanticAnalyzeFail if the pointer alignment does not work, 12776 // otherwise return ErrorNone. Does not emit any instructions. 12777 // Assumes that the pointer types have element types with the same ABI alignment. Avoids resolving the 12778 // pointer types' alignments if both of the pointer types are ABI aligned. 12779 static Error ir_cast_ptr_align(IrAnalyze *ira, IrInstruction *source_instr, ZigType *dest_ptr_type, 12780 ZigType *src_ptr_type, AstNode *src_source_node) 12781 { 12782 Error err; 12783 12784 ir_assert(dest_ptr_type->id == ZigTypeIdPointer, source_instr); 12785 ir_assert(src_ptr_type->id == ZigTypeIdPointer, source_instr); 12786 12787 if (dest_ptr_type->data.pointer.explicit_alignment == 0 && 12788 src_ptr_type->data.pointer.explicit_alignment == 0) 12789 { 12790 return ErrorNone; 12791 } 12792 12793 if ((err = type_resolve(ira->codegen, dest_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 12794 return ErrorSemanticAnalyzeFail; 12795 12796 if ((err = type_resolve(ira->codegen, src_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 12797 return ErrorSemanticAnalyzeFail; 12798 12799 uint32_t wanted_align = get_ptr_align(ira->codegen, dest_ptr_type); 12800 uint32_t actual_align = get_ptr_align(ira->codegen, src_ptr_type); 12801 if (wanted_align > actual_align) { 12802 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 12803 add_error_note(ira->codegen, msg, src_source_node, 12804 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_ptr_type->name), actual_align)); 12805 add_error_note(ira->codegen, msg, source_instr->source_node, 12806 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_ptr_type->name), wanted_align)); 12807 return ErrorSemanticAnalyzeFail; 12808 } 12809 12810 return ErrorNone; 12811 } 12812 12813 static IrInstruction *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInstruction *source_instr, 12814 IrInstruction *struct_operand, TypeStructField *field) 12815 { 12816 IrInstruction *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false); 12817 IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, struct_ptr, 12818 struct_operand->value->type, false); 12819 return ir_get_deref(ira, source_instr, field_ptr, nullptr); 12820 } 12821 12822 static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, 12823 ZigType *wanted_type, IrInstruction *value) 12824 { 12825 Error err; 12826 ZigType *actual_type = value->value->type; 12827 AstNode *source_node = source_instr->source_node; 12828 12829 if (type_is_invalid(wanted_type) || type_is_invalid(actual_type)) { 12830 return ira->codegen->invalid_instruction; 12831 } 12832 12833 // This means the wanted type is anything. 12834 if (wanted_type == ira->codegen->builtin_types.entry_var) { 12835 return value; 12836 } 12837 12838 // perfect match or non-const to const 12839 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, 12840 source_node, false); 12841 if (const_cast_result.id == ConstCastResultIdInvalid) 12842 return ira->codegen->invalid_instruction; 12843 if (const_cast_result.id == ConstCastResultIdOk) { 12844 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); 12845 } 12846 12847 if (const_cast_result.id == ConstCastResultIdFnCC) { 12848 ir_assert(value->value->type->id == ZigTypeIdFn, source_instr); 12849 // ConstCastResultIdFnCC is guaranteed to be the last one reported, meaning everything else is ok. 12850 if (wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync && 12851 actual_type->data.fn.fn_type_id.cc == CallingConventionUnspecified) 12852 { 12853 ir_assert(value->value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 12854 ZigFn *fn = value->value->data.x_ptr.data.fn.fn_entry; 12855 if (fn->inferred_async_node == nullptr) { 12856 fn->inferred_async_node = source_instr->source_node; 12857 } 12858 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); 12859 } 12860 } 12861 12862 // cast from T to ?T 12863 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism 12864 if (wanted_type->id == ZigTypeIdOptional) { 12865 ZigType *wanted_child_type = wanted_type->data.maybe.child_type; 12866 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, 12867 false).id == ConstCastResultIdOk) 12868 { 12869 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); 12870 } else if (actual_type->id == ZigTypeIdComptimeInt || 12871 actual_type->id == ZigTypeIdComptimeFloat) 12872 { 12873 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { 12874 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); 12875 } else { 12876 return ira->codegen->invalid_instruction; 12877 } 12878 } else if ( 12879 wanted_child_type->id == ZigTypeIdPointer && 12880 wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && 12881 actual_type->id == ZigTypeIdPointer && 12882 actual_type->data.pointer.ptr_len == PtrLenSingle && 12883 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 12884 { 12885 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 12886 return ira->codegen->invalid_instruction; 12887 if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 12888 return ira->codegen->invalid_instruction; 12889 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && 12890 types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, 12891 actual_type->data.pointer.child_type->data.array.child_type, source_node, 12892 !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) 12893 { 12894 IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, 12895 wanted_child_type); 12896 if (type_is_invalid(cast1->value->type)) 12897 return ira->codegen->invalid_instruction; 12898 return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type, nullptr); 12899 } 12900 } 12901 } 12902 12903 // T to E!T 12904 if (wanted_type->id == ZigTypeIdErrorUnion) { 12905 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, 12906 source_node, false).id == ConstCastResultIdOk) 12907 { 12908 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); 12909 } else if (actual_type->id == ZigTypeIdComptimeInt || 12910 actual_type->id == ZigTypeIdComptimeFloat) 12911 { 12912 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { 12913 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); 12914 } else { 12915 return ira->codegen->invalid_instruction; 12916 } 12917 } 12918 } 12919 12920 // cast from T to E!?T 12921 if (wanted_type->id == ZigTypeIdErrorUnion && 12922 wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && 12923 actual_type->id != ZigTypeIdOptional) 12924 { 12925 ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; 12926 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || 12927 actual_type->id == ZigTypeIdNull || 12928 actual_type->id == ZigTypeIdComptimeInt || 12929 actual_type->id == ZigTypeIdComptimeFloat) 12930 { 12931 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); 12932 if (type_is_invalid(cast1->value->type)) 12933 return ira->codegen->invalid_instruction; 12934 12935 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 12936 if (type_is_invalid(cast2->value->type)) 12937 return ira->codegen->invalid_instruction; 12938 12939 return cast2; 12940 } 12941 } 12942 12943 12944 // cast from comptime-known number to another number type 12945 if (instr_is_comptime(value) && 12946 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt || 12947 actual_type->id == ZigTypeIdFloat || actual_type->id == ZigTypeIdComptimeFloat) && 12948 (wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdComptimeInt || 12949 wanted_type->id == ZigTypeIdFloat || wanted_type->id == ZigTypeIdComptimeFloat)) 12950 { 12951 if (value->value->special == ConstValSpecialUndef) { 12952 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12953 result->value->special = ConstValSpecialUndef; 12954 return result; 12955 } 12956 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { 12957 if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { 12958 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12959 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 12960 copy_const_val(result->value, value->value, false); 12961 result->value->type = wanted_type; 12962 } else { 12963 float_init_bigint(&result->value->data.x_bigint, value->value); 12964 } 12965 return result; 12966 } else if (wanted_type->id == ZigTypeIdComptimeFloat || wanted_type->id == ZigTypeIdFloat) { 12967 IrInstruction *result = ir_const(ira, source_instr, wanted_type); 12968 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 12969 BigFloat bf; 12970 bigfloat_init_bigint(&bf, &value->value->data.x_bigint); 12971 float_init_bigfloat(result->value, &bf); 12972 } else { 12973 float_init_float(result->value, value->value); 12974 } 12975 return result; 12976 } 12977 zig_unreachable(); 12978 } else { 12979 return ira->codegen->invalid_instruction; 12980 } 12981 } 12982 12983 // widening conversion 12984 if (wanted_type->id == ZigTypeIdInt && 12985 actual_type->id == ZigTypeIdInt && 12986 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed && 12987 wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count) 12988 { 12989 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 12990 } 12991 12992 // small enough unsigned ints can get casted to large enough signed ints 12993 if (wanted_type->id == ZigTypeIdInt && wanted_type->data.integral.is_signed && 12994 actual_type->id == ZigTypeIdInt && !actual_type->data.integral.is_signed && 12995 wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count) 12996 { 12997 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 12998 } 12999 13000 // float widening conversion 13001 if (wanted_type->id == ZigTypeIdFloat && 13002 actual_type->id == ZigTypeIdFloat && 13003 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count) 13004 { 13005 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 13006 } 13007 13008 // *[N]T to ?[]const T 13009 if (wanted_type->id == ZigTypeIdOptional && 13010 is_slice(wanted_type->data.maybe.child_type) && 13011 actual_type->id == ZigTypeIdPointer && 13012 actual_type->data.pointer.ptr_len == PtrLenSingle && 13013 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 13014 { 13015 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); 13016 if (type_is_invalid(cast1->value->type)) 13017 return ira->codegen->invalid_instruction; 13018 13019 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 13020 if (type_is_invalid(cast2->value->type)) 13021 return ira->codegen->invalid_instruction; 13022 13023 return cast2; 13024 } 13025 13026 // *[N]T to [*]T and [*c]T 13027 if (wanted_type->id == ZigTypeIdPointer && 13028 (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC) && 13029 actual_type->id == ZigTypeIdPointer && 13030 actual_type->data.pointer.ptr_len == PtrLenSingle && 13031 actual_type->data.pointer.child_type->id == ZigTypeIdArray && 13032 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && 13033 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) 13034 { 13035 ZigType *actual_array_type = actual_type->data.pointer.child_type; 13036 if (wanted_type->data.pointer.sentinel == nullptr || 13037 (actual_array_type->data.array.sentinel != nullptr && 13038 const_values_equal(ira->codegen, wanted_type->data.pointer.sentinel, 13039 actual_array_type->data.array.sentinel))) 13040 { 13041 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 13042 return ira->codegen->invalid_instruction; 13043 if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 13044 return ira->codegen->invalid_instruction; 13045 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) && 13046 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 13047 actual_type->data.pointer.child_type->data.array.child_type, source_node, 13048 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 13049 { 13050 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type); 13051 } 13052 } 13053 } 13054 13055 // *[N]T to []T 13056 // *[N]T to E![]T 13057 if ((is_slice(wanted_type) || 13058 (wanted_type->id == ZigTypeIdErrorUnion && 13059 is_slice(wanted_type->data.error_union.payload_type))) && 13060 actual_type->id == ZigTypeIdPointer && 13061 actual_type->data.pointer.ptr_len == PtrLenSingle && 13062 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 13063 { 13064 ZigType *slice_type = (wanted_type->id == ZigTypeIdErrorUnion) ? 13065 wanted_type->data.error_union.payload_type : wanted_type; 13066 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 13067 assert(slice_ptr_type->id == ZigTypeIdPointer); 13068 ZigType *array_type = actual_type->data.pointer.child_type; 13069 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 13070 || !actual_type->data.pointer.is_const); 13071 if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 13072 array_type->data.array.child_type, source_node, 13073 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) 13074 { 13075 // If the pointers both have ABI align, it works. 13076 // Or if the array length is 0, alignment doesn't matter. 13077 bool ok_align = array_type->data.array.len == 0 || 13078 (slice_ptr_type->data.pointer.explicit_alignment == 0 && 13079 actual_type->data.pointer.explicit_alignment == 0); 13080 if (!ok_align) { 13081 // If either one has non ABI align, we have to resolve them both 13082 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, 13083 ResolveStatusAlignmentKnown))) 13084 { 13085 return ira->codegen->invalid_instruction; 13086 } 13087 if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type, 13088 ResolveStatusAlignmentKnown))) 13089 { 13090 return ira->codegen->invalid_instruction; 13091 } 13092 ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type); 13093 } 13094 if (ok_align) { 13095 if (wanted_type->id == ZigTypeIdErrorUnion) { 13096 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, slice_type, value); 13097 if (type_is_invalid(cast1->value->type)) 13098 return ira->codegen->invalid_instruction; 13099 13100 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 13101 if (type_is_invalid(cast2->value->type)) 13102 return ira->codegen->invalid_instruction; 13103 13104 return cast2; 13105 } else { 13106 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, slice_type, nullptr); 13107 } 13108 } 13109 } 13110 } 13111 13112 // *[N]T to E![]T 13113 if (wanted_type->id == ZigTypeIdErrorUnion && 13114 is_slice(wanted_type->data.error_union.payload_type) && 13115 actual_type->id == ZigTypeIdPointer && 13116 actual_type->data.pointer.ptr_len == PtrLenSingle && 13117 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 13118 { 13119 ZigType *slice_type = wanted_type->data.error_union.payload_type; 13120 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 13121 assert(slice_ptr_type->id == ZigTypeIdPointer); 13122 ZigType *array_type = actual_type->data.pointer.child_type; 13123 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 13124 || !actual_type->data.pointer.is_const); 13125 if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 13126 array_type->data.array.child_type, source_node, 13127 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) 13128 { 13129 // If the pointers both have ABI align, it works. 13130 bool ok_align = slice_ptr_type->data.pointer.explicit_alignment == 0 && 13131 actual_type->data.pointer.explicit_alignment == 0; 13132 if (!ok_align) { 13133 // If either one has non ABI align, we have to resolve them both 13134 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, 13135 ResolveStatusAlignmentKnown))) 13136 { 13137 return ira->codegen->invalid_instruction; 13138 } 13139 if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type, 13140 ResolveStatusAlignmentKnown))) 13141 { 13142 return ira->codegen->invalid_instruction; 13143 } 13144 ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type); 13145 } 13146 if (ok_align) { 13147 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, slice_type, nullptr); 13148 } 13149 } 13150 } 13151 13152 // *@Frame(func) to anyframe->T or anyframe 13153 // *@Frame(func) to ?anyframe->T or ?anyframe 13154 // *@Frame(func) to E!anyframe->T or E!anyframe 13155 if (actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle && 13156 !actual_type->data.pointer.is_const && 13157 actual_type->data.pointer.child_type->id == ZigTypeIdFnFrame) 13158 { 13159 ZigType *anyframe_type; 13160 if (wanted_type->id == ZigTypeIdAnyFrame) { 13161 anyframe_type = wanted_type; 13162 } else if (wanted_type->id == ZigTypeIdOptional && 13163 wanted_type->data.maybe.child_type->id == ZigTypeIdAnyFrame) 13164 { 13165 anyframe_type = wanted_type->data.maybe.child_type; 13166 } else if (wanted_type->id == ZigTypeIdErrorUnion && 13167 wanted_type->data.error_union.payload_type->id == ZigTypeIdAnyFrame) 13168 { 13169 anyframe_type = wanted_type->data.error_union.payload_type; 13170 } else { 13171 anyframe_type = nullptr; 13172 } 13173 if (anyframe_type != nullptr) { 13174 bool ok = true; 13175 if (anyframe_type->data.any_frame.result_type != nullptr) { 13176 ZigFn *fn = actual_type->data.pointer.child_type->data.frame.fn; 13177 ZigType *fn_return_type = fn->type_entry->data.fn.fn_type_id.return_type; 13178 if (anyframe_type->data.any_frame.result_type != fn_return_type) { 13179 ok = false; 13180 } 13181 } 13182 if (ok) { 13183 IrInstruction *cast1 = ir_analyze_frame_ptr_to_anyframe(ira, source_instr, value, anyframe_type); 13184 if (anyframe_type == wanted_type) 13185 return cast1; 13186 return ir_analyze_cast(ira, source_instr, wanted_type, cast1); 13187 } 13188 } 13189 } 13190 13191 // anyframe->T to anyframe 13192 if (actual_type->id == ZigTypeIdAnyFrame && actual_type->data.any_frame.result_type != nullptr && 13193 wanted_type->id == ZigTypeIdAnyFrame && wanted_type->data.any_frame.result_type == nullptr) 13194 { 13195 return ir_analyze_anyframe_to_anyframe(ira, source_instr, value, wanted_type); 13196 } 13197 13198 // cast from null literal to maybe type 13199 if (wanted_type->id == ZigTypeIdOptional && 13200 actual_type->id == ZigTypeIdNull) 13201 { 13202 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); 13203 } 13204 13205 // cast from null literal to C pointer 13206 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 13207 actual_type->id == ZigTypeIdNull) 13208 { 13209 return ir_analyze_null_to_c_pointer(ira, source_instr, value, wanted_type); 13210 } 13211 13212 // cast from E to E!T 13213 if (wanted_type->id == ZigTypeIdErrorUnion && 13214 actual_type->id == ZigTypeIdErrorSet) 13215 { 13216 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type, nullptr); 13217 } 13218 13219 // cast from typed number to integer or float literal. 13220 // works when the number is known at compile time 13221 if (instr_is_comptime(value) && 13222 ((actual_type->id == ZigTypeIdInt && wanted_type->id == ZigTypeIdComptimeInt) || 13223 (actual_type->id == ZigTypeIdFloat && wanted_type->id == ZigTypeIdComptimeFloat))) 13224 { 13225 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type); 13226 } 13227 13228 // cast from enum literal to enum with matching field name 13229 if (actual_type->id == ZigTypeIdEnumLiteral && wanted_type->id == ZigTypeIdEnum) 13230 { 13231 return ir_analyze_enum_literal(ira, source_instr, value, wanted_type); 13232 } 13233 13234 // cast from enum literal to optional enum 13235 if (actual_type->id == ZigTypeIdEnumLiteral && 13236 (wanted_type->id == ZigTypeIdOptional && wanted_type->data.maybe.child_type->id == ZigTypeIdEnum)) 13237 { 13238 IrInstruction *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.maybe.child_type); 13239 if (result == ira->codegen->invalid_instruction) 13240 return result; 13241 13242 return ir_analyze_optional_wrap(ira, result, value, wanted_type, nullptr); 13243 } 13244 13245 // cast from enum literal to error union when payload is an enum 13246 if (actual_type->id == ZigTypeIdEnumLiteral && 13247 (wanted_type->id == ZigTypeIdErrorUnion && wanted_type->data.error_union.payload_type->id == ZigTypeIdEnum)) 13248 { 13249 IrInstruction *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.error_union.payload_type); 13250 if (result == ira->codegen->invalid_instruction) 13251 return result; 13252 13253 return ir_analyze_err_wrap_payload(ira, result, value, wanted_type, nullptr); 13254 } 13255 13256 // cast from union to the enum type of the union 13257 if (actual_type->id == ZigTypeIdUnion && wanted_type->id == ZigTypeIdEnum) { 13258 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) 13259 return ira->codegen->invalid_instruction; 13260 13261 if (actual_type->data.unionation.tag_type == wanted_type) { 13262 return ir_analyze_union_to_tag(ira, source_instr, value, wanted_type); 13263 } 13264 } 13265 13266 // enum to union which has the enum as the tag type, or 13267 // enum literal to union which has a matching enum as the tag type 13268 if (is_tagged_union(wanted_type) && (actual_type->id == ZigTypeIdEnum || 13269 actual_type->id == ZigTypeIdEnumLiteral)) 13270 { 13271 return ir_analyze_enum_to_union(ira, source_instr, value, wanted_type); 13272 } 13273 13274 // cast from *T to *[1]T 13275 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 13276 actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle) 13277 { 13278 ZigType *array_type = wanted_type->data.pointer.child_type; 13279 if (array_type->id == ZigTypeIdArray && array_type->data.array.len == 1 && 13280 types_match_const_cast_only(ira, array_type->data.array.child_type, 13281 actual_type->data.pointer.child_type, source_node, 13282 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk && 13283 // `types_match_const_cast_only` only gets info for child_types 13284 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && 13285 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) 13286 { 13287 if ((err = ir_cast_ptr_align(ira, source_instr, wanted_type, actual_type, value->source_node))) 13288 return ira->codegen->invalid_instruction; 13289 13290 return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type); 13291 } 13292 } 13293 13294 // [:x]T to [*:x]T 13295 // [:x]T to [*c]T 13296 if (wanted_type->id == ZigTypeIdPointer && is_slice(actual_type) && 13297 ((wanted_type->data.pointer.ptr_len == PtrLenUnknown && wanted_type->data.pointer.sentinel != nullptr) || 13298 wanted_type->data.pointer.ptr_len == PtrLenC)) 13299 { 13300 ZigType *slice_ptr_type = resolve_struct_field_type(ira->codegen, 13301 actual_type->data.structure.fields[slice_ptr_index]); 13302 if (types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 13303 slice_ptr_type->data.pointer.child_type, source_node, 13304 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk && 13305 (slice_ptr_type->data.pointer.sentinel != nullptr && 13306 (wanted_type->data.pointer.ptr_len == PtrLenC || 13307 const_values_equal(ira->codegen, wanted_type->data.pointer.sentinel, 13308 slice_ptr_type->data.pointer.sentinel)))) 13309 { 13310 TypeStructField *ptr_field = actual_type->data.structure.fields[slice_ptr_index]; 13311 IrInstruction *slice_ptr = ir_analyze_struct_value_field_value(ira, source_instr, value, ptr_field); 13312 return ir_implicit_cast2(ira, source_instr, slice_ptr, wanted_type); 13313 } 13314 } 13315 13316 // cast from *T and [*]T to *c_void and ?*c_void 13317 // but don't do it if the actual type is a double pointer 13318 if (is_pointery_and_elem_is_not_pointery(actual_type)) { 13319 ZigType *dest_ptr_type = nullptr; 13320 if (wanted_type->id == ZigTypeIdPointer && 13321 wanted_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 13322 { 13323 dest_ptr_type = wanted_type; 13324 } else if (wanted_type->id == ZigTypeIdOptional && 13325 wanted_type->data.maybe.child_type->id == ZigTypeIdPointer && 13326 wanted_type->data.maybe.child_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 13327 { 13328 dest_ptr_type = wanted_type->data.maybe.child_type; 13329 } 13330 if (dest_ptr_type != nullptr) { 13331 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true); 13332 } 13333 } 13334 13335 // cast from T to *T where T is zero bits 13336 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 13337 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 13338 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 13339 { 13340 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) { 13341 return ira->codegen->invalid_instruction; 13342 } 13343 if (!type_has_bits(actual_type)) { 13344 return ir_get_ref(ira, source_instr, value, false, false); 13345 } 13346 } 13347 13348 // cast from @Vector(N, T) to [N]T 13349 if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdVector && 13350 wanted_type->data.array.len == actual_type->data.vector.len && 13351 types_match_const_cast_only(ira, wanted_type->data.array.child_type, 13352 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 13353 { 13354 return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type, nullptr); 13355 } 13356 13357 // cast from [N]T to @Vector(N, T) 13358 if (actual_type->id == ZigTypeIdArray && wanted_type->id == ZigTypeIdVector && 13359 actual_type->data.array.len == wanted_type->data.vector.len && 13360 types_match_const_cast_only(ira, actual_type->data.array.child_type, 13361 wanted_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 13362 { 13363 return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type); 13364 } 13365 13366 // casting between C pointers and normal pointers 13367 if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer && 13368 (wanted_type->data.pointer.ptr_len == PtrLenC || actual_type->data.pointer.ptr_len == PtrLenC) && 13369 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 13370 actual_type->data.pointer.child_type, source_node, 13371 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 13372 { 13373 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true); 13374 } 13375 13376 // cast from integer to C pointer 13377 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 13378 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt)) 13379 { 13380 return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type); 13381 } 13382 13383 // cast from inferred struct type to array, union, or struct 13384 if (actual_type->id == ZigTypeIdStruct && actual_type->data.structure.is_inferred) { 13385 AstNode *decl_node = actual_type->data.structure.decl_node; 13386 ir_assert(decl_node->type == NodeTypeContainerInitExpr, source_instr); 13387 ContainerInitKind init_kind = decl_node->data.container_init_expr.kind; 13388 uint32_t field_count = actual_type->data.structure.src_field_count; 13389 if (wanted_type->id == ZigTypeIdArray && (init_kind == ContainerInitKindArray || field_count == 0) && 13390 wanted_type->data.array.len == field_count) 13391 { 13392 return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type); 13393 } else if (wanted_type->id == ZigTypeIdStruct && 13394 (init_kind == ContainerInitKindStruct || field_count == 0)) 13395 { 13396 return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type); 13397 } else if (wanted_type->id == ZigTypeIdUnion && init_kind == ContainerInitKindStruct && field_count == 1) { 13398 return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type); 13399 } 13400 } 13401 13402 // cast from undefined to anything 13403 if (actual_type->id == ZigTypeIdUndefined) { 13404 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); 13405 } 13406 13407 // T to ?U, where T implicitly casts to U 13408 if (wanted_type->id == ZigTypeIdOptional && actual_type->id != ZigTypeIdOptional) { 13409 IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); 13410 if (type_is_invalid(cast1->value->type)) 13411 return ira->codegen->invalid_instruction; 13412 return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); 13413 } 13414 13415 // T to E!U, where T implicitly casts to U 13416 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id != ZigTypeIdErrorUnion && 13417 actual_type->id != ZigTypeIdErrorSet) 13418 { 13419 IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.error_union.payload_type); 13420 if (type_is_invalid(cast1->value->type)) 13421 return ira->codegen->invalid_instruction; 13422 return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); 13423 } 13424 13425 ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, 13426 buf_sprintf("expected type '%s', found '%s'", 13427 buf_ptr(&wanted_type->name), 13428 buf_ptr(&actual_type->name))); 13429 report_recursive_error(ira, source_instr->source_node, &const_cast_result, parent_msg); 13430 return ira->codegen->invalid_instruction; 13431 } 13432 13433 static IrInstruction *ir_implicit_cast2(IrAnalyze *ira, IrInstruction *value_source_instr, 13434 IrInstruction *value, ZigType *expected_type) 13435 { 13436 assert(value); 13437 assert(value != ira->codegen->invalid_instruction); 13438 assert(!expected_type || !type_is_invalid(expected_type)); 13439 assert(value->value->type); 13440 assert(!type_is_invalid(value->value->type)); 13441 if (expected_type == nullptr) 13442 return value; // anything will do 13443 if (expected_type == value->value->type) 13444 return value; // match 13445 if (value->value->type->id == ZigTypeIdUnreachable) 13446 return value; 13447 13448 return ir_analyze_cast(ira, value_source_instr, expected_type, value); 13449 } 13450 13451 static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { 13452 return ir_implicit_cast2(ira, value, value, expected_type); 13453 } 13454 13455 static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, 13456 ResultLoc *result_loc) 13457 { 13458 Error err; 13459 ZigType *ptr_type = ptr->value->type; 13460 if (type_is_invalid(ptr_type)) 13461 return ira->codegen->invalid_instruction; 13462 13463 if (ptr_type->id != ZigTypeIdPointer) { 13464 ir_add_error_node(ira, source_instruction->source_node, 13465 buf_sprintf("attempt to dereference non-pointer type '%s'", 13466 buf_ptr(&ptr_type->name))); 13467 return ira->codegen->invalid_instruction; 13468 } 13469 13470 ZigType *child_type = ptr_type->data.pointer.child_type; 13471 // if the child type has one possible value, the deref is comptime 13472 switch (type_has_one_possible_value(ira->codegen, child_type)) { 13473 case OnePossibleValueInvalid: 13474 return ira->codegen->invalid_instruction; 13475 case OnePossibleValueYes: 13476 return ir_const(ira, source_instruction, child_type); 13477 case OnePossibleValueNo: 13478 break; 13479 } 13480 if (instr_is_comptime(ptr)) { 13481 if (ptr->value->special == ConstValSpecialUndef) { 13482 ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); 13483 return ira->codegen->invalid_instruction; 13484 } 13485 if (ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 13486 ZigValue *pointee = const_ptr_pointee_unchecked(ira->codegen, ptr->value); 13487 if (child_type == ira->codegen->builtin_types.entry_var) { 13488 child_type = pointee->type; 13489 } 13490 if (pointee->special != ConstValSpecialRuntime) { 13491 IrInstruction *result = ir_const(ira, source_instruction, child_type); 13492 13493 if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, result->value, 13494 ptr->value))) 13495 { 13496 return ira->codegen->invalid_instruction; 13497 } 13498 result->value->type = child_type; 13499 return result; 13500 } 13501 } 13502 } 13503 13504 // if the instruction is a const ref instruction we can skip it 13505 if (ptr->id == IrInstructionIdRef) { 13506 IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr); 13507 return ref_inst->value; 13508 } 13509 13510 // If the instruction is a element pointer instruction to a vector, we emit 13511 // vector element extract instruction rather than load pointer. If the 13512 // pointer type has non-VECTOR_INDEX_RUNTIME value, it would have been 13513 // possible to implement this in the codegen for IrInstructionLoadPtrGen. 13514 // However if it has VECTOR_INDEX_RUNTIME then we must emit a compile error 13515 // if the vector index cannot be determined right here, right now, because 13516 // the type information does not contain enough information to actually 13517 // perform a dereference. 13518 if (ptr_type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) { 13519 if (ptr->id == IrInstructionIdElemPtr) { 13520 IrInstructionElemPtr *elem_ptr = (IrInstructionElemPtr *)ptr; 13521 IrInstruction *vector_loaded = ir_get_deref(ira, elem_ptr->array_ptr, 13522 elem_ptr->array_ptr, nullptr); 13523 IrInstruction *elem_index = elem_ptr->elem_index; 13524 return ir_build_vector_extract_elem(ira, source_instruction, vector_loaded, elem_index); 13525 } 13526 ir_add_error(ira, ptr, 13527 buf_sprintf("unable to determine vector element index of type '%s'", buf_ptr(&ptr_type->name))); 13528 return ira->codegen->invalid_instruction; 13529 } 13530 13531 IrInstruction *result_loc_inst; 13532 if (ptr_type->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { 13533 if (result_loc == nullptr) result_loc = no_result_loc(); 13534 result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, 13535 true, false, true); 13536 if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { 13537 return result_loc_inst; 13538 } 13539 } else { 13540 result_loc_inst = nullptr; 13541 } 13542 13543 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); 13544 } 13545 13546 static bool ir_resolve_const_align(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, 13547 ZigValue *const_val, uint32_t *out) 13548 { 13549 Error err; 13550 if ((err = ir_resolve_const_val(codegen, exec, source_node, const_val, UndefBad))) 13551 return false; 13552 13553 uint32_t align_bytes = bigint_as_u32(&const_val->data.x_bigint); 13554 if (align_bytes == 0) { 13555 exec_add_error_node(codegen, exec, source_node, buf_sprintf("alignment must be >= 1")); 13556 return false; 13557 } 13558 13559 if (!is_power_of_2(align_bytes)) { 13560 exec_add_error_node(codegen, exec, source_node, 13561 buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); 13562 return false; 13563 } 13564 13565 *out = align_bytes; 13566 return true; 13567 } 13568 13569 static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, ZigType *elem_type, uint32_t *out) { 13570 if (type_is_invalid(value->value->type)) 13571 return false; 13572 13573 // Look for this pattern: `*align(@alignOf(T)) T`. 13574 // This can be resolved to be `*out = 0` without resolving any alignment. 13575 if (elem_type != nullptr && value->value->special == ConstValSpecialLazy && 13576 value->value->data.x_lazy->id == LazyValueIdAlignOf) 13577 { 13578 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(value->value->data.x_lazy); 13579 13580 ZigType *lazy_elem_type = ir_resolve_type(lazy_align_of->ira, lazy_align_of->target_type); 13581 if (type_is_invalid(lazy_elem_type)) 13582 return false; 13583 13584 if (elem_type == lazy_elem_type) { 13585 *out = 0; 13586 return true; 13587 } 13588 } 13589 13590 IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); 13591 if (type_is_invalid(casted_value->value->type)) 13592 return false; 13593 13594 return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->source_node, 13595 casted_value->value, out); 13596 } 13597 13598 static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { 13599 if (type_is_invalid(value->value->type)) 13600 return false; 13601 13602 IrInstruction *casted_value = ir_implicit_cast(ira, value, int_type); 13603 if (type_is_invalid(casted_value->value->type)) 13604 return false; 13605 13606 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 13607 if (!const_val) 13608 return false; 13609 13610 *out = bigint_as_u64(&const_val->data.x_bigint); 13611 return true; 13612 } 13613 13614 static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) { 13615 return ir_resolve_unsigned(ira, value, ira->codegen->builtin_types.entry_usize, out); 13616 } 13617 13618 static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) { 13619 if (type_is_invalid(value->value->type)) 13620 return false; 13621 13622 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_bool); 13623 if (type_is_invalid(casted_value->value->type)) 13624 return false; 13625 13626 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 13627 if (!const_val) 13628 return false; 13629 13630 *out = const_val->data.x_bool; 13631 return true; 13632 } 13633 13634 static bool ir_resolve_comptime(IrAnalyze *ira, IrInstruction *value, bool *out) { 13635 if (!value) { 13636 *out = false; 13637 return true; 13638 } 13639 return ir_resolve_bool(ira, value, out); 13640 } 13641 13642 static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, AtomicOrder *out) { 13643 if (type_is_invalid(value->value->type)) 13644 return false; 13645 13646 ZigValue *atomic_order_val = get_builtin_value(ira->codegen, "AtomicOrder"); 13647 assert(atomic_order_val->type->id == ZigTypeIdMetaType); 13648 ZigType *atomic_order_type = atomic_order_val->data.x_type; 13649 13650 IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_order_type); 13651 if (type_is_invalid(casted_value->value->type)) 13652 return false; 13653 13654 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 13655 if (!const_val) 13656 return false; 13657 13658 *out = (AtomicOrder)bigint_as_u32(&const_val->data.x_enum_tag); 13659 return true; 13660 } 13661 13662 static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstruction *value, AtomicRmwOp *out) { 13663 if (type_is_invalid(value->value->type)) 13664 return false; 13665 13666 ZigValue *atomic_rmw_op_val = get_builtin_value(ira->codegen, "AtomicRmwOp"); 13667 assert(atomic_rmw_op_val->type->id == ZigTypeIdMetaType); 13668 ZigType *atomic_rmw_op_type = atomic_rmw_op_val->data.x_type; 13669 13670 IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_rmw_op_type); 13671 if (type_is_invalid(casted_value->value->type)) 13672 return false; 13673 13674 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 13675 if (!const_val) 13676 return false; 13677 13678 *out = (AtomicRmwOp)bigint_as_u32(&const_val->data.x_enum_tag); 13679 return true; 13680 } 13681 13682 static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstruction *value, GlobalLinkageId *out) { 13683 if (type_is_invalid(value->value->type)) 13684 return false; 13685 13686 ZigValue *global_linkage_val = get_builtin_value(ira->codegen, "GlobalLinkage"); 13687 assert(global_linkage_val->type->id == ZigTypeIdMetaType); 13688 ZigType *global_linkage_type = global_linkage_val->data.x_type; 13689 13690 IrInstruction *casted_value = ir_implicit_cast(ira, value, global_linkage_type); 13691 if (type_is_invalid(casted_value->value->type)) 13692 return false; 13693 13694 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 13695 if (!const_val) 13696 return false; 13697 13698 *out = (GlobalLinkageId)bigint_as_u32(&const_val->data.x_enum_tag); 13699 return true; 13700 } 13701 13702 static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMode *out) { 13703 if (type_is_invalid(value->value->type)) 13704 return false; 13705 13706 ZigValue *float_mode_val = get_builtin_value(ira->codegen, "FloatMode"); 13707 assert(float_mode_val->type->id == ZigTypeIdMetaType); 13708 ZigType *float_mode_type = float_mode_val->data.x_type; 13709 13710 IrInstruction *casted_value = ir_implicit_cast(ira, value, float_mode_type); 13711 if (type_is_invalid(casted_value->value->type)) 13712 return false; 13713 13714 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 13715 if (!const_val) 13716 return false; 13717 13718 *out = (FloatMode)bigint_as_u32(&const_val->data.x_enum_tag); 13719 return true; 13720 } 13721 13722 static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { 13723 if (type_is_invalid(value->value->type)) 13724 return nullptr; 13725 13726 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 13727 true, false, PtrLenUnknown, 0, 0, 0, false); 13728 ZigType *str_type = get_slice_type(ira->codegen, ptr_type); 13729 IrInstruction *casted_value = ir_implicit_cast(ira, value, str_type); 13730 if (type_is_invalid(casted_value->value->type)) 13731 return nullptr; 13732 13733 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 13734 if (!const_val) 13735 return nullptr; 13736 13737 ZigValue *ptr_field = const_val->data.x_struct.fields[slice_ptr_index]; 13738 ZigValue *len_field = const_val->data.x_struct.fields[slice_len_index]; 13739 13740 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); 13741 ZigValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; 13742 expand_undef_array(ira->codegen, array_val); 13743 size_t len = bigint_as_usize(&len_field->data.x_bigint); 13744 if (array_val->data.x_array.special == ConstArraySpecialBuf && len == buf_len(array_val->data.x_array.data.s_buf)) { 13745 return array_val->data.x_array.data.s_buf; 13746 } 13747 Buf *result = buf_alloc(); 13748 buf_resize(result, len); 13749 for (size_t i = 0; i < len; i += 1) { 13750 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; 13751 ZigValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index]; 13752 if (char_val->special == ConstValSpecialUndef) { 13753 ir_add_error(ira, casted_value, buf_sprintf("use of undefined value")); 13754 return nullptr; 13755 } 13756 uint64_t big_c = bigint_as_u64(&char_val->data.x_bigint); 13757 assert(big_c <= UINT8_MAX); 13758 uint8_t c = (uint8_t)big_c; 13759 buf_ptr(result)[i] = c; 13760 } 13761 return result; 13762 } 13763 13764 static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, 13765 IrInstructionAddImplicitReturnType *instruction) 13766 { 13767 IrInstruction *value = instruction->value->child; 13768 if (type_is_invalid(value->value->type)) 13769 return ir_unreach_error(ira); 13770 13771 if (instruction->result_loc_ret == nullptr || !instruction->result_loc_ret->implicit_return_type_done) { 13772 ira->src_implicit_return_type_list.append(value); 13773 } 13774 13775 return ir_const_void(ira, &instruction->base); 13776 } 13777 13778 static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructionReturn *instruction) { 13779 IrInstruction *operand = instruction->operand->child; 13780 if (type_is_invalid(operand->value->type)) 13781 return ir_unreach_error(ira); 13782 13783 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type); 13784 if (type_is_invalid(casted_operand->value->type)) { 13785 AstNode *source_node = ira->explicit_return_type_source_node; 13786 if (source_node != nullptr) { 13787 ErrorMsg *msg = ira->codegen->errors.last(); 13788 add_error_note(ira->codegen, msg, source_node, 13789 buf_sprintf("return type declared here")); 13790 } 13791 return ir_unreach_error(ira); 13792 } 13793 13794 if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr && 13795 handle_is_ptr(ira->explicit_return_type)) 13796 { 13797 // result location mechanism took care of it. 13798 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, 13799 instruction->base.source_node, nullptr); 13800 result->value->type = ira->codegen->builtin_types.entry_unreachable; 13801 return ir_finish_anal(ira, result); 13802 } 13803 13804 if (casted_operand->value->special == ConstValSpecialRuntime && 13805 casted_operand->value->type->id == ZigTypeIdPointer && 13806 casted_operand->value->data.rh_ptr == RuntimeHintPtrStack) 13807 { 13808 ir_add_error(ira, casted_operand, buf_sprintf("function returns address of local variable")); 13809 return ir_unreach_error(ira); 13810 } 13811 13812 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, 13813 instruction->base.source_node, casted_operand); 13814 result->value->type = ira->codegen->builtin_types.entry_unreachable; 13815 return ir_finish_anal(ira, result); 13816 } 13817 13818 static IrInstruction *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *instruction) { 13819 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 13820 copy_const_val(result->value, instruction->base.value, true); 13821 return result; 13822 } 13823 13824 static IrInstruction *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 13825 IrInstruction *op1 = bin_op_instruction->op1->child; 13826 if (type_is_invalid(op1->value->type)) 13827 return ira->codegen->invalid_instruction; 13828 13829 IrInstruction *op2 = bin_op_instruction->op2->child; 13830 if (type_is_invalid(op2->value->type)) 13831 return ira->codegen->invalid_instruction; 13832 13833 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 13834 13835 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, bool_type); 13836 if (casted_op1 == ira->codegen->invalid_instruction) 13837 return ira->codegen->invalid_instruction; 13838 13839 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, bool_type); 13840 if (casted_op2 == ira->codegen->invalid_instruction) 13841 return ira->codegen->invalid_instruction; 13842 13843 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 13844 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 13845 if (op1_val == nullptr) 13846 return ira->codegen->invalid_instruction; 13847 13848 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 13849 if (op2_val == nullptr) 13850 return ira->codegen->invalid_instruction; 13851 13852 assert(casted_op1->value->type->id == ZigTypeIdBool); 13853 assert(casted_op2->value->type->id == ZigTypeIdBool); 13854 bool result_bool; 13855 if (bin_op_instruction->op_id == IrBinOpBoolOr) { 13856 result_bool = op1_val->data.x_bool || op2_val->data.x_bool; 13857 } else if (bin_op_instruction->op_id == IrBinOpBoolAnd) { 13858 result_bool = op1_val->data.x_bool && op2_val->data.x_bool; 13859 } else { 13860 zig_unreachable(); 13861 } 13862 return ir_const_bool(ira, &bin_op_instruction->base, result_bool); 13863 } 13864 13865 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 13866 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 13867 bin_op_instruction->op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 13868 result->value->type = bool_type; 13869 return result; 13870 } 13871 13872 static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) { 13873 switch (op_id) { 13874 case IrBinOpCmpEq: 13875 return cmp == CmpEQ; 13876 case IrBinOpCmpNotEq: 13877 return cmp != CmpEQ; 13878 case IrBinOpCmpLessThan: 13879 return cmp == CmpLT; 13880 case IrBinOpCmpGreaterThan: 13881 return cmp == CmpGT; 13882 case IrBinOpCmpLessOrEq: 13883 return cmp != CmpGT; 13884 case IrBinOpCmpGreaterOrEq: 13885 return cmp != CmpLT; 13886 default: 13887 zig_unreachable(); 13888 } 13889 } 13890 13891 static bool optional_value_is_null(ZigValue *val) { 13892 assert(val->special == ConstValSpecialStatic); 13893 if (get_codegen_ptr_type(val->type) != nullptr) { 13894 if (val->data.x_ptr.special == ConstPtrSpecialNull) { 13895 return true; 13896 } else if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 13897 return val->data.x_ptr.data.hard_coded_addr.addr == 0; 13898 } else { 13899 return false; 13900 } 13901 } else if (is_opt_err_set(val->type)) { 13902 return val->data.x_err_set == nullptr; 13903 } else { 13904 return val->data.x_optional == nullptr; 13905 } 13906 } 13907 13908 static IrInstruction *ir_evaluate_bin_op_cmp(IrAnalyze *ira, ZigType *resolved_type, 13909 ZigValue *op1_val, ZigValue *op2_val, IrInstructionBinOp *bin_op_instruction, IrBinOp op_id, 13910 bool one_possible_value) { 13911 if (op1_val->special == ConstValSpecialUndef || 13912 op2_val->special == ConstValSpecialUndef) 13913 return ir_const_undef(ira, &bin_op_instruction->base, resolved_type); 13914 if (resolved_type->id == ZigTypeIdComptimeFloat || resolved_type->id == ZigTypeIdFloat) { 13915 if (float_is_nan(op1_val) || float_is_nan(op2_val)) { 13916 return ir_const_bool(ira, &bin_op_instruction->base, op_id == IrBinOpCmpNotEq); 13917 } 13918 Cmp cmp_result = float_cmp(op1_val, op2_val); 13919 bool answer = resolve_cmp_op_id(op_id, cmp_result); 13920 return ir_const_bool(ira, &bin_op_instruction->base, answer); 13921 } else if (resolved_type->id == ZigTypeIdComptimeInt || resolved_type->id == ZigTypeIdInt) { 13922 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); 13923 bool answer = resolve_cmp_op_id(op_id, cmp_result); 13924 return ir_const_bool(ira, &bin_op_instruction->base, answer); 13925 } else if (resolved_type->id == ZigTypeIdPointer && op_id != IrBinOpCmpEq && op_id != IrBinOpCmpNotEq) { 13926 if ((op1_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 13927 op1_val->data.x_ptr.special == ConstPtrSpecialNull) && 13928 (op2_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 13929 op2_val->data.x_ptr.special == ConstPtrSpecialNull)) 13930 { 13931 uint64_t op1_addr = op1_val->data.x_ptr.special == ConstPtrSpecialNull ? 13932 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; 13933 uint64_t op2_addr = op2_val->data.x_ptr.special == ConstPtrSpecialNull ? 13934 0 : op2_val->data.x_ptr.data.hard_coded_addr.addr; 13935 Cmp cmp_result; 13936 if (op1_addr > op2_addr) { 13937 cmp_result = CmpGT; 13938 } else if (op1_addr < op2_addr) { 13939 cmp_result = CmpLT; 13940 } else { 13941 cmp_result = CmpEQ; 13942 } 13943 bool answer = resolve_cmp_op_id(op_id, cmp_result); 13944 return ir_const_bool(ira, &bin_op_instruction->base, answer); 13945 } 13946 } else { 13947 bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val); 13948 bool answer; 13949 if (op_id == IrBinOpCmpEq) { 13950 answer = are_equal; 13951 } else if (op_id == IrBinOpCmpNotEq) { 13952 answer = !are_equal; 13953 } else { 13954 zig_unreachable(); 13955 } 13956 return ir_const_bool(ira, &bin_op_instruction->base, answer); 13957 } 13958 zig_unreachable(); 13959 } 13960 13961 // Returns ErrorNotLazy when the value cannot be determined 13962 static Error lazy_cmp_zero(AstNode *source_node, ZigValue *val, Cmp *result) { 13963 Error err; 13964 13965 switch (val->special) { 13966 case ConstValSpecialRuntime: 13967 case ConstValSpecialUndef: 13968 return ErrorNotLazy; 13969 case ConstValSpecialStatic: 13970 switch (val->type->id) { 13971 case ZigTypeIdComptimeInt: 13972 case ZigTypeIdInt: 13973 *result = bigint_cmp_zero(&val->data.x_bigint); 13974 return ErrorNone; 13975 default: 13976 return ErrorNotLazy; 13977 } 13978 case ConstValSpecialLazy: 13979 switch (val->data.x_lazy->id) { 13980 case LazyValueIdInvalid: 13981 zig_unreachable(); 13982 case LazyValueIdAlignOf: 13983 *result = CmpGT; 13984 return ErrorNone; 13985 case LazyValueIdSizeOf: { 13986 LazyValueSizeOf *lazy_size_of = reinterpret_cast<LazyValueSizeOf *>(val->data.x_lazy); 13987 IrAnalyze *ira = lazy_size_of->ira; 13988 bool is_zero_bits; 13989 if ((err = type_val_resolve_zero_bits(ira->codegen, lazy_size_of->target_type->value, 13990 nullptr, nullptr, &is_zero_bits))) 13991 { 13992 return err; 13993 } 13994 *result = is_zero_bits ? CmpEQ : CmpGT; 13995 return ErrorNone; 13996 } 13997 default: 13998 return ErrorNotLazy; 13999 } 14000 } 14001 zig_unreachable(); 14002 } 14003 14004 static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 14005 Error err; 14006 14007 IrInstruction *op1 = bin_op_instruction->op1->child; 14008 if (type_is_invalid(op1->value->type)) 14009 return ira->codegen->invalid_instruction; 14010 14011 IrInstruction *op2 = bin_op_instruction->op2->child; 14012 if (type_is_invalid(op2->value->type)) 14013 return ira->codegen->invalid_instruction; 14014 14015 AstNode *source_node = bin_op_instruction->base.source_node; 14016 14017 IrBinOp op_id = bin_op_instruction->op_id; 14018 bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 14019 if (is_equality_cmp && op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdNull) { 14020 return ir_const_bool(ira, &bin_op_instruction->base, (op_id == IrBinOpCmpEq)); 14021 } else if (is_equality_cmp && 14022 ((op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdOptional) || 14023 (op2->value->type->id == ZigTypeIdNull && op1->value->type->id == ZigTypeIdOptional))) 14024 { 14025 IrInstruction *maybe_op; 14026 if (op1->value->type->id == ZigTypeIdNull) { 14027 maybe_op = op2; 14028 } else if (op2->value->type->id == ZigTypeIdNull) { 14029 maybe_op = op1; 14030 } else { 14031 zig_unreachable(); 14032 } 14033 if (instr_is_comptime(maybe_op)) { 14034 ZigValue *maybe_val = ir_resolve_const(ira, maybe_op, UndefBad); 14035 if (!maybe_val) 14036 return ira->codegen->invalid_instruction; 14037 bool is_null = optional_value_is_null(maybe_val); 14038 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 14039 return ir_const_bool(ira, &bin_op_instruction->base, bool_result); 14040 } 14041 14042 IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope, 14043 source_node, maybe_op); 14044 is_non_null->value->type = ira->codegen->builtin_types.entry_bool; 14045 14046 if (op_id == IrBinOpCmpEq) { 14047 IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope, 14048 bin_op_instruction->base.source_node, is_non_null); 14049 result->value->type = ira->codegen->builtin_types.entry_bool; 14050 return result; 14051 } else { 14052 return is_non_null; 14053 } 14054 } else if (is_equality_cmp && 14055 ((op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdPointer && 14056 op2->value->type->data.pointer.ptr_len == PtrLenC) || 14057 (op2->value->type->id == ZigTypeIdNull && op1->value->type->id == ZigTypeIdPointer && 14058 op1->value->type->data.pointer.ptr_len == PtrLenC))) 14059 { 14060 IrInstruction *c_ptr_op; 14061 if (op1->value->type->id == ZigTypeIdNull) { 14062 c_ptr_op = op2; 14063 } else if (op2->value->type->id == ZigTypeIdNull) { 14064 c_ptr_op = op1; 14065 } else { 14066 zig_unreachable(); 14067 } 14068 if (instr_is_comptime(c_ptr_op)) { 14069 ZigValue *c_ptr_val = ir_resolve_const(ira, c_ptr_op, UndefOk); 14070 if (!c_ptr_val) 14071 return ira->codegen->invalid_instruction; 14072 if (c_ptr_val->special == ConstValSpecialUndef) 14073 return ir_const_undef(ira, &bin_op_instruction->base, ira->codegen->builtin_types.entry_bool); 14074 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 14075 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 14076 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 14077 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 14078 return ir_const_bool(ira, &bin_op_instruction->base, bool_result); 14079 } 14080 IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope, 14081 source_node, c_ptr_op); 14082 is_non_null->value->type = ira->codegen->builtin_types.entry_bool; 14083 14084 if (op_id == IrBinOpCmpEq) { 14085 IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope, 14086 bin_op_instruction->base.source_node, is_non_null); 14087 result->value->type = ira->codegen->builtin_types.entry_bool; 14088 return result; 14089 } else { 14090 return is_non_null; 14091 } 14092 } else if (op1->value->type->id == ZigTypeIdNull || op2->value->type->id == ZigTypeIdNull) { 14093 ZigType *non_null_type = (op1->value->type->id == ZigTypeIdNull) ? op2->value->type : op1->value->type; 14094 ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null", 14095 buf_ptr(&non_null_type->name))); 14096 return ira->codegen->invalid_instruction; 14097 } else if (is_equality_cmp && ( 14098 (op1->value->type->id == ZigTypeIdEnumLiteral && op2->value->type->id == ZigTypeIdUnion) || 14099 (op2->value->type->id == ZigTypeIdEnumLiteral && op1->value->type->id == ZigTypeIdUnion))) 14100 { 14101 // Support equality comparison between a union's tag value and a enum literal 14102 IrInstruction *union_val = op1->value->type->id == ZigTypeIdUnion ? op1 : op2; 14103 IrInstruction *enum_val = op1->value->type->id == ZigTypeIdUnion ? op2 : op1; 14104 14105 ZigType *tag_type = union_val->value->type->data.unionation.tag_type; 14106 assert(tag_type != nullptr); 14107 14108 IrInstruction *casted_union = ir_implicit_cast(ira, union_val, tag_type); 14109 if (type_is_invalid(casted_union->value->type)) 14110 return ira->codegen->invalid_instruction; 14111 14112 IrInstruction *casted_val = ir_implicit_cast(ira, enum_val, tag_type); 14113 if (type_is_invalid(casted_val->value->type)) 14114 return ira->codegen->invalid_instruction; 14115 14116 if (instr_is_comptime(casted_union)) { 14117 ZigValue *const_union_val = ir_resolve_const(ira, casted_union, UndefBad); 14118 if (!const_union_val) 14119 return ira->codegen->invalid_instruction; 14120 14121 ZigValue *const_enum_val = ir_resolve_const(ira, casted_val, UndefBad); 14122 if (!const_enum_val) 14123 return ira->codegen->invalid_instruction; 14124 14125 Cmp cmp_result = bigint_cmp(&const_union_val->data.x_union.tag, &const_enum_val->data.x_enum_tag); 14126 bool bool_result = (op_id == IrBinOpCmpEq) ? cmp_result == CmpEQ : cmp_result != CmpEQ; 14127 14128 return ir_const_bool(ira, &bin_op_instruction->base, bool_result); 14129 } 14130 14131 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 14132 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 14133 op_id, casted_union, casted_val, bin_op_instruction->safety_check_on); 14134 result->value->type = ira->codegen->builtin_types.entry_bool; 14135 14136 return result; 14137 } 14138 14139 if (op1->value->type->id == ZigTypeIdErrorSet && op2->value->type->id == ZigTypeIdErrorSet) { 14140 if (!is_equality_cmp) { 14141 ir_add_error_node(ira, source_node, buf_sprintf("operator not allowed for errors")); 14142 return ira->codegen->invalid_instruction; 14143 } 14144 ZigType *intersect_type = get_error_set_intersection(ira, op1->value->type, op2->value->type, source_node); 14145 if (type_is_invalid(intersect_type)) { 14146 return ira->codegen->invalid_instruction; 14147 } 14148 14149 if (!resolve_inferred_error_set(ira->codegen, intersect_type, source_node)) { 14150 return ira->codegen->invalid_instruction; 14151 } 14152 14153 // exception if one of the operators has the type of the empty error set, we allow the comparison 14154 // (and make it comptime known) 14155 // this is a function which is evaluated at comptime and returns an inferred error set will have an empty 14156 // error set. 14157 if (op1->value->type->data.error_set.err_count == 0 || op2->value->type->data.error_set.err_count == 0) { 14158 bool are_equal = false; 14159 bool answer; 14160 if (op_id == IrBinOpCmpEq) { 14161 answer = are_equal; 14162 } else if (op_id == IrBinOpCmpNotEq) { 14163 answer = !are_equal; 14164 } else { 14165 zig_unreachable(); 14166 } 14167 return ir_const_bool(ira, &bin_op_instruction->base, answer); 14168 } 14169 14170 if (!type_is_global_error_set(intersect_type)) { 14171 if (intersect_type->data.error_set.err_count == 0) { 14172 ir_add_error_node(ira, source_node, 14173 buf_sprintf("error sets '%s' and '%s' have no common errors", 14174 buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); 14175 return ira->codegen->invalid_instruction; 14176 } 14177 if (op1->value->type->data.error_set.err_count == 1 && op2->value->type->data.error_set.err_count == 1) { 14178 bool are_equal = true; 14179 bool answer; 14180 if (op_id == IrBinOpCmpEq) { 14181 answer = are_equal; 14182 } else if (op_id == IrBinOpCmpNotEq) { 14183 answer = !are_equal; 14184 } else { 14185 zig_unreachable(); 14186 } 14187 return ir_const_bool(ira, &bin_op_instruction->base, answer); 14188 } 14189 } 14190 14191 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 14192 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 14193 if (op1_val == nullptr) 14194 return ira->codegen->invalid_instruction; 14195 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 14196 if (op2_val == nullptr) 14197 return ira->codegen->invalid_instruction; 14198 14199 bool answer; 14200 bool are_equal = op1_val->data.x_err_set->value == op2_val->data.x_err_set->value; 14201 if (op_id == IrBinOpCmpEq) { 14202 answer = are_equal; 14203 } else if (op_id == IrBinOpCmpNotEq) { 14204 answer = !are_equal; 14205 } else { 14206 zig_unreachable(); 14207 } 14208 14209 return ir_const_bool(ira, &bin_op_instruction->base, answer); 14210 } 14211 14212 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 14213 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 14214 op_id, op1, op2, bin_op_instruction->safety_check_on); 14215 result->value->type = ira->codegen->builtin_types.entry_bool; 14216 return result; 14217 } 14218 14219 IrInstruction *instructions[] = {op1, op2}; 14220 ZigType *resolved_type = ir_resolve_peer_types(ira, source_node, nullptr, instructions, 2); 14221 if (type_is_invalid(resolved_type)) 14222 return ira->codegen->invalid_instruction; 14223 14224 bool operator_allowed; 14225 switch (resolved_type->id) { 14226 case ZigTypeIdInvalid: 14227 zig_unreachable(); // handled above 14228 14229 case ZigTypeIdComptimeFloat: 14230 case ZigTypeIdComptimeInt: 14231 case ZigTypeIdInt: 14232 case ZigTypeIdFloat: 14233 case ZigTypeIdVector: 14234 operator_allowed = true; 14235 break; 14236 14237 case ZigTypeIdBool: 14238 case ZigTypeIdMetaType: 14239 case ZigTypeIdVoid: 14240 case ZigTypeIdErrorSet: 14241 case ZigTypeIdFn: 14242 case ZigTypeIdOpaque: 14243 case ZigTypeIdBoundFn: 14244 case ZigTypeIdArgTuple: 14245 case ZigTypeIdEnum: 14246 case ZigTypeIdEnumLiteral: 14247 case ZigTypeIdAnyFrame: 14248 operator_allowed = is_equality_cmp; 14249 break; 14250 14251 case ZigTypeIdPointer: 14252 operator_allowed = is_equality_cmp || (resolved_type->data.pointer.ptr_len == PtrLenC); 14253 break; 14254 14255 case ZigTypeIdUnreachable: 14256 case ZigTypeIdArray: 14257 case ZigTypeIdStruct: 14258 case ZigTypeIdUndefined: 14259 case ZigTypeIdNull: 14260 case ZigTypeIdErrorUnion: 14261 case ZigTypeIdUnion: 14262 case ZigTypeIdFnFrame: 14263 operator_allowed = false; 14264 break; 14265 case ZigTypeIdOptional: 14266 operator_allowed = is_equality_cmp && get_codegen_ptr_type(resolved_type) != nullptr; 14267 break; 14268 } 14269 if (!operator_allowed) { 14270 ir_add_error_node(ira, source_node, 14271 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); 14272 return ira->codegen->invalid_instruction; 14273 } 14274 14275 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 14276 if (casted_op1 == ira->codegen->invalid_instruction) 14277 return ira->codegen->invalid_instruction; 14278 14279 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 14280 if (casted_op2 == ira->codegen->invalid_instruction) 14281 return ira->codegen->invalid_instruction; 14282 14283 bool one_possible_value; 14284 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 14285 case OnePossibleValueInvalid: 14286 return ira->codegen->invalid_instruction; 14287 case OnePossibleValueYes: 14288 one_possible_value = true; 14289 break; 14290 case OnePossibleValueNo: 14291 one_possible_value = false; 14292 break; 14293 } 14294 14295 if (one_possible_value || (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2))) { 14296 { 14297 // Before resolving the values, we special case comparisons against zero. These can often be done 14298 // without resolving lazy values, preventing potential dependency loops. 14299 Cmp op1_cmp_zero; 14300 if ((err = lazy_cmp_zero(bin_op_instruction->base.source_node, casted_op1->value, &op1_cmp_zero))) { 14301 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally; 14302 return ira->codegen->invalid_instruction; 14303 } 14304 Cmp op2_cmp_zero; 14305 if ((err = lazy_cmp_zero(bin_op_instruction->base.source_node, casted_op2->value, &op2_cmp_zero))) { 14306 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally; 14307 return ira->codegen->invalid_instruction; 14308 } 14309 bool can_cmp_zero = false; 14310 Cmp cmp_result; 14311 if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpEQ) { 14312 can_cmp_zero = true; 14313 cmp_result = CmpEQ; 14314 } else if (op1_cmp_zero == CmpGT && op2_cmp_zero == CmpEQ) { 14315 can_cmp_zero = true; 14316 cmp_result = CmpGT; 14317 } else if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpGT) { 14318 can_cmp_zero = true; 14319 cmp_result = CmpLT; 14320 } else if (op1_cmp_zero == CmpLT && op2_cmp_zero == CmpEQ) { 14321 can_cmp_zero = true; 14322 cmp_result = CmpLT; 14323 } else if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpLT) { 14324 can_cmp_zero = true; 14325 cmp_result = CmpGT; 14326 } else if (op1_cmp_zero == CmpLT && op2_cmp_zero == CmpGT) { 14327 can_cmp_zero = true; 14328 cmp_result = CmpLT; 14329 } else if (op1_cmp_zero == CmpGT && op2_cmp_zero == CmpLT) { 14330 can_cmp_zero = true; 14331 cmp_result = CmpGT; 14332 } 14333 if (can_cmp_zero) { 14334 bool answer = resolve_cmp_op_id(op_id, cmp_result); 14335 return ir_const_bool(ira, &bin_op_instruction->base, answer); 14336 } 14337 } 14338 never_mind_just_calculate_it_normally: 14339 14340 ZigValue *op1_val = one_possible_value ? casted_op1->value : ir_resolve_const(ira, casted_op1, UndefBad); 14341 if (op1_val == nullptr) 14342 return ira->codegen->invalid_instruction; 14343 ZigValue *op2_val = one_possible_value ? casted_op2->value : ir_resolve_const(ira, casted_op2, UndefBad); 14344 if (op2_val == nullptr) 14345 return ira->codegen->invalid_instruction; 14346 if (resolved_type->id != ZigTypeIdVector) 14347 return ir_evaluate_bin_op_cmp(ira, resolved_type, op1_val, op2_val, bin_op_instruction, op_id, one_possible_value); 14348 IrInstruction *result = ir_const(ira, &bin_op_instruction->base, 14349 get_vector_type(ira->codegen, resolved_type->data.vector.len, ira->codegen->builtin_types.entry_bool)); 14350 result->value->data.x_array.data.s_none.elements = 14351 create_const_vals(resolved_type->data.vector.len); 14352 14353 expand_undef_array(ira->codegen, result->value); 14354 for (size_t i = 0;i < resolved_type->data.vector.len;i++) { 14355 IrInstruction *cur_res = ir_evaluate_bin_op_cmp(ira, resolved_type->data.vector.elem_type, 14356 &op1_val->data.x_array.data.s_none.elements[i], 14357 &op2_val->data.x_array.data.s_none.elements[i], 14358 bin_op_instruction, op_id, one_possible_value); 14359 copy_const_val(&result->value->data.x_array.data.s_none.elements[i], cur_res->value, false); 14360 } 14361 return result; 14362 } 14363 14364 // some comparisons with unsigned numbers can be evaluated 14365 if (resolved_type->id == ZigTypeIdInt && !resolved_type->data.integral.is_signed) { 14366 ZigValue *known_left_val; 14367 IrBinOp flipped_op_id; 14368 if (instr_is_comptime(casted_op1)) { 14369 known_left_val = ir_resolve_const(ira, casted_op1, UndefBad); 14370 if (known_left_val == nullptr) 14371 return ira->codegen->invalid_instruction; 14372 14373 flipped_op_id = op_id; 14374 } else if (instr_is_comptime(casted_op2)) { 14375 known_left_val = ir_resolve_const(ira, casted_op2, UndefBad); 14376 if (known_left_val == nullptr) 14377 return ira->codegen->invalid_instruction; 14378 14379 if (op_id == IrBinOpCmpLessThan) { 14380 flipped_op_id = IrBinOpCmpGreaterThan; 14381 } else if (op_id == IrBinOpCmpGreaterThan) { 14382 flipped_op_id = IrBinOpCmpLessThan; 14383 } else if (op_id == IrBinOpCmpLessOrEq) { 14384 flipped_op_id = IrBinOpCmpGreaterOrEq; 14385 } else if (op_id == IrBinOpCmpGreaterOrEq) { 14386 flipped_op_id = IrBinOpCmpLessOrEq; 14387 } else { 14388 flipped_op_id = op_id; 14389 } 14390 } else { 14391 known_left_val = nullptr; 14392 } 14393 if (known_left_val != nullptr && bigint_cmp_zero(&known_left_val->data.x_bigint) == CmpEQ && 14394 (flipped_op_id == IrBinOpCmpLessOrEq || flipped_op_id == IrBinOpCmpGreaterThan)) 14395 { 14396 bool answer = (flipped_op_id == IrBinOpCmpLessOrEq); 14397 return ir_const_bool(ira, &bin_op_instruction->base, answer); 14398 } 14399 } 14400 14401 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 14402 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 14403 op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 14404 if (resolved_type->id == ZigTypeIdVector) { 14405 result->value->type = get_vector_type(ira->codegen, resolved_type->data.vector.len, 14406 ira->codegen->builtin_types.entry_bool); 14407 } else { 14408 result->value->type = ira->codegen->builtin_types.entry_bool; 14409 } 14410 return result; 14411 } 14412 14413 static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *type_entry, 14414 ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val, ZigValue *out_val) 14415 { 14416 bool is_int; 14417 bool is_float; 14418 Cmp op2_zcmp; 14419 if (type_entry->id == ZigTypeIdInt || type_entry->id == ZigTypeIdComptimeInt) { 14420 is_int = true; 14421 is_float = false; 14422 op2_zcmp = bigint_cmp_zero(&op2_val->data.x_bigint); 14423 } else if (type_entry->id == ZigTypeIdFloat || 14424 type_entry->id == ZigTypeIdComptimeFloat) 14425 { 14426 is_int = false; 14427 is_float = true; 14428 op2_zcmp = float_cmp_zero(op2_val); 14429 } else { 14430 zig_unreachable(); 14431 } 14432 14433 if ((op_id == IrBinOpDivUnspecified || op_id == IrBinOpRemRem || op_id == IrBinOpRemMod || 14434 op_id == IrBinOpDivTrunc || op_id == IrBinOpDivFloor) && op2_zcmp == CmpEQ) 14435 { 14436 return ir_add_error(ira, source_instr, buf_sprintf("division by zero")); 14437 } 14438 if ((op_id == IrBinOpRemRem || op_id == IrBinOpRemMod) && op2_zcmp == CmpLT) { 14439 return ir_add_error(ira, source_instr, buf_sprintf("negative denominator")); 14440 } 14441 14442 switch (op_id) { 14443 case IrBinOpInvalid: 14444 case IrBinOpBoolOr: 14445 case IrBinOpBoolAnd: 14446 case IrBinOpCmpEq: 14447 case IrBinOpCmpNotEq: 14448 case IrBinOpCmpLessThan: 14449 case IrBinOpCmpGreaterThan: 14450 case IrBinOpCmpLessOrEq: 14451 case IrBinOpCmpGreaterOrEq: 14452 case IrBinOpArrayCat: 14453 case IrBinOpArrayMult: 14454 case IrBinOpRemUnspecified: 14455 zig_unreachable(); 14456 case IrBinOpBinOr: 14457 assert(is_int); 14458 bigint_or(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14459 break; 14460 case IrBinOpBinXor: 14461 assert(is_int); 14462 bigint_xor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14463 break; 14464 case IrBinOpBinAnd: 14465 assert(is_int); 14466 bigint_and(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14467 break; 14468 case IrBinOpBitShiftLeftExact: 14469 assert(is_int); 14470 bigint_shl(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14471 break; 14472 case IrBinOpBitShiftLeftLossy: 14473 assert(type_entry->id == ZigTypeIdInt); 14474 bigint_shl_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 14475 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 14476 break; 14477 case IrBinOpBitShiftRightExact: 14478 { 14479 assert(is_int); 14480 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14481 BigInt orig_bigint; 14482 bigint_shl(&orig_bigint, &out_val->data.x_bigint, &op2_val->data.x_bigint); 14483 if (bigint_cmp(&op1_val->data.x_bigint, &orig_bigint) != CmpEQ) { 14484 return ir_add_error(ira, source_instr, buf_sprintf("exact shift shifted out 1 bits")); 14485 } 14486 break; 14487 } 14488 case IrBinOpBitShiftRightLossy: 14489 assert(is_int); 14490 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14491 break; 14492 case IrBinOpAdd: 14493 if (is_int) { 14494 bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14495 } else { 14496 float_add(out_val, op1_val, op2_val); 14497 } 14498 break; 14499 case IrBinOpAddWrap: 14500 assert(type_entry->id == ZigTypeIdInt); 14501 bigint_add_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 14502 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 14503 break; 14504 case IrBinOpSub: 14505 if (is_int) { 14506 bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14507 } else { 14508 float_sub(out_val, op1_val, op2_val); 14509 } 14510 break; 14511 case IrBinOpSubWrap: 14512 assert(type_entry->id == ZigTypeIdInt); 14513 bigint_sub_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 14514 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 14515 break; 14516 case IrBinOpMult: 14517 if (is_int) { 14518 bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14519 } else { 14520 float_mul(out_val, op1_val, op2_val); 14521 } 14522 break; 14523 case IrBinOpMultWrap: 14524 assert(type_entry->id == ZigTypeIdInt); 14525 bigint_mul_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 14526 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 14527 break; 14528 case IrBinOpDivUnspecified: 14529 assert(is_float); 14530 float_div(out_val, op1_val, op2_val); 14531 break; 14532 case IrBinOpDivTrunc: 14533 if (is_int) { 14534 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14535 } else { 14536 float_div_trunc(out_val, op1_val, op2_val); 14537 } 14538 break; 14539 case IrBinOpDivFloor: 14540 if (is_int) { 14541 bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14542 } else { 14543 float_div_floor(out_val, op1_val, op2_val); 14544 } 14545 break; 14546 case IrBinOpDivExact: 14547 if (is_int) { 14548 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14549 BigInt remainder; 14550 bigint_rem(&remainder, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14551 if (bigint_cmp_zero(&remainder) != CmpEQ) { 14552 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 14553 } 14554 } else { 14555 float_div_trunc(out_val, op1_val, op2_val); 14556 ZigValue remainder = {}; 14557 float_rem(&remainder, op1_val, op2_val); 14558 if (float_cmp_zero(&remainder) != CmpEQ) { 14559 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 14560 } 14561 } 14562 break; 14563 case IrBinOpRemRem: 14564 if (is_int) { 14565 bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14566 } else { 14567 float_rem(out_val, op1_val, op2_val); 14568 } 14569 break; 14570 case IrBinOpRemMod: 14571 if (is_int) { 14572 bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14573 } else { 14574 float_mod(out_val, op1_val, op2_val); 14575 } 14576 break; 14577 } 14578 14579 if (type_entry->id == ZigTypeIdInt) { 14580 if (!bigint_fits_in_bits(&out_val->data.x_bigint, type_entry->data.integral.bit_count, 14581 type_entry->data.integral.is_signed)) 14582 { 14583 return ir_add_error(ira, source_instr, buf_sprintf("operation caused overflow")); 14584 } 14585 } 14586 14587 out_val->type = type_entry; 14588 out_val->special = ConstValSpecialStatic; 14589 return nullptr; 14590 } 14591 14592 // This works on operands that have already been checked to be comptime known. 14593 static IrInstruction *ir_analyze_math_op(IrAnalyze *ira, IrInstruction *source_instr, 14594 ZigType *type_entry, ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val) 14595 { 14596 IrInstruction *result_instruction = ir_const(ira, source_instr, type_entry); 14597 ZigValue *out_val = result_instruction->value; 14598 if (type_entry->id == ZigTypeIdVector) { 14599 expand_undef_array(ira->codegen, op1_val); 14600 expand_undef_array(ira->codegen, op2_val); 14601 out_val->special = ConstValSpecialUndef; 14602 expand_undef_array(ira->codegen, out_val); 14603 size_t len = type_entry->data.vector.len; 14604 ZigType *scalar_type = type_entry->data.vector.elem_type; 14605 for (size_t i = 0; i < len; i += 1) { 14606 ZigValue *scalar_op1_val = &op1_val->data.x_array.data.s_none.elements[i]; 14607 ZigValue *scalar_op2_val = &op2_val->data.x_array.data.s_none.elements[i]; 14608 ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 14609 assert(scalar_op1_val->type == scalar_type); 14610 assert(scalar_op2_val->type == scalar_type); 14611 assert(scalar_out_val->type == scalar_type); 14612 ErrorMsg *msg = ir_eval_math_op_scalar(ira, source_instr, scalar_type, 14613 scalar_op1_val, op_id, scalar_op2_val, scalar_out_val); 14614 if (msg != nullptr) { 14615 add_error_note(ira->codegen, msg, source_instr->source_node, 14616 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 14617 return ira->codegen->invalid_instruction; 14618 } 14619 } 14620 out_val->type = type_entry; 14621 out_val->special = ConstValSpecialStatic; 14622 } else { 14623 if (ir_eval_math_op_scalar(ira, source_instr, type_entry, op1_val, op_id, op2_val, out_val) != nullptr) { 14624 return ira->codegen->invalid_instruction; 14625 } 14626 } 14627 return ir_implicit_cast(ira, result_instruction, type_entry); 14628 } 14629 14630 static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 14631 IrInstruction *op1 = bin_op_instruction->op1->child; 14632 if (type_is_invalid(op1->value->type)) 14633 return ira->codegen->invalid_instruction; 14634 14635 if (op1->value->type->id != ZigTypeIdInt && op1->value->type->id != ZigTypeIdComptimeInt) { 14636 ir_add_error(ira, bin_op_instruction->op1, 14637 buf_sprintf("bit shifting operation expected integer type, found '%s'", 14638 buf_ptr(&op1->value->type->name))); 14639 return ira->codegen->invalid_instruction; 14640 } 14641 14642 IrInstruction *op2 = bin_op_instruction->op2->child; 14643 if (type_is_invalid(op2->value->type)) 14644 return ira->codegen->invalid_instruction; 14645 14646 if (op2->value->type->id != ZigTypeIdInt && op2->value->type->id != ZigTypeIdComptimeInt) { 14647 ir_add_error(ira, bin_op_instruction->op2, 14648 buf_sprintf("shift amount has to be an integer type, but found '%s'", 14649 buf_ptr(&op2->value->type->name))); 14650 return ira->codegen->invalid_instruction; 14651 } 14652 14653 IrInstruction *casted_op2; 14654 IrBinOp op_id = bin_op_instruction->op_id; 14655 if (op1->value->type->id == ZigTypeIdComptimeInt) { 14656 casted_op2 = op2; 14657 14658 if (op_id == IrBinOpBitShiftLeftLossy) { 14659 op_id = IrBinOpBitShiftLeftExact; 14660 } 14661 14662 if (casted_op2->value->data.x_bigint.is_negative) { 14663 Buf *val_buf = buf_alloc(); 14664 bigint_append_buf(val_buf, &casted_op2->value->data.x_bigint, 10); 14665 ir_add_error(ira, casted_op2, buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); 14666 return ira->codegen->invalid_instruction; 14667 } 14668 } else { 14669 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 14670 op1->value->type->data.integral.bit_count - 1); 14671 if (bin_op_instruction->op_id == IrBinOpBitShiftLeftLossy && 14672 op2->value->type->id == ZigTypeIdComptimeInt) { 14673 if (!bigint_fits_in_bits(&op2->value->data.x_bigint, 14674 shift_amt_type->data.integral.bit_count, 14675 op2->value->data.x_bigint.is_negative)) { 14676 Buf *val_buf = buf_alloc(); 14677 bigint_append_buf(val_buf, &op2->value->data.x_bigint, 10); 14678 ErrorMsg* msg = ir_add_error(ira, 14679 &bin_op_instruction->base, 14680 buf_sprintf("RHS of shift is too large for LHS type")); 14681 add_error_note( 14682 ira->codegen, 14683 msg, 14684 op2->source_node, 14685 buf_sprintf("value %s cannot fit into type %s", 14686 buf_ptr(val_buf), 14687 buf_ptr(&shift_amt_type->name))); 14688 return ira->codegen->invalid_instruction; 14689 } 14690 } 14691 14692 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 14693 if (casted_op2 == ira->codegen->invalid_instruction) 14694 return ira->codegen->invalid_instruction; 14695 } 14696 14697 if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { 14698 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 14699 if (op1_val == nullptr) 14700 return ira->codegen->invalid_instruction; 14701 14702 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 14703 if (op2_val == nullptr) 14704 return ira->codegen->invalid_instruction; 14705 14706 return ir_analyze_math_op(ira, &bin_op_instruction->base, op1->value->type, op1_val, op_id, op2_val); 14707 } else if (op1->value->type->id == ZigTypeIdComptimeInt) { 14708 ir_add_error(ira, &bin_op_instruction->base, 14709 buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known")); 14710 return ira->codegen->invalid_instruction; 14711 } else if (instr_is_comptime(casted_op2) && bigint_cmp_zero(&casted_op2->value->data.x_bigint) == CmpEQ) { 14712 IrInstruction *result = ir_build_cast(&ira->new_irb, bin_op_instruction->base.scope, 14713 bin_op_instruction->base.source_node, op1->value->type, op1, CastOpNoop); 14714 result->value->type = op1->value->type; 14715 return result; 14716 } 14717 14718 IrInstruction *result = ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.scope, 14719 bin_op_instruction->base.source_node, op_id, 14720 op1, casted_op2, bin_op_instruction->safety_check_on); 14721 result->value->type = op1->value->type; 14722 return result; 14723 } 14724 14725 static bool ok_float_op(IrBinOp op) { 14726 switch (op) { 14727 case IrBinOpInvalid: 14728 zig_unreachable(); 14729 case IrBinOpAdd: 14730 case IrBinOpSub: 14731 case IrBinOpMult: 14732 case IrBinOpDivUnspecified: 14733 case IrBinOpDivTrunc: 14734 case IrBinOpDivFloor: 14735 case IrBinOpDivExact: 14736 case IrBinOpRemRem: 14737 case IrBinOpRemMod: 14738 return true; 14739 14740 case IrBinOpBoolOr: 14741 case IrBinOpBoolAnd: 14742 case IrBinOpCmpEq: 14743 case IrBinOpCmpNotEq: 14744 case IrBinOpCmpLessThan: 14745 case IrBinOpCmpGreaterThan: 14746 case IrBinOpCmpLessOrEq: 14747 case IrBinOpCmpGreaterOrEq: 14748 case IrBinOpBinOr: 14749 case IrBinOpBinXor: 14750 case IrBinOpBinAnd: 14751 case IrBinOpBitShiftLeftLossy: 14752 case IrBinOpBitShiftLeftExact: 14753 case IrBinOpBitShiftRightLossy: 14754 case IrBinOpBitShiftRightExact: 14755 case IrBinOpAddWrap: 14756 case IrBinOpSubWrap: 14757 case IrBinOpMultWrap: 14758 case IrBinOpRemUnspecified: 14759 case IrBinOpArrayCat: 14760 case IrBinOpArrayMult: 14761 return false; 14762 } 14763 zig_unreachable(); 14764 } 14765 14766 static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { 14767 switch (op) { 14768 case IrBinOpAdd: 14769 case IrBinOpSub: 14770 break; 14771 default: 14772 return false; 14773 } 14774 if (lhs_type->id != ZigTypeIdPointer) 14775 return false; 14776 switch (lhs_type->data.pointer.ptr_len) { 14777 case PtrLenSingle: 14778 return lhs_type->data.pointer.child_type->id == ZigTypeIdArray; 14779 case PtrLenUnknown: 14780 case PtrLenC: 14781 return true; 14782 } 14783 zig_unreachable(); 14784 } 14785 14786 static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) { 14787 Error err; 14788 14789 IrInstruction *op1 = instruction->op1->child; 14790 if (type_is_invalid(op1->value->type)) 14791 return ira->codegen->invalid_instruction; 14792 14793 IrInstruction *op2 = instruction->op2->child; 14794 if (type_is_invalid(op2->value->type)) 14795 return ira->codegen->invalid_instruction; 14796 14797 IrBinOp op_id = instruction->op_id; 14798 14799 // look for pointer math 14800 if (is_pointer_arithmetic_allowed(op1->value->type, op_id)) { 14801 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize); 14802 if (type_is_invalid(casted_op2->value->type)) 14803 return ira->codegen->invalid_instruction; 14804 14805 // If either operand is undef, result is undef. 14806 ZigValue *op1_val = nullptr; 14807 ZigValue *op2_val = nullptr; 14808 if (instr_is_comptime(op1)) { 14809 op1_val = ir_resolve_const(ira, op1, UndefOk); 14810 if (op1_val == nullptr) 14811 return ira->codegen->invalid_instruction; 14812 if (op1_val->special == ConstValSpecialUndef) 14813 return ir_const_undef(ira, &instruction->base, op1->value->type); 14814 } 14815 if (instr_is_comptime(casted_op2)) { 14816 op2_val = ir_resolve_const(ira, casted_op2, UndefOk); 14817 if (op2_val == nullptr) 14818 return ira->codegen->invalid_instruction; 14819 if (op2_val->special == ConstValSpecialUndef) 14820 return ir_const_undef(ira, &instruction->base, op1->value->type); 14821 } 14822 14823 if (op2_val != nullptr && op1_val != nullptr && 14824 (op1->value->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 14825 op1->value->data.x_ptr.special == ConstPtrSpecialNull)) 14826 { 14827 uint64_t start_addr = (op1_val->data.x_ptr.special == ConstPtrSpecialNull) ? 14828 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; 14829 uint64_t elem_offset; 14830 if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) 14831 return ira->codegen->invalid_instruction; 14832 ZigType *elem_type = op1_val->type->data.pointer.child_type; 14833 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) 14834 return ira->codegen->invalid_instruction; 14835 uint64_t byte_offset = type_size(ira->codegen, elem_type) * elem_offset; 14836 uint64_t new_addr; 14837 if (op_id == IrBinOpAdd) { 14838 new_addr = start_addr + byte_offset; 14839 } else if (op_id == IrBinOpSub) { 14840 new_addr = start_addr - byte_offset; 14841 } else { 14842 zig_unreachable(); 14843 } 14844 IrInstruction *result = ir_const(ira, &instruction->base, op1_val->type); 14845 result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 14846 result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; 14847 result->value->data.x_ptr.data.hard_coded_addr.addr = new_addr; 14848 return result; 14849 } 14850 14851 IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope, 14852 instruction->base.source_node, op_id, op1, casted_op2, true); 14853 result->value->type = op1->value->type; 14854 return result; 14855 } 14856 14857 IrInstruction *instructions[] = {op1, op2}; 14858 ZigType *resolved_type = ir_resolve_peer_types(ira, instruction->base.source_node, nullptr, instructions, 2); 14859 if (type_is_invalid(resolved_type)) 14860 return ira->codegen->invalid_instruction; 14861 14862 bool is_int = resolved_type->id == ZigTypeIdInt || resolved_type->id == ZigTypeIdComptimeInt; 14863 bool is_float = resolved_type->id == ZigTypeIdFloat || resolved_type->id == ZigTypeIdComptimeFloat; 14864 bool is_signed_div = ( 14865 (resolved_type->id == ZigTypeIdInt && resolved_type->data.integral.is_signed) || 14866 resolved_type->id == ZigTypeIdFloat || 14867 (resolved_type->id == ZigTypeIdComptimeFloat && 14868 ((bigfloat_cmp_zero(&op1->value->data.x_bigfloat) != CmpGT) != 14869 (bigfloat_cmp_zero(&op2->value->data.x_bigfloat) != CmpGT))) || 14870 (resolved_type->id == ZigTypeIdComptimeInt && 14871 ((bigint_cmp_zero(&op1->value->data.x_bigint) != CmpGT) != 14872 (bigint_cmp_zero(&op2->value->data.x_bigint) != CmpGT))) 14873 ); 14874 if (op_id == IrBinOpDivUnspecified && is_int) { 14875 if (is_signed_div) { 14876 bool ok = false; 14877 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 14878 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 14879 if (op1_val == nullptr) 14880 return ira->codegen->invalid_instruction; 14881 14882 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 14883 if (op2_val == nullptr) 14884 return ira->codegen->invalid_instruction; 14885 14886 if (bigint_cmp_zero(&op2_val->data.x_bigint) == CmpEQ) { 14887 // the division by zero error will be caught later, but we don't have a 14888 // division function ambiguity problem. 14889 op_id = IrBinOpDivTrunc; 14890 ok = true; 14891 } else { 14892 BigInt trunc_result; 14893 BigInt floor_result; 14894 bigint_div_trunc(&trunc_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14895 bigint_div_floor(&floor_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14896 if (bigint_cmp(&trunc_result, &floor_result) == CmpEQ) { 14897 ok = true; 14898 op_id = IrBinOpDivTrunc; 14899 } 14900 } 14901 } 14902 if (!ok) { 14903 ir_add_error(ira, &instruction->base, 14904 buf_sprintf("division with '%s' and '%s': signed integers must use @divTrunc, @divFloor, or @divExact", 14905 buf_ptr(&op1->value->type->name), 14906 buf_ptr(&op2->value->type->name))); 14907 return ira->codegen->invalid_instruction; 14908 } 14909 } else { 14910 op_id = IrBinOpDivTrunc; 14911 } 14912 } else if (op_id == IrBinOpRemUnspecified) { 14913 if (is_signed_div && (is_int || is_float)) { 14914 bool ok = false; 14915 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 14916 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 14917 if (op1_val == nullptr) 14918 return ira->codegen->invalid_instruction; 14919 14920 if (is_int) { 14921 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 14922 if (op2_val == nullptr) 14923 return ira->codegen->invalid_instruction; 14924 14925 if (bigint_cmp_zero(&op2->value->data.x_bigint) == CmpEQ) { 14926 // the division by zero error will be caught later, but we don't 14927 // have a remainder function ambiguity problem 14928 ok = true; 14929 } else { 14930 BigInt rem_result; 14931 BigInt mod_result; 14932 bigint_rem(&rem_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14933 bigint_mod(&mod_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 14934 ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ; 14935 } 14936 } else { 14937 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 14938 if (casted_op2 == ira->codegen->invalid_instruction) 14939 return ira->codegen->invalid_instruction; 14940 14941 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 14942 if (op2_val == nullptr) 14943 return ira->codegen->invalid_instruction; 14944 14945 if (float_cmp_zero(casted_op2->value) == CmpEQ) { 14946 // the division by zero error will be caught later, but we don't 14947 // have a remainder function ambiguity problem 14948 ok = true; 14949 } else { 14950 ZigValue rem_result = {}; 14951 ZigValue mod_result = {}; 14952 float_rem(&rem_result, op1_val, op2_val); 14953 float_mod(&mod_result, op1_val, op2_val); 14954 ok = float_cmp(&rem_result, &mod_result) == CmpEQ; 14955 } 14956 } 14957 } 14958 if (!ok) { 14959 ir_add_error(ira, &instruction->base, 14960 buf_sprintf("remainder division with '%s' and '%s': signed integers and floats must use @rem or @mod", 14961 buf_ptr(&op1->value->type->name), 14962 buf_ptr(&op2->value->type->name))); 14963 return ira->codegen->invalid_instruction; 14964 } 14965 } 14966 op_id = IrBinOpRemRem; 14967 } 14968 14969 bool ok = false; 14970 if (is_int) { 14971 ok = true; 14972 } else if (is_float && ok_float_op(op_id)) { 14973 ok = true; 14974 } else if (resolved_type->id == ZigTypeIdVector) { 14975 ZigType *elem_type = resolved_type->data.vector.elem_type; 14976 if (elem_type->id == ZigTypeIdInt || elem_type->id == ZigTypeIdComptimeInt) { 14977 ok = true; 14978 } else if ((elem_type->id == ZigTypeIdFloat || elem_type->id == ZigTypeIdComptimeFloat) && ok_float_op(op_id)) { 14979 ok = true; 14980 } 14981 } 14982 if (!ok) { 14983 AstNode *source_node = instruction->base.source_node; 14984 ir_add_error_node(ira, source_node, 14985 buf_sprintf("invalid operands to binary expression: '%s' and '%s'", 14986 buf_ptr(&op1->value->type->name), 14987 buf_ptr(&op2->value->type->name))); 14988 return ira->codegen->invalid_instruction; 14989 } 14990 14991 if (resolved_type->id == ZigTypeIdComptimeInt) { 14992 if (op_id == IrBinOpAddWrap) { 14993 op_id = IrBinOpAdd; 14994 } else if (op_id == IrBinOpSubWrap) { 14995 op_id = IrBinOpSub; 14996 } else if (op_id == IrBinOpMultWrap) { 14997 op_id = IrBinOpMult; 14998 } 14999 } 15000 15001 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 15002 if (casted_op1 == ira->codegen->invalid_instruction) 15003 return ira->codegen->invalid_instruction; 15004 15005 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 15006 if (casted_op2 == ira->codegen->invalid_instruction) 15007 return ira->codegen->invalid_instruction; 15008 15009 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 15010 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 15011 if (op1_val == nullptr) 15012 return ira->codegen->invalid_instruction; 15013 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 15014 if (op2_val == nullptr) 15015 return ira->codegen->invalid_instruction; 15016 15017 return ir_analyze_math_op(ira, &instruction->base, resolved_type, op1_val, op_id, op2_val); 15018 } 15019 15020 IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope, 15021 instruction->base.source_node, op_id, casted_op1, casted_op2, instruction->safety_check_on); 15022 result->value->type = resolved_type; 15023 return result; 15024 } 15025 15026 static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruction) { 15027 IrInstruction *op1 = instruction->op1->child; 15028 ZigType *op1_type = op1->value->type; 15029 if (type_is_invalid(op1_type)) 15030 return ira->codegen->invalid_instruction; 15031 15032 IrInstruction *op2 = instruction->op2->child; 15033 ZigType *op2_type = op2->value->type; 15034 if (type_is_invalid(op2_type)) 15035 return ira->codegen->invalid_instruction; 15036 15037 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 15038 if (!op1_val) 15039 return ira->codegen->invalid_instruction; 15040 15041 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 15042 if (!op2_val) 15043 return ira->codegen->invalid_instruction; 15044 15045 ZigValue *sentinel1 = nullptr; 15046 ZigValue *op1_array_val; 15047 size_t op1_array_index; 15048 size_t op1_array_end; 15049 ZigType *child_type; 15050 if (op1_type->id == ZigTypeIdArray) { 15051 child_type = op1_type->data.array.child_type; 15052 op1_array_val = op1_val; 15053 op1_array_index = 0; 15054 op1_array_end = op1_type->data.array.len; 15055 sentinel1 = op1_type->data.array.sentinel; 15056 } else if (op1_type->id == ZigTypeIdPointer && 15057 op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 15058 op1_type->data.pointer.sentinel != nullptr && 15059 op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray) 15060 { 15061 child_type = op1_type->data.pointer.child_type; 15062 op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; 15063 op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; 15064 op1_array_end = op1_array_val->type->data.array.len; 15065 sentinel1 = op1_type->data.pointer.sentinel; 15066 } else if (is_slice(op1_type)) { 15067 ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry; 15068 child_type = ptr_type->data.pointer.child_type; 15069 ZigValue *ptr_val = op1_val->data.x_struct.fields[slice_ptr_index]; 15070 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 15071 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 15072 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 15073 ZigValue *len_val = op1_val->data.x_struct.fields[slice_len_index]; 15074 op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint); 15075 sentinel1 = ptr_type->data.pointer.sentinel; 15076 } else if (op1_type->id == ZigTypeIdPointer && op1_type->data.pointer.ptr_len == PtrLenSingle && 15077 op1_type->data.pointer.child_type->id == ZigTypeIdArray) 15078 { 15079 ZigType *array_type = op1_type->data.pointer.child_type; 15080 child_type = array_type->data.array.child_type; 15081 op1_array_val = const_ptr_pointee(ira, ira->codegen, op1_val, op1->source_node); 15082 if (op1_array_val == nullptr) 15083 return ira->codegen->invalid_instruction; 15084 op1_array_index = 0; 15085 op1_array_end = array_type->data.array.len; 15086 sentinel1 = array_type->data.array.sentinel; 15087 } else { 15088 ir_add_error(ira, op1, buf_sprintf("expected array, found '%s'", buf_ptr(&op1->value->type->name))); 15089 return ira->codegen->invalid_instruction; 15090 } 15091 15092 ZigValue *sentinel2 = nullptr; 15093 ZigValue *op2_array_val; 15094 size_t op2_array_index; 15095 size_t op2_array_end; 15096 bool op2_type_valid; 15097 if (op2_type->id == ZigTypeIdArray) { 15098 op2_type_valid = op2_type->data.array.child_type == child_type; 15099 op2_array_val = op2_val; 15100 op2_array_index = 0; 15101 op2_array_end = op2_array_val->type->data.array.len; 15102 sentinel2 = op2_type->data.array.sentinel; 15103 } else if (op2_type->id == ZigTypeIdPointer && 15104 op2_type->data.pointer.sentinel != nullptr && 15105 op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray) 15106 { 15107 op2_type_valid = op2_type->data.pointer.child_type == child_type; 15108 op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; 15109 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; 15110 op2_array_end = op2_array_val->type->data.array.len; 15111 15112 sentinel2 = op2_type->data.pointer.sentinel; 15113 } else if (is_slice(op2_type)) { 15114 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry; 15115 op2_type_valid = ptr_type->data.pointer.child_type == child_type; 15116 ZigValue *ptr_val = op2_val->data.x_struct.fields[slice_ptr_index]; 15117 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 15118 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 15119 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 15120 ZigValue *len_val = op2_val->data.x_struct.fields[slice_len_index]; 15121 op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint); 15122 15123 sentinel2 = ptr_type->data.pointer.sentinel; 15124 } else if (op2_type->id == ZigTypeIdPointer && op2_type->data.pointer.ptr_len == PtrLenSingle && 15125 op2_type->data.pointer.child_type->id == ZigTypeIdArray) 15126 { 15127 ZigType *array_type = op2_type->data.pointer.child_type; 15128 op2_type_valid = array_type->data.array.child_type == child_type; 15129 op2_array_val = const_ptr_pointee(ira, ira->codegen, op2_val, op2->source_node); 15130 if (op2_array_val == nullptr) 15131 return ira->codegen->invalid_instruction; 15132 op2_array_index = 0; 15133 op2_array_end = array_type->data.array.len; 15134 15135 sentinel2 = array_type->data.array.sentinel; 15136 } else { 15137 ir_add_error(ira, op2, 15138 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value->type->name))); 15139 return ira->codegen->invalid_instruction; 15140 } 15141 if (!op2_type_valid) { 15142 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", 15143 buf_ptr(&child_type->name), 15144 buf_ptr(&op2->value->type->name))); 15145 return ira->codegen->invalid_instruction; 15146 } 15147 15148 ZigValue *sentinel; 15149 if (sentinel1 != nullptr && sentinel2 != nullptr) { 15150 // When there is a sentinel mismatch, no sentinel on the result. The type system 15151 // will catch this if it is a problem. 15152 sentinel = const_values_equal(ira->codegen, sentinel1, sentinel2) ? sentinel1 : nullptr; 15153 } else if (sentinel1 != nullptr) { 15154 sentinel = sentinel1; 15155 } else if (sentinel2 != nullptr) { 15156 sentinel = sentinel2; 15157 } else { 15158 sentinel = nullptr; 15159 } 15160 15161 // The type of result is populated in the following if blocks 15162 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 15163 ZigValue *out_val = result->value; 15164 15165 ZigValue *out_array_val; 15166 size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); 15167 if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { 15168 out_array_val = create_const_vals(1); 15169 out_array_val->special = ConstValSpecialStatic; 15170 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 15171 15172 out_val->data.x_ptr.special = ConstPtrSpecialRef; 15173 out_val->data.x_ptr.data.ref.pointee = out_array_val; 15174 out_val->type = get_pointer_to_type(ira->codegen, out_array_val->type, true); 15175 } else if (is_slice(op1_type) || is_slice(op2_type)) { 15176 ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, child_type, 15177 true, false, PtrLenUnknown, 0, 0, 0, false, 15178 VECTOR_INDEX_NONE, nullptr, sentinel); 15179 result->value->type = get_slice_type(ira->codegen, ptr_type); 15180 out_array_val = create_const_vals(1); 15181 out_array_val->special = ConstValSpecialStatic; 15182 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 15183 15184 out_val->data.x_struct.fields = alloc_const_vals_ptrs(2); 15185 15186 out_val->data.x_struct.fields[slice_ptr_index]->type = ptr_type; 15187 out_val->data.x_struct.fields[slice_ptr_index]->special = ConstValSpecialStatic; 15188 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.special = ConstPtrSpecialBaseArray; 15189 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.array_val = out_array_val; 15190 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.elem_index = 0; 15191 15192 out_val->data.x_struct.fields[slice_len_index]->type = ira->codegen->builtin_types.entry_usize; 15193 out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic; 15194 bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len); 15195 } else if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { 15196 result->value->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 15197 out_array_val = out_val; 15198 } else { 15199 result->value->type = get_pointer_to_type_extra2(ira->codegen, child_type, true, false, PtrLenUnknown, 15200 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, sentinel); 15201 out_array_val = create_const_vals(1); 15202 out_array_val->special = ConstValSpecialStatic; 15203 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 15204 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 15205 out_val->data.x_ptr.data.base_array.array_val = out_array_val; 15206 out_val->data.x_ptr.data.base_array.elem_index = 0; 15207 } 15208 15209 if (op1_array_val->data.x_array.special == ConstArraySpecialUndef && 15210 op2_array_val->data.x_array.special == ConstArraySpecialUndef) 15211 { 15212 out_array_val->data.x_array.special = ConstArraySpecialUndef; 15213 return result; 15214 } 15215 15216 uint64_t full_len = new_len + ((sentinel != nullptr) ? 1 : 0); 15217 out_array_val->data.x_array.data.s_none.elements = create_const_vals(full_len); 15218 // TODO handle the buf case here for an optimization 15219 expand_undef_array(ira->codegen, op1_array_val); 15220 expand_undef_array(ira->codegen, op2_array_val); 15221 15222 size_t next_index = 0; 15223 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { 15224 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 15225 copy_const_val(elem_dest_val, &op1_array_val->data.x_array.data.s_none.elements[i], false); 15226 elem_dest_val->parent.id = ConstParentIdArray; 15227 elem_dest_val->parent.data.p_array.array_val = out_array_val; 15228 elem_dest_val->parent.data.p_array.elem_index = next_index; 15229 } 15230 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { 15231 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 15232 copy_const_val(elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i], false); 15233 elem_dest_val->parent.id = ConstParentIdArray; 15234 elem_dest_val->parent.data.p_array.array_val = out_array_val; 15235 elem_dest_val->parent.data.p_array.elem_index = next_index; 15236 } 15237 if (next_index < full_len) { 15238 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 15239 copy_const_val(elem_dest_val, sentinel, false); 15240 elem_dest_val->parent.id = ConstParentIdArray; 15241 elem_dest_val->parent.data.p_array.array_val = out_array_val; 15242 elem_dest_val->parent.data.p_array.elem_index = next_index; 15243 next_index += 1; 15244 } 15245 assert(next_index == full_len); 15246 15247 return result; 15248 } 15249 15250 static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instruction) { 15251 IrInstruction *op1 = instruction->op1->child; 15252 if (type_is_invalid(op1->value->type)) 15253 return ira->codegen->invalid_instruction; 15254 15255 IrInstruction *op2 = instruction->op2->child; 15256 if (type_is_invalid(op2->value->type)) 15257 return ira->codegen->invalid_instruction; 15258 15259 bool want_ptr_to_array = false; 15260 ZigType *array_type; 15261 ZigValue *array_val; 15262 if (op1->value->type->id == ZigTypeIdArray) { 15263 array_type = op1->value->type; 15264 array_val = ir_resolve_const(ira, op1, UndefOk); 15265 if (array_val == nullptr) 15266 return ira->codegen->invalid_instruction; 15267 } else if (op1->value->type->id == ZigTypeIdPointer && op1->value->type->data.pointer.ptr_len == PtrLenSingle && 15268 op1->value->type->data.pointer.child_type->id == ZigTypeIdArray) 15269 { 15270 array_type = op1->value->type->data.pointer.child_type; 15271 IrInstruction *array_inst = ir_get_deref(ira, op1, op1, nullptr); 15272 if (type_is_invalid(array_inst->value->type)) 15273 return ira->codegen->invalid_instruction; 15274 array_val = ir_resolve_const(ira, array_inst, UndefOk); 15275 if (array_val == nullptr) 15276 return ira->codegen->invalid_instruction; 15277 want_ptr_to_array = true; 15278 } else { 15279 ir_add_error(ira, op1, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value->type->name))); 15280 return ira->codegen->invalid_instruction; 15281 } 15282 15283 uint64_t mult_amt; 15284 if (!ir_resolve_usize(ira, op2, &mult_amt)) 15285 return ira->codegen->invalid_instruction; 15286 15287 uint64_t old_array_len = array_type->data.array.len; 15288 uint64_t new_array_len; 15289 15290 if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) { 15291 ir_add_error(ira, &instruction->base, buf_sprintf("operation results in overflow")); 15292 return ira->codegen->invalid_instruction; 15293 } 15294 15295 ZigType *child_type = array_type->data.array.child_type; 15296 ZigType *result_array_type = get_array_type(ira->codegen, child_type, new_array_len, 15297 array_type->data.array.sentinel); 15298 15299 IrInstruction *array_result; 15300 if (array_val->special == ConstValSpecialUndef || array_val->data.x_array.special == ConstArraySpecialUndef) { 15301 array_result = ir_const_undef(ira, &instruction->base, result_array_type); 15302 } else { 15303 array_result = ir_const(ira, &instruction->base, result_array_type); 15304 ZigValue *out_val = array_result->value; 15305 15306 switch (type_has_one_possible_value(ira->codegen, result_array_type)) { 15307 case OnePossibleValueInvalid: 15308 return ira->codegen->invalid_instruction; 15309 case OnePossibleValueYes: 15310 goto skip_computation; 15311 case OnePossibleValueNo: 15312 break; 15313 } 15314 15315 // TODO optimize the buf case 15316 expand_undef_array(ira->codegen, array_val); 15317 size_t extra_null_term = (array_type->data.array.sentinel != nullptr) ? 1 : 0; 15318 out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len + extra_null_term); 15319 15320 uint64_t i = 0; 15321 for (uint64_t x = 0; x < mult_amt; x += 1) { 15322 for (uint64_t y = 0; y < old_array_len; y += 1) { 15323 ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; 15324 copy_const_val(elem_dest_val, &array_val->data.x_array.data.s_none.elements[y], false); 15325 elem_dest_val->parent.id = ConstParentIdArray; 15326 elem_dest_val->parent.data.p_array.array_val = out_val; 15327 elem_dest_val->parent.data.p_array.elem_index = i; 15328 i += 1; 15329 } 15330 } 15331 assert(i == new_array_len); 15332 15333 if (array_type->data.array.sentinel != nullptr) { 15334 ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; 15335 copy_const_val(elem_dest_val, array_type->data.array.sentinel, false); 15336 elem_dest_val->parent.id = ConstParentIdArray; 15337 elem_dest_val->parent.data.p_array.array_val = out_val; 15338 elem_dest_val->parent.data.p_array.elem_index = i; 15339 i += 1; 15340 } 15341 } 15342 skip_computation: 15343 if (want_ptr_to_array) { 15344 return ir_get_ref(ira, &instruction->base, array_result, true, false); 15345 } else { 15346 return array_result; 15347 } 15348 } 15349 15350 static IrInstruction *ir_analyze_instruction_merge_err_sets(IrAnalyze *ira, 15351 IrInstructionMergeErrSets *instruction) 15352 { 15353 ZigType *op1_type = ir_resolve_error_set_type(ira, &instruction->base, instruction->op1->child); 15354 if (type_is_invalid(op1_type)) 15355 return ira->codegen->invalid_instruction; 15356 15357 ZigType *op2_type = ir_resolve_error_set_type(ira, &instruction->base, instruction->op2->child); 15358 if (type_is_invalid(op2_type)) 15359 return ira->codegen->invalid_instruction; 15360 15361 if (type_is_global_error_set(op1_type) || 15362 type_is_global_error_set(op2_type)) 15363 { 15364 return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_global_error_set); 15365 } 15366 15367 if (!resolve_inferred_error_set(ira->codegen, op1_type, instruction->op1->child->source_node)) { 15368 return ira->codegen->invalid_instruction; 15369 } 15370 15371 if (!resolve_inferred_error_set(ira->codegen, op2_type, instruction->op2->child->source_node)) { 15372 return ira->codegen->invalid_instruction; 15373 } 15374 15375 size_t errors_count = ira->codegen->errors_by_index.length; 15376 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(errors_count, "ErrorTableEntry *"); 15377 for (uint32_t i = 0, count = op1_type->data.error_set.err_count; i < count; i += 1) { 15378 ErrorTableEntry *error_entry = op1_type->data.error_set.errors[i]; 15379 assert(errors[error_entry->value] == nullptr); 15380 errors[error_entry->value] = error_entry; 15381 } 15382 ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type, instruction->type_name); 15383 deallocate(errors, errors_count, "ErrorTableEntry *"); 15384 15385 return ir_const_type(ira, &instruction->base, result_type); 15386 } 15387 15388 15389 static IrInstruction *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 15390 IrBinOp op_id = bin_op_instruction->op_id; 15391 switch (op_id) { 15392 case IrBinOpInvalid: 15393 zig_unreachable(); 15394 case IrBinOpBoolOr: 15395 case IrBinOpBoolAnd: 15396 return ir_analyze_bin_op_bool(ira, bin_op_instruction); 15397 case IrBinOpCmpEq: 15398 case IrBinOpCmpNotEq: 15399 case IrBinOpCmpLessThan: 15400 case IrBinOpCmpGreaterThan: 15401 case IrBinOpCmpLessOrEq: 15402 case IrBinOpCmpGreaterOrEq: 15403 return ir_analyze_bin_op_cmp(ira, bin_op_instruction); 15404 case IrBinOpBitShiftLeftLossy: 15405 case IrBinOpBitShiftLeftExact: 15406 case IrBinOpBitShiftRightLossy: 15407 case IrBinOpBitShiftRightExact: 15408 return ir_analyze_bit_shift(ira, bin_op_instruction); 15409 case IrBinOpBinOr: 15410 case IrBinOpBinXor: 15411 case IrBinOpBinAnd: 15412 case IrBinOpAdd: 15413 case IrBinOpAddWrap: 15414 case IrBinOpSub: 15415 case IrBinOpSubWrap: 15416 case IrBinOpMult: 15417 case IrBinOpMultWrap: 15418 case IrBinOpDivUnspecified: 15419 case IrBinOpDivTrunc: 15420 case IrBinOpDivFloor: 15421 case IrBinOpDivExact: 15422 case IrBinOpRemUnspecified: 15423 case IrBinOpRemRem: 15424 case IrBinOpRemMod: 15425 return ir_analyze_bin_op_math(ira, bin_op_instruction); 15426 case IrBinOpArrayCat: 15427 return ir_analyze_array_cat(ira, bin_op_instruction); 15428 case IrBinOpArrayMult: 15429 return ir_analyze_array_mult(ira, bin_op_instruction); 15430 } 15431 zig_unreachable(); 15432 } 15433 15434 static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, 15435 IrInstructionDeclVarSrc *decl_var_instruction) 15436 { 15437 Error err; 15438 ZigVar *var = decl_var_instruction->var; 15439 15440 ZigType *explicit_type = nullptr; 15441 IrInstruction *var_type = nullptr; 15442 if (decl_var_instruction->var_type != nullptr) { 15443 var_type = decl_var_instruction->var_type->child; 15444 ZigType *proposed_type = ir_resolve_type(ira, var_type); 15445 explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type); 15446 if (type_is_invalid(explicit_type)) { 15447 var->var_type = ira->codegen->builtin_types.entry_invalid; 15448 return ira->codegen->invalid_instruction; 15449 } 15450 } 15451 15452 AstNode *source_node = decl_var_instruction->base.source_node; 15453 15454 bool is_comptime_var = ir_get_var_is_comptime(var); 15455 15456 bool var_class_requires_const = false; 15457 15458 IrInstruction *var_ptr = decl_var_instruction->ptr->child; 15459 // if this is null, a compiler error happened and did not initialize the variable. 15460 // if there are no compile errors there may be a missing ir_expr_wrap in pass1 IR generation. 15461 if (var_ptr == nullptr || type_is_invalid(var_ptr->value->type)) { 15462 ir_assert(var_ptr != nullptr || ira->codegen->errors.length != 0, &decl_var_instruction->base); 15463 var->var_type = ira->codegen->builtin_types.entry_invalid; 15464 return ira->codegen->invalid_instruction; 15465 } 15466 15467 // The ir_build_var_decl_src call is supposed to pass a pointer to the allocation, not an initialization value. 15468 ir_assert(var_ptr->value->type->id == ZigTypeIdPointer, &decl_var_instruction->base); 15469 15470 ZigType *result_type = var_ptr->value->type->data.pointer.child_type; 15471 if (type_is_invalid(result_type)) { 15472 result_type = ira->codegen->builtin_types.entry_invalid; 15473 } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { 15474 zig_unreachable(); 15475 } 15476 15477 ZigValue *init_val = nullptr; 15478 if (instr_is_comptime(var_ptr) && var_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 15479 init_val = const_ptr_pointee(ira, ira->codegen, var_ptr->value, decl_var_instruction->base.source_node); 15480 if (is_comptime_var) { 15481 if (var->gen_is_const) { 15482 var->const_value = init_val; 15483 } else { 15484 var->const_value = create_const_vals(1); 15485 copy_const_val(var->const_value, init_val, false); 15486 } 15487 } 15488 } 15489 15490 switch (type_requires_comptime(ira->codegen, result_type)) { 15491 case ReqCompTimeInvalid: 15492 result_type = ira->codegen->builtin_types.entry_invalid; 15493 break; 15494 case ReqCompTimeYes: 15495 var_class_requires_const = true; 15496 if (!var->gen_is_const && !is_comptime_var) { 15497 ir_add_error_node(ira, source_node, 15498 buf_sprintf("variable of type '%s' must be const or comptime", 15499 buf_ptr(&result_type->name))); 15500 result_type = ira->codegen->builtin_types.entry_invalid; 15501 } 15502 break; 15503 case ReqCompTimeNo: 15504 if (init_val != nullptr && value_is_comptime(init_val)) { 15505 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 15506 decl_var_instruction->base.source_node, init_val, UndefOk))) 15507 { 15508 result_type = ira->codegen->builtin_types.entry_invalid; 15509 } else if (init_val->type->id == ZigTypeIdFn && 15510 init_val->special != ConstValSpecialUndef && 15511 init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 15512 init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) 15513 { 15514 var_class_requires_const = true; 15515 if (!var->src_is_const && !is_comptime_var) { 15516 ErrorMsg *msg = ir_add_error_node(ira, source_node, 15517 buf_sprintf("functions marked inline must be stored in const or comptime var")); 15518 AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node; 15519 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); 15520 result_type = ira->codegen->builtin_types.entry_invalid; 15521 } 15522 } 15523 } 15524 break; 15525 } 15526 15527 if (var->var_type != nullptr && !is_comptime_var) { 15528 // This is at least the second time we've seen this variable declaration during analysis. 15529 // This means that this is actually a different variable due to, e.g. an inline while loop. 15530 // We make a new variable so that it can hold a different type, and so the debug info can 15531 // be distinct. 15532 ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope, 15533 buf_create_from_str(var->name), var->src_is_const, var->gen_is_const, 15534 var->shadowable, var->is_comptime, true); 15535 new_var->owner_exec = var->owner_exec; 15536 new_var->align_bytes = var->align_bytes; 15537 if (var->mem_slot_index != SIZE_MAX) { 15538 ZigValue *vals = create_const_vals(1); 15539 new_var->mem_slot_index = ira->exec_context.mem_slot_list.length; 15540 ira->exec_context.mem_slot_list.append(vals); 15541 } 15542 15543 var->next_var = new_var; 15544 var = new_var; 15545 } 15546 15547 // This must be done after possibly creating a new variable above 15548 var->ref_count = 0; 15549 15550 var->var_type = result_type; 15551 assert(var->var_type); 15552 15553 if (type_is_invalid(result_type)) { 15554 return ir_const_void(ira, &decl_var_instruction->base); 15555 } 15556 15557 if (decl_var_instruction->align_value == nullptr) { 15558 if ((err = type_resolve(ira->codegen, result_type, ResolveStatusAlignmentKnown))) { 15559 var->var_type = ira->codegen->builtin_types.entry_invalid; 15560 return ir_const_void(ira, &decl_var_instruction->base); 15561 } 15562 var->align_bytes = get_abi_alignment(ira->codegen, result_type); 15563 } else { 15564 if (!ir_resolve_align(ira, decl_var_instruction->align_value->child, nullptr, &var->align_bytes)) { 15565 var->var_type = ira->codegen->builtin_types.entry_invalid; 15566 } 15567 } 15568 15569 if (init_val != nullptr && value_is_comptime(init_val)) { 15570 // Resolve ConstPtrMutInfer 15571 if (var->gen_is_const) { 15572 var_ptr->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 15573 } else if (is_comptime_var) { 15574 var_ptr->value->data.x_ptr.mut = ConstPtrMutComptimeVar; 15575 } else { 15576 // we need a runtime ptr but we have a comptime val. 15577 // since it's a comptime val there are no instructions for it. 15578 // we memcpy the init value here 15579 IrInstruction *deref = ir_get_deref(ira, var_ptr, var_ptr, nullptr); 15580 if (type_is_invalid(deref->value->type)) { 15581 var->var_type = ira->codegen->builtin_types.entry_invalid; 15582 return ira->codegen->invalid_instruction; 15583 } 15584 // If this assertion trips, something is wrong with the IR instructions, because 15585 // we expected the above deref to return a constant value, but it created a runtime 15586 // instruction. 15587 assert(deref->value->special != ConstValSpecialRuntime); 15588 var_ptr->value->special = ConstValSpecialRuntime; 15589 ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref, false); 15590 } 15591 15592 if (instr_is_comptime(var_ptr) && var->mem_slot_index != SIZE_MAX) { 15593 assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); 15594 ZigValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); 15595 copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); 15596 15597 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { 15598 return ir_const_void(ira, &decl_var_instruction->base); 15599 } 15600 } 15601 } else if (is_comptime_var) { 15602 ir_add_error(ira, &decl_var_instruction->base, 15603 buf_sprintf("cannot store runtime value in compile time variable")); 15604 var->var_type = ira->codegen->builtin_types.entry_invalid; 15605 return ira->codegen->invalid_instruction; 15606 } 15607 15608 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 15609 if (fn_entry) 15610 fn_entry->variable_list.append(var); 15611 15612 return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr); 15613 } 15614 15615 static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { 15616 Error err; 15617 15618 IrInstruction *name = instruction->name->child; 15619 Buf *symbol_name = ir_resolve_str(ira, name); 15620 if (symbol_name == nullptr) { 15621 return ira->codegen->invalid_instruction; 15622 } 15623 15624 IrInstruction *target = instruction->target->child; 15625 if (type_is_invalid(target->value->type)) { 15626 return ira->codegen->invalid_instruction; 15627 } 15628 15629 GlobalLinkageId global_linkage_id = GlobalLinkageIdStrong; 15630 if (instruction->linkage != nullptr) { 15631 IrInstruction *linkage_value = instruction->linkage->child; 15632 if (!ir_resolve_global_linkage(ira, linkage_value, &global_linkage_id)) { 15633 return ira->codegen->invalid_instruction; 15634 } 15635 } 15636 15637 // TODO: This function needs to be audited. 15638 // It's not clear how all the different types are supposed to be handled. 15639 // Need comprehensive tests for exporting one thing in one file and declaring an extern var 15640 // in another file. 15641 TldFn *tld_fn = allocate<TldFn>(1); 15642 tld_fn->base.id = TldIdFn; 15643 tld_fn->base.source_node = instruction->base.source_node; 15644 15645 auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, &tld_fn->base); 15646 if (entry) { 15647 AstNode *other_export_node = entry->value->source_node; 15648 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 15649 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name))); 15650 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); 15651 return ira->codegen->invalid_instruction; 15652 } 15653 15654 bool want_var_export = false; 15655 switch (target->value->type->id) { 15656 case ZigTypeIdInvalid: 15657 case ZigTypeIdUnreachable: 15658 zig_unreachable(); 15659 case ZigTypeIdFn: { 15660 assert(target->value->data.x_ptr.special == ConstPtrSpecialFunction); 15661 ZigFn *fn_entry = target->value->data.x_ptr.data.fn.fn_entry; 15662 tld_fn->fn_entry = fn_entry; 15663 CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc; 15664 switch (cc) { 15665 case CallingConventionUnspecified: { 15666 ErrorMsg *msg = ir_add_error(ira, target, 15667 buf_sprintf("exported function must specify calling convention")); 15668 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 15669 } break; 15670 case CallingConventionAsync: { 15671 ErrorMsg *msg = ir_add_error(ira, target, 15672 buf_sprintf("exported function cannot be async")); 15673 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 15674 } break; 15675 case CallingConventionC: 15676 case CallingConventionNaked: 15677 case CallingConventionCold: 15678 case CallingConventionStdcall: 15679 add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, 15680 cc == CallingConventionC); 15681 break; 15682 } 15683 } break; 15684 case ZigTypeIdStruct: 15685 if (is_slice(target->value->type)) { 15686 ir_add_error(ira, target, 15687 buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value->type->name))); 15688 } else if (target->value->type->data.structure.layout != ContainerLayoutExtern) { 15689 ErrorMsg *msg = ir_add_error(ira, target, 15690 buf_sprintf("exported struct value must be declared extern")); 15691 add_error_note(ira->codegen, msg, target->value->type->data.structure.decl_node, buf_sprintf("declared here")); 15692 } else { 15693 want_var_export = true; 15694 } 15695 break; 15696 case ZigTypeIdUnion: 15697 if (target->value->type->data.unionation.layout != ContainerLayoutExtern) { 15698 ErrorMsg *msg = ir_add_error(ira, target, 15699 buf_sprintf("exported union value must be declared extern")); 15700 add_error_note(ira->codegen, msg, target->value->type->data.unionation.decl_node, buf_sprintf("declared here")); 15701 } else { 15702 want_var_export = true; 15703 } 15704 break; 15705 case ZigTypeIdEnum: 15706 if (target->value->type->data.enumeration.layout != ContainerLayoutExtern) { 15707 ErrorMsg *msg = ir_add_error(ira, target, 15708 buf_sprintf("exported enum value must be declared extern")); 15709 add_error_note(ira->codegen, msg, target->value->type->data.enumeration.decl_node, buf_sprintf("declared here")); 15710 } else { 15711 want_var_export = true; 15712 } 15713 break; 15714 case ZigTypeIdArray: { 15715 bool ok_type; 15716 if ((err = type_allowed_in_extern(ira->codegen, target->value->type->data.array.child_type, &ok_type))) 15717 return ira->codegen->invalid_instruction; 15718 15719 if (!ok_type) { 15720 ir_add_error(ira, target, 15721 buf_sprintf("array element type '%s' not extern-compatible", 15722 buf_ptr(&target->value->type->data.array.child_type->name))); 15723 } else { 15724 want_var_export = true; 15725 } 15726 break; 15727 } 15728 case ZigTypeIdMetaType: { 15729 ZigType *type_value = target->value->data.x_type; 15730 switch (type_value->id) { 15731 case ZigTypeIdInvalid: 15732 zig_unreachable(); 15733 case ZigTypeIdStruct: 15734 if (is_slice(type_value)) { 15735 ir_add_error(ira, target, 15736 buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name))); 15737 } else if (type_value->data.structure.layout != ContainerLayoutExtern) { 15738 ErrorMsg *msg = ir_add_error(ira, target, 15739 buf_sprintf("exported struct must be declared extern")); 15740 add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here")); 15741 } 15742 break; 15743 case ZigTypeIdUnion: 15744 if (type_value->data.unionation.layout != ContainerLayoutExtern) { 15745 ErrorMsg *msg = ir_add_error(ira, target, 15746 buf_sprintf("exported union must be declared extern")); 15747 add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here")); 15748 } 15749 break; 15750 case ZigTypeIdEnum: 15751 if (type_value->data.enumeration.layout != ContainerLayoutExtern) { 15752 ErrorMsg *msg = ir_add_error(ira, target, 15753 buf_sprintf("exported enum must be declared extern")); 15754 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); 15755 } 15756 break; 15757 case ZigTypeIdFn: { 15758 if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 15759 ir_add_error(ira, target, 15760 buf_sprintf("exported function type must specify calling convention")); 15761 } 15762 } break; 15763 case ZigTypeIdInt: 15764 case ZigTypeIdFloat: 15765 case ZigTypeIdPointer: 15766 case ZigTypeIdArray: 15767 case ZigTypeIdBool: 15768 case ZigTypeIdVector: 15769 break; 15770 case ZigTypeIdMetaType: 15771 case ZigTypeIdVoid: 15772 case ZigTypeIdUnreachable: 15773 case ZigTypeIdComptimeFloat: 15774 case ZigTypeIdComptimeInt: 15775 case ZigTypeIdEnumLiteral: 15776 case ZigTypeIdUndefined: 15777 case ZigTypeIdNull: 15778 case ZigTypeIdOptional: 15779 case ZigTypeIdErrorUnion: 15780 case ZigTypeIdErrorSet: 15781 case ZigTypeIdBoundFn: 15782 case ZigTypeIdArgTuple: 15783 case ZigTypeIdOpaque: 15784 case ZigTypeIdFnFrame: 15785 case ZigTypeIdAnyFrame: 15786 ir_add_error(ira, target, 15787 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); 15788 break; 15789 } 15790 } break; 15791 case ZigTypeIdInt: 15792 break; 15793 case ZigTypeIdVoid: 15794 case ZigTypeIdBool: 15795 case ZigTypeIdFloat: 15796 case ZigTypeIdPointer: 15797 case ZigTypeIdComptimeFloat: 15798 case ZigTypeIdComptimeInt: 15799 case ZigTypeIdUndefined: 15800 case ZigTypeIdNull: 15801 case ZigTypeIdOptional: 15802 case ZigTypeIdErrorUnion: 15803 case ZigTypeIdErrorSet: 15804 case ZigTypeIdVector: 15805 zig_panic("TODO export const value of type %s", buf_ptr(&target->value->type->name)); 15806 case ZigTypeIdBoundFn: 15807 case ZigTypeIdArgTuple: 15808 case ZigTypeIdOpaque: 15809 case ZigTypeIdEnumLiteral: 15810 case ZigTypeIdFnFrame: 15811 case ZigTypeIdAnyFrame: 15812 ir_add_error(ira, target, 15813 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value->type->name))); 15814 break; 15815 } 15816 15817 // TODO audit the various ways to use @export 15818 if (want_var_export && target->id == IrInstructionIdLoadPtrGen) { 15819 IrInstructionLoadPtrGen *load_ptr = reinterpret_cast<IrInstructionLoadPtrGen *>(target); 15820 if (load_ptr->ptr->id == IrInstructionIdVarPtr) { 15821 IrInstructionVarPtr *var_ptr = reinterpret_cast<IrInstructionVarPtr *>(load_ptr->ptr); 15822 ZigVar *var = var_ptr->var; 15823 add_var_export(ira->codegen, var, buf_ptr(symbol_name), global_linkage_id); 15824 } 15825 } 15826 15827 return ir_const_void(ira, &instruction->base); 15828 } 15829 15830 static bool exec_has_err_ret_trace(CodeGen *g, IrExecutable *exec) { 15831 ZigFn *fn_entry = exec_fn_entry(exec); 15832 return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing; 15833 } 15834 15835 static IrInstruction *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, 15836 IrInstructionErrorReturnTrace *instruction) 15837 { 15838 ZigType *ptr_to_stack_trace_type = get_pointer_to_type(ira->codegen, get_stack_trace_type(ira->codegen), false); 15839 if (instruction->optional == IrInstructionErrorReturnTrace::Null) { 15840 ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type); 15841 if (!exec_has_err_ret_trace(ira->codegen, ira->new_irb.exec)) { 15842 IrInstruction *result = ir_const(ira, &instruction->base, optional_type); 15843 ZigValue *out_val = result->value; 15844 assert(get_codegen_ptr_type(optional_type) != nullptr); 15845 out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 15846 out_val->data.x_ptr.data.hard_coded_addr.addr = 0; 15847 return result; 15848 } 15849 IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, 15850 instruction->base.source_node, instruction->optional); 15851 new_instruction->value->type = optional_type; 15852 return new_instruction; 15853 } else { 15854 assert(ira->codegen->have_err_ret_tracing); 15855 IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, 15856 instruction->base.source_node, instruction->optional); 15857 new_instruction->value->type = ptr_to_stack_trace_type; 15858 return new_instruction; 15859 } 15860 } 15861 15862 static IrInstruction *ir_analyze_instruction_error_union(IrAnalyze *ira, 15863 IrInstructionErrorUnion *instruction) 15864 { 15865 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); 15866 result->value->special = ConstValSpecialLazy; 15867 15868 LazyValueErrUnionType *lazy_err_union_type = allocate<LazyValueErrUnionType>(1); 15869 lazy_err_union_type->ira = ira; 15870 result->value->data.x_lazy = &lazy_err_union_type->base; 15871 lazy_err_union_type->base.id = LazyValueIdErrUnionType; 15872 15873 lazy_err_union_type->err_set_type = instruction->err_set->child; 15874 if (ir_resolve_type_lazy(ira, lazy_err_union_type->err_set_type) == nullptr) 15875 return ira->codegen->invalid_instruction; 15876 15877 lazy_err_union_type->payload_type = instruction->payload->child; 15878 if (ir_resolve_type_lazy(ira, lazy_err_union_type->payload_type) == nullptr) 15879 return ira->codegen->invalid_instruction; 15880 15881 return result; 15882 } 15883 15884 static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type, 15885 uint32_t align, const char *name_hint, bool force_comptime) 15886 { 15887 Error err; 15888 15889 ZigValue *pointee = create_const_vals(1); 15890 pointee->special = ConstValSpecialUndef; 15891 15892 IrInstructionAllocaGen *result = ir_build_alloca_gen(ira, source_inst, align, name_hint); 15893 result->base.value->special = ConstValSpecialStatic; 15894 result->base.value->data.x_ptr.special = ConstPtrSpecialRef; 15895 result->base.value->data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer; 15896 result->base.value->data.x_ptr.data.ref.pointee = pointee; 15897 15898 bool var_type_has_bits; 15899 if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits))) 15900 return ira->codegen->invalid_instruction; 15901 if (align != 0) { 15902 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown))) 15903 return ira->codegen->invalid_instruction; 15904 if (!var_type_has_bits) { 15905 ir_add_error(ira, source_inst, 15906 buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned", 15907 name_hint, buf_ptr(&var_type->name))); 15908 return ira->codegen->invalid_instruction; 15909 } 15910 } 15911 assert(result->base.value->data.x_ptr.special != ConstPtrSpecialInvalid); 15912 15913 pointee->type = var_type; 15914 result->base.value->type = get_pointer_to_type_extra(ira->codegen, var_type, false, false, 15915 PtrLenSingle, align, 0, 0, false); 15916 15917 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 15918 if (fn_entry != nullptr) { 15919 fn_entry->alloca_gen_list.append(result); 15920 } 15921 result->base.is_gen = true; 15922 return &result->base; 15923 } 15924 15925 static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspend_source_instr, 15926 ResultLoc *result_loc) 15927 { 15928 switch (result_loc->id) { 15929 case ResultLocIdInvalid: 15930 case ResultLocIdPeerParent: 15931 zig_unreachable(); 15932 case ResultLocIdNone: 15933 case ResultLocIdVar: 15934 case ResultLocIdBitCast: 15935 case ResultLocIdCast: 15936 return nullptr; 15937 case ResultLocIdInstruction: 15938 return result_loc->source_instruction->child->value->type; 15939 case ResultLocIdReturn: 15940 return ira->explicit_return_type; 15941 case ResultLocIdPeer: 15942 return reinterpret_cast<ResultLocPeer*>(result_loc)->parent->resolved_type; 15943 } 15944 zig_unreachable(); 15945 } 15946 15947 static bool type_can_bit_cast(ZigType *t) { 15948 switch (t->id) { 15949 case ZigTypeIdInvalid: 15950 zig_unreachable(); 15951 case ZigTypeIdMetaType: 15952 case ZigTypeIdOpaque: 15953 case ZigTypeIdBoundFn: 15954 case ZigTypeIdArgTuple: 15955 case ZigTypeIdUnreachable: 15956 case ZigTypeIdComptimeFloat: 15957 case ZigTypeIdComptimeInt: 15958 case ZigTypeIdEnumLiteral: 15959 case ZigTypeIdUndefined: 15960 case ZigTypeIdNull: 15961 case ZigTypeIdPointer: 15962 return false; 15963 default: 15964 // TODO list these types out explicitly, there are probably some other invalid ones here 15965 return true; 15966 } 15967 } 15968 15969 static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { 15970 ZigValue *undef_child = create_const_vals(1); 15971 undef_child->type = ptr->value->type->data.pointer.child_type; 15972 undef_child->special = ConstValSpecialUndef; 15973 ptr->value->special = ConstValSpecialStatic; 15974 ptr->value->data.x_ptr.mut = ConstPtrMutInfer; 15975 ptr->value->data.x_ptr.special = ConstPtrSpecialRef; 15976 ptr->value->data.x_ptr.data.ref.pointee = undef_child; 15977 } 15978 15979 static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out) { 15980 switch (result_loc->id) { 15981 case ResultLocIdInvalid: 15982 case ResultLocIdPeerParent: 15983 zig_unreachable(); 15984 case ResultLocIdNone: 15985 case ResultLocIdPeer: 15986 *out = false; 15987 return ErrorNone; 15988 case ResultLocIdReturn: 15989 case ResultLocIdInstruction: 15990 case ResultLocIdBitCast: 15991 *out = true; 15992 return ErrorNone; 15993 case ResultLocIdCast: { 15994 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); 15995 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); 15996 if (type_is_invalid(dest_type)) 15997 return ErrorSemanticAnalyzeFail; 15998 *out = (dest_type != ira->codegen->builtin_types.entry_var); 15999 return ErrorNone; 16000 } 16001 case ResultLocIdVar: 16002 *out = reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; 16003 return ErrorNone; 16004 } 16005 zig_unreachable(); 16006 } 16007 16008 static IrInstruction *ir_resolve_no_result_loc(IrAnalyze *ira, IrInstruction *suspend_source_instr, 16009 ResultLoc *result_loc, ZigType *value_type, bool force_runtime, bool non_null_comptime) 16010 { 16011 IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, ""); 16012 alloca_gen->base.value->type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, 16013 PtrLenSingle, 0, 0, 0, false); 16014 set_up_result_loc_for_inferred_comptime(&alloca_gen->base); 16015 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 16016 if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) { 16017 fn_entry->alloca_gen_list.append(alloca_gen); 16018 } 16019 result_loc->written = true; 16020 result_loc->resolved_loc = &alloca_gen->base; 16021 return result_loc->resolved_loc; 16022 } 16023 16024 // when calling this function, at the callsite must check for result type noreturn and propagate it up 16025 static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, 16026 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, 16027 bool non_null_comptime, bool allow_discard) 16028 { 16029 Error err; 16030 if (result_loc->resolved_loc != nullptr) { 16031 // allow to redo the result location if the value is known and comptime and the previous one isn't 16032 if (value == nullptr || !instr_is_comptime(value) || instr_is_comptime(result_loc->resolved_loc)) { 16033 return result_loc->resolved_loc; 16034 } 16035 } 16036 result_loc->gen_instruction = value; 16037 result_loc->implicit_elem_type = value_type; 16038 switch (result_loc->id) { 16039 case ResultLocIdInvalid: 16040 case ResultLocIdPeerParent: 16041 zig_unreachable(); 16042 case ResultLocIdNone: { 16043 if (value != nullptr) { 16044 return nullptr; 16045 } 16046 // need to return a result location and don't have one. use a stack allocation 16047 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, 16048 force_runtime, non_null_comptime); 16049 } 16050 case ResultLocIdVar: { 16051 ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); 16052 assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc); 16053 16054 if (value_type->id == ZigTypeIdUnreachable || value_type->id == ZigTypeIdOpaque) { 16055 ir_add_error(ira, result_loc->source_instruction, 16056 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&value_type->name))); 16057 return ira->codegen->invalid_instruction; 16058 } 16059 16060 IrInstructionAllocaSrc *alloca_src = 16061 reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); 16062 bool force_comptime; 16063 if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) 16064 return ira->codegen->invalid_instruction; 16065 bool is_comptime = force_comptime || (!force_runtime && value != nullptr && 16066 value->value->special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); 16067 16068 if (alloca_src->base.child == nullptr || is_comptime) { 16069 uint32_t align = 0; 16070 if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, nullptr, &align)) { 16071 return ira->codegen->invalid_instruction; 16072 } 16073 IrInstruction *alloca_gen; 16074 if (is_comptime && value != nullptr) { 16075 if (align > value->value->global_refs->align) { 16076 value->value->global_refs->align = align; 16077 } 16078 alloca_gen = ir_get_ref(ira, result_loc->source_instruction, value, true, false); 16079 } else { 16080 alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, 16081 alloca_src->name_hint, force_comptime); 16082 } 16083 if (alloca_src->base.child != nullptr && !result_loc->written) { 16084 alloca_src->base.child->ref_count = 0; 16085 } 16086 alloca_src->base.child = alloca_gen; 16087 } 16088 result_loc->written = true; 16089 result_loc->resolved_loc = is_comptime ? nullptr : alloca_src->base.child; 16090 return result_loc->resolved_loc; 16091 } 16092 case ResultLocIdInstruction: { 16093 result_loc->written = true; 16094 result_loc->resolved_loc = result_loc->source_instruction->child; 16095 return result_loc->resolved_loc; 16096 } 16097 case ResultLocIdReturn: { 16098 if (value != nullptr) { 16099 reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = true; 16100 ira->src_implicit_return_type_list.append(value); 16101 } 16102 if (!non_null_comptime) { 16103 bool is_comptime = value != nullptr && value->value->special != ConstValSpecialRuntime; 16104 if (is_comptime) 16105 return nullptr; 16106 } 16107 if ((err = type_resolve(ira->codegen, ira->explicit_return_type, ResolveStatusZeroBitsKnown))) { 16108 return ira->codegen->invalid_instruction; 16109 } 16110 if (!type_has_bits(ira->explicit_return_type) || !handle_is_ptr(ira->explicit_return_type)) { 16111 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 16112 if (fn_entry == nullptr || fn_entry->inferred_async_node == nullptr) { 16113 return nullptr; 16114 } 16115 } 16116 16117 ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false); 16118 result_loc->written = true; 16119 result_loc->resolved_loc = ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type); 16120 if (ir_should_inline(ira->old_irb.exec, result_loc->source_instruction->scope)) { 16121 set_up_result_loc_for_inferred_comptime(result_loc->resolved_loc); 16122 } 16123 return result_loc->resolved_loc; 16124 } 16125 case ResultLocIdPeer: { 16126 ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(result_loc); 16127 ResultLocPeerParent *peer_parent = result_peer->parent; 16128 16129 if (peer_parent->peers.length == 1) { 16130 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 16131 value_type, value, force_runtime, non_null_comptime, true); 16132 result_peer->suspend_pos.basic_block_index = SIZE_MAX; 16133 result_peer->suspend_pos.instruction_index = SIZE_MAX; 16134 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 16135 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 16136 { 16137 return parent_result_loc; 16138 } 16139 result_loc->written = true; 16140 result_loc->resolved_loc = parent_result_loc; 16141 return result_loc->resolved_loc; 16142 } 16143 16144 bool is_condition_comptime; 16145 if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_condition_comptime)) 16146 return ira->codegen->invalid_instruction; 16147 if (is_condition_comptime) { 16148 peer_parent->skipped = true; 16149 if (non_null_comptime) { 16150 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 16151 value_type, value, force_runtime, non_null_comptime, true); 16152 } 16153 return nullptr; 16154 } 16155 bool peer_parent_has_type; 16156 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) 16157 return ira->codegen->invalid_instruction; 16158 if (peer_parent_has_type) { 16159 peer_parent->skipped = true; 16160 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 16161 value_type, value, force_runtime || !is_condition_comptime, true, true); 16162 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 16163 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 16164 { 16165 return parent_result_loc; 16166 } 16167 peer_parent->parent->written = true; 16168 result_loc->written = true; 16169 result_loc->resolved_loc = parent_result_loc; 16170 return result_loc->resolved_loc; 16171 } 16172 16173 if (peer_parent->resolved_type == nullptr) { 16174 if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { 16175 peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr; 16176 } 16177 IrInstruction *unreach_inst = ira_suspend(ira, suspend_source_instr, result_peer->next_bb, 16178 &result_peer->suspend_pos); 16179 if (result_peer->next_bb == nullptr) { 16180 ir_start_next_bb(ira); 16181 } 16182 return unreach_inst; 16183 } 16184 16185 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 16186 peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime, true); 16187 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 16188 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 16189 { 16190 return parent_result_loc; 16191 } 16192 // because is_condition_comptime is false, we mark this a runtime pointer 16193 parent_result_loc->value->special = ConstValSpecialRuntime; 16194 result_loc->written = true; 16195 result_loc->resolved_loc = parent_result_loc; 16196 return result_loc->resolved_loc; 16197 } 16198 case ResultLocIdCast: { 16199 if (value != nullptr && value->value->special != ConstValSpecialRuntime && !non_null_comptime) 16200 return nullptr; 16201 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); 16202 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); 16203 if (type_is_invalid(dest_type)) 16204 return ira->codegen->invalid_instruction; 16205 16206 if (dest_type == ira->codegen->builtin_types.entry_var) { 16207 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, 16208 force_runtime, non_null_comptime); 16209 } 16210 16211 IrInstruction *casted_value; 16212 if (value != nullptr) { 16213 casted_value = ir_implicit_cast(ira, value, dest_type); 16214 if (type_is_invalid(casted_value->value->type)) 16215 return ira->codegen->invalid_instruction; 16216 dest_type = casted_value->value->type; 16217 } else { 16218 casted_value = nullptr; 16219 } 16220 16221 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent, 16222 dest_type, casted_value, force_runtime, non_null_comptime, true); 16223 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 16224 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 16225 { 16226 return parent_result_loc; 16227 } 16228 16229 ZigType *parent_ptr_type = parent_result_loc->value->type; 16230 assert(parent_ptr_type->id == ZigTypeIdPointer); 16231 if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, 16232 ResolveStatusAlignmentKnown))) 16233 { 16234 return ira->codegen->invalid_instruction; 16235 } 16236 uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); 16237 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { 16238 return ira->codegen->invalid_instruction; 16239 } 16240 if (!type_has_bits(value_type)) { 16241 parent_ptr_align = 0; 16242 } 16243 // If we're casting from a sentinel-terminated array to a non-sentinel-terminated array, 16244 // we actually need the result location pointer to *not* have a sentinel. Otherwise the generated 16245 // memcpy will write an extra byte to the destination, and THAT'S NO GOOD. 16246 ZigType *ptr_elem_type; 16247 if (value_type->id == ZigTypeIdArray && value_type->data.array.sentinel != nullptr && 16248 dest_type->id == ZigTypeIdArray && dest_type->data.array.sentinel == nullptr) 16249 { 16250 ptr_elem_type = get_array_type(ira->codegen, value_type->data.array.child_type, 16251 value_type->data.array.len, nullptr); 16252 } else { 16253 ptr_elem_type = value_type; 16254 } 16255 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ptr_elem_type, 16256 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, 16257 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); 16258 16259 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, 16260 parent_result_loc->value->type, ptr_type, 16261 result_cast->base.source_instruction->source_node, false); 16262 if (const_cast_result.id == ConstCastResultIdInvalid) 16263 return ira->codegen->invalid_instruction; 16264 if (const_cast_result.id != ConstCastResultIdOk) { 16265 if (allow_discard) { 16266 return parent_result_loc; 16267 } 16268 // We will not be able to provide a result location for this value. Create 16269 // a new result location. 16270 result_cast->parent->written = false; 16271 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, 16272 force_runtime, non_null_comptime); 16273 } 16274 16275 return ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, 16276 ptr_type, result_cast->base.source_instruction, false); 16277 } 16278 case ResultLocIdBitCast: { 16279 ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc); 16280 ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child); 16281 if (type_is_invalid(dest_type)) 16282 return ira->codegen->invalid_instruction; 16283 16284 if (get_codegen_ptr_type(dest_type) != nullptr) { 16285 ir_add_error(ira, result_loc->source_instruction, 16286 buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); 16287 return ira->codegen->invalid_instruction; 16288 } 16289 16290 if (!type_can_bit_cast(dest_type)) { 16291 ir_add_error(ira, result_loc->source_instruction, 16292 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); 16293 return ira->codegen->invalid_instruction; 16294 } 16295 16296 if (get_codegen_ptr_type(value_type) != nullptr) { 16297 ir_add_error(ira, suspend_source_instr, 16298 buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&value_type->name))); 16299 return ira->codegen->invalid_instruction; 16300 } 16301 16302 if (!type_can_bit_cast(value_type)) { 16303 ir_add_error(ira, suspend_source_instr, 16304 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&value_type->name))); 16305 return ira->codegen->invalid_instruction; 16306 } 16307 16308 IrInstruction *bitcasted_value; 16309 if (value != nullptr) { 16310 bitcasted_value = ir_analyze_bit_cast(ira, result_loc->source_instruction, value, dest_type); 16311 } else { 16312 bitcasted_value = nullptr; 16313 } 16314 16315 if (bitcasted_value == nullptr || type_is_invalid(bitcasted_value->value->type)) { 16316 return bitcasted_value; 16317 } 16318 16319 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent, 16320 dest_type, bitcasted_value, force_runtime, non_null_comptime, true); 16321 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 16322 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 16323 { 16324 return parent_result_loc; 16325 } 16326 ZigType *parent_ptr_type = parent_result_loc->value->type; 16327 assert(parent_ptr_type->id == ZigTypeIdPointer); 16328 if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, 16329 ResolveStatusAlignmentKnown))) 16330 { 16331 return ira->codegen->invalid_instruction; 16332 } 16333 uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); 16334 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { 16335 return ira->codegen->invalid_instruction; 16336 } 16337 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, 16338 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, 16339 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); 16340 16341 result_loc->written = true; 16342 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, 16343 ptr_type, result_bit_cast->base.source_instruction, false); 16344 return result_loc->resolved_loc; 16345 } 16346 } 16347 zig_unreachable(); 16348 } 16349 16350 static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, 16351 ResultLoc *result_loc_pass1, ZigType *value_type, IrInstruction *value, bool force_runtime, 16352 bool non_null_comptime, bool allow_discard) 16353 { 16354 if (!allow_discard && result_loc_pass1->id == ResultLocIdInstruction && 16355 instr_is_comptime(result_loc_pass1->source_instruction) && 16356 result_loc_pass1->source_instruction->value->type->id == ZigTypeIdPointer && 16357 result_loc_pass1->source_instruction->value->data.x_ptr.special == ConstPtrSpecialDiscard) 16358 { 16359 result_loc_pass1 = no_result_loc(); 16360 } 16361 IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, 16362 value, force_runtime, non_null_comptime, allow_discard); 16363 if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value->type))) 16364 return result_loc; 16365 16366 if ((force_runtime || (value != nullptr && !instr_is_comptime(value))) && 16367 result_loc_pass1->written && result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) 16368 { 16369 result_loc->value->special = ConstValSpecialRuntime; 16370 } 16371 16372 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, suspend_source_instr); 16373 ZigType *actual_elem_type = result_loc->value->type->data.pointer.child_type; 16374 if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && 16375 value_type->id != ZigTypeIdNull && value == nullptr) 16376 { 16377 result_loc_pass1->written = false; 16378 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); 16379 } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion && value == nullptr) { 16380 if (value_type->id == ZigTypeIdErrorSet) { 16381 return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); 16382 } else { 16383 IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, 16384 result_loc, false, true); 16385 ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; 16386 if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && 16387 value_type->id != ZigTypeIdNull) { 16388 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); 16389 } else { 16390 return unwrapped_err_ptr; 16391 } 16392 } 16393 } 16394 return result_loc; 16395 } 16396 16397 static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, 16398 IrInstructionResolveResult *instruction) 16399 { 16400 ZigType *implicit_elem_type; 16401 if (instruction->ty == nullptr) { 16402 if (instruction->result_loc->id == ResultLocIdCast) { 16403 implicit_elem_type = ir_resolve_type(ira, 16404 instruction->result_loc->source_instruction->child); 16405 if (type_is_invalid(implicit_elem_type)) 16406 return ira->codegen->invalid_instruction; 16407 } else if (instruction->result_loc->id == ResultLocIdReturn) { 16408 implicit_elem_type = ira->explicit_return_type; 16409 if (type_is_invalid(implicit_elem_type)) 16410 return ira->codegen->invalid_instruction; 16411 } else { 16412 implicit_elem_type = ira->codegen->builtin_types.entry_var; 16413 } 16414 if (implicit_elem_type == ira->codegen->builtin_types.entry_var) { 16415 Buf *bare_name = buf_alloc(); 16416 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), 16417 instruction->base.scope, instruction->base.source_node, bare_name); 16418 16419 ZigType *inferred_struct_type = get_partial_container_type(ira->codegen, 16420 instruction->base.scope, ContainerKindStruct, instruction->base.source_node, 16421 buf_ptr(name), bare_name, ContainerLayoutAuto); 16422 inferred_struct_type->data.structure.is_inferred = true; 16423 inferred_struct_type->data.structure.resolve_status = ResolveStatusBeingInferred; 16424 implicit_elem_type = inferred_struct_type; 16425 } 16426 } else { 16427 implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); 16428 if (type_is_invalid(implicit_elem_type)) 16429 return ira->codegen->invalid_instruction; 16430 } 16431 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 16432 implicit_elem_type, nullptr, false, true, true); 16433 if (result_loc != nullptr) 16434 return result_loc; 16435 16436 ZigFn *fn = exec_fn_entry(ira->new_irb.exec); 16437 if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync && 16438 instruction->result_loc->id == ResultLocIdReturn) 16439 { 16440 result_loc = ir_resolve_result(ira, &instruction->base, no_result_loc(), 16441 implicit_elem_type, nullptr, false, true, true); 16442 if (result_loc != nullptr && 16443 (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) 16444 { 16445 return result_loc; 16446 } 16447 result_loc->value->special = ConstValSpecialRuntime; 16448 return result_loc; 16449 } 16450 16451 IrInstruction *result = ir_const(ira, &instruction->base, implicit_elem_type); 16452 result->value->special = ConstValSpecialUndef; 16453 IrInstruction *ptr = ir_get_ref(ira, &instruction->base, result, false, false); 16454 ptr->value->data.x_ptr.mut = ConstPtrMutComptimeVar; 16455 return ptr; 16456 } 16457 16458 static void ir_reset_result(ResultLoc *result_loc) { 16459 result_loc->written = false; 16460 result_loc->resolved_loc = nullptr; 16461 result_loc->gen_instruction = nullptr; 16462 result_loc->implicit_elem_type = nullptr; 16463 switch (result_loc->id) { 16464 case ResultLocIdInvalid: 16465 zig_unreachable(); 16466 case ResultLocIdPeerParent: { 16467 ResultLocPeerParent *peer_parent = reinterpret_cast<ResultLocPeerParent *>(result_loc); 16468 peer_parent->skipped = false; 16469 peer_parent->done_resuming = false; 16470 peer_parent->resolved_type = nullptr; 16471 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 16472 ir_reset_result(&peer_parent->peers.at(i)->base); 16473 } 16474 break; 16475 } 16476 case ResultLocIdVar: { 16477 IrInstructionAllocaSrc *alloca_src = 16478 reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); 16479 alloca_src->base.child = nullptr; 16480 break; 16481 } 16482 case ResultLocIdReturn: 16483 reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = false; 16484 break; 16485 case ResultLocIdPeer: 16486 case ResultLocIdNone: 16487 case ResultLocIdInstruction: 16488 case ResultLocIdBitCast: 16489 case ResultLocIdCast: 16490 break; 16491 } 16492 } 16493 16494 static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInstructionResetResult *instruction) { 16495 ir_reset_result(instruction->result_loc); 16496 return ir_const_void(ira, &instruction->base); 16497 } 16498 16499 static IrInstruction *get_async_call_result_loc(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, 16500 ZigType *fn_ret_type) 16501 { 16502 ir_assert(call_instruction->is_async_call_builtin, &call_instruction->base); 16503 IrInstruction *ret_ptr_uncasted = call_instruction->args[call_instruction->arg_count]->child; 16504 if (type_is_invalid(ret_ptr_uncasted->value->type)) 16505 return ira->codegen->invalid_instruction; 16506 if (ret_ptr_uncasted->value->type->id == ZigTypeIdVoid) { 16507 // Result location will be inside the async frame. 16508 return nullptr; 16509 } 16510 return ir_implicit_cast(ira, ret_ptr_uncasted, get_pointer_to_type(ira->codegen, fn_ret_type, false)); 16511 } 16512 16513 static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry, 16514 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, 16515 IrInstruction *casted_new_stack) 16516 { 16517 if (fn_entry == nullptr) { 16518 if (fn_type->data.fn.fn_type_id.cc != CallingConventionAsync) { 16519 ir_add_error(ira, fn_ref, 16520 buf_sprintf("expected async function, found '%s'", buf_ptr(&fn_type->name))); 16521 return ira->codegen->invalid_instruction; 16522 } 16523 if (casted_new_stack == nullptr) { 16524 ir_add_error(ira, fn_ref, buf_sprintf("function is not comptime-known; @asyncCall required")); 16525 return ira->codegen->invalid_instruction; 16526 } 16527 } 16528 if (casted_new_stack != nullptr) { 16529 ZigType *fn_ret_type = fn_type->data.fn.fn_type_id.return_type; 16530 IrInstruction *ret_ptr = get_async_call_result_loc(ira, call_instruction, fn_ret_type); 16531 if (ret_ptr != nullptr && type_is_invalid(ret_ptr->value->type)) 16532 return ira->codegen->invalid_instruction; 16533 16534 ZigType *anyframe_type = get_any_frame_type(ira->codegen, fn_ret_type); 16535 16536 IrInstructionCallGen *call_gen = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, 16537 arg_count, casted_args, FnInlineAuto, CallModifierAsync, casted_new_stack, 16538 call_instruction->is_async_call_builtin, ret_ptr, anyframe_type); 16539 return &call_gen->base; 16540 } else { 16541 ZigType *frame_type = get_fn_frame_type(ira->codegen, fn_entry); 16542 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, 16543 frame_type, nullptr, true, true, false); 16544 if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { 16545 return result_loc; 16546 } 16547 result_loc = ir_implicit_cast(ira, result_loc, get_pointer_to_type(ira->codegen, frame_type, false)); 16548 if (type_is_invalid(result_loc->value->type)) 16549 return ira->codegen->invalid_instruction; 16550 return &ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count, 16551 casted_args, FnInlineAuto, CallModifierAsync, casted_new_stack, 16552 call_instruction->is_async_call_builtin, result_loc, frame_type)->base; 16553 } 16554 } 16555 static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, 16556 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) 16557 { 16558 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 16559 assert(param_decl_node->type == NodeTypeParamDecl); 16560 16561 IrInstruction *casted_arg; 16562 if (param_decl_node->data.param_decl.var_token == nullptr) { 16563 AstNode *param_type_node = param_decl_node->data.param_decl.type; 16564 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); 16565 if (type_is_invalid(param_type)) 16566 return false; 16567 16568 casted_arg = ir_implicit_cast(ira, arg, param_type); 16569 if (type_is_invalid(casted_arg->value->type)) 16570 return false; 16571 } else { 16572 casted_arg = arg; 16573 } 16574 16575 ZigValue *arg_val = ir_resolve_const(ira, casted_arg, UndefOk); 16576 if (!arg_val) 16577 return false; 16578 16579 Buf *param_name = param_decl_node->data.param_decl.name; 16580 ZigVar *var = add_variable(ira->codegen, param_decl_node, 16581 *exec_scope, param_name, true, arg_val, nullptr, arg_val->type); 16582 *exec_scope = var->child_scope; 16583 *next_proto_i += 1; 16584 16585 return true; 16586 } 16587 16588 static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, 16589 IrInstruction *arg, Scope **child_scope, size_t *next_proto_i, 16590 GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args, 16591 ZigFn *impl_fn) 16592 { 16593 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 16594 assert(param_decl_node->type == NodeTypeParamDecl); 16595 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 16596 bool arg_part_of_generic_id = false; 16597 IrInstruction *casted_arg; 16598 if (is_var_args) { 16599 arg_part_of_generic_id = true; 16600 casted_arg = arg; 16601 } else { 16602 if (param_decl_node->data.param_decl.var_token == nullptr) { 16603 AstNode *param_type_node = param_decl_node->data.param_decl.type; 16604 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node); 16605 if (type_is_invalid(param_type)) 16606 return false; 16607 16608 casted_arg = ir_implicit_cast(ira, arg, param_type); 16609 if (type_is_invalid(casted_arg->value->type)) 16610 return false; 16611 } else { 16612 arg_part_of_generic_id = true; 16613 casted_arg = arg; 16614 } 16615 } 16616 16617 bool comptime_arg = param_decl_node->data.param_decl.is_comptime || 16618 casted_arg->value->type->id == ZigTypeIdComptimeInt || casted_arg->value->type->id == ZigTypeIdComptimeFloat; 16619 16620 ZigValue *arg_val; 16621 16622 if (comptime_arg) { 16623 arg_part_of_generic_id = true; 16624 arg_val = ir_resolve_const(ira, casted_arg, UndefBad); 16625 if (!arg_val) 16626 return false; 16627 } else { 16628 arg_val = create_const_runtime(casted_arg->value->type); 16629 } 16630 if (arg_part_of_generic_id) { 16631 copy_const_val(&generic_id->params[generic_id->param_count], arg_val, true); 16632 generic_id->param_count += 1; 16633 } 16634 16635 Buf *param_name = param_decl_node->data.param_decl.name; 16636 if (!param_name) return false; 16637 if (!is_var_args) { 16638 ZigVar *var = add_variable(ira->codegen, param_decl_node, 16639 *child_scope, param_name, true, arg_val, nullptr, arg_val->type); 16640 *child_scope = var->child_scope; 16641 var->shadowable = !comptime_arg; 16642 16643 *next_proto_i += 1; 16644 } else if (casted_arg->value->type->id == ZigTypeIdComptimeInt || 16645 casted_arg->value->type->id == ZigTypeIdComptimeFloat) 16646 { 16647 ir_add_error(ira, casted_arg, 16648 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557")); 16649 return false; 16650 } 16651 16652 if (!comptime_arg) { 16653 switch (type_requires_comptime(ira->codegen, casted_arg->value->type)) { 16654 case ReqCompTimeYes: 16655 ir_add_error(ira, casted_arg, 16656 buf_sprintf("parameter of type '%s' requires comptime", buf_ptr(&casted_arg->value->type->name))); 16657 return false; 16658 case ReqCompTimeInvalid: 16659 return false; 16660 case ReqCompTimeNo: 16661 break; 16662 } 16663 16664 casted_args[fn_type_id->param_count] = casted_arg; 16665 FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count]; 16666 param_info->type = casted_arg->value->type; 16667 param_info->is_noalias = param_decl_node->data.param_decl.is_noalias; 16668 impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node; 16669 fn_type_id->param_count += 1; 16670 } 16671 16672 return true; 16673 } 16674 16675 static ZigVar *get_fn_var_by_index(ZigFn *fn_entry, size_t index) { 16676 FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[index]; 16677 if (!type_has_bits(src_param_info->type)) 16678 return nullptr; 16679 16680 size_t next_var_i = 0; 16681 for (size_t param_i = 0; param_i < index; param_i += 1) { 16682 FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[param_i]; 16683 if (!type_has_bits(src_param_info->type)) { 16684 continue; 16685 } 16686 16687 next_var_i += 1; 16688 } 16689 return fn_entry->variable_list.at(next_var_i); 16690 } 16691 16692 static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var) { 16693 while (var->next_var != nullptr) { 16694 var = var->next_var; 16695 } 16696 16697 if (var->mem_slot_index != SIZE_MAX && var->owner_exec->analysis == nullptr) { 16698 assert(ira->codegen->errors.length != 0); 16699 return ira->codegen->invalid_instruction; 16700 } 16701 if (var->var_type == nullptr || type_is_invalid(var->var_type)) 16702 return ira->codegen->invalid_instruction; 16703 16704 ZigValue *mem_slot = nullptr; 16705 16706 bool comptime_var_mem = ir_get_var_is_comptime(var); 16707 bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern; 16708 bool is_volatile = false; 16709 16710 IrInstruction *result = ir_build_var_ptr(&ira->new_irb, 16711 instruction->scope, instruction->source_node, var); 16712 result->value->type = get_pointer_to_type_extra(ira->codegen, var->var_type, 16713 var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0, false); 16714 16715 if (linkage_makes_it_runtime) 16716 goto no_mem_slot; 16717 16718 if (value_is_comptime(var->const_value)) { 16719 mem_slot = var->const_value; 16720 } else if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { 16721 // find the relevant exec_context 16722 assert(var->owner_exec != nullptr); 16723 assert(var->owner_exec->analysis != nullptr); 16724 IrExecContext *exec_context = &var->owner_exec->analysis->exec_context; 16725 assert(var->mem_slot_index < exec_context->mem_slot_list.length); 16726 mem_slot = exec_context->mem_slot_list.at(var->mem_slot_index); 16727 } 16728 16729 if (mem_slot != nullptr) { 16730 switch (mem_slot->special) { 16731 case ConstValSpecialRuntime: 16732 goto no_mem_slot; 16733 case ConstValSpecialStatic: // fallthrough 16734 case ConstValSpecialLazy: // fallthrough 16735 case ConstValSpecialUndef: { 16736 ConstPtrMut ptr_mut; 16737 if (comptime_var_mem) { 16738 ptr_mut = ConstPtrMutComptimeVar; 16739 } else if (var->gen_is_const) { 16740 ptr_mut = ConstPtrMutComptimeConst; 16741 } else { 16742 assert(!comptime_var_mem); 16743 ptr_mut = ConstPtrMutRuntimeVar; 16744 } 16745 result->value->special = ConstValSpecialStatic; 16746 result->value->data.x_ptr.mut = ptr_mut; 16747 result->value->data.x_ptr.special = ConstPtrSpecialRef; 16748 result->value->data.x_ptr.data.ref.pointee = mem_slot; 16749 return result; 16750 } 16751 } 16752 zig_unreachable(); 16753 } 16754 16755 no_mem_slot: 16756 16757 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr); 16758 result->value->data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack; 16759 16760 return result; 16761 } 16762 16763 // This function is called when a comptime value becomes accessible at runtime. 16764 static void mark_comptime_value_escape(IrAnalyze *ira, IrInstruction *source_instr, ZigValue *val) { 16765 ir_assert(value_is_comptime(val), source_instr); 16766 if (val->special == ConstValSpecialUndef) 16767 return; 16768 16769 if (val->type->id == ZigTypeIdFn && val->type->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 16770 ir_assert(val->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 16771 if (val->data.x_ptr.data.fn.fn_entry->non_async_node == nullptr) { 16772 val->data.x_ptr.data.fn.fn_entry->non_async_node = source_instr->source_node; 16773 } 16774 } 16775 } 16776 16777 static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, 16778 IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const) 16779 { 16780 assert(ptr->value->type->id == ZigTypeIdPointer); 16781 16782 if (ptr->value->data.x_ptr.special == ConstPtrSpecialDiscard) { 16783 if (uncasted_value->value->type->id == ZigTypeIdErrorUnion || 16784 uncasted_value->value->type->id == ZigTypeIdErrorSet) 16785 { 16786 ir_add_error(ira, source_instr, buf_sprintf("error is discarded")); 16787 return ira->codegen->invalid_instruction; 16788 } 16789 return ir_const_void(ira, source_instr); 16790 } 16791 16792 InferredStructField *isf = ptr->value->type->data.pointer.inferred_struct_field; 16793 if (allow_write_through_const && isf != nullptr) { 16794 // Now it's time to add the field to the struct type. 16795 uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count; 16796 uint32_t new_field_count = old_field_count + 1; 16797 isf->inferred_struct_type->data.structure.src_field_count = new_field_count; 16798 isf->inferred_struct_type->data.structure.fields = realloc_type_struct_fields( 16799 isf->inferred_struct_type->data.structure.fields, old_field_count, new_field_count); 16800 16801 TypeStructField *field = isf->inferred_struct_type->data.structure.fields[old_field_count]; 16802 field->name = isf->field_name; 16803 field->type_entry = uncasted_value->value->type; 16804 field->type_val = create_const_type(ira->codegen, field->type_entry); 16805 field->src_index = old_field_count; 16806 field->decl_node = uncasted_value->source_node; 16807 16808 ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false); 16809 IrInstruction *casted_ptr; 16810 if (instr_is_comptime(ptr)) { 16811 casted_ptr = ir_const(ira, source_instr, struct_ptr_type); 16812 copy_const_val(casted_ptr->value, ptr->value, false); 16813 casted_ptr->value->type = struct_ptr_type; 16814 } else { 16815 casted_ptr = ir_build_cast(&ira->new_irb, source_instr->scope, 16816 source_instr->source_node, struct_ptr_type, ptr, CastOpNoop); 16817 casted_ptr->value->type = struct_ptr_type; 16818 } 16819 if (instr_is_comptime(casted_ptr)) { 16820 ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); 16821 if (!ptr_val) 16822 return ira->codegen->invalid_instruction; 16823 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 16824 ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, 16825 source_instr->source_node); 16826 struct_val->special = ConstValSpecialStatic; 16827 struct_val->data.x_struct.fields = realloc_const_vals_ptrs(struct_val->data.x_struct.fields, 16828 old_field_count, new_field_count); 16829 16830 ZigValue *field_val = struct_val->data.x_struct.fields[old_field_count]; 16831 field_val->special = ConstValSpecialUndef; 16832 field_val->type = field->type_entry; 16833 field_val->parent.id = ConstParentIdStruct; 16834 field_val->parent.data.p_struct.struct_val = struct_val; 16835 field_val->parent.data.p_struct.field_index = old_field_count; 16836 } 16837 } 16838 16839 ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, casted_ptr, 16840 isf->inferred_struct_type, true); 16841 } 16842 16843 if (ptr->value->type->data.pointer.is_const && !allow_write_through_const) { 16844 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 16845 return ira->codegen->invalid_instruction; 16846 } 16847 16848 ZigType *child_type = ptr->value->type->data.pointer.child_type; 16849 IrInstruction *value = ir_implicit_cast(ira, uncasted_value, child_type); 16850 if (value == ira->codegen->invalid_instruction) 16851 return ira->codegen->invalid_instruction; 16852 16853 switch (type_has_one_possible_value(ira->codegen, child_type)) { 16854 case OnePossibleValueInvalid: 16855 return ira->codegen->invalid_instruction; 16856 case OnePossibleValueYes: 16857 return ir_const_void(ira, source_instr); 16858 case OnePossibleValueNo: 16859 break; 16860 } 16861 16862 if (instr_is_comptime(ptr) && ptr->value->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 16863 if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst) { 16864 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 16865 return ira->codegen->invalid_instruction; 16866 } 16867 if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar || 16868 ptr->value->data.x_ptr.mut == ConstPtrMutInfer) 16869 { 16870 if (instr_is_comptime(value)) { 16871 ZigValue *dest_val = const_ptr_pointee(ira, ira->codegen, ptr->value, source_instr->source_node); 16872 if (dest_val == nullptr) 16873 return ira->codegen->invalid_instruction; 16874 if (dest_val->special != ConstValSpecialRuntime) { 16875 // TODO this allows a value stored to have the original value modified and then 16876 // have that affect what should be a copy. We need some kind of advanced copy-on-write 16877 // system to make these two tests pass at the same time: 16878 // * "string literal used as comptime slice is memoized" 16879 // * "comptime modification of const struct field" - except modified to avoid 16880 // ConstPtrMutComptimeVar, thus defeating the logic below. 16881 bool same_global_refs = ptr->value->data.x_ptr.mut != ConstPtrMutComptimeVar; 16882 copy_const_val(dest_val, value->value, same_global_refs); 16883 if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar && 16884 !ira->new_irb.current_basic_block->must_be_comptime_source_instr) 16885 { 16886 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; 16887 } 16888 return ir_const_void(ira, source_instr); 16889 } 16890 } 16891 if (ptr->value->data.x_ptr.mut == ConstPtrMutInfer) { 16892 ptr->value->special = ConstValSpecialRuntime; 16893 } else { 16894 ir_add_error(ira, source_instr, 16895 buf_sprintf("cannot store runtime value in compile time variable")); 16896 ZigValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, ptr->value); 16897 dest_val->type = ira->codegen->builtin_types.entry_invalid; 16898 16899 return ira->codegen->invalid_instruction; 16900 } 16901 } 16902 } 16903 16904 switch (type_requires_comptime(ira->codegen, child_type)) { 16905 case ReqCompTimeInvalid: 16906 return ira->codegen->invalid_instruction; 16907 case ReqCompTimeYes: 16908 switch (type_has_one_possible_value(ira->codegen, ptr->value->type)) { 16909 case OnePossibleValueInvalid: 16910 return ira->codegen->invalid_instruction; 16911 case OnePossibleValueNo: 16912 ir_add_error(ira, source_instr, 16913 buf_sprintf("cannot store runtime value in type '%s'", buf_ptr(&child_type->name))); 16914 return ira->codegen->invalid_instruction; 16915 case OnePossibleValueYes: 16916 return ir_const_void(ira, source_instr); 16917 } 16918 zig_unreachable(); 16919 case ReqCompTimeNo: 16920 break; 16921 } 16922 16923 if (instr_is_comptime(value)) { 16924 mark_comptime_value_escape(ira, source_instr, value->value); 16925 } 16926 16927 // If this is a store to a pointer with a runtime-known vector index, 16928 // we have to figure out the IrInstruction which represents the index and 16929 // emit a IrInstructionVectorStoreElem, or emit a compile error 16930 // explaining why it is impossible for this store to work. Which is that 16931 // the pointer address is of the vector; without the element index being known 16932 // we cannot properly perform the insertion. 16933 if (ptr->value->type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) { 16934 if (ptr->id == IrInstructionIdElemPtr) { 16935 IrInstructionElemPtr *elem_ptr = (IrInstructionElemPtr *)ptr; 16936 return ir_build_vector_store_elem(ira, source_instr, elem_ptr->array_ptr, 16937 elem_ptr->elem_index, value); 16938 } 16939 ir_add_error(ira, ptr, 16940 buf_sprintf("unable to determine vector element index of type '%s'", 16941 buf_ptr(&ptr->value->type->name))); 16942 return ira->codegen->invalid_instruction; 16943 } 16944 16945 IrInstructionStorePtr *store_ptr = ir_build_store_ptr(&ira->new_irb, source_instr->scope, 16946 source_instr->source_node, ptr, value); 16947 return &store_ptr->base; 16948 } 16949 16950 static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, 16951 ZigFn *fn_entry) 16952 { 16953 if (call_instruction->new_stack == nullptr) 16954 return nullptr; 16955 16956 if (!call_instruction->is_async_call_builtin && 16957 arch_stack_pointer_register_name(ira->codegen->zig_target->arch) == nullptr) 16958 { 16959 ir_add_error(ira, &call_instruction->base, 16960 buf_sprintf("target arch '%s' does not support @newStackCall", 16961 target_arch_name(ira->codegen->zig_target->arch))); 16962 } 16963 16964 IrInstruction *new_stack = call_instruction->new_stack->child; 16965 if (type_is_invalid(new_stack->value->type)) 16966 return ira->codegen->invalid_instruction; 16967 16968 if (call_instruction->is_async_call_builtin && 16969 fn_entry != nullptr && new_stack->value->type->id == ZigTypeIdPointer && 16970 new_stack->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 16971 { 16972 ZigType *needed_frame_type = get_pointer_to_type(ira->codegen, 16973 get_fn_frame_type(ira->codegen, fn_entry), false); 16974 return ir_implicit_cast(ira, new_stack, needed_frame_type); 16975 } else { 16976 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 16977 false, false, PtrLenUnknown, target_fn_align(ira->codegen->zig_target), 0, 0, false); 16978 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 16979 ira->codegen->need_frame_size_prefix_data = true; 16980 return ir_implicit_cast(ira, new_stack, u8_slice); 16981 } 16982 } 16983 16984 static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, 16985 ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, 16986 IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) 16987 { 16988 Error err; 16989 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 16990 size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0; 16991 16992 // for extern functions, the var args argument is not counted. 16993 // for zig functions, it is. 16994 size_t var_args_1_or_0; 16995 if (fn_type_id->cc == CallingConventionC) { 16996 var_args_1_or_0 = 0; 16997 } else { 16998 var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0; 16999 } 17000 size_t src_param_count = fn_type_id->param_count - var_args_1_or_0; 17001 17002 size_t call_param_count = call_instruction->arg_count + first_arg_1_or_0; 17003 for (size_t i = 0; i < call_instruction->arg_count; i += 1) { 17004 ZigValue *arg_tuple_value = call_instruction->args[i]->child->value; 17005 if (arg_tuple_value->type->id == ZigTypeIdArgTuple) { 17006 call_param_count -= 1; 17007 call_param_count += arg_tuple_value->data.x_arg_tuple.end_index - 17008 arg_tuple_value->data.x_arg_tuple.start_index; 17009 } 17010 } 17011 AstNode *source_node = call_instruction->base.source_node; 17012 17013 AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;; 17014 17015 if (fn_type_id->cc == CallingConventionNaked) { 17016 ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("unable to call function with naked calling convention")); 17017 if (fn_proto_node) { 17018 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 17019 } 17020 return ira->codegen->invalid_instruction; 17021 } 17022 17023 17024 if (fn_type_id->is_var_args) { 17025 if (call_param_count < src_param_count) { 17026 ErrorMsg *msg = ir_add_error_node(ira, source_node, 17027 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 17028 if (fn_proto_node) { 17029 add_error_note(ira->codegen, msg, fn_proto_node, 17030 buf_sprintf("declared here")); 17031 } 17032 return ira->codegen->invalid_instruction; 17033 } 17034 } else if (src_param_count != call_param_count) { 17035 ErrorMsg *msg = ir_add_error_node(ira, source_node, 17036 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 17037 if (fn_proto_node) { 17038 add_error_note(ira->codegen, msg, fn_proto_node, 17039 buf_sprintf("declared here")); 17040 } 17041 return ira->codegen->invalid_instruction; 17042 } 17043 17044 if (comptime_fn_call) { 17045 // No special handling is needed for compile time evaluation of generic functions. 17046 if (!fn_entry || fn_entry->body_node == nullptr) { 17047 ir_add_error(ira, fn_ref, buf_sprintf("unable to evaluate constant expression")); 17048 return ira->codegen->invalid_instruction; 17049 } 17050 17051 if (!ir_emit_backward_branch(ira, &call_instruction->base)) 17052 return ira->codegen->invalid_instruction; 17053 17054 // Fork a scope of the function with known values for the parameters. 17055 Scope *exec_scope = &fn_entry->fndef_scope->base; 17056 17057 size_t next_proto_i = 0; 17058 if (first_arg_ptr) { 17059 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 17060 17061 bool first_arg_known_bare = false; 17062 if (fn_type_id->next_param_index >= 1) { 17063 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 17064 if (type_is_invalid(param_type)) 17065 return ira->codegen->invalid_instruction; 17066 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 17067 } 17068 17069 IrInstruction *first_arg; 17070 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) { 17071 first_arg = first_arg_ptr; 17072 } else { 17073 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); 17074 if (type_is_invalid(first_arg->value->type)) 17075 return ira->codegen->invalid_instruction; 17076 } 17077 17078 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, first_arg, &exec_scope, &next_proto_i)) 17079 return ira->codegen->invalid_instruction; 17080 } 17081 17082 if (fn_proto_node->data.fn_proto.is_var_args) { 17083 ir_add_error(ira, &call_instruction->base, 17084 buf_sprintf("compiler bug: unable to call var args function at compile time. https://github.com/ziglang/zig/issues/313")); 17085 return ira->codegen->invalid_instruction; 17086 } 17087 17088 17089 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 17090 IrInstruction *old_arg = call_instruction->args[call_i]->child; 17091 if (type_is_invalid(old_arg->value->type)) 17092 return ira->codegen->invalid_instruction; 17093 17094 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i)) 17095 return ira->codegen->invalid_instruction; 17096 } 17097 17098 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 17099 ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node); 17100 if (type_is_invalid(specified_return_type)) 17101 return ira->codegen->invalid_instruction; 17102 ZigType *return_type; 17103 ZigType *inferred_err_set_type = nullptr; 17104 if (fn_proto_node->data.fn_proto.auto_err_set) { 17105 inferred_err_set_type = get_auto_err_set_type(ira->codegen, fn_entry); 17106 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 17107 return ira->codegen->invalid_instruction; 17108 return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 17109 } else { 17110 return_type = specified_return_type; 17111 } 17112 17113 bool cacheable = fn_eval_cacheable(exec_scope, return_type); 17114 ZigValue *result = nullptr; 17115 if (cacheable) { 17116 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope); 17117 if (entry) 17118 result = entry->value; 17119 } 17120 17121 if (result == nullptr) { 17122 // Analyze the fn body block like any other constant expression. 17123 AstNode *body_node = fn_entry->body_node; 17124 result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, 17125 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, 17126 nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node, 17127 UndefOk); 17128 17129 if (inferred_err_set_type != nullptr) { 17130 inferred_err_set_type->data.error_set.incomplete = false; 17131 if (result->type->id == ZigTypeIdErrorUnion) { 17132 ErrorTableEntry *err = result->data.x_err_union.error_set->data.x_err_set; 17133 if (err != nullptr) { 17134 inferred_err_set_type->data.error_set.err_count = 1; 17135 inferred_err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1); 17136 inferred_err_set_type->data.error_set.errors[0] = err; 17137 } 17138 ZigType *fn_inferred_err_set_type = result->type->data.error_union.err_set_type; 17139 inferred_err_set_type->data.error_set.err_count = fn_inferred_err_set_type->data.error_set.err_count; 17140 inferred_err_set_type->data.error_set.errors = fn_inferred_err_set_type->data.error_set.errors; 17141 } else if (result->type->id == ZigTypeIdErrorSet) { 17142 inferred_err_set_type->data.error_set.err_count = result->type->data.error_set.err_count; 17143 inferred_err_set_type->data.error_set.errors = result->type->data.error_set.errors; 17144 } 17145 } 17146 17147 if (cacheable) { 17148 ira->codegen->memoized_fn_eval_table.put(exec_scope, result); 17149 } 17150 17151 if (type_is_invalid(result->type)) { 17152 return ira->codegen->invalid_instruction; 17153 } 17154 } 17155 17156 IrInstruction *new_instruction = ir_const(ira, &call_instruction->base, result->type); 17157 copy_const_val(new_instruction->value, result, true); 17158 new_instruction->value->type = return_type; 17159 return ir_finish_anal(ira, new_instruction); 17160 } 17161 17162 if (fn_type->data.fn.is_generic) { 17163 if (!fn_entry) { 17164 ir_add_error(ira, call_instruction->fn_ref, 17165 buf_sprintf("calling a generic function requires compile-time known function value")); 17166 return ira->codegen->invalid_instruction; 17167 } 17168 17169 // Count the arguments of the function type id we are creating 17170 size_t new_fn_arg_count = first_arg_1_or_0; 17171 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 17172 IrInstruction *arg = call_instruction->args[call_i]->child; 17173 if (type_is_invalid(arg->value->type)) 17174 return ira->codegen->invalid_instruction; 17175 17176 if (arg->value->type->id == ZigTypeIdArgTuple) { 17177 new_fn_arg_count += arg->value->data.x_arg_tuple.end_index - arg->value->data.x_arg_tuple.start_index; 17178 } else { 17179 new_fn_arg_count += 1; 17180 } 17181 } 17182 17183 IrInstruction **casted_args = allocate<IrInstruction *>(new_fn_arg_count); 17184 17185 // Fork a scope of the function with known values for the parameters. 17186 Scope *parent_scope = fn_entry->fndef_scope->base.parent; 17187 ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node); 17188 impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count); 17189 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); 17190 impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); 17191 impl_fn->child_scope = &impl_fn->fndef_scope->base; 17192 FnTypeId inst_fn_type_id = {0}; 17193 init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count); 17194 inst_fn_type_id.param_count = 0; 17195 inst_fn_type_id.is_var_args = false; 17196 17197 // TODO maybe GenericFnTypeId can be replaced with using the child_scope directly 17198 // as the key in generic_table 17199 GenericFnTypeId *generic_id = allocate<GenericFnTypeId>(1); 17200 generic_id->fn_entry = fn_entry; 17201 generic_id->param_count = 0; 17202 generic_id->params = create_const_vals(new_fn_arg_count); 17203 size_t next_proto_i = 0; 17204 17205 if (first_arg_ptr) { 17206 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 17207 17208 bool first_arg_known_bare = false; 17209 if (fn_type_id->next_param_index >= 1) { 17210 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 17211 if (type_is_invalid(param_type)) 17212 return ira->codegen->invalid_instruction; 17213 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 17214 } 17215 17216 IrInstruction *first_arg; 17217 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) { 17218 first_arg = first_arg_ptr; 17219 } else { 17220 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); 17221 if (type_is_invalid(first_arg->value->type)) 17222 return ira->codegen->invalid_instruction; 17223 } 17224 17225 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, &impl_fn->child_scope, 17226 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 17227 { 17228 return ira->codegen->invalid_instruction; 17229 } 17230 } 17231 17232 bool found_first_var_arg = false; 17233 size_t first_var_arg; 17234 17235 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 17236 assert(parent_fn_entry); 17237 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 17238 IrInstruction *arg = call_instruction->args[call_i]->child; 17239 if (type_is_invalid(arg->value->type)) 17240 return ira->codegen->invalid_instruction; 17241 17242 if (arg->value->type->id == ZigTypeIdArgTuple) { 17243 for (size_t arg_tuple_i = arg->value->data.x_arg_tuple.start_index; 17244 arg_tuple_i < arg->value->data.x_arg_tuple.end_index; arg_tuple_i += 1) 17245 { 17246 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 17247 assert(param_decl_node->type == NodeTypeParamDecl); 17248 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 17249 if (is_var_args && !found_first_var_arg) { 17250 first_var_arg = inst_fn_type_id.param_count; 17251 found_first_var_arg = true; 17252 } 17253 17254 ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i); 17255 if (arg_var == nullptr) { 17256 ir_add_error(ira, arg, 17257 buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557")); 17258 return ira->codegen->invalid_instruction; 17259 } 17260 IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, arg, arg_var); 17261 if (type_is_invalid(arg_var_ptr_inst->value->type)) 17262 return ira->codegen->invalid_instruction; 17263 17264 IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst, nullptr); 17265 if (type_is_invalid(arg_tuple_arg->value->type)) 17266 return ira->codegen->invalid_instruction; 17267 17268 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg_tuple_arg, &impl_fn->child_scope, 17269 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 17270 { 17271 return ira->codegen->invalid_instruction; 17272 } 17273 } 17274 } else { 17275 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 17276 assert(param_decl_node->type == NodeTypeParamDecl); 17277 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 17278 if (is_var_args && !found_first_var_arg) { 17279 first_var_arg = inst_fn_type_id.param_count; 17280 found_first_var_arg = true; 17281 } 17282 17283 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope, 17284 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 17285 { 17286 return ira->codegen->invalid_instruction; 17287 } 17288 } 17289 } 17290 17291 if (fn_proto_node->data.fn_proto.is_var_args) { 17292 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 17293 Buf *param_name = param_decl_node->data.param_decl.name; 17294 17295 if (!found_first_var_arg) { 17296 first_var_arg = inst_fn_type_id.param_count; 17297 } 17298 17299 ZigValue *var_args_val = create_const_arg_tuple(ira->codegen, 17300 first_var_arg, inst_fn_type_id.param_count); 17301 ZigVar *var = add_variable(ira->codegen, param_decl_node, 17302 impl_fn->child_scope, param_name, true, var_args_val, nullptr, var_args_val->type); 17303 impl_fn->child_scope = var->child_scope; 17304 } 17305 17306 if (fn_proto_node->data.fn_proto.align_expr != nullptr) { 17307 ZigValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, 17308 fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), 17309 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 17310 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, 17311 nullptr, UndefBad); 17312 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 17313 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); 17314 copy_const_val(const_instruction->base.value, align_result, true); 17315 17316 uint32_t align_bytes = 0; 17317 ir_resolve_align(ira, &const_instruction->base, nullptr, &align_bytes); 17318 impl_fn->align_bytes = align_bytes; 17319 inst_fn_type_id.alignment = align_bytes; 17320 } 17321 17322 if (fn_proto_node->data.fn_proto.return_var_token == nullptr) { 17323 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 17324 ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node); 17325 if (type_is_invalid(specified_return_type)) 17326 return ira->codegen->invalid_instruction; 17327 if (fn_proto_node->data.fn_proto.auto_err_set) { 17328 ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn); 17329 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 17330 return ira->codegen->invalid_instruction; 17331 inst_fn_type_id.return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 17332 } else { 17333 inst_fn_type_id.return_type = specified_return_type; 17334 } 17335 17336 switch (type_requires_comptime(ira->codegen, specified_return_type)) { 17337 case ReqCompTimeYes: 17338 // Throw out our work and call the function as if it were comptime. 17339 return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, 17340 true, FnInlineAuto); 17341 case ReqCompTimeInvalid: 17342 return ira->codegen->invalid_instruction; 17343 case ReqCompTimeNo: 17344 break; 17345 } 17346 } 17347 17348 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn); 17349 if (existing_entry) { 17350 // throw away all our work and use the existing function 17351 impl_fn = existing_entry->value; 17352 } else { 17353 // finish instantiating the function 17354 impl_fn->type_entry = get_fn_type(ira->codegen, &inst_fn_type_id); 17355 if (type_is_invalid(impl_fn->type_entry)) 17356 return ira->codegen->invalid_instruction; 17357 17358 impl_fn->ir_executable.source_node = call_instruction->base.source_node; 17359 impl_fn->ir_executable.parent_exec = ira->new_irb.exec; 17360 impl_fn->analyzed_executable.source_node = call_instruction->base.source_node; 17361 impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; 17362 impl_fn->analyzed_executable.backward_branch_quota = ira->new_irb.exec->backward_branch_quota; 17363 impl_fn->analyzed_executable.is_generic_instantiation = true; 17364 17365 ira->codegen->fn_defs.append(impl_fn); 17366 } 17367 17368 FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; 17369 17370 if (fn_type_can_fail(impl_fn_type_id)) { 17371 parent_fn_entry->calls_or_awaits_errorable_fn = true; 17372 } 17373 17374 IrInstruction *casted_new_stack = analyze_casted_new_stack(ira, call_instruction, impl_fn); 17375 if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) 17376 return ira->codegen->invalid_instruction; 17377 17378 size_t impl_param_count = impl_fn_type_id->param_count; 17379 if (call_instruction->modifier == CallModifierAsync) { 17380 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, 17381 nullptr, casted_args, impl_param_count, casted_new_stack); 17382 return ir_finish_anal(ira, result); 17383 } 17384 17385 IrInstruction *result_loc; 17386 if (handle_is_ptr(impl_fn_type_id->return_type)) { 17387 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, 17388 impl_fn_type_id->return_type, nullptr, true, true, false); 17389 if (result_loc != nullptr) { 17390 if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { 17391 return result_loc; 17392 } 17393 if (!handle_is_ptr(result_loc->value->type->data.pointer.child_type)) { 17394 ir_reset_result(call_instruction->result_loc); 17395 result_loc = nullptr; 17396 } 17397 } 17398 } else if (call_instruction->is_async_call_builtin) { 17399 result_loc = get_async_call_result_loc(ira, call_instruction, impl_fn_type_id->return_type); 17400 if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) 17401 return ira->codegen->invalid_instruction; 17402 } else { 17403 result_loc = nullptr; 17404 } 17405 17406 if (impl_fn_type_id->cc == CallingConventionAsync && 17407 parent_fn_entry->inferred_async_node == nullptr && 17408 call_instruction->modifier != CallModifierNoAsync) 17409 { 17410 parent_fn_entry->inferred_async_node = fn_ref->source_node; 17411 parent_fn_entry->inferred_async_fn = impl_fn; 17412 } 17413 17414 IrInstructionCallGen *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, 17415 impl_fn, nullptr, impl_param_count, casted_args, fn_inline, 17416 call_instruction->modifier, casted_new_stack, call_instruction->is_async_call_builtin, result_loc, 17417 impl_fn_type_id->return_type); 17418 17419 if (get_scope_typeof(call_instruction->base.scope) == nullptr) { 17420 parent_fn_entry->call_list.append(new_call_instruction); 17421 } 17422 17423 return ir_finish_anal(ira, &new_call_instruction->base); 17424 } 17425 17426 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 17427 assert(fn_type_id->return_type != nullptr); 17428 assert(parent_fn_entry != nullptr); 17429 if (fn_type_can_fail(fn_type_id)) { 17430 parent_fn_entry->calls_or_awaits_errorable_fn = true; 17431 } 17432 17433 17434 IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count); 17435 size_t next_arg_index = 0; 17436 if (first_arg_ptr) { 17437 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 17438 17439 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 17440 if (type_is_invalid(param_type)) 17441 return ira->codegen->invalid_instruction; 17442 17443 IrInstruction *first_arg; 17444 if (param_type->id == ZigTypeIdPointer && 17445 handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) 17446 { 17447 first_arg = first_arg_ptr; 17448 } else { 17449 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); 17450 if (type_is_invalid(first_arg->value->type)) 17451 return ira->codegen->invalid_instruction; 17452 } 17453 17454 IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type); 17455 if (type_is_invalid(casted_arg->value->type)) 17456 return ira->codegen->invalid_instruction; 17457 17458 casted_args[next_arg_index] = casted_arg; 17459 next_arg_index += 1; 17460 } 17461 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 17462 IrInstruction *old_arg = call_instruction->args[call_i]->child; 17463 if (type_is_invalid(old_arg->value->type)) 17464 return ira->codegen->invalid_instruction; 17465 17466 if (old_arg->value->type->id == ZigTypeIdArgTuple) { 17467 for (size_t arg_tuple_i = old_arg->value->data.x_arg_tuple.start_index; 17468 arg_tuple_i < old_arg->value->data.x_arg_tuple.end_index; arg_tuple_i += 1) 17469 { 17470 ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i); 17471 if (arg_var == nullptr) { 17472 ir_add_error(ira, old_arg, 17473 buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557")); 17474 return ira->codegen->invalid_instruction; 17475 } 17476 IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, old_arg, arg_var); 17477 if (type_is_invalid(arg_var_ptr_inst->value->type)) 17478 return ira->codegen->invalid_instruction; 17479 17480 IrInstruction *arg_tuple_arg = ir_get_deref(ira, old_arg, arg_var_ptr_inst, nullptr); 17481 if (type_is_invalid(arg_tuple_arg->value->type)) 17482 return ira->codegen->invalid_instruction; 17483 17484 IrInstruction *casted_arg; 17485 if (next_arg_index < src_param_count) { 17486 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 17487 if (type_is_invalid(param_type)) 17488 return ira->codegen->invalid_instruction; 17489 casted_arg = ir_implicit_cast(ira, arg_tuple_arg, param_type); 17490 if (type_is_invalid(casted_arg->value->type)) 17491 return ira->codegen->invalid_instruction; 17492 } else { 17493 casted_arg = arg_tuple_arg; 17494 } 17495 17496 casted_args[next_arg_index] = casted_arg; 17497 next_arg_index += 1; 17498 } 17499 } else { 17500 IrInstruction *casted_arg; 17501 if (next_arg_index < src_param_count) { 17502 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 17503 if (type_is_invalid(param_type)) 17504 return ira->codegen->invalid_instruction; 17505 casted_arg = ir_implicit_cast(ira, old_arg, param_type); 17506 if (type_is_invalid(casted_arg->value->type)) 17507 return ira->codegen->invalid_instruction; 17508 } else { 17509 casted_arg = old_arg; 17510 } 17511 17512 casted_args[next_arg_index] = casted_arg; 17513 next_arg_index += 1; 17514 } 17515 } 17516 17517 assert(next_arg_index == call_param_count); 17518 17519 ZigType *return_type = fn_type_id->return_type; 17520 if (type_is_invalid(return_type)) 17521 return ira->codegen->invalid_instruction; 17522 17523 if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) { 17524 ir_add_error(ira, &call_instruction->base, 17525 buf_sprintf("no-inline call of inline function")); 17526 return ira->codegen->invalid_instruction; 17527 } 17528 17529 IrInstruction *casted_new_stack = analyze_casted_new_stack(ira, call_instruction, fn_entry); 17530 if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) 17531 return ira->codegen->invalid_instruction; 17532 17533 if (call_instruction->modifier == CallModifierAsync) { 17534 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, 17535 casted_args, call_param_count, casted_new_stack); 17536 return ir_finish_anal(ira, result); 17537 } 17538 17539 if (fn_type_id->cc == CallingConventionAsync && 17540 parent_fn_entry->inferred_async_node == nullptr && 17541 call_instruction->modifier != CallModifierNoAsync) 17542 { 17543 parent_fn_entry->inferred_async_node = fn_ref->source_node; 17544 parent_fn_entry->inferred_async_fn = fn_entry; 17545 } 17546 17547 IrInstruction *result_loc; 17548 if (handle_is_ptr(return_type)) { 17549 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, 17550 return_type, nullptr, true, true, false); 17551 if (result_loc != nullptr) { 17552 if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { 17553 return result_loc; 17554 } 17555 if (!handle_is_ptr(result_loc->value->type->data.pointer.child_type)) { 17556 ir_reset_result(call_instruction->result_loc); 17557 result_loc = nullptr; 17558 } 17559 } 17560 } else if (call_instruction->is_async_call_builtin) { 17561 result_loc = get_async_call_result_loc(ira, call_instruction, return_type); 17562 if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) 17563 return ira->codegen->invalid_instruction; 17564 } else { 17565 result_loc = nullptr; 17566 } 17567 17568 IrInstructionCallGen *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, 17569 call_param_count, casted_args, fn_inline, call_instruction->modifier, casted_new_stack, 17570 call_instruction->is_async_call_builtin, result_loc, return_type); 17571 if (get_scope_typeof(call_instruction->base.scope) == nullptr) { 17572 parent_fn_entry->call_list.append(new_call_instruction); 17573 } 17574 return ir_finish_anal(ira, &new_call_instruction->base); 17575 } 17576 17577 static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) { 17578 IrInstruction *fn_ref = call_instruction->fn_ref->child; 17579 if (type_is_invalid(fn_ref->value->type)) 17580 return ira->codegen->invalid_instruction; 17581 17582 bool is_comptime = call_instruction->is_comptime || 17583 ir_should_inline(ira->new_irb.exec, call_instruction->base.scope); 17584 17585 if (is_comptime || instr_is_comptime(fn_ref)) { 17586 if (fn_ref->value->type->id == ZigTypeIdMetaType) { 17587 ZigType *ty = ir_resolve_type(ira, fn_ref); 17588 if (ty == nullptr) 17589 return ira->codegen->invalid_instruction; 17590 ErrorMsg *msg = ir_add_error_node(ira, fn_ref->source_node, 17591 buf_sprintf("type '%s' not a function", buf_ptr(&ty->name))); 17592 add_error_note(ira->codegen, msg, call_instruction->base.source_node, 17593 buf_sprintf("use @as builtin for type coercion")); 17594 return ira->codegen->invalid_instruction; 17595 } else if (fn_ref->value->type->id == ZigTypeIdFn) { 17596 ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); 17597 ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value->type; 17598 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_type, 17599 fn_ref, nullptr, is_comptime, call_instruction->fn_inline); 17600 } else if (fn_ref->value->type->id == ZigTypeIdBoundFn) { 17601 assert(fn_ref->value->special == ConstValSpecialStatic); 17602 ZigFn *fn_table_entry = fn_ref->value->data.x_bound_fn.fn; 17603 IrInstruction *first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; 17604 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 17605 fn_ref, first_arg_ptr, is_comptime, call_instruction->fn_inline); 17606 } else { 17607 ir_add_error_node(ira, fn_ref->source_node, 17608 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); 17609 return ira->codegen->invalid_instruction; 17610 } 17611 } 17612 17613 if (fn_ref->value->type->id == ZigTypeIdFn) { 17614 return ir_analyze_fn_call(ira, call_instruction, nullptr, fn_ref->value->type, 17615 fn_ref, nullptr, false, call_instruction->fn_inline); 17616 } else { 17617 ir_add_error_node(ira, fn_ref->source_node, 17618 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); 17619 return ira->codegen->invalid_instruction; 17620 } 17621 } 17622 17623 // out_val->type must be the type to read the pointer as 17624 // if the type is different than the actual type then it does a comptime byte reinterpretation 17625 static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 17626 ZigValue *out_val, ZigValue *ptr_val) 17627 { 17628 Error err; 17629 assert(out_val->type != nullptr); 17630 17631 ZigValue *pointee = const_ptr_pointee_unchecked(codegen, ptr_val); 17632 src_assert(pointee->type != nullptr, source_node); 17633 17634 if ((err = type_resolve(codegen, pointee->type, ResolveStatusSizeKnown))) 17635 return ErrorSemanticAnalyzeFail; 17636 if ((err = type_resolve(codegen, out_val->type, ResolveStatusSizeKnown))) 17637 return ErrorSemanticAnalyzeFail; 17638 17639 size_t src_size = type_size(codegen, pointee->type); 17640 size_t dst_size = type_size(codegen, out_val->type); 17641 17642 if (dst_size <= src_size) { 17643 if (src_size == dst_size && types_have_same_zig_comptime_repr(codegen, out_val->type, pointee->type)) { 17644 copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar); 17645 return ErrorNone; 17646 } 17647 Buf buf = BUF_INIT; 17648 buf_resize(&buf, src_size); 17649 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf), pointee); 17650 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 17651 return err; 17652 return ErrorNone; 17653 } 17654 17655 switch (ptr_val->data.x_ptr.special) { 17656 case ConstPtrSpecialInvalid: 17657 zig_unreachable(); 17658 case ConstPtrSpecialNull: 17659 if (dst_size == 0) 17660 return ErrorNone; 17661 opt_ir_add_error_node(ira, codegen, source_node, 17662 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from null pointer", 17663 dst_size)); 17664 return ErrorSemanticAnalyzeFail; 17665 case ConstPtrSpecialRef: { 17666 opt_ir_add_error_node(ira, codegen, source_node, 17667 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from pointer to %s which is %" ZIG_PRI_usize " bytes", 17668 dst_size, buf_ptr(&pointee->type->name), src_size)); 17669 return ErrorSemanticAnalyzeFail; 17670 } 17671 case ConstPtrSpecialBaseArray: { 17672 ZigValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val; 17673 assert(array_val->type->id == ZigTypeIdArray); 17674 if (array_val->data.x_array.special != ConstArraySpecialNone) 17675 zig_panic("TODO"); 17676 size_t elem_size = src_size; 17677 size_t elem_index = ptr_val->data.x_ptr.data.base_array.elem_index; 17678 src_size = elem_size * (array_val->type->data.array.len - elem_index); 17679 if (dst_size > src_size) { 17680 opt_ir_add_error_node(ira, codegen, source_node, 17681 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from %s at index %" ZIG_PRI_usize " which is %" ZIG_PRI_usize " bytes", 17682 dst_size, buf_ptr(&array_val->type->name), elem_index, src_size)); 17683 return ErrorSemanticAnalyzeFail; 17684 } 17685 size_t elem_count = (dst_size % elem_size == 0) ? (dst_size / elem_size) : (dst_size / elem_size + 1); 17686 Buf buf = BUF_INIT; 17687 buf_resize(&buf, elem_count * elem_size); 17688 for (size_t i = 0; i < elem_count; i += 1) { 17689 ZigValue *elem_val = &array_val->data.x_array.data.s_none.elements[elem_index + i]; 17690 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); 17691 } 17692 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 17693 return err; 17694 return ErrorNone; 17695 } 17696 case ConstPtrSpecialBaseStruct: 17697 case ConstPtrSpecialBaseErrorUnionCode: 17698 case ConstPtrSpecialBaseErrorUnionPayload: 17699 case ConstPtrSpecialBaseOptionalPayload: 17700 case ConstPtrSpecialDiscard: 17701 case ConstPtrSpecialHardCodedAddr: 17702 case ConstPtrSpecialFunction: 17703 zig_panic("TODO"); 17704 } 17705 zig_unreachable(); 17706 } 17707 17708 static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *instruction) { 17709 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); 17710 result->value->special = ConstValSpecialLazy; 17711 17712 LazyValueOptType *lazy_opt_type = allocate<LazyValueOptType>(1); 17713 lazy_opt_type->ira = ira; 17714 result->value->data.x_lazy = &lazy_opt_type->base; 17715 lazy_opt_type->base.id = LazyValueIdOptType; 17716 17717 lazy_opt_type->payload_type = instruction->value->child; 17718 if (ir_resolve_type_lazy(ira, lazy_opt_type->payload_type) == nullptr) 17719 return ira->codegen->invalid_instruction; 17720 17721 return result; 17722 } 17723 17724 static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *scalar_type, 17725 ZigValue *operand_val, ZigValue *scalar_out_val, bool is_wrap_op) 17726 { 17727 bool is_float = (scalar_type->id == ZigTypeIdFloat || scalar_type->id == ZigTypeIdComptimeFloat); 17728 17729 bool ok_type = ((scalar_type->id == ZigTypeIdInt && scalar_type->data.integral.is_signed) || 17730 scalar_type->id == ZigTypeIdComptimeInt || (is_float && !is_wrap_op)); 17731 17732 if (!ok_type) { 17733 const char *fmt = is_wrap_op ? "invalid wrapping negation type: '%s'" : "invalid negation type: '%s'"; 17734 return ir_add_error(ira, source_instr, buf_sprintf(fmt, buf_ptr(&scalar_type->name))); 17735 } 17736 17737 if (is_float) { 17738 float_negate(scalar_out_val, operand_val); 17739 } else if (is_wrap_op) { 17740 bigint_negate_wrap(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint, 17741 scalar_type->data.integral.bit_count); 17742 } else { 17743 bigint_negate(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint); 17744 } 17745 17746 scalar_out_val->type = scalar_type; 17747 scalar_out_val->special = ConstValSpecialStatic; 17748 17749 if (is_wrap_op || is_float || scalar_type->id == ZigTypeIdComptimeInt) { 17750 return nullptr; 17751 } 17752 17753 if (!bigint_fits_in_bits(&scalar_out_val->data.x_bigint, scalar_type->data.integral.bit_count, true)) { 17754 return ir_add_error(ira, source_instr, buf_sprintf("negation caused overflow")); 17755 } 17756 return nullptr; 17757 } 17758 17759 static IrInstruction *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *instruction) { 17760 IrInstruction *value = instruction->value->child; 17761 ZigType *expr_type = value->value->type; 17762 if (type_is_invalid(expr_type)) 17763 return ira->codegen->invalid_instruction; 17764 17765 if (!(expr_type->id == ZigTypeIdInt || expr_type->id == ZigTypeIdComptimeInt || 17766 expr_type->id == ZigTypeIdFloat || expr_type->id == ZigTypeIdComptimeFloat || 17767 expr_type->id == ZigTypeIdVector)) 17768 { 17769 ir_add_error(ira, &instruction->base, 17770 buf_sprintf("negation of type '%s'", buf_ptr(&expr_type->name))); 17771 return ira->codegen->invalid_instruction; 17772 } 17773 17774 bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap); 17775 17776 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 17777 17778 if (instr_is_comptime(value)) { 17779 ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad); 17780 if (!operand_val) 17781 return ira->codegen->invalid_instruction; 17782 17783 IrInstruction *result_instruction = ir_const(ira, &instruction->base, expr_type); 17784 ZigValue *out_val = result_instruction->value; 17785 if (expr_type->id == ZigTypeIdVector) { 17786 expand_undef_array(ira->codegen, operand_val); 17787 out_val->special = ConstValSpecialUndef; 17788 expand_undef_array(ira->codegen, out_val); 17789 size_t len = expr_type->data.vector.len; 17790 for (size_t i = 0; i < len; i += 1) { 17791 ZigValue *scalar_operand_val = &operand_val->data.x_array.data.s_none.elements[i]; 17792 ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 17793 assert(scalar_operand_val->type == scalar_type); 17794 assert(scalar_out_val->type == scalar_type); 17795 ErrorMsg *msg = ir_eval_negation_scalar(ira, &instruction->base, scalar_type, 17796 scalar_operand_val, scalar_out_val, is_wrap_op); 17797 if (msg != nullptr) { 17798 add_error_note(ira->codegen, msg, instruction->base.source_node, 17799 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 17800 return ira->codegen->invalid_instruction; 17801 } 17802 } 17803 out_val->type = expr_type; 17804 out_val->special = ConstValSpecialStatic; 17805 } else { 17806 if (ir_eval_negation_scalar(ira, &instruction->base, scalar_type, operand_val, out_val, 17807 is_wrap_op) != nullptr) 17808 { 17809 return ira->codegen->invalid_instruction; 17810 } 17811 } 17812 return result_instruction; 17813 } 17814 17815 IrInstruction *result = ir_build_un_op(&ira->new_irb, 17816 instruction->base.scope, instruction->base.source_node, 17817 instruction->op_id, value); 17818 result->value->type = expr_type; 17819 return result; 17820 } 17821 17822 static IrInstruction *ir_analyze_bin_not(IrAnalyze *ira, IrInstructionUnOp *instruction) { 17823 IrInstruction *value = instruction->value->child; 17824 ZigType *expr_type = value->value->type; 17825 if (type_is_invalid(expr_type)) 17826 return ira->codegen->invalid_instruction; 17827 17828 if (expr_type->id == ZigTypeIdInt) { 17829 if (instr_is_comptime(value)) { 17830 ZigValue *target_const_val = ir_resolve_const(ira, value, UndefBad); 17831 if (target_const_val == nullptr) 17832 return ira->codegen->invalid_instruction; 17833 17834 IrInstruction *result = ir_const(ira, &instruction->base, expr_type); 17835 bigint_not(&result->value->data.x_bigint, &target_const_val->data.x_bigint, 17836 expr_type->data.integral.bit_count, expr_type->data.integral.is_signed); 17837 return result; 17838 } 17839 17840 IrInstruction *result = ir_build_un_op(&ira->new_irb, instruction->base.scope, 17841 instruction->base.source_node, IrUnOpBinNot, value); 17842 result->value->type = expr_type; 17843 return result; 17844 } 17845 17846 ir_add_error(ira, &instruction->base, 17847 buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name))); 17848 return ira->codegen->invalid_instruction; 17849 } 17850 17851 static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *instruction) { 17852 IrUnOp op_id = instruction->op_id; 17853 switch (op_id) { 17854 case IrUnOpInvalid: 17855 zig_unreachable(); 17856 case IrUnOpBinNot: 17857 return ir_analyze_bin_not(ira, instruction); 17858 case IrUnOpNegation: 17859 case IrUnOpNegationWrap: 17860 return ir_analyze_negation(ira, instruction); 17861 case IrUnOpDereference: { 17862 IrInstruction *ptr = instruction->value->child; 17863 if (type_is_invalid(ptr->value->type)) 17864 return ira->codegen->invalid_instruction; 17865 ZigType *ptr_type = ptr->value->type; 17866 if (ptr_type->id == ZigTypeIdPointer && ptr_type->data.pointer.ptr_len == PtrLenUnknown) { 17867 ir_add_error_node(ira, instruction->base.source_node, 17868 buf_sprintf("index syntax required for unknown-length pointer type '%s'", 17869 buf_ptr(&ptr_type->name))); 17870 return ira->codegen->invalid_instruction; 17871 } 17872 17873 IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr, instruction->result_loc); 17874 if (result == ira->codegen->invalid_instruction) 17875 return ira->codegen->invalid_instruction; 17876 17877 // If the result needs to be an lvalue, type check it 17878 if (instruction->lval == LValPtr && result->value->type->id != ZigTypeIdPointer) { 17879 ir_add_error(ira, &instruction->base, 17880 buf_sprintf("attempt to dereference non-pointer type '%s'", buf_ptr(&result->value->type->name))); 17881 return ira->codegen->invalid_instruction; 17882 } 17883 17884 return result; 17885 } 17886 case IrUnOpOptional: 17887 return ir_analyze_optional_type(ira, instruction); 17888 } 17889 zig_unreachable(); 17890 } 17891 17892 static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) { 17893 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index); 17894 if (old_bb->in_resume_stack) return; 17895 ira->resume_stack.append(pos); 17896 old_bb->in_resume_stack = true; 17897 } 17898 17899 static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlock *old_bb) { 17900 if (ira->resume_stack.length != 0) { 17901 ir_push_resume(ira, {old_bb->index, 0}); 17902 } 17903 } 17904 17905 static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { 17906 IrBasicBlock *old_dest_block = br_instruction->dest_block; 17907 17908 bool is_comptime; 17909 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) 17910 return ir_unreach_error(ira); 17911 17912 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) 17913 return ir_inline_bb(ira, &br_instruction->base, old_dest_block); 17914 17915 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); 17916 if (new_bb == nullptr) 17917 return ir_unreach_error(ira); 17918 17919 ir_push_resume_block(ira, old_dest_block); 17920 17921 IrInstruction *result = ir_build_br(&ira->new_irb, 17922 br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); 17923 result->value->type = ira->codegen->builtin_types.entry_unreachable; 17924 return ir_finish_anal(ira, result); 17925 } 17926 17927 static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) { 17928 IrInstruction *condition = cond_br_instruction->condition->child; 17929 if (type_is_invalid(condition->value->type)) 17930 return ir_unreach_error(ira); 17931 17932 bool is_comptime; 17933 if (!ir_resolve_comptime(ira, cond_br_instruction->is_comptime->child, &is_comptime)) 17934 return ir_unreach_error(ira); 17935 17936 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 17937 IrInstruction *casted_condition = ir_implicit_cast(ira, condition, bool_type); 17938 if (type_is_invalid(casted_condition->value->type)) 17939 return ir_unreach_error(ira); 17940 17941 if (is_comptime || instr_is_comptime(casted_condition)) { 17942 bool cond_is_true; 17943 if (!ir_resolve_bool(ira, casted_condition, &cond_is_true)) 17944 return ir_unreach_error(ira); 17945 17946 IrBasicBlock *old_dest_block = cond_is_true ? 17947 cond_br_instruction->then_block : cond_br_instruction->else_block; 17948 17949 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) 17950 return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); 17951 17952 IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); 17953 if (new_dest_block == nullptr) 17954 return ir_unreach_error(ira); 17955 17956 ir_push_resume_block(ira, old_dest_block); 17957 17958 IrInstruction *result = ir_build_br(&ira->new_irb, 17959 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); 17960 result->value->type = ira->codegen->builtin_types.entry_unreachable; 17961 return ir_finish_anal(ira, result); 17962 } 17963 17964 assert(cond_br_instruction->then_block != cond_br_instruction->else_block); 17965 IrBasicBlock *new_then_block = ir_get_new_bb_runtime(ira, cond_br_instruction->then_block, &cond_br_instruction->base); 17966 if (new_then_block == nullptr) 17967 return ir_unreach_error(ira); 17968 17969 IrBasicBlock *new_else_block = ir_get_new_bb_runtime(ira, cond_br_instruction->else_block, &cond_br_instruction->base); 17970 if (new_else_block == nullptr) 17971 return ir_unreach_error(ira); 17972 17973 ir_push_resume_block(ira, cond_br_instruction->else_block); 17974 ir_push_resume_block(ira, cond_br_instruction->then_block); 17975 17976 IrInstruction *result = ir_build_cond_br(&ira->new_irb, 17977 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, 17978 casted_condition, new_then_block, new_else_block, nullptr); 17979 result->value->type = ira->codegen->builtin_types.entry_unreachable; 17980 return ir_finish_anal(ira, result); 17981 } 17982 17983 static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira, 17984 IrInstructionUnreachable *unreachable_instruction) 17985 { 17986 IrInstruction *result = ir_build_unreachable(&ira->new_irb, 17987 unreachable_instruction->base.scope, unreachable_instruction->base.source_node); 17988 result->value->type = ira->codegen->builtin_types.entry_unreachable; 17989 return ir_finish_anal(ira, result); 17990 } 17991 17992 static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) { 17993 Error err; 17994 17995 if (ira->const_predecessor_bb) { 17996 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 17997 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; 17998 if (predecessor != ira->const_predecessor_bb) 17999 continue; 18000 IrInstruction *value = phi_instruction->incoming_values[i]->child; 18001 assert(value->value->type); 18002 if (type_is_invalid(value->value->type)) 18003 return ira->codegen->invalid_instruction; 18004 18005 if (value->value->special != ConstValSpecialRuntime) { 18006 IrInstruction *result = ir_const(ira, &phi_instruction->base, nullptr); 18007 copy_const_val(result->value, value->value, true); 18008 return result; 18009 } else { 18010 return value; 18011 } 18012 } 18013 zig_unreachable(); 18014 } 18015 18016 ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; 18017 if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming && 18018 peer_parent->peers.length >= 2) 18019 { 18020 if (peer_parent->resolved_type == nullptr) { 18021 IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peers.length); 18022 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 18023 ResultLocPeer *this_peer = peer_parent->peers.at(i); 18024 18025 IrInstruction *gen_instruction = this_peer->base.gen_instruction; 18026 if (gen_instruction == nullptr) { 18027 // unreachable instructions will cause implicit_elem_type to be null 18028 if (this_peer->base.implicit_elem_type == nullptr) { 18029 instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction); 18030 } else { 18031 instructions[i] = ir_const(ira, this_peer->base.source_instruction, 18032 this_peer->base.implicit_elem_type); 18033 instructions[i]->value->special = ConstValSpecialRuntime; 18034 } 18035 } else { 18036 instructions[i] = gen_instruction; 18037 } 18038 18039 } 18040 ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent); 18041 peer_parent->resolved_type = ir_resolve_peer_types(ira, 18042 peer_parent->base.source_instruction->source_node, expected_type, instructions, 18043 peer_parent->peers.length); 18044 if (type_is_invalid(peer_parent->resolved_type)) 18045 return ira->codegen->invalid_instruction; 18046 18047 // the logic below assumes there are no instructions in the new current basic block yet 18048 ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base); 18049 18050 // In case resolving the parent activates a suspend, do it now 18051 IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent, 18052 peer_parent->resolved_type, nullptr, false, false, true); 18053 if (parent_result_loc != nullptr && 18054 (type_is_invalid(parent_result_loc->value->type) || instr_is_unreachable(parent_result_loc))) 18055 { 18056 return parent_result_loc; 18057 } 18058 // If the above code generated any instructions in the current basic block, we need 18059 // to move them to the peer parent predecessor. 18060 ZigList<IrInstruction *> instrs_to_move = {}; 18061 while (ira->new_irb.current_basic_block->instruction_list.length != 0) { 18062 instrs_to_move.append(ira->new_irb.current_basic_block->instruction_list.pop()); 18063 } 18064 if (instrs_to_move.length != 0) { 18065 IrBasicBlock *predecessor = peer_parent->base.source_instruction->child->owner_bb; 18066 IrInstruction *branch_instruction = predecessor->instruction_list.pop(); 18067 ir_assert(branch_instruction->value->type->id == ZigTypeIdUnreachable, &phi_instruction->base); 18068 while (instrs_to_move.length != 0) { 18069 predecessor->instruction_list.append(instrs_to_move.pop()); 18070 } 18071 predecessor->instruction_list.append(branch_instruction); 18072 } 18073 } 18074 18075 IrSuspendPosition suspend_pos; 18076 ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); 18077 ir_push_resume(ira, suspend_pos); 18078 18079 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 18080 ResultLocPeer *opposite_peer = peer_parent->peers.at(peer_parent->peers.length - i - 1); 18081 if (opposite_peer->base.implicit_elem_type != nullptr && 18082 opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) 18083 { 18084 ir_push_resume(ira, opposite_peer->suspend_pos); 18085 } 18086 } 18087 18088 peer_parent->done_resuming = true; 18089 return ira_resume(ira); 18090 } 18091 18092 ZigList<IrBasicBlock*> new_incoming_blocks = {0}; 18093 ZigList<IrInstruction*> new_incoming_values = {0}; 18094 18095 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 18096 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; 18097 if (predecessor->ref_count == 0) 18098 continue; 18099 18100 18101 IrInstruction *old_value = phi_instruction->incoming_values[i]; 18102 assert(old_value); 18103 IrInstruction *new_value = old_value->child; 18104 if (!new_value || new_value->value->type->id == ZigTypeIdUnreachable || predecessor->other == nullptr) 18105 continue; 18106 18107 if (type_is_invalid(new_value->value->type)) 18108 return ira->codegen->invalid_instruction; 18109 18110 18111 assert(predecessor->other); 18112 new_incoming_blocks.append(predecessor->other); 18113 new_incoming_values.append(new_value); 18114 } 18115 18116 if (new_incoming_blocks.length == 0) { 18117 IrInstruction *result = ir_build_unreachable(&ira->new_irb, 18118 phi_instruction->base.scope, phi_instruction->base.source_node); 18119 result->value->type = ira->codegen->builtin_types.entry_unreachable; 18120 return ir_finish_anal(ira, result); 18121 } 18122 18123 if (new_incoming_blocks.length == 1) { 18124 return new_incoming_values.at(0); 18125 } 18126 18127 ZigType *resolved_type; 18128 if (peer_parent != nullptr) { 18129 bool peer_parent_has_type; 18130 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) 18131 return ira->codegen->invalid_instruction; 18132 if (peer_parent_has_type) { 18133 if (peer_parent->parent->id == ResultLocIdReturn) { 18134 resolved_type = ira->explicit_return_type; 18135 } else if (peer_parent->parent->id == ResultLocIdCast) { 18136 resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child); 18137 if (type_is_invalid(resolved_type)) 18138 return ira->codegen->invalid_instruction; 18139 } else { 18140 ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value->type; 18141 ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base); 18142 resolved_type = resolved_loc_ptr_type->data.pointer.child_type; 18143 } 18144 goto skip_resolve_peer_types; 18145 } 18146 } 18147 { 18148 resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, 18149 new_incoming_values.items, new_incoming_values.length); 18150 if (type_is_invalid(resolved_type)) 18151 return ira->codegen->invalid_instruction; 18152 } 18153 skip_resolve_peer_types: 18154 18155 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 18156 case OnePossibleValueInvalid: 18157 return ira->codegen->invalid_instruction; 18158 case OnePossibleValueYes: 18159 return ir_const(ira, &phi_instruction->base, resolved_type); 18160 case OnePossibleValueNo: 18161 break; 18162 } 18163 18164 switch (type_requires_comptime(ira->codegen, resolved_type)) { 18165 case ReqCompTimeInvalid: 18166 return ira->codegen->invalid_instruction; 18167 case ReqCompTimeYes: 18168 ir_add_error_node(ira, phi_instruction->base.source_node, 18169 buf_sprintf("values of type '%s' must be comptime known", buf_ptr(&resolved_type->name))); 18170 return ira->codegen->invalid_instruction; 18171 case ReqCompTimeNo: 18172 break; 18173 } 18174 18175 bool all_stack_ptrs = (resolved_type->id == ZigTypeIdPointer); 18176 18177 // cast all values to the resolved type. however we can't put cast instructions in front of the phi instruction. 18178 // so we go back and insert the casts as the last instruction in the corresponding predecessor blocks, and 18179 // then make sure the branch instruction is preserved. 18180 IrBasicBlock *cur_bb = ira->new_irb.current_basic_block; 18181 for (size_t i = 0; i < new_incoming_values.length; i += 1) { 18182 IrInstruction *new_value = new_incoming_values.at(i); 18183 IrBasicBlock *predecessor = new_incoming_blocks.at(i); 18184 ir_assert(predecessor->instruction_list.length != 0, &phi_instruction->base); 18185 IrInstruction *branch_instruction = predecessor->instruction_list.pop(); 18186 ir_set_cursor_at_end(&ira->new_irb, predecessor); 18187 IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); 18188 if (type_is_invalid(casted_value->value->type)) { 18189 return ira->codegen->invalid_instruction; 18190 } 18191 new_incoming_values.items[i] = casted_value; 18192 predecessor->instruction_list.append(branch_instruction); 18193 18194 if (all_stack_ptrs && (casted_value->value->special != ConstValSpecialRuntime || 18195 casted_value->value->data.rh_ptr != RuntimeHintPtrStack)) 18196 { 18197 all_stack_ptrs = false; 18198 } 18199 } 18200 ir_set_cursor_at_end(&ira->new_irb, cur_bb); 18201 18202 IrInstruction *result = ir_build_phi(&ira->new_irb, 18203 phi_instruction->base.scope, phi_instruction->base.source_node, 18204 new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, nullptr); 18205 result->value->type = resolved_type; 18206 18207 if (all_stack_ptrs) { 18208 assert(result->value->special == ConstValSpecialRuntime); 18209 result->value->data.rh_ptr = RuntimeHintPtrStack; 18210 } 18211 18212 return result; 18213 } 18214 18215 static IrInstruction *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *instruction) { 18216 ZigVar *var = instruction->var; 18217 IrInstruction *result = ir_get_var_ptr(ira, &instruction->base, var); 18218 if (instruction->crossed_fndef_scope != nullptr && !instr_is_comptime(result)) { 18219 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 18220 buf_sprintf("'%s' not accessible from inner function", var->name)); 18221 add_error_note(ira->codegen, msg, instruction->crossed_fndef_scope->base.source_node, 18222 buf_sprintf("crossed function definition here")); 18223 add_error_note(ira->codegen, msg, var->decl_node, 18224 buf_sprintf("declared here")); 18225 return ira->codegen->invalid_instruction; 18226 } 18227 return result; 18228 } 18229 18230 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align) { 18231 assert(ptr_type->id == ZigTypeIdPointer); 18232 return get_pointer_to_type_extra2(g, 18233 ptr_type->data.pointer.child_type, 18234 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 18235 ptr_type->data.pointer.ptr_len, 18236 new_align, 18237 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 18238 ptr_type->data.pointer.allow_zero, 18239 ptr_type->data.pointer.vector_index, 18240 ptr_type->data.pointer.inferred_struct_field, 18241 ptr_type->data.pointer.sentinel); 18242 } 18243 18244 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) { 18245 assert(is_slice(slice_type)); 18246 ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index]->type_entry, 18247 new_align); 18248 return get_slice_type(g, ptr_type); 18249 } 18250 18251 static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) { 18252 assert(ptr_type->id == ZigTypeIdPointer); 18253 return get_pointer_to_type_extra(g, 18254 ptr_type->data.pointer.child_type, 18255 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 18256 ptr_len, 18257 ptr_type->data.pointer.explicit_alignment, 18258 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 18259 ptr_type->data.pointer.allow_zero); 18260 } 18261 18262 static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { 18263 Error err; 18264 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->child; 18265 if (type_is_invalid(array_ptr->value->type)) 18266 return ira->codegen->invalid_instruction; 18267 18268 ZigValue *orig_array_ptr_val = array_ptr->value; 18269 18270 IrInstruction *elem_index = elem_ptr_instruction->elem_index->child; 18271 if (type_is_invalid(elem_index->value->type)) 18272 return ira->codegen->invalid_instruction; 18273 18274 ZigType *ptr_type = orig_array_ptr_val->type; 18275 assert(ptr_type->id == ZigTypeIdPointer); 18276 18277 ZigType *array_type = ptr_type->data.pointer.child_type; 18278 18279 // At first return_type will be the pointer type we want to return, except with an optimistic alignment. 18280 // We will adjust return_type's alignment before returning it. 18281 ZigType *return_type; 18282 18283 if (type_is_invalid(array_type)) { 18284 return ira->codegen->invalid_instruction; 18285 } else if (array_type->id == ZigTypeIdArray || 18286 (array_type->id == ZigTypeIdPointer && 18287 array_type->data.pointer.ptr_len == PtrLenSingle && 18288 array_type->data.pointer.child_type->id == ZigTypeIdArray)) 18289 { 18290 if (array_type->id == ZigTypeIdPointer) { 18291 array_type = array_type->data.pointer.child_type; 18292 ptr_type = ptr_type->data.pointer.child_type; 18293 if (orig_array_ptr_val->special != ConstValSpecialRuntime) { 18294 orig_array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val, 18295 elem_ptr_instruction->base.source_node); 18296 if (orig_array_ptr_val == nullptr) 18297 return ira->codegen->invalid_instruction; 18298 } 18299 } 18300 if (array_type->data.array.len == 0) { 18301 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 18302 buf_sprintf("index 0 outside array of size 0")); 18303 return ira->codegen->invalid_instruction; 18304 } 18305 ZigType *child_type = array_type->data.array.child_type; 18306 if (ptr_type->data.pointer.host_int_bytes == 0) { 18307 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 18308 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 18309 elem_ptr_instruction->ptr_len, 18310 ptr_type->data.pointer.explicit_alignment, 0, 0, false); 18311 } else { 18312 uint64_t elem_val_scalar; 18313 if (!ir_resolve_usize(ira, elem_index, &elem_val_scalar)) 18314 return ira->codegen->invalid_instruction; 18315 18316 size_t bit_width = type_size_bits(ira->codegen, child_type); 18317 size_t bit_offset = bit_width * elem_val_scalar; 18318 18319 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 18320 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 18321 elem_ptr_instruction->ptr_len, 18322 1, (uint32_t)bit_offset, ptr_type->data.pointer.host_int_bytes, false); 18323 } 18324 } else if (array_type->id == ZigTypeIdPointer) { 18325 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 18326 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 18327 buf_sprintf("index of single-item pointer")); 18328 return ira->codegen->invalid_instruction; 18329 } 18330 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len); 18331 } else if (is_slice(array_type)) { 18332 return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index]->type_entry, 18333 elem_ptr_instruction->ptr_len); 18334 } else if (array_type->id == ZigTypeIdArgTuple) { 18335 ZigValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); 18336 if (!ptr_val) 18337 return ira->codegen->invalid_instruction; 18338 ZigValue *args_val = const_ptr_pointee(ira, ira->codegen, ptr_val, elem_ptr_instruction->base.source_node); 18339 if (args_val == nullptr) 18340 return ira->codegen->invalid_instruction; 18341 size_t start = args_val->data.x_arg_tuple.start_index; 18342 size_t end = args_val->data.x_arg_tuple.end_index; 18343 uint64_t elem_index_val; 18344 if (!ir_resolve_usize(ira, elem_index, &elem_index_val)) 18345 return ira->codegen->invalid_instruction; 18346 size_t index = elem_index_val; 18347 size_t len = end - start; 18348 if (index >= len) { 18349 ir_add_error(ira, &elem_ptr_instruction->base, 18350 buf_sprintf("index %" ZIG_PRI_usize " outside argument list of size %" ZIG_PRI_usize "", index, len)); 18351 return ira->codegen->invalid_instruction; 18352 } 18353 size_t abs_index = start + index; 18354 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 18355 assert(fn_entry); 18356 ZigVar *var = get_fn_var_by_index(fn_entry, abs_index); 18357 bool is_const = true; 18358 bool is_volatile = false; 18359 if (var) { 18360 return ir_get_var_ptr(ira, &elem_ptr_instruction->base, var); 18361 } else { 18362 return ir_get_const_ptr(ira, &elem_ptr_instruction->base, ira->codegen->intern.for_void(), 18363 ira->codegen->builtin_types.entry_void, ConstPtrMutComptimeConst, is_const, is_volatile, 0); 18364 } 18365 } else if (array_type->id == ZigTypeIdVector) { 18366 // This depends on whether the element index is comptime, so it is computed later. 18367 return_type = nullptr; 18368 } else if (elem_ptr_instruction->init_array_type_source_node != nullptr && 18369 array_type->id == ZigTypeIdStruct && 18370 array_type->data.structure.resolve_status == ResolveStatusBeingInferred) 18371 { 18372 ZigType *usize = ira->codegen->builtin_types.entry_usize; 18373 IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 18374 if (casted_elem_index == ira->codegen->invalid_instruction) 18375 return ira->codegen->invalid_instruction; 18376 ir_assert(instr_is_comptime(casted_elem_index), &elem_ptr_instruction->base); 18377 Buf *field_name = buf_alloc(); 18378 bigint_append_buf(field_name, &casted_elem_index->value->data.x_bigint, 10); 18379 return ir_analyze_inferred_field_ptr(ira, field_name, &elem_ptr_instruction->base, 18380 array_ptr, array_type); 18381 } else { 18382 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 18383 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name))); 18384 return ira->codegen->invalid_instruction; 18385 } 18386 18387 ZigType *usize = ira->codegen->builtin_types.entry_usize; 18388 IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 18389 if (casted_elem_index == ira->codegen->invalid_instruction) 18390 return ira->codegen->invalid_instruction; 18391 18392 bool safety_check_on = elem_ptr_instruction->safety_check_on; 18393 if (instr_is_comptime(casted_elem_index)) { 18394 uint64_t index = bigint_as_u64(&casted_elem_index->value->data.x_bigint); 18395 if (array_type->id == ZigTypeIdArray) { 18396 uint64_t array_len = array_type->data.array.len; 18397 if (index == array_len && array_type->data.array.sentinel != nullptr) { 18398 ZigType *elem_type = array_type->data.array.child_type; 18399 IrInstruction *sentinel_elem = ir_const(ira, &elem_ptr_instruction->base, elem_type); 18400 copy_const_val(sentinel_elem->value, array_type->data.array.sentinel, false); 18401 return ir_get_ref(ira, &elem_ptr_instruction->base, sentinel_elem, true, false); 18402 } 18403 if (index >= array_len) { 18404 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 18405 buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, 18406 index, array_len)); 18407 return ira->codegen->invalid_instruction; 18408 } 18409 safety_check_on = false; 18410 } 18411 if (array_type->id == ZigTypeIdVector) { 18412 ZigType *elem_type = array_type->data.vector.elem_type; 18413 uint32_t host_vec_len = array_type->data.vector.len; 18414 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 18415 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 18416 elem_ptr_instruction->ptr_len, 18417 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index, 18418 nullptr, nullptr); 18419 } else if (return_type->data.pointer.explicit_alignment != 0) { 18420 // figure out the largest alignment possible 18421 18422 if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown))) 18423 return ira->codegen->invalid_instruction; 18424 18425 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); 18426 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); 18427 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type); 18428 18429 uint64_t chosen_align = abi_align; 18430 if (ptr_align >= abi_align) { 18431 while (ptr_align > abi_align) { 18432 if ((index * elem_size) % ptr_align == 0) { 18433 chosen_align = ptr_align; 18434 break; 18435 } 18436 ptr_align >>= 1; 18437 } 18438 } else if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 18439 chosen_align = ptr_align; 18440 } else { 18441 // can't get here because guaranteed elem_size >= abi_align 18442 zig_unreachable(); 18443 } 18444 return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align); 18445 } 18446 18447 if (orig_array_ptr_val->special != ConstValSpecialRuntime && 18448 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || 18449 array_type->id == ZigTypeIdArray)) 18450 { 18451 ZigValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val, 18452 elem_ptr_instruction->base.source_node); 18453 if (array_ptr_val == nullptr) 18454 return ira->codegen->invalid_instruction; 18455 18456 if (array_ptr_val->special == ConstValSpecialUndef && 18457 elem_ptr_instruction->init_array_type_source_node != nullptr) 18458 { 18459 if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) { 18460 array_ptr_val->data.x_array.special = ConstArraySpecialNone; 18461 array_ptr_val->data.x_array.data.s_none.elements = create_const_vals(array_type->data.array.len); 18462 array_ptr_val->special = ConstValSpecialStatic; 18463 for (size_t i = 0; i < array_type->data.array.len; i += 1) { 18464 ZigValue *elem_val = &array_ptr_val->data.x_array.data.s_none.elements[i]; 18465 elem_val->special = ConstValSpecialUndef; 18466 elem_val->type = array_type->data.array.child_type; 18467 elem_val->parent.id = ConstParentIdArray; 18468 elem_val->parent.data.p_array.array_val = array_ptr_val; 18469 elem_val->parent.data.p_array.elem_index = i; 18470 } 18471 } else if (is_slice(array_type)) { 18472 ir_assert(array_ptr->value->type->id == ZigTypeIdPointer, &elem_ptr_instruction->base); 18473 ZigType *actual_array_type = array_ptr->value->type->data.pointer.child_type; 18474 18475 if (type_is_invalid(actual_array_type)) 18476 return ira->codegen->invalid_instruction; 18477 if (actual_array_type->id != ZigTypeIdArray) { 18478 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, 18479 buf_sprintf("expected array type or [_], found slice")); 18480 return ira->codegen->invalid_instruction; 18481 } 18482 18483 ZigValue *array_init_val = create_const_vals(1); 18484 array_init_val->special = ConstValSpecialStatic; 18485 array_init_val->type = actual_array_type; 18486 array_init_val->data.x_array.special = ConstArraySpecialNone; 18487 array_init_val->data.x_array.data.s_none.elements = create_const_vals(actual_array_type->data.array.len); 18488 array_init_val->special = ConstValSpecialStatic; 18489 for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) { 18490 ZigValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i]; 18491 elem_val->special = ConstValSpecialUndef; 18492 elem_val->type = actual_array_type->data.array.child_type; 18493 elem_val->parent.id = ConstParentIdArray; 18494 elem_val->parent.data.p_array.array_val = array_init_val; 18495 elem_val->parent.data.p_array.elem_index = i; 18496 } 18497 18498 init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len, 18499 false); 18500 array_ptr_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutInfer; 18501 } else { 18502 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, 18503 buf_sprintf("expected array type or [_], found '%s'", 18504 buf_ptr(&array_type->name))); 18505 return ira->codegen->invalid_instruction; 18506 } 18507 } 18508 18509 if (array_ptr_val->special != ConstValSpecialRuntime && 18510 (array_type->id != ZigTypeIdPointer || 18511 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) 18512 { 18513 if (array_type->id == ZigTypeIdPointer) { 18514 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); 18515 ZigValue *out_val = result->value; 18516 out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 18517 size_t new_index; 18518 size_t mem_size; 18519 size_t old_size; 18520 switch (array_ptr_val->data.x_ptr.special) { 18521 case ConstPtrSpecialInvalid: 18522 case ConstPtrSpecialDiscard: 18523 zig_unreachable(); 18524 case ConstPtrSpecialRef: 18525 if (array_ptr_val->data.x_ptr.data.ref.pointee->type->id == ZigTypeIdArray) { 18526 ZigValue *array_val = array_ptr_val->data.x_ptr.data.ref.pointee; 18527 new_index = index; 18528 ZigType *array_type = array_val->type; 18529 mem_size = array_type->data.array.len; 18530 if (array_type->data.array.sentinel != nullptr) { 18531 mem_size += 1; 18532 } 18533 old_size = mem_size; 18534 18535 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 18536 out_val->data.x_ptr.data.base_array.array_val = array_val; 18537 out_val->data.x_ptr.data.base_array.elem_index = new_index; 18538 } else { 18539 mem_size = 1; 18540 old_size = 1; 18541 new_index = index; 18542 18543 out_val->data.x_ptr.special = ConstPtrSpecialRef; 18544 out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee; 18545 } 18546 break; 18547 case ConstPtrSpecialBaseArray: 18548 { 18549 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; 18550 new_index = offset + index; 18551 ZigType *array_type = array_ptr_val->data.x_ptr.data.base_array.array_val->type; 18552 mem_size = array_type->data.array.len; 18553 if (array_type->data.array.sentinel != nullptr) { 18554 mem_size += 1; 18555 } 18556 old_size = mem_size - offset; 18557 18558 assert(array_ptr_val->data.x_ptr.data.base_array.array_val); 18559 18560 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 18561 out_val->data.x_ptr.data.base_array.array_val = 18562 array_ptr_val->data.x_ptr.data.base_array.array_val; 18563 out_val->data.x_ptr.data.base_array.elem_index = new_index; 18564 18565 break; 18566 } 18567 case ConstPtrSpecialBaseStruct: 18568 zig_panic("TODO elem ptr on a const inner struct"); 18569 case ConstPtrSpecialBaseErrorUnionCode: 18570 zig_panic("TODO elem ptr on a const inner error union code"); 18571 case ConstPtrSpecialBaseErrorUnionPayload: 18572 zig_panic("TODO elem ptr on a const inner error union payload"); 18573 case ConstPtrSpecialBaseOptionalPayload: 18574 zig_panic("TODO elem ptr on a const inner optional payload"); 18575 case ConstPtrSpecialHardCodedAddr: 18576 zig_unreachable(); 18577 case ConstPtrSpecialFunction: 18578 zig_panic("TODO element ptr of a function casted to a ptr"); 18579 case ConstPtrSpecialNull: 18580 zig_panic("TODO elem ptr on a null pointer"); 18581 } 18582 if (new_index >= mem_size) { 18583 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 18584 buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size)); 18585 return ira->codegen->invalid_instruction; 18586 } 18587 return result; 18588 } else if (is_slice(array_type)) { 18589 ZigValue *ptr_field = array_ptr_val->data.x_struct.fields[slice_ptr_index]; 18590 ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base); 18591 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 18592 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, 18593 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false, 18594 elem_ptr_instruction->ptr_len, nullptr); 18595 result->value->type = return_type; 18596 return result; 18597 } 18598 ZigValue *len_field = array_ptr_val->data.x_struct.fields[slice_len_index]; 18599 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); 18600 ZigValue *out_val = result->value; 18601 ZigType *slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; 18602 uint64_t slice_len = bigint_as_u64(&len_field->data.x_bigint); 18603 uint64_t full_slice_len = slice_len + 18604 ((slice_ptr_type->data.pointer.sentinel != nullptr) ? 1 : 0); 18605 if (index >= full_slice_len) { 18606 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 18607 buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64, 18608 index, slice_len)); 18609 return ira->codegen->invalid_instruction; 18610 } 18611 out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut; 18612 switch (ptr_field->data.x_ptr.special) { 18613 case ConstPtrSpecialInvalid: 18614 case ConstPtrSpecialDiscard: 18615 zig_unreachable(); 18616 case ConstPtrSpecialRef: 18617 out_val->data.x_ptr.special = ConstPtrSpecialRef; 18618 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee; 18619 break; 18620 case ConstPtrSpecialBaseArray: 18621 { 18622 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index; 18623 uint64_t new_index = offset + index; 18624 if (ptr_field->data.x_ptr.data.base_array.array_val->data.x_array.special != 18625 ConstArraySpecialBuf) 18626 { 18627 ir_assert(new_index < 18628 ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len, 18629 &elem_ptr_instruction->base); 18630 } 18631 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 18632 out_val->data.x_ptr.data.base_array.array_val = 18633 ptr_field->data.x_ptr.data.base_array.array_val; 18634 out_val->data.x_ptr.data.base_array.elem_index = new_index; 18635 break; 18636 } 18637 case ConstPtrSpecialBaseStruct: 18638 zig_panic("TODO elem ptr on a slice backed by const inner struct"); 18639 case ConstPtrSpecialBaseErrorUnionCode: 18640 zig_panic("TODO elem ptr on a slice backed by const inner error union code"); 18641 case ConstPtrSpecialBaseErrorUnionPayload: 18642 zig_panic("TODO elem ptr on a slice backed by const inner error union payload"); 18643 case ConstPtrSpecialBaseOptionalPayload: 18644 zig_panic("TODO elem ptr on a slice backed by const optional payload"); 18645 case ConstPtrSpecialHardCodedAddr: 18646 zig_unreachable(); 18647 case ConstPtrSpecialFunction: 18648 zig_panic("TODO elem ptr on a slice that was ptrcast from a function"); 18649 case ConstPtrSpecialNull: 18650 zig_panic("TODO elem ptr on a slice has a null pointer"); 18651 } 18652 return result; 18653 } else if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) { 18654 IrInstruction *result; 18655 if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 18656 result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, 18657 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, 18658 false, elem_ptr_instruction->ptr_len, nullptr); 18659 result->value->type = return_type; 18660 result->value->special = ConstValSpecialStatic; 18661 } else { 18662 result = ir_const(ira, &elem_ptr_instruction->base, return_type); 18663 } 18664 ZigValue *out_val = result->value; 18665 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 18666 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; 18667 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val; 18668 out_val->data.x_ptr.data.base_array.elem_index = index; 18669 return result; 18670 } else { 18671 zig_unreachable(); 18672 } 18673 } 18674 } 18675 } else if (array_type->id == ZigTypeIdVector) { 18676 // runtime known element index 18677 ZigType *elem_type = array_type->data.vector.elem_type; 18678 uint32_t host_vec_len = array_type->data.vector.len; 18679 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 18680 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 18681 elem_ptr_instruction->ptr_len, 18682 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME, 18683 nullptr, nullptr); 18684 } else { 18685 // runtime known element index 18686 switch (type_requires_comptime(ira->codegen, return_type)) { 18687 case ReqCompTimeYes: 18688 ir_add_error(ira, elem_index, 18689 buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known", 18690 buf_ptr(&return_type->data.pointer.child_type->name))); 18691 return ira->codegen->invalid_instruction; 18692 case ReqCompTimeInvalid: 18693 return ira->codegen->invalid_instruction; 18694 case ReqCompTimeNo: 18695 break; 18696 } 18697 18698 if (return_type->data.pointer.explicit_alignment != 0) { 18699 if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown))) 18700 return ira->codegen->invalid_instruction; 18701 18702 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); 18703 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); 18704 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type); 18705 if (ptr_align < abi_align) { 18706 if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 18707 return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align); 18708 } else { 18709 // can't get here because guaranteed elem_size >= abi_align 18710 zig_unreachable(); 18711 } 18712 } else { 18713 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align); 18714 } 18715 } 18716 } 18717 18718 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, 18719 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on, 18720 elem_ptr_instruction->ptr_len, nullptr); 18721 result->value->type = return_type; 18722 return result; 18723 } 18724 18725 static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, 18726 ZigType *bare_struct_type, Buf *field_name, IrInstruction *source_instr, 18727 IrInstruction *container_ptr, ZigType *container_type) 18728 { 18729 if (!is_slice(bare_struct_type)) { 18730 ScopeDecls *container_scope = get_container_scope(bare_struct_type); 18731 assert(container_scope != nullptr); 18732 auto tld = find_container_decl(ira->codegen, container_scope, field_name); 18733 if (tld) { 18734 if (tld->id == TldIdFn) { 18735 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); 18736 if (tld->resolution == TldResolutionInvalid) 18737 return ira->codegen->invalid_instruction; 18738 TldFn *tld_fn = (TldFn *)tld; 18739 ZigFn *fn_entry = tld_fn->fn_entry; 18740 if (type_is_invalid(fn_entry->type_entry)) 18741 return ira->codegen->invalid_instruction; 18742 18743 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope, 18744 source_instr->source_node, fn_entry, container_ptr); 18745 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 18746 } else if (tld->id == TldIdVar) { 18747 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); 18748 if (tld->resolution == TldResolutionInvalid) 18749 return ira->codegen->invalid_instruction; 18750 TldVar *tld_var = (TldVar *)tld; 18751 ZigVar *var = tld_var->var; 18752 if (type_is_invalid(var->var_type)) 18753 return ira->codegen->invalid_instruction; 18754 18755 if (var->const_value->type->id == ZigTypeIdFn) { 18756 ir_assert(var->const_value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 18757 ZigFn *fn = var->const_value->data.x_ptr.data.fn.fn_entry; 18758 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope, 18759 source_instr->source_node, fn, container_ptr); 18760 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 18761 } 18762 } 18763 } 18764 } 18765 const char *prefix_name; 18766 if (is_slice(bare_struct_type)) { 18767 prefix_name = ""; 18768 } else if (bare_struct_type->id == ZigTypeIdStruct) { 18769 prefix_name = "struct "; 18770 } else if (bare_struct_type->id == ZigTypeIdEnum) { 18771 prefix_name = "enum "; 18772 } else if (bare_struct_type->id == ZigTypeIdUnion) { 18773 prefix_name = "union "; 18774 } else { 18775 prefix_name = ""; 18776 } 18777 ir_add_error_node(ira, source_instr->source_node, 18778 buf_sprintf("no member named '%s' in %s'%s'", buf_ptr(field_name), prefix_name, buf_ptr(&bare_struct_type->name))); 18779 return ira->codegen->invalid_instruction; 18780 } 18781 18782 static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, 18783 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing) 18784 { 18785 Error err; 18786 ZigType *field_type = resolve_struct_field_type(ira->codegen, field); 18787 if (field_type == nullptr) 18788 return ira->codegen->invalid_instruction; 18789 switch (type_has_one_possible_value(ira->codegen, field_type)) { 18790 case OnePossibleValueInvalid: 18791 return ira->codegen->invalid_instruction; 18792 case OnePossibleValueYes: { 18793 IrInstruction *elem = ir_const(ira, source_instr, field_type); 18794 return ir_get_ref(ira, source_instr, elem, false, false); 18795 } 18796 case OnePossibleValueNo: 18797 break; 18798 } 18799 bool is_const = struct_ptr->value->type->data.pointer.is_const; 18800 bool is_volatile = struct_ptr->value->type->data.pointer.is_volatile; 18801 ZigType *ptr_type; 18802 if (struct_type->data.structure.is_inferred) { 18803 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 18804 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 18805 } else { 18806 ResolveStatus needed_resolve_status = 18807 (struct_type->data.structure.layout == ContainerLayoutAuto) ? 18808 ResolveStatusZeroBitsKnown : ResolveStatusSizeKnown; 18809 if ((err = type_resolve(ira->codegen, struct_type, needed_resolve_status))) 18810 return ira->codegen->invalid_instruction; 18811 assert(struct_ptr->value->type->id == ZigTypeIdPointer); 18812 uint32_t ptr_bit_offset = struct_ptr->value->type->data.pointer.bit_offset_in_host; 18813 uint32_t ptr_host_int_bytes = struct_ptr->value->type->data.pointer.host_int_bytes; 18814 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? 18815 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes; 18816 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 18817 is_const, is_volatile, PtrLenSingle, field->align, 18818 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), 18819 (uint32_t)host_int_bytes_for_result_type, false); 18820 } 18821 if (instr_is_comptime(struct_ptr)) { 18822 ZigValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); 18823 if (!ptr_val) 18824 return ira->codegen->invalid_instruction; 18825 18826 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 18827 ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 18828 if (struct_val == nullptr) 18829 return ira->codegen->invalid_instruction; 18830 if (type_is_invalid(struct_val->type)) 18831 return ira->codegen->invalid_instruction; 18832 if (initializing && struct_val->special == ConstValSpecialUndef) { 18833 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(struct_type->data.structure.src_field_count); 18834 struct_val->special = ConstValSpecialStatic; 18835 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { 18836 ZigValue *field_val = struct_val->data.x_struct.fields[i]; 18837 field_val->special = ConstValSpecialUndef; 18838 field_val->type = resolve_struct_field_type(ira->codegen, 18839 struct_type->data.structure.fields[i]); 18840 field_val->parent.id = ConstParentIdStruct; 18841 field_val->parent.data.p_struct.struct_val = struct_val; 18842 field_val->parent.data.p_struct.field_index = i; 18843 } 18844 } 18845 IrInstruction *result; 18846 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 18847 result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, 18848 source_instr->source_node, struct_ptr, field); 18849 result->value->type = ptr_type; 18850 result->value->special = ConstValSpecialStatic; 18851 } else { 18852 result = ir_const(ira, source_instr, ptr_type); 18853 } 18854 ZigValue *const_val = result->value; 18855 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; 18856 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 18857 const_val->data.x_ptr.data.base_struct.struct_val = struct_val; 18858 const_val->data.x_ptr.data.base_struct.field_index = field->src_index; 18859 return result; 18860 } 18861 } 18862 IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, 18863 struct_ptr, field); 18864 result->value->type = ptr_type; 18865 return result; 18866 } 18867 18868 static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, 18869 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type) 18870 { 18871 // The type of the field is not available until a store using this pointer happens. 18872 // So, here we create a special pointer type which has the inferred struct type and 18873 // field name encoded in the type. Later, when there is a store via this pointer, 18874 // the field type will then be available, and the field will be added to the inferred 18875 // struct. 18876 18877 ZigType *container_ptr_type = container_ptr->value->type; 18878 ir_assert(container_ptr_type->id == ZigTypeIdPointer, source_instr); 18879 18880 InferredStructField *inferred_struct_field = allocate<InferredStructField>(1, "InferredStructField"); 18881 inferred_struct_field->inferred_struct_type = container_type; 18882 inferred_struct_field->field_name = field_name; 18883 18884 ZigType *elem_type = ira->codegen->builtin_types.entry_var; 18885 ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 18886 container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile, 18887 PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field, nullptr); 18888 18889 if (instr_is_comptime(container_ptr)) { 18890 IrInstruction *result = ir_const(ira, source_instr, field_ptr_type); 18891 copy_const_val(result->value, container_ptr->value, false); 18892 result->value->type = field_ptr_type; 18893 return result; 18894 } 18895 18896 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, 18897 source_instr->source_node, field_ptr_type, container_ptr, CastOpNoop); 18898 result->value->type = field_ptr_type; 18899 return result; 18900 } 18901 18902 static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 18903 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing) 18904 { 18905 Error err; 18906 18907 ZigType *bare_type = container_ref_type(container_type); 18908 18909 if (initializing && bare_type->id == ZigTypeIdStruct && 18910 bare_type->data.structure.resolve_status == ResolveStatusBeingInferred) 18911 { 18912 return ir_analyze_inferred_field_ptr(ira, field_name, source_instr, container_ptr, bare_type); 18913 } 18914 18915 if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown))) 18916 return ira->codegen->invalid_instruction; 18917 18918 assert(container_ptr->value->type->id == ZigTypeIdPointer); 18919 if (bare_type->id == ZigTypeIdStruct) { 18920 TypeStructField *field = find_struct_type_field(bare_type, field_name); 18921 if (field != nullptr) { 18922 return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); 18923 } else { 18924 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 18925 source_instr, container_ptr, container_type); 18926 } 18927 } 18928 18929 if (bare_type->id == ZigTypeIdEnum) { 18930 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 18931 source_instr, container_ptr, container_type); 18932 } 18933 18934 if (bare_type->id == ZigTypeIdUnion) { 18935 bool is_const = container_ptr->value->type->data.pointer.is_const; 18936 bool is_volatile = container_ptr->value->type->data.pointer.is_volatile; 18937 18938 TypeUnionField *field = find_union_type_field(bare_type, field_name); 18939 if (field == nullptr) { 18940 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 18941 source_instr, container_ptr, container_type); 18942 } 18943 18944 ZigType *field_type = resolve_union_field_type(ira->codegen, field); 18945 if (field_type == nullptr) 18946 return ira->codegen->invalid_instruction; 18947 18948 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 18949 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 18950 if (instr_is_comptime(container_ptr)) { 18951 ZigValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 18952 if (!ptr_val) 18953 return ira->codegen->invalid_instruction; 18954 18955 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && 18956 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 18957 ZigValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 18958 if (union_val == nullptr) 18959 return ira->codegen->invalid_instruction; 18960 if (type_is_invalid(union_val->type)) 18961 return ira->codegen->invalid_instruction; 18962 18963 if (initializing) { 18964 ZigValue *payload_val = create_const_vals(1); 18965 payload_val->special = ConstValSpecialUndef; 18966 payload_val->type = field_type; 18967 payload_val->parent.id = ConstParentIdUnion; 18968 payload_val->parent.data.p_union.union_val = union_val; 18969 18970 union_val->special = ConstValSpecialStatic; 18971 bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); 18972 union_val->data.x_union.payload = payload_val; 18973 } else if (bare_type->data.unionation.layout != ContainerLayoutExtern) { 18974 TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); 18975 if (actual_field == nullptr) 18976 zig_unreachable(); 18977 18978 if (field != actual_field) { 18979 ir_add_error_node(ira, source_instr->source_node, 18980 buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), 18981 buf_ptr(actual_field->name))); 18982 return ira->codegen->invalid_instruction; 18983 } 18984 } 18985 18986 ZigValue *payload_val = union_val->data.x_union.payload; 18987 18988 IrInstruction *result; 18989 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 18990 result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, 18991 source_instr->source_node, container_ptr, field, true, initializing); 18992 result->value->type = ptr_type; 18993 result->value->special = ConstValSpecialStatic; 18994 } else { 18995 result = ir_const(ira, source_instr, ptr_type); 18996 } 18997 ZigValue *const_val = result->value; 18998 const_val->data.x_ptr.special = ConstPtrSpecialRef; 18999 const_val->data.x_ptr.mut = container_ptr->value->data.x_ptr.mut; 19000 const_val->data.x_ptr.data.ref.pointee = payload_val; 19001 return result; 19002 } 19003 } 19004 19005 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, 19006 source_instr->source_node, container_ptr, field, true, initializing); 19007 result->value->type = ptr_type; 19008 return result; 19009 } 19010 19011 zig_unreachable(); 19012 } 19013 19014 static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { 19015 bool is_libc = target_is_libc_lib_name(ira->codegen->zig_target, buf_ptr(lib_name)); 19016 if (is_libc && ira->codegen->libc_link_lib == nullptr && !ira->codegen->reported_bad_link_libc_error) { 19017 ir_add_error_node(ira, source_node, 19018 buf_sprintf("dependency on library c must be explicitly specified in the build command")); 19019 ira->codegen->reported_bad_link_libc_error = true; 19020 } 19021 19022 LinkLib *link_lib = add_link_lib(ira->codegen, lib_name); 19023 for (size_t i = 0; i < link_lib->symbols.length; i += 1) { 19024 Buf *existing_symbol_name = link_lib->symbols.at(i); 19025 if (buf_eql_buf(existing_symbol_name, symbol_name)) { 19026 return; 19027 } 19028 } 19029 19030 if (!is_libc && !target_is_wasm(ira->codegen->zig_target) && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) { 19031 ErrorMsg *msg = ir_add_error_node(ira, source_node, 19032 buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code", 19033 buf_ptr(lib_name))); 19034 add_error_note(ira->codegen, msg, source_node, 19035 buf_sprintf("fixed by `--library %s` or `-fPIC`", buf_ptr(lib_name))); 19036 ira->codegen->reported_bad_link_libc_error = true; 19037 } 19038 19039 for (size_t i = 0; i < ira->codegen->forbidden_libs.length; i += 1) { 19040 Buf *forbidden_lib_name = ira->codegen->forbidden_libs.at(i); 19041 if (buf_eql_buf(lib_name, forbidden_lib_name)) { 19042 ir_add_error_node(ira, source_node, 19043 buf_sprintf("linking against forbidden library '%s'", buf_ptr(symbol_name))); 19044 } 19045 } 19046 link_lib->symbols.append(symbol_name); 19047 } 19048 19049 static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { 19050 ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); 19051 return ira->codegen->invalid_instruction; 19052 } 19053 19054 static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { 19055 resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node, true); 19056 if (tld->resolution == TldResolutionInvalid) { 19057 return ira->codegen->invalid_instruction; 19058 } 19059 19060 switch (tld->id) { 19061 case TldIdContainer: 19062 case TldIdCompTime: 19063 case TldIdUsingNamespace: 19064 zig_unreachable(); 19065 case TldIdVar: { 19066 TldVar *tld_var = (TldVar *)tld; 19067 ZigVar *var = tld_var->var; 19068 if (var == nullptr) { 19069 return ir_error_dependency_loop(ira, source_instruction); 19070 } 19071 if (tld_var->extern_lib_name != nullptr) { 19072 add_link_lib_symbol(ira, tld_var->extern_lib_name, buf_create_from_str(var->name), 19073 source_instruction->source_node); 19074 } 19075 19076 return ir_get_var_ptr(ira, source_instruction, var); 19077 } 19078 case TldIdFn: { 19079 TldFn *tld_fn = (TldFn *)tld; 19080 ZigFn *fn_entry = tld_fn->fn_entry; 19081 assert(fn_entry->type_entry); 19082 19083 if (type_is_invalid(fn_entry->type_entry)) 19084 return ira->codegen->invalid_instruction; 19085 19086 if (tld_fn->extern_lib_name != nullptr) { 19087 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); 19088 } 19089 19090 IrInstruction *fn_inst = ir_create_const_fn(&ira->new_irb, source_instruction->scope, 19091 source_instruction->source_node, fn_entry); 19092 return ir_get_ref(ira, source_instruction, fn_inst, true, false); 19093 } 19094 } 19095 zig_unreachable(); 19096 } 19097 19098 static ErrorTableEntry *find_err_table_entry(ZigType *err_set_type, Buf *field_name) { 19099 assert(err_set_type->id == ZigTypeIdErrorSet); 19100 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 19101 ErrorTableEntry *err_table_entry = err_set_type->data.error_set.errors[i]; 19102 if (buf_eql_buf(&err_table_entry->name, field_name)) { 19103 return err_table_entry; 19104 } 19105 } 19106 return nullptr; 19107 } 19108 19109 static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) { 19110 Error err; 19111 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->child; 19112 if (type_is_invalid(container_ptr->value->type)) 19113 return ira->codegen->invalid_instruction; 19114 19115 ZigType *container_type = container_ptr->value->type->data.pointer.child_type; 19116 19117 Buf *field_name = field_ptr_instruction->field_name_buffer; 19118 if (!field_name) { 19119 IrInstruction *field_name_expr = field_ptr_instruction->field_name_expr->child; 19120 field_name = ir_resolve_str(ira, field_name_expr); 19121 if (!field_name) 19122 return ira->codegen->invalid_instruction; 19123 } 19124 19125 19126 AstNode *source_node = field_ptr_instruction->base.source_node; 19127 19128 if (type_is_invalid(container_type)) { 19129 return ira->codegen->invalid_instruction; 19130 } else if (is_slice(container_type) || is_container_ref(container_type)) { 19131 assert(container_ptr->value->type->id == ZigTypeIdPointer); 19132 if (container_type->id == ZigTypeIdPointer) { 19133 ZigType *bare_type = container_ref_type(container_type); 19134 IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr, nullptr); 19135 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type, field_ptr_instruction->initializing); 19136 return result; 19137 } else { 19138 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type, field_ptr_instruction->initializing); 19139 return result; 19140 } 19141 } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) { 19142 if (buf_eql_str(field_name, "len")) { 19143 ZigValue *len_val = create_const_vals(1); 19144 if (container_type->id == ZigTypeIdPointer) { 19145 init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len); 19146 } else { 19147 init_const_usize(ira->codegen, len_val, container_type->data.array.len); 19148 } 19149 19150 ZigType *usize = ira->codegen->builtin_types.entry_usize; 19151 bool ptr_is_const = true; 19152 bool ptr_is_volatile = false; 19153 return ir_get_const_ptr(ira, &field_ptr_instruction->base, len_val, 19154 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19155 } else { 19156 ir_add_error_node(ira, source_node, 19157 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), 19158 buf_ptr(&container_type->name))); 19159 return ira->codegen->invalid_instruction; 19160 } 19161 } else if (container_type->id == ZigTypeIdArgTuple) { 19162 ZigValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 19163 if (!container_ptr_val) 19164 return ira->codegen->invalid_instruction; 19165 19166 assert(container_ptr->value->type->id == ZigTypeIdPointer); 19167 ZigValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node); 19168 if (child_val == nullptr) 19169 return ira->codegen->invalid_instruction; 19170 19171 if (buf_eql_str(field_name, "len")) { 19172 ZigValue *len_val = create_const_vals(1); 19173 size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index; 19174 init_const_usize(ira->codegen, len_val, len); 19175 19176 ZigType *usize = ira->codegen->builtin_types.entry_usize; 19177 bool ptr_is_const = true; 19178 bool ptr_is_volatile = false; 19179 return ir_get_const_ptr(ira, &field_ptr_instruction->base, len_val, 19180 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19181 } else { 19182 ir_add_error_node(ira, source_node, 19183 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), 19184 buf_ptr(&container_type->name))); 19185 return ira->codegen->invalid_instruction; 19186 } 19187 } else if (container_type->id == ZigTypeIdMetaType) { 19188 ZigValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 19189 if (!container_ptr_val) 19190 return ira->codegen->invalid_instruction; 19191 19192 assert(container_ptr->value->type->id == ZigTypeIdPointer); 19193 ZigValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node); 19194 if (child_val == nullptr) 19195 return ira->codegen->invalid_instruction; 19196 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 19197 field_ptr_instruction->base.source_node, child_val, UndefBad))) 19198 { 19199 return ira->codegen->invalid_instruction; 19200 } 19201 ZigType *child_type = child_val->data.x_type; 19202 19203 if (type_is_invalid(child_type)) { 19204 return ira->codegen->invalid_instruction; 19205 } else if (is_container(child_type)) { 19206 if (child_type->id == ZigTypeIdEnum) { 19207 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) 19208 return ira->codegen->invalid_instruction; 19209 19210 TypeEnumField *field = find_enum_type_field(child_type, field_name); 19211 if (field) { 19212 bool ptr_is_const = true; 19213 bool ptr_is_volatile = false; 19214 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19215 create_const_enum(child_type, &field->value), child_type, 19216 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19217 } 19218 } 19219 ScopeDecls *container_scope = get_container_scope(child_type); 19220 Tld *tld = find_container_decl(ira->codegen, container_scope, field_name); 19221 if (tld) { 19222 if (tld->visib_mod == VisibModPrivate && 19223 tld->import != get_scope_import(field_ptr_instruction->base.scope)) 19224 { 19225 ErrorMsg *msg = ir_add_error(ira, &field_ptr_instruction->base, 19226 buf_sprintf("'%s' is private", buf_ptr(field_name))); 19227 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); 19228 return ira->codegen->invalid_instruction; 19229 } 19230 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld); 19231 } 19232 if (child_type->id == ZigTypeIdUnion && 19233 (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr || 19234 child_type->data.unionation.decl_node->data.container_decl.auto_enum)) 19235 { 19236 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) 19237 return ira->codegen->invalid_instruction; 19238 TypeUnionField *field = find_union_type_field(child_type, field_name); 19239 if (field) { 19240 ZigType *enum_type = child_type->data.unionation.tag_type; 19241 bool ptr_is_const = true; 19242 bool ptr_is_volatile = false; 19243 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19244 create_const_enum(enum_type, &field->enum_field->value), enum_type, 19245 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19246 } 19247 } 19248 const char *container_name = (child_type == ira->codegen->root_import) ? 19249 "root source file" : buf_ptr(buf_sprintf("container '%s'", buf_ptr(&child_type->name))); 19250 ir_add_error(ira, &field_ptr_instruction->base, 19251 buf_sprintf("%s has no member called '%s'", 19252 container_name, buf_ptr(field_name))); 19253 return ira->codegen->invalid_instruction; 19254 } else if (child_type->id == ZigTypeIdErrorSet) { 19255 ErrorTableEntry *err_entry; 19256 ZigType *err_set_type; 19257 if (type_is_global_error_set(child_type)) { 19258 auto existing_entry = ira->codegen->error_table.maybe_get(field_name); 19259 if (existing_entry) { 19260 err_entry = existing_entry->value; 19261 } else { 19262 err_entry = allocate<ErrorTableEntry>(1); 19263 err_entry->decl_node = field_ptr_instruction->base.source_node; 19264 buf_init_from_buf(&err_entry->name, field_name); 19265 size_t error_value_count = ira->codegen->errors_by_index.length; 19266 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); 19267 err_entry->value = error_value_count; 19268 ira->codegen->errors_by_index.append(err_entry); 19269 ira->codegen->error_table.put(field_name, err_entry); 19270 } 19271 if (err_entry->set_with_only_this_in_it == nullptr) { 19272 err_entry->set_with_only_this_in_it = make_err_set_with_one_item(ira->codegen, 19273 field_ptr_instruction->base.scope, field_ptr_instruction->base.source_node, 19274 err_entry); 19275 } 19276 err_set_type = err_entry->set_with_only_this_in_it; 19277 } else { 19278 if (!resolve_inferred_error_set(ira->codegen, child_type, field_ptr_instruction->base.source_node)) { 19279 return ira->codegen->invalid_instruction; 19280 } 19281 err_entry = find_err_table_entry(child_type, field_name); 19282 if (err_entry == nullptr) { 19283 ir_add_error(ira, &field_ptr_instruction->base, 19284 buf_sprintf("no error named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&child_type->name))); 19285 return ira->codegen->invalid_instruction; 19286 } 19287 err_set_type = child_type; 19288 } 19289 ZigValue *const_val = create_const_vals(1); 19290 const_val->special = ConstValSpecialStatic; 19291 const_val->type = err_set_type; 19292 const_val->data.x_err_set = err_entry; 19293 19294 bool ptr_is_const = true; 19295 bool ptr_is_volatile = false; 19296 return ir_get_const_ptr(ira, &field_ptr_instruction->base, const_val, 19297 err_set_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19298 } else if (child_type->id == ZigTypeIdInt) { 19299 if (buf_eql_str(field_name, "bit_count")) { 19300 bool ptr_is_const = true; 19301 bool ptr_is_volatile = false; 19302 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19303 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 19304 child_type->data.integral.bit_count, false), 19305 ira->codegen->builtin_types.entry_num_lit_int, 19306 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19307 } else if (buf_eql_str(field_name, "is_signed")) { 19308 bool ptr_is_const = true; 19309 bool ptr_is_volatile = false; 19310 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19311 create_const_bool(ira->codegen, child_type->data.integral.is_signed), 19312 ira->codegen->builtin_types.entry_bool, 19313 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19314 } else { 19315 ir_add_error(ira, &field_ptr_instruction->base, 19316 buf_sprintf("type '%s' has no member called '%s'", 19317 buf_ptr(&child_type->name), buf_ptr(field_name))); 19318 return ira->codegen->invalid_instruction; 19319 } 19320 } else if (child_type->id == ZigTypeIdFloat) { 19321 if (buf_eql_str(field_name, "bit_count")) { 19322 bool ptr_is_const = true; 19323 bool ptr_is_volatile = false; 19324 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19325 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 19326 child_type->data.floating.bit_count, false), 19327 ira->codegen->builtin_types.entry_num_lit_int, 19328 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19329 } else { 19330 ir_add_error(ira, &field_ptr_instruction->base, 19331 buf_sprintf("type '%s' has no member called '%s'", 19332 buf_ptr(&child_type->name), buf_ptr(field_name))); 19333 return ira->codegen->invalid_instruction; 19334 } 19335 } else if (child_type->id == ZigTypeIdPointer) { 19336 if (buf_eql_str(field_name, "Child")) { 19337 bool ptr_is_const = true; 19338 bool ptr_is_volatile = false; 19339 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19340 create_const_type(ira->codegen, child_type->data.pointer.child_type), 19341 ira->codegen->builtin_types.entry_type, 19342 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19343 } else if (buf_eql_str(field_name, "alignment")) { 19344 bool ptr_is_const = true; 19345 bool ptr_is_volatile = false; 19346 if ((err = type_resolve(ira->codegen, child_type->data.pointer.child_type, 19347 ResolveStatusAlignmentKnown))) 19348 { 19349 return ira->codegen->invalid_instruction; 19350 } 19351 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19352 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 19353 get_ptr_align(ira->codegen, child_type), false), 19354 ira->codegen->builtin_types.entry_num_lit_int, 19355 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19356 } else { 19357 ir_add_error(ira, &field_ptr_instruction->base, 19358 buf_sprintf("type '%s' has no member called '%s'", 19359 buf_ptr(&child_type->name), buf_ptr(field_name))); 19360 return ira->codegen->invalid_instruction; 19361 } 19362 } else if (child_type->id == ZigTypeIdArray) { 19363 if (buf_eql_str(field_name, "Child")) { 19364 bool ptr_is_const = true; 19365 bool ptr_is_volatile = false; 19366 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19367 create_const_type(ira->codegen, child_type->data.array.child_type), 19368 ira->codegen->builtin_types.entry_type, 19369 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19370 } else if (buf_eql_str(field_name, "len")) { 19371 bool ptr_is_const = true; 19372 bool ptr_is_volatile = false; 19373 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19374 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 19375 child_type->data.array.len, false), 19376 ira->codegen->builtin_types.entry_num_lit_int, 19377 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19378 } else { 19379 ir_add_error(ira, &field_ptr_instruction->base, 19380 buf_sprintf("type '%s' has no member called '%s'", 19381 buf_ptr(&child_type->name), buf_ptr(field_name))); 19382 return ira->codegen->invalid_instruction; 19383 } 19384 } else if (child_type->id == ZigTypeIdErrorUnion) { 19385 if (buf_eql_str(field_name, "Payload")) { 19386 bool ptr_is_const = true; 19387 bool ptr_is_volatile = false; 19388 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19389 create_const_type(ira->codegen, child_type->data.error_union.payload_type), 19390 ira->codegen->builtin_types.entry_type, 19391 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19392 } else if (buf_eql_str(field_name, "ErrorSet")) { 19393 bool ptr_is_const = true; 19394 bool ptr_is_volatile = false; 19395 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19396 create_const_type(ira->codegen, child_type->data.error_union.err_set_type), 19397 ira->codegen->builtin_types.entry_type, 19398 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19399 } else { 19400 ir_add_error(ira, &field_ptr_instruction->base, 19401 buf_sprintf("type '%s' has no member called '%s'", 19402 buf_ptr(&child_type->name), buf_ptr(field_name))); 19403 return ira->codegen->invalid_instruction; 19404 } 19405 } else if (child_type->id == ZigTypeIdOptional) { 19406 if (buf_eql_str(field_name, "Child")) { 19407 bool ptr_is_const = true; 19408 bool ptr_is_volatile = false; 19409 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19410 create_const_type(ira->codegen, child_type->data.maybe.child_type), 19411 ira->codegen->builtin_types.entry_type, 19412 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19413 } else { 19414 ir_add_error(ira, &field_ptr_instruction->base, 19415 buf_sprintf("type '%s' has no member called '%s'", 19416 buf_ptr(&child_type->name), buf_ptr(field_name))); 19417 return ira->codegen->invalid_instruction; 19418 } 19419 } else if (child_type->id == ZigTypeIdFn) { 19420 if (buf_eql_str(field_name, "ReturnType")) { 19421 if (child_type->data.fn.fn_type_id.return_type == nullptr) { 19422 // Return type can only ever be null, if the function is generic 19423 assert(child_type->data.fn.is_generic); 19424 19425 ir_add_error(ira, &field_ptr_instruction->base, 19426 buf_sprintf("ReturnType has not been resolved because '%s' is generic", buf_ptr(&child_type->name))); 19427 return ira->codegen->invalid_instruction; 19428 } 19429 19430 bool ptr_is_const = true; 19431 bool ptr_is_volatile = false; 19432 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19433 create_const_type(ira->codegen, child_type->data.fn.fn_type_id.return_type), 19434 ira->codegen->builtin_types.entry_type, 19435 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19436 } else if (buf_eql_str(field_name, "is_var_args")) { 19437 bool ptr_is_const = true; 19438 bool ptr_is_volatile = false; 19439 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19440 create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), 19441 ira->codegen->builtin_types.entry_bool, 19442 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19443 } else if (buf_eql_str(field_name, "arg_count")) { 19444 bool ptr_is_const = true; 19445 bool ptr_is_volatile = false; 19446 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 19447 create_const_usize(ira->codegen, child_type->data.fn.fn_type_id.param_count), 19448 ira->codegen->builtin_types.entry_usize, 19449 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 19450 } else { 19451 ir_add_error(ira, &field_ptr_instruction->base, 19452 buf_sprintf("type '%s' has no member called '%s'", 19453 buf_ptr(&child_type->name), buf_ptr(field_name))); 19454 return ira->codegen->invalid_instruction; 19455 } 19456 } else { 19457 ir_add_error(ira, &field_ptr_instruction->base, 19458 buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); 19459 return ira->codegen->invalid_instruction; 19460 } 19461 } else if (field_ptr_instruction->initializing) { 19462 ir_add_error(ira, &field_ptr_instruction->base, 19463 buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name))); 19464 return ira->codegen->invalid_instruction; 19465 } else { 19466 ir_add_error_node(ira, field_ptr_instruction->base.source_node, 19467 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); 19468 return ira->codegen->invalid_instruction; 19469 } 19470 } 19471 19472 static IrInstruction *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstructionStorePtr *instruction) { 19473 IrInstruction *ptr = instruction->ptr->child; 19474 if (type_is_invalid(ptr->value->type)) 19475 return ira->codegen->invalid_instruction; 19476 19477 IrInstruction *value = instruction->value->child; 19478 if (type_is_invalid(value->value->type)) 19479 return ira->codegen->invalid_instruction; 19480 19481 return ir_analyze_store_ptr(ira, &instruction->base, ptr, value, instruction->allow_write_through_const); 19482 } 19483 19484 static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *instruction) { 19485 IrInstruction *ptr = instruction->ptr->child; 19486 if (type_is_invalid(ptr->value->type)) 19487 return ira->codegen->invalid_instruction; 19488 return ir_get_deref(ira, &instruction->base, ptr, nullptr); 19489 } 19490 19491 static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { 19492 IrInstruction *expr_value = typeof_instruction->value->child; 19493 ZigType *type_entry = expr_value->value->type; 19494 if (type_is_invalid(type_entry)) 19495 return ira->codegen->invalid_instruction; 19496 return ir_const_type(ira, &typeof_instruction->base, type_entry); 19497 } 19498 19499 static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { 19500 if (ira->new_irb.exec->is_inline) { 19501 // ignore setCold when running functions at compile time 19502 return ir_const_void(ira, &instruction->base); 19503 } 19504 19505 IrInstruction *is_cold_value = instruction->is_cold->child; 19506 bool want_cold; 19507 if (!ir_resolve_bool(ira, is_cold_value, &want_cold)) 19508 return ira->codegen->invalid_instruction; 19509 19510 ZigFn *fn_entry = scope_fn_entry(instruction->base.scope); 19511 if (fn_entry == nullptr) { 19512 ir_add_error(ira, &instruction->base, buf_sprintf("@setCold outside function")); 19513 return ira->codegen->invalid_instruction; 19514 } 19515 19516 if (fn_entry->set_cold_node != nullptr) { 19517 ErrorMsg *msg = ir_add_error(ira, &instruction->base, buf_sprintf("cold set twice in same function")); 19518 add_error_note(ira->codegen, msg, fn_entry->set_cold_node, buf_sprintf("first set here")); 19519 return ira->codegen->invalid_instruction; 19520 } 19521 19522 fn_entry->set_cold_node = instruction->base.source_node; 19523 fn_entry->is_cold = want_cold; 19524 19525 return ir_const_void(ira, &instruction->base); 19526 } 19527 19528 static IrInstruction *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira, 19529 IrInstructionSetRuntimeSafety *set_runtime_safety_instruction) 19530 { 19531 if (ira->new_irb.exec->is_inline) { 19532 // ignore setRuntimeSafety when running functions at compile time 19533 return ir_const_void(ira, &set_runtime_safety_instruction->base); 19534 } 19535 19536 bool *safety_off_ptr; 19537 AstNode **safety_set_node_ptr; 19538 19539 Scope *scope = set_runtime_safety_instruction->base.scope; 19540 while (scope != nullptr) { 19541 if (scope->id == ScopeIdBlock) { 19542 ScopeBlock *block_scope = (ScopeBlock *)scope; 19543 safety_off_ptr = &block_scope->safety_off; 19544 safety_set_node_ptr = &block_scope->safety_set_node; 19545 break; 19546 } else if (scope->id == ScopeIdFnDef) { 19547 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 19548 ZigFn *target_fn = def_scope->fn_entry; 19549 assert(target_fn->def_scope != nullptr); 19550 safety_off_ptr = &target_fn->def_scope->safety_off; 19551 safety_set_node_ptr = &target_fn->def_scope->safety_set_node; 19552 break; 19553 } else if (scope->id == ScopeIdDecls) { 19554 ScopeDecls *decls_scope = (ScopeDecls *)scope; 19555 safety_off_ptr = &decls_scope->safety_off; 19556 safety_set_node_ptr = &decls_scope->safety_set_node; 19557 break; 19558 } else { 19559 scope = scope->parent; 19560 continue; 19561 } 19562 } 19563 assert(scope != nullptr); 19564 19565 IrInstruction *safety_on_value = set_runtime_safety_instruction->safety_on->child; 19566 bool want_runtime_safety; 19567 if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety)) 19568 return ira->codegen->invalid_instruction; 19569 19570 AstNode *source_node = set_runtime_safety_instruction->base.source_node; 19571 if (*safety_set_node_ptr) { 19572 ErrorMsg *msg = ir_add_error_node(ira, source_node, 19573 buf_sprintf("runtime safety set twice for same scope")); 19574 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here")); 19575 return ira->codegen->invalid_instruction; 19576 } 19577 *safety_set_node_ptr = source_node; 19578 *safety_off_ptr = !want_runtime_safety; 19579 19580 return ir_const_void(ira, &set_runtime_safety_instruction->base); 19581 } 19582 19583 static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, 19584 IrInstructionSetFloatMode *instruction) 19585 { 19586 if (ira->new_irb.exec->is_inline) { 19587 // ignore setFloatMode when running functions at compile time 19588 return ir_const_void(ira, &instruction->base); 19589 } 19590 19591 bool *fast_math_on_ptr; 19592 AstNode **fast_math_set_node_ptr; 19593 19594 Scope *scope = instruction->base.scope; 19595 while (scope != nullptr) { 19596 if (scope->id == ScopeIdBlock) { 19597 ScopeBlock *block_scope = (ScopeBlock *)scope; 19598 fast_math_on_ptr = &block_scope->fast_math_on; 19599 fast_math_set_node_ptr = &block_scope->fast_math_set_node; 19600 break; 19601 } else if (scope->id == ScopeIdFnDef) { 19602 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 19603 ZigFn *target_fn = def_scope->fn_entry; 19604 assert(target_fn->def_scope != nullptr); 19605 fast_math_on_ptr = &target_fn->def_scope->fast_math_on; 19606 fast_math_set_node_ptr = &target_fn->def_scope->fast_math_set_node; 19607 break; 19608 } else if (scope->id == ScopeIdDecls) { 19609 ScopeDecls *decls_scope = (ScopeDecls *)scope; 19610 fast_math_on_ptr = &decls_scope->fast_math_on; 19611 fast_math_set_node_ptr = &decls_scope->fast_math_set_node; 19612 break; 19613 } else { 19614 scope = scope->parent; 19615 continue; 19616 } 19617 } 19618 assert(scope != nullptr); 19619 19620 IrInstruction *float_mode_value = instruction->mode_value->child; 19621 FloatMode float_mode_scalar; 19622 if (!ir_resolve_float_mode(ira, float_mode_value, &float_mode_scalar)) 19623 return ira->codegen->invalid_instruction; 19624 19625 AstNode *source_node = instruction->base.source_node; 19626 if (*fast_math_set_node_ptr) { 19627 ErrorMsg *msg = ir_add_error_node(ira, source_node, 19628 buf_sprintf("float mode set twice for same scope")); 19629 add_error_note(ira->codegen, msg, *fast_math_set_node_ptr, buf_sprintf("first set here")); 19630 return ira->codegen->invalid_instruction; 19631 } 19632 *fast_math_set_node_ptr = source_node; 19633 *fast_math_on_ptr = (float_mode_scalar == FloatModeOptimized); 19634 19635 return ir_const_void(ira, &instruction->base); 19636 } 19637 19638 static IrInstruction *ir_analyze_instruction_any_frame_type(IrAnalyze *ira, 19639 IrInstructionAnyFrameType *instruction) 19640 { 19641 ZigType *payload_type = nullptr; 19642 if (instruction->payload_type != nullptr) { 19643 payload_type = ir_resolve_type(ira, instruction->payload_type->child); 19644 if (type_is_invalid(payload_type)) 19645 return ira->codegen->invalid_instruction; 19646 } 19647 19648 ZigType *any_frame_type = get_any_frame_type(ira->codegen, payload_type); 19649 return ir_const_type(ira, &instruction->base, any_frame_type); 19650 } 19651 19652 static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, 19653 IrInstructionSliceType *slice_type_instruction) 19654 { 19655 IrInstruction *result = ir_const(ira, &slice_type_instruction->base, ira->codegen->builtin_types.entry_type); 19656 result->value->special = ConstValSpecialLazy; 19657 19658 LazyValueSliceType *lazy_slice_type = allocate<LazyValueSliceType>(1); 19659 lazy_slice_type->ira = ira; 19660 result->value->data.x_lazy = &lazy_slice_type->base; 19661 lazy_slice_type->base.id = LazyValueIdSliceType; 19662 19663 if (slice_type_instruction->align_value != nullptr) { 19664 lazy_slice_type->align_inst = slice_type_instruction->align_value->child; 19665 if (ir_resolve_const(ira, lazy_slice_type->align_inst, LazyOk) == nullptr) 19666 return ira->codegen->invalid_instruction; 19667 } 19668 19669 if (slice_type_instruction->sentinel != nullptr) { 19670 lazy_slice_type->sentinel = slice_type_instruction->sentinel->child; 19671 if (ir_resolve_const(ira, lazy_slice_type->sentinel, LazyOk) == nullptr) 19672 return ira->codegen->invalid_instruction; 19673 } 19674 19675 lazy_slice_type->elem_type = slice_type_instruction->child_type->child; 19676 if (ir_resolve_type_lazy(ira, lazy_slice_type->elem_type) == nullptr) 19677 return ira->codegen->invalid_instruction; 19678 19679 lazy_slice_type->is_const = slice_type_instruction->is_const; 19680 lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; 19681 lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero; 19682 19683 return result; 19684 } 19685 19686 static IrInstruction *ir_analyze_instruction_global_asm(IrAnalyze *ira, IrInstructionGlobalAsm *instruction) { 19687 buf_append_char(&ira->codegen->global_asm, '\n'); 19688 buf_append_buf(&ira->codegen->global_asm, instruction->asm_code); 19689 19690 return ir_const_void(ira, &instruction->base); 19691 } 19692 19693 static IrInstruction *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsm *asm_instruction) { 19694 assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr); 19695 19696 AstNodeAsmExpr *asm_expr = &asm_instruction->base.source_node->data.asm_expr; 19697 19698 if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base)) 19699 return ira->codegen->invalid_instruction; 19700 19701 // TODO validate the output types and variable types 19702 19703 IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length); 19704 IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length); 19705 19706 ZigType *return_type = ira->codegen->builtin_types.entry_void; 19707 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 19708 AsmOutput *asm_output = asm_expr->output_list.at(i); 19709 if (asm_output->return_type) { 19710 output_types[i] = asm_instruction->output_types[i]->child; 19711 return_type = ir_resolve_type(ira, output_types[i]); 19712 if (type_is_invalid(return_type)) 19713 return ira->codegen->invalid_instruction; 19714 } 19715 } 19716 19717 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 19718 IrInstruction *const input_value = asm_instruction->input_list[i]->child; 19719 if (type_is_invalid(input_value->value->type)) 19720 return ira->codegen->invalid_instruction; 19721 19722 if (instr_is_comptime(input_value) && 19723 (input_value->value->type->id == ZigTypeIdComptimeInt || 19724 input_value->value->type->id == ZigTypeIdComptimeFloat)) { 19725 ir_add_error_node(ira, input_value->source_node, 19726 buf_sprintf("expected sized integer or sized float, found %s", buf_ptr(&input_value->value->type->name))); 19727 return ira->codegen->invalid_instruction; 19728 } 19729 19730 input_list[i] = input_value; 19731 } 19732 19733 IrInstruction *result = ir_build_asm(&ira->new_irb, 19734 asm_instruction->base.scope, asm_instruction->base.source_node, 19735 asm_instruction->asm_template, asm_instruction->token_list, asm_instruction->token_list_len, 19736 input_list, output_types, asm_instruction->output_vars, asm_instruction->return_count, 19737 asm_instruction->has_side_effects); 19738 result->value->type = return_type; 19739 return result; 19740 } 19741 19742 static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, 19743 IrInstructionArrayType *array_type_instruction) 19744 { 19745 Error err; 19746 19747 IrInstruction *size_value = array_type_instruction->size->child; 19748 uint64_t size; 19749 if (!ir_resolve_usize(ira, size_value, &size)) 19750 return ira->codegen->invalid_instruction; 19751 19752 IrInstruction *child_type_value = array_type_instruction->child_type->child; 19753 ZigType *child_type = ir_resolve_type(ira, child_type_value); 19754 if (type_is_invalid(child_type)) 19755 return ira->codegen->invalid_instruction; 19756 19757 ZigValue *sentinel_val; 19758 if (array_type_instruction->sentinel != nullptr) { 19759 IrInstruction *uncasted_sentinel = array_type_instruction->sentinel->child; 19760 if (type_is_invalid(uncasted_sentinel->value->type)) 19761 return ira->codegen->invalid_instruction; 19762 IrInstruction *sentinel = ir_implicit_cast(ira, uncasted_sentinel, child_type); 19763 if (type_is_invalid(sentinel->value->type)) 19764 return ira->codegen->invalid_instruction; 19765 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 19766 if (sentinel_val == nullptr) 19767 return ira->codegen->invalid_instruction; 19768 } else { 19769 sentinel_val = nullptr; 19770 } 19771 19772 switch (child_type->id) { 19773 case ZigTypeIdInvalid: // handled above 19774 zig_unreachable(); 19775 case ZigTypeIdUnreachable: 19776 case ZigTypeIdUndefined: 19777 case ZigTypeIdNull: 19778 case ZigTypeIdArgTuple: 19779 case ZigTypeIdOpaque: 19780 ir_add_error_node(ira, array_type_instruction->base.source_node, 19781 buf_sprintf("array of type '%s' not allowed", buf_ptr(&child_type->name))); 19782 return ira->codegen->invalid_instruction; 19783 case ZigTypeIdMetaType: 19784 case ZigTypeIdVoid: 19785 case ZigTypeIdBool: 19786 case ZigTypeIdInt: 19787 case ZigTypeIdFloat: 19788 case ZigTypeIdPointer: 19789 case ZigTypeIdArray: 19790 case ZigTypeIdStruct: 19791 case ZigTypeIdComptimeFloat: 19792 case ZigTypeIdComptimeInt: 19793 case ZigTypeIdEnumLiteral: 19794 case ZigTypeIdOptional: 19795 case ZigTypeIdErrorUnion: 19796 case ZigTypeIdErrorSet: 19797 case ZigTypeIdEnum: 19798 case ZigTypeIdUnion: 19799 case ZigTypeIdFn: 19800 case ZigTypeIdBoundFn: 19801 case ZigTypeIdVector: 19802 case ZigTypeIdFnFrame: 19803 case ZigTypeIdAnyFrame: 19804 { 19805 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) 19806 return ira->codegen->invalid_instruction; 19807 ZigType *result_type = get_array_type(ira->codegen, child_type, size, sentinel_val); 19808 return ir_const_type(ira, &array_type_instruction->base, result_type); 19809 } 19810 } 19811 zig_unreachable(); 19812 } 19813 19814 static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstructionSizeOf *instruction) { 19815 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); 19816 result->value->special = ConstValSpecialLazy; 19817 19818 LazyValueSizeOf *lazy_size_of = allocate<LazyValueSizeOf>(1); 19819 lazy_size_of->ira = ira; 19820 result->value->data.x_lazy = &lazy_size_of->base; 19821 lazy_size_of->base.id = LazyValueIdSizeOf; 19822 19823 lazy_size_of->target_type = instruction->type_value->child; 19824 if (ir_resolve_type_lazy(ira, lazy_size_of->target_type) == nullptr) 19825 return ira->codegen->invalid_instruction; 19826 19827 return result; 19828 } 19829 19830 static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) { 19831 ZigType *type_entry = value->value->type; 19832 19833 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) { 19834 if (instr_is_comptime(value)) { 19835 ZigValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk); 19836 if (c_ptr_val == nullptr) 19837 return ira->codegen->invalid_instruction; 19838 if (c_ptr_val->special == ConstValSpecialUndef) 19839 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 19840 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 19841 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 19842 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 19843 return ir_const_bool(ira, source_inst, !is_null); 19844 } 19845 19846 IrInstruction *result = ir_build_test_nonnull(&ira->new_irb, 19847 source_inst->scope, source_inst->source_node, value); 19848 result->value->type = ira->codegen->builtin_types.entry_bool; 19849 return result; 19850 } else if (type_entry->id == ZigTypeIdOptional) { 19851 if (instr_is_comptime(value)) { 19852 ZigValue *maybe_val = ir_resolve_const(ira, value, UndefOk); 19853 if (maybe_val == nullptr) 19854 return ira->codegen->invalid_instruction; 19855 if (maybe_val->special == ConstValSpecialUndef) 19856 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 19857 19858 return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val)); 19859 } 19860 19861 IrInstruction *result = ir_build_test_nonnull(&ira->new_irb, 19862 source_inst->scope, source_inst->source_node, value); 19863 result->value->type = ira->codegen->builtin_types.entry_bool; 19864 return result; 19865 } else if (type_entry->id == ZigTypeIdNull) { 19866 return ir_const_bool(ira, source_inst, false); 19867 } else { 19868 return ir_const_bool(ira, source_inst, true); 19869 } 19870 } 19871 19872 static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrInstructionTestNonNull *instruction) { 19873 IrInstruction *value = instruction->value->child; 19874 if (type_is_invalid(value->value->type)) 19875 return ira->codegen->invalid_instruction; 19876 19877 return ir_analyze_test_non_null(ira, &instruction->base, value); 19878 } 19879 19880 static ZigType *get_ptr_elem_type(CodeGen *g, IrInstruction *ptr) { 19881 ir_assert(ptr->value->type->id == ZigTypeIdPointer, ptr); 19882 ZigType *elem_type = ptr->value->type->data.pointer.child_type; 19883 if (elem_type != g->builtin_types.entry_var) 19884 return elem_type; 19885 19886 if (ir_resolve_lazy(g, ptr->source_node, ptr->value)) 19887 return g->builtin_types.entry_invalid; 19888 19889 assert(value_is_comptime(ptr->value)); 19890 ZigValue *pointee = const_ptr_pointee_unchecked(g, ptr->value); 19891 return pointee->type; 19892 } 19893 19894 static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, 19895 IrInstruction *base_ptr, bool safety_check_on, bool initializing) 19896 { 19897 ZigType *type_entry = get_ptr_elem_type(ira->codegen, base_ptr); 19898 if (type_is_invalid(type_entry)) 19899 return ira->codegen->invalid_instruction; 19900 19901 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.ptr_len == PtrLenC) { 19902 if (instr_is_comptime(base_ptr)) { 19903 ZigValue *val = ir_resolve_const(ira, base_ptr, UndefBad); 19904 if (!val) 19905 return ira->codegen->invalid_instruction; 19906 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 19907 ZigValue *c_ptr_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 19908 if (c_ptr_val == nullptr) 19909 return ira->codegen->invalid_instruction; 19910 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 19911 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 19912 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 19913 if (is_null) { 19914 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 19915 return ira->codegen->invalid_instruction; 19916 } 19917 return base_ptr; 19918 } 19919 } 19920 if (!safety_check_on) 19921 return base_ptr; 19922 IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr); 19923 ir_build_assert_non_null(ira, source_instr, c_ptr_val); 19924 return base_ptr; 19925 } 19926 19927 if (type_entry->id != ZigTypeIdOptional) { 19928 ir_add_error_node(ira, base_ptr->source_node, 19929 buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name))); 19930 return ira->codegen->invalid_instruction; 19931 } 19932 19933 ZigType *child_type = type_entry->data.maybe.child_type; 19934 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, 19935 base_ptr->value->type->data.pointer.is_const, base_ptr->value->type->data.pointer.is_volatile, 19936 PtrLenSingle, 0, 0, 0, false); 19937 19938 bool same_comptime_repr = types_have_same_zig_comptime_repr(ira->codegen, child_type, type_entry); 19939 19940 if (instr_is_comptime(base_ptr)) { 19941 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 19942 if (!ptr_val) 19943 return ira->codegen->invalid_instruction; 19944 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 19945 ZigValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 19946 if (optional_val == nullptr) 19947 return ira->codegen->invalid_instruction; 19948 19949 if (initializing) { 19950 switch (type_has_one_possible_value(ira->codegen, child_type)) { 19951 case OnePossibleValueInvalid: 19952 return ira->codegen->invalid_instruction; 19953 case OnePossibleValueNo: 19954 if (!same_comptime_repr) { 19955 ZigValue *payload_val = create_const_vals(1); 19956 payload_val->type = child_type; 19957 payload_val->special = ConstValSpecialUndef; 19958 payload_val->parent.id = ConstParentIdOptionalPayload; 19959 payload_val->parent.data.p_optional_payload.optional_val = optional_val; 19960 19961 optional_val->data.x_optional = payload_val; 19962 optional_val->special = ConstValSpecialStatic; 19963 } 19964 break; 19965 case OnePossibleValueYes: { 19966 ZigValue *pointee = create_const_vals(1); 19967 pointee->special = ConstValSpecialStatic; 19968 pointee->type = child_type; 19969 pointee->parent.id = ConstParentIdOptionalPayload; 19970 pointee->parent.data.p_optional_payload.optional_val = optional_val; 19971 19972 optional_val->special = ConstValSpecialStatic; 19973 optional_val->data.x_optional = pointee; 19974 break; 19975 } 19976 } 19977 } else if (optional_value_is_null(optional_val)) { 19978 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 19979 return ira->codegen->invalid_instruction; 19980 } 19981 19982 IrInstruction *result; 19983 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 19984 result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, 19985 source_instr->source_node, base_ptr, false, initializing); 19986 result->value->type = result_type; 19987 result->value->special = ConstValSpecialStatic; 19988 } else { 19989 result = ir_const(ira, source_instr, result_type); 19990 } 19991 ZigValue *result_val = result->value; 19992 result_val->data.x_ptr.special = ConstPtrSpecialRef; 19993 result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 19994 switch (type_has_one_possible_value(ira->codegen, child_type)) { 19995 case OnePossibleValueInvalid: 19996 return ira->codegen->invalid_instruction; 19997 case OnePossibleValueNo: 19998 if (same_comptime_repr) { 19999 result_val->data.x_ptr.data.ref.pointee = optional_val; 20000 } else { 20001 assert(optional_val->data.x_optional != nullptr); 20002 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; 20003 } 20004 break; 20005 case OnePossibleValueYes: 20006 assert(optional_val->data.x_optional != nullptr); 20007 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; 20008 break; 20009 } 20010 return result; 20011 } 20012 } 20013 20014 IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, 20015 source_instr->source_node, base_ptr, safety_check_on, initializing); 20016 result->value->type = result_type; 20017 return result; 20018 } 20019 20020 static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, 20021 IrInstructionOptionalUnwrapPtr *instruction) 20022 { 20023 IrInstruction *base_ptr = instruction->base_ptr->child; 20024 if (type_is_invalid(base_ptr->value->type)) 20025 return ira->codegen->invalid_instruction; 20026 20027 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, 20028 instruction->safety_check_on, false); 20029 } 20030 20031 static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { 20032 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 20033 if (type_is_invalid(int_type)) 20034 return ira->codegen->invalid_instruction; 20035 20036 IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); 20037 if (type_is_invalid(op->value->type)) 20038 return ira->codegen->invalid_instruction; 20039 20040 if (int_type->data.integral.bit_count == 0) 20041 return ir_const_unsigned(ira, &instruction->base, 0); 20042 20043 if (instr_is_comptime(op)) { 20044 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 20045 if (val == nullptr) 20046 return ira->codegen->invalid_instruction; 20047 if (val->special == ConstValSpecialUndef) 20048 return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); 20049 size_t result_usize = bigint_ctz(&op->value->data.x_bigint, int_type->data.integral.bit_count); 20050 return ir_const_unsigned(ira, &instruction->base, result_usize); 20051 } 20052 20053 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 20054 IrInstruction *result = ir_build_ctz(&ira->new_irb, instruction->base.scope, 20055 instruction->base.source_node, nullptr, op); 20056 result->value->type = return_type; 20057 return result; 20058 } 20059 20060 static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *instruction) { 20061 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 20062 if (type_is_invalid(int_type)) 20063 return ira->codegen->invalid_instruction; 20064 20065 IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); 20066 if (type_is_invalid(op->value->type)) 20067 return ira->codegen->invalid_instruction; 20068 20069 if (int_type->data.integral.bit_count == 0) 20070 return ir_const_unsigned(ira, &instruction->base, 0); 20071 20072 if (instr_is_comptime(op)) { 20073 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 20074 if (val == nullptr) 20075 return ira->codegen->invalid_instruction; 20076 if (val->special == ConstValSpecialUndef) 20077 return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); 20078 size_t result_usize = bigint_clz(&op->value->data.x_bigint, int_type->data.integral.bit_count); 20079 return ir_const_unsigned(ira, &instruction->base, result_usize); 20080 } 20081 20082 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 20083 IrInstruction *result = ir_build_clz(&ira->new_irb, instruction->base.scope, 20084 instruction->base.source_node, nullptr, op); 20085 result->value->type = return_type; 20086 return result; 20087 } 20088 20089 static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) { 20090 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 20091 if (type_is_invalid(int_type)) 20092 return ira->codegen->invalid_instruction; 20093 20094 IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); 20095 if (type_is_invalid(op->value->type)) 20096 return ira->codegen->invalid_instruction; 20097 20098 if (int_type->data.integral.bit_count == 0) 20099 return ir_const_unsigned(ira, &instruction->base, 0); 20100 20101 if (instr_is_comptime(op)) { 20102 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 20103 if (val == nullptr) 20104 return ira->codegen->invalid_instruction; 20105 if (val->special == ConstValSpecialUndef) 20106 return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); 20107 20108 if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { 20109 size_t result = bigint_popcount_unsigned(&val->data.x_bigint); 20110 return ir_const_unsigned(ira, &instruction->base, result); 20111 } 20112 size_t result = bigint_popcount_signed(&val->data.x_bigint, int_type->data.integral.bit_count); 20113 return ir_const_unsigned(ira, &instruction->base, result); 20114 } 20115 20116 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 20117 IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope, 20118 instruction->base.source_node, nullptr, op); 20119 result->value->type = return_type; 20120 return result; 20121 } 20122 20123 static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value) { 20124 if (type_is_invalid(value->value->type)) 20125 return ira->codegen->invalid_instruction; 20126 20127 if (value->value->type->id == ZigTypeIdEnum) { 20128 return value; 20129 } 20130 20131 if (value->value->type->id != ZigTypeIdUnion) { 20132 ir_add_error(ira, value, 20133 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value->type->name))); 20134 return ira->codegen->invalid_instruction; 20135 } 20136 if (!value->value->type->data.unionation.have_explicit_tag_type && !source_instr->is_gen) { 20137 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum")); 20138 if (value->value->type->data.unionation.decl_node != nullptr) { 20139 add_error_note(ira->codegen, msg, value->value->type->data.unionation.decl_node, 20140 buf_sprintf("declared here")); 20141 } 20142 return ira->codegen->invalid_instruction; 20143 } 20144 20145 ZigType *tag_type = value->value->type->data.unionation.tag_type; 20146 assert(tag_type->id == ZigTypeIdEnum); 20147 20148 if (instr_is_comptime(value)) { 20149 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 20150 if (!val) 20151 return ira->codegen->invalid_instruction; 20152 20153 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 20154 source_instr->scope, source_instr->source_node); 20155 const_instruction->base.value->type = tag_type; 20156 const_instruction->base.value->special = ConstValSpecialStatic; 20157 bigint_init_bigint(&const_instruction->base.value->data.x_enum_tag, &val->data.x_union.tag); 20158 return &const_instruction->base; 20159 } 20160 20161 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 20162 result->value->type = tag_type; 20163 return result; 20164 } 20165 20166 static IrInstruction *ir_analyze_instruction_switch_br(IrAnalyze *ira, 20167 IrInstructionSwitchBr *switch_br_instruction) 20168 { 20169 IrInstruction *target_value = switch_br_instruction->target_value->child; 20170 if (type_is_invalid(target_value->value->type)) 20171 return ir_unreach_error(ira); 20172 20173 if (switch_br_instruction->switch_prongs_void != nullptr) { 20174 if (type_is_invalid(switch_br_instruction->switch_prongs_void->child->value->type)) { 20175 return ir_unreach_error(ira); 20176 } 20177 } 20178 20179 20180 size_t case_count = switch_br_instruction->case_count; 20181 20182 bool is_comptime; 20183 if (!ir_resolve_comptime(ira, switch_br_instruction->is_comptime->child, &is_comptime)) 20184 return ira->codegen->invalid_instruction; 20185 20186 if (is_comptime || instr_is_comptime(target_value)) { 20187 ZigValue *target_val = ir_resolve_const(ira, target_value, UndefBad); 20188 if (!target_val) 20189 return ir_unreach_error(ira); 20190 20191 IrBasicBlock *old_dest_block = switch_br_instruction->else_block; 20192 for (size_t i = 0; i < case_count; i += 1) { 20193 IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 20194 IrInstruction *case_value = old_case->value->child; 20195 if (type_is_invalid(case_value->value->type)) 20196 return ir_unreach_error(ira); 20197 20198 if (case_value->value->type->id == ZigTypeIdEnum) { 20199 case_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, case_value); 20200 if (type_is_invalid(case_value->value->type)) 20201 return ir_unreach_error(ira); 20202 } 20203 20204 IrInstruction *casted_case_value = ir_implicit_cast(ira, case_value, target_value->value->type); 20205 if (type_is_invalid(casted_case_value->value->type)) 20206 return ir_unreach_error(ira); 20207 20208 ZigValue *case_val = ir_resolve_const(ira, casted_case_value, UndefBad); 20209 if (!case_val) 20210 return ir_unreach_error(ira); 20211 20212 if (const_values_equal(ira->codegen, target_val, case_val)) { 20213 old_dest_block = old_case->block; 20214 break; 20215 } 20216 } 20217 20218 if (is_comptime || old_dest_block->ref_count == 1) { 20219 return ir_inline_bb(ira, &switch_br_instruction->base, old_dest_block); 20220 } else { 20221 IrBasicBlock *new_dest_block = ir_get_new_bb(ira, old_dest_block, &switch_br_instruction->base); 20222 IrInstruction *result = ir_build_br(&ira->new_irb, 20223 switch_br_instruction->base.scope, switch_br_instruction->base.source_node, 20224 new_dest_block, nullptr); 20225 result->value->type = ira->codegen->builtin_types.entry_unreachable; 20226 return ir_finish_anal(ira, result); 20227 } 20228 } 20229 20230 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(case_count); 20231 for (size_t i = 0; i < case_count; i += 1) { 20232 IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 20233 IrInstructionSwitchBrCase *new_case = &cases[i]; 20234 new_case->block = ir_get_new_bb(ira, old_case->block, &switch_br_instruction->base); 20235 new_case->value = ira->codegen->invalid_instruction; 20236 20237 // Calling ir_get_new_bb set the ref_instruction on the new basic block. 20238 // However a switch br may branch to the same basic block which would trigger an 20239 // incorrect re-generation of the block. So we set it to null here and assign 20240 // it back after the loop. 20241 new_case->block->ref_instruction = nullptr; 20242 20243 IrInstruction *old_value = old_case->value; 20244 IrInstruction *new_value = old_value->child; 20245 if (type_is_invalid(new_value->value->type)) 20246 continue; 20247 20248 if (new_value->value->type->id == ZigTypeIdEnum) { 20249 new_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, new_value); 20250 if (type_is_invalid(new_value->value->type)) 20251 continue; 20252 } 20253 20254 IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, target_value->value->type); 20255 if (type_is_invalid(casted_new_value->value->type)) 20256 continue; 20257 20258 if (!ir_resolve_const(ira, casted_new_value, UndefBad)) 20259 continue; 20260 20261 new_case->value = casted_new_value; 20262 } 20263 20264 for (size_t i = 0; i < case_count; i += 1) { 20265 IrInstructionSwitchBrCase *new_case = &cases[i]; 20266 if (new_case->value == ira->codegen->invalid_instruction) 20267 return ir_unreach_error(ira); 20268 new_case->block->ref_instruction = &switch_br_instruction->base; 20269 } 20270 20271 IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); 20272 IrInstructionSwitchBr *switch_br = ir_build_switch_br(&ira->new_irb, 20273 switch_br_instruction->base.scope, switch_br_instruction->base.source_node, 20274 target_value, new_else_block, case_count, cases, nullptr, nullptr); 20275 switch_br->base.value->type = ira->codegen->builtin_types.entry_unreachable; 20276 return ir_finish_anal(ira, &switch_br->base); 20277 } 20278 20279 static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, 20280 IrInstructionSwitchTarget *switch_target_instruction) 20281 { 20282 Error err; 20283 IrInstruction *target_value_ptr = switch_target_instruction->target_value_ptr->child; 20284 if (type_is_invalid(target_value_ptr->value->type)) 20285 return ira->codegen->invalid_instruction; 20286 20287 if (target_value_ptr->value->type->id == ZigTypeIdMetaType) { 20288 assert(instr_is_comptime(target_value_ptr)); 20289 ZigType *ptr_type = target_value_ptr->value->data.x_type; 20290 assert(ptr_type->id == ZigTypeIdPointer); 20291 return ir_const_type(ira, &switch_target_instruction->base, ptr_type->data.pointer.child_type); 20292 } 20293 20294 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 20295 ZigValue *pointee_val = nullptr; 20296 if (instr_is_comptime(target_value_ptr) && target_value_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 20297 pointee_val = const_ptr_pointee(ira, ira->codegen, target_value_ptr->value, target_value_ptr->source_node); 20298 if (pointee_val == nullptr) 20299 return ira->codegen->invalid_instruction; 20300 20301 if (pointee_val->special == ConstValSpecialRuntime) 20302 pointee_val = nullptr; 20303 } 20304 if ((err = type_resolve(ira->codegen, target_type, ResolveStatusSizeKnown))) 20305 return ira->codegen->invalid_instruction; 20306 20307 switch (target_type->id) { 20308 case ZigTypeIdInvalid: 20309 zig_unreachable(); 20310 case ZigTypeIdMetaType: 20311 case ZigTypeIdVoid: 20312 case ZigTypeIdBool: 20313 case ZigTypeIdInt: 20314 case ZigTypeIdFloat: 20315 case ZigTypeIdComptimeFloat: 20316 case ZigTypeIdComptimeInt: 20317 case ZigTypeIdEnumLiteral: 20318 case ZigTypeIdPointer: 20319 case ZigTypeIdFn: 20320 case ZigTypeIdErrorSet: { 20321 if (pointee_val) { 20322 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, nullptr); 20323 copy_const_val(result->value, pointee_val, true); 20324 result->value->type = target_type; 20325 return result; 20326 } 20327 20328 IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); 20329 result->value->type = target_type; 20330 return result; 20331 } 20332 case ZigTypeIdUnion: { 20333 AstNode *decl_node = target_type->data.unionation.decl_node; 20334 if (!decl_node->data.container_decl.auto_enum && 20335 decl_node->data.container_decl.init_arg_expr == nullptr) 20336 { 20337 ErrorMsg *msg = ir_add_error(ira, target_value_ptr, 20338 buf_sprintf("switch on union which has no attached enum")); 20339 add_error_note(ira->codegen, msg, decl_node, 20340 buf_sprintf("consider 'union(enum)' here")); 20341 return ira->codegen->invalid_instruction; 20342 } 20343 ZigType *tag_type = target_type->data.unionation.tag_type; 20344 assert(tag_type != nullptr); 20345 assert(tag_type->id == ZigTypeIdEnum); 20346 if (pointee_val) { 20347 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, tag_type); 20348 bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_union.tag); 20349 return result; 20350 } 20351 if (tag_type->data.enumeration.src_field_count == 1) { 20352 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, tag_type); 20353 TypeEnumField *only_field = &tag_type->data.enumeration.fields[0]; 20354 bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value); 20355 return result; 20356 } 20357 20358 IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); 20359 union_value->value->type = target_type; 20360 20361 IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, 20362 switch_target_instruction->base.source_node, union_value); 20363 union_tag_inst->value->type = tag_type; 20364 return union_tag_inst; 20365 } 20366 case ZigTypeIdEnum: { 20367 if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown))) 20368 return ira->codegen->invalid_instruction; 20369 if (target_type->data.enumeration.src_field_count < 2) { 20370 TypeEnumField *only_field = &target_type->data.enumeration.fields[0]; 20371 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type); 20372 bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value); 20373 return result; 20374 } 20375 20376 if (pointee_val) { 20377 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type); 20378 bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_enum_tag); 20379 return result; 20380 } 20381 20382 IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); 20383 enum_value->value->type = target_type; 20384 return enum_value; 20385 } 20386 case ZigTypeIdErrorUnion: 20387 case ZigTypeIdUnreachable: 20388 case ZigTypeIdArray: 20389 case ZigTypeIdStruct: 20390 case ZigTypeIdUndefined: 20391 case ZigTypeIdNull: 20392 case ZigTypeIdOptional: 20393 case ZigTypeIdBoundFn: 20394 case ZigTypeIdArgTuple: 20395 case ZigTypeIdOpaque: 20396 case ZigTypeIdVector: 20397 case ZigTypeIdFnFrame: 20398 case ZigTypeIdAnyFrame: 20399 ir_add_error(ira, &switch_target_instruction->base, 20400 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); 20401 return ira->codegen->invalid_instruction; 20402 } 20403 zig_unreachable(); 20404 } 20405 20406 static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstructionSwitchVar *instruction) { 20407 IrInstruction *target_value_ptr = instruction->target_value_ptr->child; 20408 if (type_is_invalid(target_value_ptr->value->type)) 20409 return ira->codegen->invalid_instruction; 20410 20411 ZigType *ref_type = target_value_ptr->value->type; 20412 assert(ref_type->id == ZigTypeIdPointer); 20413 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 20414 if (target_type->id == ZigTypeIdUnion) { 20415 ZigType *enum_type = target_type->data.unionation.tag_type; 20416 assert(enum_type != nullptr); 20417 assert(enum_type->id == ZigTypeIdEnum); 20418 assert(instruction->prongs_len > 0); 20419 20420 IrInstruction *first_prong_value = instruction->prongs_ptr[0]->child; 20421 if (type_is_invalid(first_prong_value->value->type)) 20422 return ira->codegen->invalid_instruction; 20423 20424 IrInstruction *first_casted_prong_value = ir_implicit_cast(ira, first_prong_value, enum_type); 20425 if (type_is_invalid(first_casted_prong_value->value->type)) 20426 return ira->codegen->invalid_instruction; 20427 20428 ZigValue *first_prong_val = ir_resolve_const(ira, first_casted_prong_value, UndefBad); 20429 if (first_prong_val == nullptr) 20430 return ira->codegen->invalid_instruction; 20431 20432 TypeUnionField *first_field = find_union_field_by_tag(target_type, &first_prong_val->data.x_enum_tag); 20433 20434 ErrorMsg *invalid_payload_msg = nullptr; 20435 for (size_t prong_i = 1; prong_i < instruction->prongs_len; prong_i += 1) { 20436 IrInstruction *this_prong_inst = instruction->prongs_ptr[prong_i]->child; 20437 if (type_is_invalid(this_prong_inst->value->type)) 20438 return ira->codegen->invalid_instruction; 20439 20440 IrInstruction *this_casted_prong_value = ir_implicit_cast(ira, this_prong_inst, enum_type); 20441 if (type_is_invalid(this_casted_prong_value->value->type)) 20442 return ira->codegen->invalid_instruction; 20443 20444 ZigValue *this_prong = ir_resolve_const(ira, this_casted_prong_value, UndefBad); 20445 if (this_prong == nullptr) 20446 return ira->codegen->invalid_instruction; 20447 20448 TypeUnionField *payload_field = find_union_field_by_tag(target_type, &this_prong->data.x_enum_tag); 20449 ZigType *payload_type = payload_field->type_entry; 20450 if (first_field->type_entry != payload_type) { 20451 if (invalid_payload_msg == nullptr) { 20452 invalid_payload_msg = ir_add_error(ira, &instruction->base, 20453 buf_sprintf("capture group with incompatible types")); 20454 add_error_note(ira->codegen, invalid_payload_msg, first_prong_value->source_node, 20455 buf_sprintf("type '%s' here", buf_ptr(&first_field->type_entry->name))); 20456 } 20457 add_error_note(ira->codegen, invalid_payload_msg, this_prong_inst->source_node, 20458 buf_sprintf("type '%s' here", buf_ptr(&payload_field->type_entry->name))); 20459 } 20460 } 20461 20462 if (invalid_payload_msg != nullptr) { 20463 return ira->codegen->invalid_instruction; 20464 } 20465 20466 if (instr_is_comptime(target_value_ptr)) { 20467 ZigValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad); 20468 if (!target_value_ptr) 20469 return ira->codegen->invalid_instruction; 20470 20471 ZigValue *pointee_val = const_ptr_pointee(ira, ira->codegen, target_val_ptr, instruction->base.source_node); 20472 if (pointee_val == nullptr) 20473 return ira->codegen->invalid_instruction; 20474 20475 IrInstruction *result = ir_const(ira, &instruction->base, 20476 get_pointer_to_type(ira->codegen, first_field->type_entry, 20477 target_val_ptr->type->data.pointer.is_const)); 20478 ZigValue *out_val = result->value; 20479 out_val->data.x_ptr.special = ConstPtrSpecialRef; 20480 out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut; 20481 out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_union.payload; 20482 return result; 20483 } 20484 20485 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, 20486 instruction->base.scope, instruction->base.source_node, target_value_ptr, first_field, false, false); 20487 result->value->type = get_pointer_to_type(ira->codegen, first_field->type_entry, 20488 target_value_ptr->value->type->data.pointer.is_const); 20489 return result; 20490 } else if (target_type->id == ZigTypeIdErrorSet) { 20491 // construct an error set from the prong values 20492 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 20493 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 20494 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 20495 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 20496 ZigList<ErrorTableEntry *> error_list = {}; 20497 buf_resize(&err_set_type->name, 0); 20498 buf_appendf(&err_set_type->name, "error{"); 20499 for (size_t i = 0; i < instruction->prongs_len; i += 1) { 20500 ErrorTableEntry *err = ir_resolve_error(ira, instruction->prongs_ptr[i]->child); 20501 if (err == nullptr) 20502 return ira->codegen->invalid_instruction; 20503 error_list.append(err); 20504 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&err->name)); 20505 } 20506 err_set_type->data.error_set.errors = error_list.items; 20507 err_set_type->data.error_set.err_count = error_list.length; 20508 buf_appendf(&err_set_type->name, "}"); 20509 20510 20511 ZigType *new_target_value_ptr_type = get_pointer_to_type_extra(ira->codegen, 20512 err_set_type, 20513 ref_type->data.pointer.is_const, ref_type->data.pointer.is_volatile, 20514 ref_type->data.pointer.ptr_len, 20515 ref_type->data.pointer.explicit_alignment, 20516 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, 20517 ref_type->data.pointer.allow_zero); 20518 return ir_analyze_ptr_cast(ira, &instruction->base, target_value_ptr, new_target_value_ptr_type, 20519 &instruction->base, false); 20520 } else { 20521 ir_add_error(ira, &instruction->base, 20522 buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); 20523 return ira->codegen->invalid_instruction; 20524 } 20525 } 20526 20527 static IrInstruction *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, 20528 IrInstructionSwitchElseVar *instruction) 20529 { 20530 IrInstruction *target_value_ptr = instruction->target_value_ptr->child; 20531 if (type_is_invalid(target_value_ptr->value->type)) 20532 return ira->codegen->invalid_instruction; 20533 20534 ZigType *ref_type = target_value_ptr->value->type; 20535 assert(ref_type->id == ZigTypeIdPointer); 20536 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 20537 if (target_type->id == ZigTypeIdErrorSet) { 20538 // make a new set that has the other cases removed 20539 if (!resolve_inferred_error_set(ira->codegen, target_type, instruction->base.source_node)) { 20540 return ira->codegen->invalid_instruction; 20541 } 20542 if (type_is_global_error_set(target_type)) { 20543 // the type of the else capture variable still has to be the global error set. 20544 // once the runtime hint system is more sophisticated, we could add some hint information here. 20545 return target_value_ptr; 20546 } 20547 // Make note of the errors handled by other cases 20548 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 20549 for (size_t case_i = 0; case_i < instruction->switch_br->case_count; case_i += 1) { 20550 IrInstructionSwitchBrCase *br_case = &instruction->switch_br->cases[case_i]; 20551 IrInstruction *case_expr = br_case->value->child; 20552 if (case_expr->value->type->id == ZigTypeIdErrorSet) { 20553 ErrorTableEntry *err = ir_resolve_error(ira, case_expr); 20554 if (err == nullptr) 20555 return ira->codegen->invalid_instruction; 20556 errors[err->value] = err; 20557 } else if (case_expr->value->type->id == ZigTypeIdMetaType) { 20558 ZigType *err_set_type = ir_resolve_type(ira, case_expr); 20559 if (type_is_invalid(err_set_type)) 20560 return ira->codegen->invalid_instruction; 20561 populate_error_set_table(errors, err_set_type); 20562 } else { 20563 zig_unreachable(); 20564 } 20565 } 20566 ZigList<ErrorTableEntry *> result_list = {}; 20567 20568 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 20569 buf_resize(&err_set_type->name, 0); 20570 buf_appendf(&err_set_type->name, "error{"); 20571 20572 // Look at all the errors in the type switched on and add them to the result_list 20573 // if they are not handled by cases. 20574 for (uint32_t i = 0; i < target_type->data.error_set.err_count; i += 1) { 20575 ErrorTableEntry *error_entry = target_type->data.error_set.errors[i]; 20576 ErrorTableEntry *existing_entry = errors[error_entry->value]; 20577 if (existing_entry == nullptr) { 20578 result_list.append(error_entry); 20579 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 20580 } 20581 } 20582 free(errors); 20583 20584 err_set_type->data.error_set.err_count = result_list.length; 20585 err_set_type->data.error_set.errors = result_list.items; 20586 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 20587 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 20588 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 20589 20590 buf_appendf(&err_set_type->name, "}"); 20591 20592 ZigType *new_target_value_ptr_type = get_pointer_to_type_extra(ira->codegen, 20593 err_set_type, 20594 ref_type->data.pointer.is_const, ref_type->data.pointer.is_volatile, 20595 ref_type->data.pointer.ptr_len, 20596 ref_type->data.pointer.explicit_alignment, 20597 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, 20598 ref_type->data.pointer.allow_zero); 20599 return ir_analyze_ptr_cast(ira, &instruction->base, target_value_ptr, new_target_value_ptr_type, 20600 &instruction->base, false); 20601 } 20602 20603 return target_value_ptr; 20604 } 20605 20606 static IrInstruction *ir_analyze_instruction_union_tag(IrAnalyze *ira, IrInstructionUnionTag *instruction) { 20607 IrInstruction *value = instruction->value->child; 20608 return ir_analyze_union_tag(ira, &instruction->base, value); 20609 } 20610 20611 static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) { 20612 Error err; 20613 20614 IrInstruction *name_value = import_instruction->name->child; 20615 Buf *import_target_str = ir_resolve_str(ira, name_value); 20616 if (!import_target_str) 20617 return ira->codegen->invalid_instruction; 20618 20619 AstNode *source_node = import_instruction->base.source_node; 20620 ZigType *import = source_node->owner; 20621 20622 ZigType *target_import; 20623 Buf *import_target_path; 20624 Buf full_path = BUF_INIT; 20625 if ((err = analyze_import(ira->codegen, import, import_target_str, &target_import, 20626 &import_target_path, &full_path))) 20627 { 20628 if (err == ErrorImportOutsidePkgPath) { 20629 ir_add_error_node(ira, source_node, 20630 buf_sprintf("import of file outside package path: '%s'", 20631 buf_ptr(import_target_path))); 20632 return ira->codegen->invalid_instruction; 20633 } else if (err == ErrorFileNotFound) { 20634 ir_add_error_node(ira, source_node, 20635 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); 20636 return ira->codegen->invalid_instruction; 20637 } else { 20638 ir_add_error_node(ira, source_node, 20639 buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); 20640 return ira->codegen->invalid_instruction; 20641 } 20642 } 20643 20644 return ir_const_type(ira, &import_instruction->base, target_import); 20645 } 20646 20647 static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) { 20648 IrInstruction *value = ref_instruction->value->child; 20649 if (type_is_invalid(value->value->type)) 20650 return ira->codegen->invalid_instruction; 20651 return ir_get_ref(ira, &ref_instruction->base, value, ref_instruction->is_const, ref_instruction->is_volatile); 20652 } 20653 20654 static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *source_instruction, 20655 AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstruction *field_result_loc, 20656 IrInstruction *result_loc) 20657 { 20658 Error err; 20659 assert(union_type->id == ZigTypeIdUnion); 20660 20661 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) 20662 return ira->codegen->invalid_instruction; 20663 20664 TypeUnionField *type_field = find_union_type_field(union_type, field_name); 20665 if (type_field == nullptr) { 20666 ir_add_error_node(ira, field_source_node, 20667 buf_sprintf("no member named '%s' in union '%s'", 20668 buf_ptr(field_name), buf_ptr(&union_type->name))); 20669 return ira->codegen->invalid_instruction; 20670 } 20671 20672 if (type_is_invalid(type_field->type_entry)) 20673 return ira->codegen->invalid_instruction; 20674 20675 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 20676 if (instr_is_comptime(field_result_loc) && 20677 field_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 20678 { 20679 // nothing 20680 } else { 20681 result_loc->value->special = ConstValSpecialRuntime; 20682 } 20683 } 20684 20685 bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instruction->scope) 20686 || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes; 20687 20688 IrInstruction *result = ir_get_deref(ira, source_instruction, result_loc, nullptr); 20689 if (is_comptime && !instr_is_comptime(result)) { 20690 ir_add_error(ira, field_result_loc, 20691 buf_sprintf("unable to evaluate constant expression")); 20692 return ira->codegen->invalid_instruction; 20693 } 20694 return result; 20695 } 20696 20697 static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, 20698 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, 20699 IrInstruction *result_loc) 20700 { 20701 Error err; 20702 if (container_type->id == ZigTypeIdUnion) { 20703 if (instr_field_count != 1) { 20704 ir_add_error(ira, instruction, 20705 buf_sprintf("union initialization expects exactly one field")); 20706 return ira->codegen->invalid_instruction; 20707 } 20708 IrInstructionContainerInitFieldsField *field = &fields[0]; 20709 IrInstruction *field_result_loc = field->result_loc->child; 20710 if (type_is_invalid(field_result_loc->value->type)) 20711 return ira->codegen->invalid_instruction; 20712 20713 return ir_analyze_union_init(ira, instruction, field->source_node, container_type, field->name, 20714 field_result_loc, result_loc); 20715 } 20716 if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { 20717 ir_add_error(ira, instruction, 20718 buf_sprintf("type '%s' does not support struct initialization syntax", 20719 buf_ptr(&container_type->name))); 20720 return ira->codegen->invalid_instruction; 20721 } 20722 20723 if (container_type->data.structure.resolve_status == ResolveStatusBeingInferred) { 20724 // We're now done inferring the type. 20725 container_type->data.structure.resolve_status = ResolveStatusUnstarted; 20726 } 20727 20728 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 20729 return ira->codegen->invalid_instruction; 20730 20731 size_t actual_field_count = container_type->data.structure.src_field_count; 20732 20733 IrInstruction *first_non_const_instruction = nullptr; 20734 20735 AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); 20736 ZigList<IrInstruction *> const_ptrs = {}; 20737 20738 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) 20739 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; 20740 20741 20742 // Here we iterate over the fields that have been initialized, and emit 20743 // compile errors for missing fields and duplicate fields. 20744 // It is only now that we find out whether the struct initialization can be a comptime 20745 // value, but we have already emitted runtime instructions for the fields that 20746 // were initialized with runtime values, and have omitted instructions that would have 20747 // initialized fields with comptime values. 20748 // So now we must clean up this situation. If it turns out the struct initialization can 20749 // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst. 20750 // Otherwise, we must emit instructions to runtime-initialize the fields that have 20751 // comptime-known values. 20752 20753 for (size_t i = 0; i < instr_field_count; i += 1) { 20754 IrInstructionContainerInitFieldsField *field = &fields[i]; 20755 20756 IrInstruction *field_result_loc = field->result_loc->child; 20757 if (type_is_invalid(field_result_loc->value->type)) 20758 return ira->codegen->invalid_instruction; 20759 20760 TypeStructField *type_field = find_struct_type_field(container_type, field->name); 20761 if (!type_field) { 20762 ir_add_error_node(ira, field->source_node, 20763 buf_sprintf("no member named '%s' in struct '%s'", 20764 buf_ptr(field->name), buf_ptr(&container_type->name))); 20765 return ira->codegen->invalid_instruction; 20766 } 20767 20768 if (type_is_invalid(type_field->type_entry)) 20769 return ira->codegen->invalid_instruction; 20770 20771 size_t field_index = type_field->src_index; 20772 AstNode *existing_assign_node = field_assign_nodes[field_index]; 20773 if (existing_assign_node) { 20774 ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field")); 20775 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); 20776 return ira->codegen->invalid_instruction; 20777 } 20778 field_assign_nodes[field_index] = field->source_node; 20779 20780 if (instr_is_comptime(field_result_loc) && 20781 field_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 20782 { 20783 const_ptrs.append(field_result_loc); 20784 } else { 20785 first_non_const_instruction = field_result_loc; 20786 } 20787 } 20788 20789 bool any_missing = false; 20790 for (size_t i = 0; i < actual_field_count; i += 1) { 20791 if (field_assign_nodes[i] != nullptr) continue; 20792 20793 // look for a default field value 20794 TypeStructField *field = container_type->data.structure.fields[i]; 20795 if (field->init_val == nullptr) { 20796 // it's not memoized. time to go analyze it 20797 AstNode *init_node; 20798 if (field->decl_node->type == NodeTypeStructField) { 20799 init_node = field->decl_node->data.struct_field.value; 20800 } else { 20801 init_node = nullptr; 20802 } 20803 if (init_node == nullptr) { 20804 ir_add_error_node(ira, instruction->source_node, 20805 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i]->name))); 20806 any_missing = true; 20807 continue; 20808 } 20809 // scope is not the scope of the struct init, it's the scope of the struct type decl 20810 Scope *analyze_scope = &get_container_scope(container_type)->base; 20811 // memoize it 20812 field->init_val = analyze_const_value(ira->codegen, analyze_scope, init_node, 20813 field->type_entry, nullptr, UndefOk); 20814 } 20815 if (type_is_invalid(field->init_val->type)) 20816 return ira->codegen->invalid_instruction; 20817 20818 IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); 20819 copy_const_val(runtime_inst->value, field->init_val, true); 20820 20821 IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc, 20822 container_type, true); 20823 ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst, false); 20824 if (instr_is_comptime(field_ptr) && field_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 20825 const_ptrs.append(field_ptr); 20826 } else { 20827 first_non_const_instruction = result_loc; 20828 } 20829 } 20830 if (any_missing) 20831 return ira->codegen->invalid_instruction; 20832 20833 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 20834 if (const_ptrs.length != actual_field_count) { 20835 result_loc->value->special = ConstValSpecialRuntime; 20836 for (size_t i = 0; i < const_ptrs.length; i += 1) { 20837 IrInstruction *field_result_loc = const_ptrs.at(i); 20838 IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr); 20839 field_result_loc->value->special = ConstValSpecialRuntime; 20840 ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref, false); 20841 } 20842 } 20843 } 20844 20845 IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); 20846 20847 if (is_comptime && !instr_is_comptime(result)) { 20848 ir_add_error_node(ira, first_non_const_instruction->source_node, 20849 buf_sprintf("unable to evaluate constant expression")); 20850 return ira->codegen->invalid_instruction; 20851 } 20852 20853 return result; 20854 } 20855 20856 static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, 20857 IrInstructionContainerInitList *instruction) 20858 { 20859 ir_assert(instruction->result_loc != nullptr, &instruction->base); 20860 IrInstruction *result_loc = instruction->result_loc->child; 20861 if (type_is_invalid(result_loc->value->type)) 20862 return result_loc; 20863 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base); 20864 20865 ZigType *container_type = result_loc->value->type->data.pointer.child_type; 20866 20867 size_t elem_count = instruction->item_count; 20868 20869 if (is_slice(container_type)) { 20870 ir_add_error_node(ira, instruction->init_array_type_source_node, 20871 buf_sprintf("expected array type or [_], found slice")); 20872 return ira->codegen->invalid_instruction; 20873 } 20874 20875 if (container_type->id == ZigTypeIdVoid) { 20876 if (elem_count != 0) { 20877 ir_add_error_node(ira, instruction->base.source_node, 20878 buf_sprintf("void expression expects no arguments")); 20879 return ira->codegen->invalid_instruction; 20880 } 20881 return ir_const_void(ira, &instruction->base); 20882 } 20883 20884 if (container_type->id == ZigTypeIdStruct && elem_count == 0) { 20885 ir_assert(instruction->result_loc != nullptr, &instruction->base); 20886 IrInstruction *result_loc = instruction->result_loc->child; 20887 if (type_is_invalid(result_loc->value->type)) 20888 return result_loc; 20889 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc); 20890 } 20891 20892 if (container_type->id == ZigTypeIdArray) { 20893 ZigType *child_type = container_type->data.array.child_type; 20894 if (container_type->data.array.len != elem_count) { 20895 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count, nullptr); 20896 20897 ir_add_error(ira, &instruction->base, 20898 buf_sprintf("expected %s literal, found %s literal", 20899 buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); 20900 return ira->codegen->invalid_instruction; 20901 } 20902 } else if (container_type->id == ZigTypeIdStruct && 20903 container_type->data.structure.resolve_status == ResolveStatusBeingInferred) 20904 { 20905 // We're now done inferring the type. 20906 container_type->data.structure.resolve_status = ResolveStatusUnstarted; 20907 } else if (container_type->id == ZigTypeIdVector) { 20908 // OK 20909 } else { 20910 ir_add_error_node(ira, instruction->base.source_node, 20911 buf_sprintf("type '%s' does not support array initialization", 20912 buf_ptr(&container_type->name))); 20913 return ira->codegen->invalid_instruction; 20914 } 20915 20916 switch (type_has_one_possible_value(ira->codegen, container_type)) { 20917 case OnePossibleValueInvalid: 20918 return ira->codegen->invalid_instruction; 20919 case OnePossibleValueYes: 20920 return ir_const(ira, &instruction->base, container_type); 20921 case OnePossibleValueNo: 20922 break; 20923 } 20924 20925 bool is_comptime; 20926 switch (type_requires_comptime(ira->codegen, container_type)) { 20927 case ReqCompTimeInvalid: 20928 return ira->codegen->invalid_instruction; 20929 case ReqCompTimeNo: 20930 is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); 20931 break; 20932 case ReqCompTimeYes: 20933 is_comptime = true; 20934 break; 20935 } 20936 20937 IrInstruction *first_non_const_instruction = nullptr; 20938 20939 // The Result Location Mechanism has already emitted runtime instructions to 20940 // initialize runtime elements and has omitted instructions for the comptime 20941 // elements. However it is only now that we find out whether the array initialization 20942 // can be a comptime value. So we must clean up the situation. If it turns out 20943 // array initialization can be a comptime value, overwrite ConstPtrMutInfer with 20944 // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the 20945 // elements that have comptime-known values. 20946 ZigList<IrInstruction *> const_ptrs = {}; 20947 20948 for (size_t i = 0; i < elem_count; i += 1) { 20949 IrInstruction *elem_result_loc = instruction->elem_result_loc_list[i]->child; 20950 if (type_is_invalid(elem_result_loc->value->type)) 20951 return ira->codegen->invalid_instruction; 20952 20953 assert(elem_result_loc->value->type->id == ZigTypeIdPointer); 20954 20955 if (instr_is_comptime(elem_result_loc) && 20956 elem_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 20957 { 20958 const_ptrs.append(elem_result_loc); 20959 } else { 20960 first_non_const_instruction = elem_result_loc; 20961 } 20962 } 20963 20964 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 20965 if (const_ptrs.length != elem_count) { 20966 result_loc->value->special = ConstValSpecialRuntime; 20967 for (size_t i = 0; i < const_ptrs.length; i += 1) { 20968 IrInstruction *elem_result_loc = const_ptrs.at(i); 20969 assert(elem_result_loc->value->special == ConstValSpecialStatic); 20970 IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr); 20971 elem_result_loc->value->special = ConstValSpecialRuntime; 20972 ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref, false); 20973 } 20974 } 20975 } 20976 20977 IrInstruction *result = ir_get_deref(ira, &instruction->base, result_loc, nullptr); 20978 if (instr_is_comptime(result)) 20979 return result; 20980 20981 if (is_comptime) { 20982 ir_add_error_node(ira, first_non_const_instruction->source_node, 20983 buf_sprintf("unable to evaluate constant expression")); 20984 return ira->codegen->invalid_instruction; 20985 } 20986 20987 ZigType *result_elem_type = result_loc->value->type->data.pointer.child_type; 20988 if (is_slice(result_elem_type)) { 20989 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 20990 buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", 20991 buf_ptr(&result_elem_type->name))); 20992 add_error_note(ira->codegen, msg, first_non_const_instruction->source_node, 20993 buf_sprintf("this value is not comptime-known")); 20994 return ira->codegen->invalid_instruction; 20995 } 20996 return result; 20997 } 20998 20999 static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, 21000 IrInstructionContainerInitFields *instruction) 21001 { 21002 ir_assert(instruction->result_loc != nullptr, &instruction->base); 21003 IrInstruction *result_loc = instruction->result_loc->child; 21004 if (type_is_invalid(result_loc->value->type)) 21005 return result_loc; 21006 21007 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base); 21008 ZigType *container_type = result_loc->value->type->data.pointer.child_type; 21009 21010 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 21011 instruction->field_count, instruction->fields, result_loc); 21012 } 21013 21014 static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, 21015 IrInstructionCompileErr *instruction) 21016 { 21017 IrInstruction *msg_value = instruction->msg->child; 21018 Buf *msg_buf = ir_resolve_str(ira, msg_value); 21019 if (!msg_buf) 21020 return ira->codegen->invalid_instruction; 21021 21022 ir_add_error(ira, &instruction->base, msg_buf); 21023 21024 return ira->codegen->invalid_instruction; 21025 } 21026 21027 static IrInstruction *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstructionCompileLog *instruction) { 21028 Buf buf = BUF_INIT; 21029 fprintf(stderr, "| "); 21030 for (size_t i = 0; i < instruction->msg_count; i += 1) { 21031 IrInstruction *msg = instruction->msg_list[i]->child; 21032 if (type_is_invalid(msg->value->type)) 21033 return ira->codegen->invalid_instruction; 21034 buf_resize(&buf, 0); 21035 if (msg->value->special == ConstValSpecialLazy) { 21036 // Resolve any lazy value that's passed, we need its value 21037 if (ir_resolve_lazy(ira->codegen, msg->source_node, msg->value)) 21038 return ira->codegen->invalid_instruction; 21039 } 21040 render_const_value(ira->codegen, &buf, msg->value); 21041 const char *comma_str = (i != 0) ? ", " : ""; 21042 fprintf(stderr, "%s%s", comma_str, buf_ptr(&buf)); 21043 } 21044 fprintf(stderr, "\n"); 21045 21046 auto *expr = &instruction->base.source_node->data.fn_call_expr; 21047 if (!expr->seen) { 21048 // Here we bypass higher level functions such as ir_add_error because we do not want 21049 // invalidate_exec to be called. 21050 add_node_error(ira->codegen, instruction->base.source_node, buf_sprintf("found compile log statement")); 21051 } 21052 expr->seen = true; 21053 21054 return ir_const_void(ira, &instruction->base); 21055 } 21056 21057 static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstructionErrName *instruction) { 21058 IrInstruction *value = instruction->value->child; 21059 if (type_is_invalid(value->value->type)) 21060 return ira->codegen->invalid_instruction; 21061 21062 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_global_error_set); 21063 if (type_is_invalid(casted_value->value->type)) 21064 return ira->codegen->invalid_instruction; 21065 21066 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 21067 true, false, PtrLenUnknown, 0, 0, 0, false); 21068 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 21069 if (instr_is_comptime(casted_value)) { 21070 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); 21071 if (val == nullptr) 21072 return ira->codegen->invalid_instruction; 21073 ErrorTableEntry *err = casted_value->value->data.x_err_set; 21074 if (!err->cached_error_name_val) { 21075 ZigValue *array_val = create_const_str_lit(ira->codegen, &err->name)->data.x_ptr.data.ref.pointee; 21076 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); 21077 } 21078 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 21079 copy_const_val(result->value, err->cached_error_name_val, true); 21080 result->value->type = str_type; 21081 return result; 21082 } 21083 21084 ira->codegen->generate_error_name_table = true; 21085 21086 IrInstruction *result = ir_build_err_name(&ira->new_irb, 21087 instruction->base.scope, instruction->base.source_node, value); 21088 result->value->type = str_type; 21089 return result; 21090 } 21091 21092 static IrInstruction *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionTagName *instruction) { 21093 Error err; 21094 IrInstruction *target = instruction->target->child; 21095 if (type_is_invalid(target->value->type)) 21096 return ira->codegen->invalid_instruction; 21097 21098 assert(target->value->type->id == ZigTypeIdEnum); 21099 21100 if (instr_is_comptime(target)) { 21101 if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusZeroBitsKnown))) 21102 return ira->codegen->invalid_instruction; 21103 TypeEnumField *field = find_enum_field_by_tag(target->value->type, &target->value->data.x_bigint); 21104 ZigValue *array_val = create_const_str_lit(ira->codegen, field->name)->data.x_ptr.data.ref.pointee; 21105 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 21106 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field->name), true); 21107 return result; 21108 } 21109 21110 IrInstruction *result = ir_build_tag_name(&ira->new_irb, instruction->base.scope, 21111 instruction->base.source_node, target); 21112 ZigType *u8_ptr_type = get_pointer_to_type_extra( 21113 ira->codegen, ira->codegen->builtin_types.entry_u8, 21114 true, false, PtrLenUnknown, 21115 0, 0, 0, false); 21116 result->value->type = get_slice_type(ira->codegen, u8_ptr_type); 21117 return result; 21118 } 21119 21120 static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, 21121 IrInstructionFieldParentPtr *instruction) 21122 { 21123 Error err; 21124 IrInstruction *type_value = instruction->type_value->child; 21125 ZigType *container_type = ir_resolve_type(ira, type_value); 21126 if (type_is_invalid(container_type)) 21127 return ira->codegen->invalid_instruction; 21128 21129 IrInstruction *field_name_value = instruction->field_name->child; 21130 Buf *field_name = ir_resolve_str(ira, field_name_value); 21131 if (!field_name) 21132 return ira->codegen->invalid_instruction; 21133 21134 IrInstruction *field_ptr = instruction->field_ptr->child; 21135 if (type_is_invalid(field_ptr->value->type)) 21136 return ira->codegen->invalid_instruction; 21137 21138 if (container_type->id != ZigTypeIdStruct) { 21139 ir_add_error(ira, type_value, 21140 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 21141 return ira->codegen->invalid_instruction; 21142 } 21143 21144 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 21145 return ira->codegen->invalid_instruction; 21146 21147 TypeStructField *field = find_struct_type_field(container_type, field_name); 21148 if (field == nullptr) { 21149 ir_add_error(ira, field_name_value, 21150 buf_sprintf("struct '%s' has no field '%s'", 21151 buf_ptr(&container_type->name), buf_ptr(field_name))); 21152 return ira->codegen->invalid_instruction; 21153 } 21154 21155 if (field_ptr->value->type->id != ZigTypeIdPointer) { 21156 ir_add_error(ira, field_ptr, 21157 buf_sprintf("expected pointer, found '%s'", buf_ptr(&field_ptr->value->type->name))); 21158 return ira->codegen->invalid_instruction; 21159 } 21160 21161 bool is_packed = (container_type->data.structure.layout == ContainerLayoutPacked); 21162 uint32_t field_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 21163 uint32_t parent_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, container_type); 21164 21165 ZigType *field_ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, 21166 field_ptr->value->type->data.pointer.is_const, 21167 field_ptr->value->type->data.pointer.is_volatile, 21168 PtrLenSingle, 21169 field_ptr_align, 0, 0, false); 21170 IrInstruction *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type); 21171 if (type_is_invalid(casted_field_ptr->value->type)) 21172 return ira->codegen->invalid_instruction; 21173 21174 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, container_type, 21175 casted_field_ptr->value->type->data.pointer.is_const, 21176 casted_field_ptr->value->type->data.pointer.is_volatile, 21177 PtrLenSingle, 21178 parent_ptr_align, 0, 0, false); 21179 21180 if (instr_is_comptime(casted_field_ptr)) { 21181 ZigValue *field_ptr_val = ir_resolve_const(ira, casted_field_ptr, UndefBad); 21182 if (!field_ptr_val) 21183 return ira->codegen->invalid_instruction; 21184 21185 if (field_ptr_val->data.x_ptr.special != ConstPtrSpecialBaseStruct) { 21186 ir_add_error(ira, field_ptr, buf_sprintf("pointer value not based on parent struct")); 21187 return ira->codegen->invalid_instruction; 21188 } 21189 21190 size_t ptr_field_index = field_ptr_val->data.x_ptr.data.base_struct.field_index; 21191 if (ptr_field_index != field->src_index) { 21192 ir_add_error(ira, &instruction->base, 21193 buf_sprintf("field '%s' has index %" ZIG_PRI_usize " but pointer value is index %" ZIG_PRI_usize " of struct '%s'", 21194 buf_ptr(field->name), field->src_index, 21195 ptr_field_index, buf_ptr(&container_type->name))); 21196 return ira->codegen->invalid_instruction; 21197 } 21198 21199 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 21200 ZigValue *out_val = result->value; 21201 out_val->data.x_ptr.special = ConstPtrSpecialRef; 21202 out_val->data.x_ptr.data.ref.pointee = field_ptr_val->data.x_ptr.data.base_struct.struct_val; 21203 out_val->data.x_ptr.mut = field_ptr_val->data.x_ptr.mut; 21204 return result; 21205 } 21206 21207 IrInstruction *result = ir_build_field_parent_ptr(&ira->new_irb, instruction->base.scope, 21208 instruction->base.source_node, type_value, field_name_value, casted_field_ptr, field); 21209 result->value->type = result_type; 21210 return result; 21211 } 21212 21213 static TypeStructField *validate_byte_offset(IrAnalyze *ira, 21214 IrInstruction *type_value, 21215 IrInstruction *field_name_value, 21216 size_t *byte_offset) 21217 { 21218 ZigType *container_type = ir_resolve_type(ira, type_value); 21219 if (type_is_invalid(container_type)) 21220 return nullptr; 21221 21222 Error err; 21223 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 21224 return nullptr; 21225 21226 Buf *field_name = ir_resolve_str(ira, field_name_value); 21227 if (!field_name) 21228 return nullptr; 21229 21230 if (container_type->id != ZigTypeIdStruct) { 21231 ir_add_error(ira, type_value, 21232 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 21233 return nullptr; 21234 } 21235 21236 TypeStructField *field = find_struct_type_field(container_type, field_name); 21237 if (field == nullptr) { 21238 ir_add_error(ira, field_name_value, 21239 buf_sprintf("struct '%s' has no field '%s'", 21240 buf_ptr(&container_type->name), buf_ptr(field_name))); 21241 return nullptr; 21242 } 21243 21244 if (!type_has_bits(field->type_entry)) { 21245 ir_add_error(ira, field_name_value, 21246 buf_sprintf("zero-bit field '%s' in struct '%s' has no offset", 21247 buf_ptr(field_name), buf_ptr(&container_type->name))); 21248 return nullptr; 21249 } 21250 21251 *byte_offset = field->offset; 21252 return field; 21253 } 21254 21255 static IrInstruction *ir_analyze_instruction_byte_offset_of(IrAnalyze *ira, 21256 IrInstructionByteOffsetOf *instruction) 21257 { 21258 IrInstruction *type_value = instruction->type_value->child; 21259 if (type_is_invalid(type_value->value->type)) 21260 return ira->codegen->invalid_instruction; 21261 21262 IrInstruction *field_name_value = instruction->field_name->child; 21263 size_t byte_offset = 0; 21264 if (!validate_byte_offset(ira, type_value, field_name_value, &byte_offset)) 21265 return ira->codegen->invalid_instruction; 21266 21267 21268 return ir_const_unsigned(ira, &instruction->base, byte_offset); 21269 } 21270 21271 static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, 21272 IrInstructionBitOffsetOf *instruction) 21273 { 21274 IrInstruction *type_value = instruction->type_value->child; 21275 if (type_is_invalid(type_value->value->type)) 21276 return ira->codegen->invalid_instruction; 21277 IrInstruction *field_name_value = instruction->field_name->child; 21278 size_t byte_offset = 0; 21279 TypeStructField *field = nullptr; 21280 if (!(field = validate_byte_offset(ira, type_value, field_name_value, &byte_offset))) 21281 return ira->codegen->invalid_instruction; 21282 21283 size_t bit_offset = byte_offset * 8 + field->bit_offset_in_host; 21284 return ir_const_unsigned(ira, &instruction->base, bit_offset); 21285 } 21286 21287 static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { 21288 Buf *field_name_buf; 21289 21290 assert(type != nullptr && !type_is_invalid(type)); 21291 // Check for our field by creating a buffer in place then using the comma operator to free it so that we don't 21292 // leak memory in debug mode. 21293 assert(find_struct_type_field(type, field_name_buf = buf_create_from_str(field_name))->src_index == index && 21294 (buf_deinit(field_name_buf), true)); 21295 } 21296 21297 static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) { 21298 Error err; 21299 ZigValue *type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); 21300 assert(type_info_var->type->id == ZigTypeIdMetaType); 21301 ZigType *type_info_type = type_info_var->data.x_type; 21302 assert(type_info_type->id == ZigTypeIdUnion); 21303 if ((err = type_resolve(ira->codegen, type_info_type, ResolveStatusSizeKnown))) { 21304 zig_unreachable(); 21305 } 21306 21307 if (type_name == nullptr && root == nullptr) 21308 return type_info_type; 21309 else if (type_name == nullptr) 21310 return root; 21311 21312 ZigType *root_type = (root == nullptr) ? type_info_type : root; 21313 21314 ScopeDecls *type_info_scope = get_container_scope(root_type); 21315 assert(type_info_scope != nullptr); 21316 21317 Buf field_name = BUF_INIT; 21318 buf_init_from_str(&field_name, type_name); 21319 auto entry = type_info_scope->decl_table.get(&field_name); 21320 buf_deinit(&field_name); 21321 21322 TldVar *tld = (TldVar *)entry; 21323 assert(tld->base.id == TldIdVar); 21324 21325 ZigVar *var = tld->var; 21326 21327 assert(var->const_value->type->id == ZigTypeIdMetaType); 21328 21329 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, nullptr, var->const_value); 21330 } 21331 21332 static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr, ZigValue *out_val, 21333 ScopeDecls *decls_scope) 21334 { 21335 Error err; 21336 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr); 21337 if ((err = type_resolve(ira->codegen, type_info_declaration_type, ResolveStatusSizeKnown))) 21338 return err; 21339 21340 ensure_field_index(type_info_declaration_type, "name", 0); 21341 ensure_field_index(type_info_declaration_type, "is_pub", 1); 21342 ensure_field_index(type_info_declaration_type, "data", 2); 21343 21344 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type); 21345 if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown))) 21346 return err; 21347 21348 ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type); 21349 if ((err = type_resolve(ira->codegen, type_info_fn_decl_type, ResolveStatusSizeKnown))) 21350 return err; 21351 21352 ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type); 21353 if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown))) 21354 return err; 21355 21356 // Loop through our declarations once to figure out how many declarations we will generate info for. 21357 auto decl_it = decls_scope->decl_table.entry_iterator(); 21358 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; 21359 int declaration_count = 0; 21360 21361 while ((curr_entry = decl_it.next()) != nullptr) { 21362 // If the declaration is unresolved, force it to be resolved again. 21363 if (curr_entry->value->resolution == TldResolutionUnresolved) { 21364 resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false); 21365 if (curr_entry->value->resolution != TldResolutionOk) { 21366 return ErrorSemanticAnalyzeFail; 21367 } 21368 } 21369 21370 // Skip comptime blocks and test functions. 21371 if (curr_entry->value->id != TldIdCompTime) { 21372 if (curr_entry->value->id == TldIdFn) { 21373 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 21374 if (fn_entry->is_test) 21375 continue; 21376 } 21377 21378 declaration_count += 1; 21379 } 21380 } 21381 21382 ZigValue *declaration_array = create_const_vals(1); 21383 declaration_array->special = ConstValSpecialStatic; 21384 declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count, nullptr); 21385 declaration_array->data.x_array.special = ConstArraySpecialNone; 21386 declaration_array->data.x_array.data.s_none.elements = create_const_vals(declaration_count); 21387 init_const_slice(ira->codegen, out_val, declaration_array, 0, declaration_count, false); 21388 21389 // Loop through the declarations and generate info. 21390 decl_it = decls_scope->decl_table.entry_iterator(); 21391 curr_entry = nullptr; 21392 int declaration_index = 0; 21393 while ((curr_entry = decl_it.next()) != nullptr) { 21394 // Skip comptime blocks and test functions. 21395 if (curr_entry->value->id == TldIdCompTime) { 21396 continue; 21397 } else if (curr_entry->value->id == TldIdFn) { 21398 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 21399 if (fn_entry->is_test) 21400 continue; 21401 } 21402 21403 ZigValue *declaration_val = &declaration_array->data.x_array.data.s_none.elements[declaration_index]; 21404 21405 declaration_val->special = ConstValSpecialStatic; 21406 declaration_val->type = type_info_declaration_type; 21407 21408 ZigValue **inner_fields = alloc_const_vals_ptrs(3); 21409 ZigValue *name = create_const_str_lit(ira->codegen, curr_entry->key)->data.x_ptr.data.ref.pointee; 21410 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(curr_entry->key), true); 21411 inner_fields[1]->special = ConstValSpecialStatic; 21412 inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; 21413 inner_fields[1]->data.x_bool = curr_entry->value->visib_mod == VisibModPub; 21414 inner_fields[2]->special = ConstValSpecialStatic; 21415 inner_fields[2]->type = type_info_declaration_data_type; 21416 inner_fields[2]->parent.id = ConstParentIdStruct; 21417 inner_fields[2]->parent.data.p_struct.struct_val = declaration_val; 21418 inner_fields[2]->parent.data.p_struct.field_index = 1; 21419 21420 switch (curr_entry->value->id) { 21421 case TldIdVar: 21422 { 21423 ZigVar *var = ((TldVar *)curr_entry->value)->var; 21424 if ((err = type_resolve(ira->codegen, var->const_value->type, ResolveStatusSizeKnown))) 21425 return ErrorSemanticAnalyzeFail; 21426 21427 if (var->const_value->type->id == ZigTypeIdMetaType) { 21428 // We have a variable of type 'type', so it's actually a type declaration. 21429 // 0: Data.Type: type 21430 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0); 21431 inner_fields[2]->data.x_union.payload = var->const_value; 21432 } else { 21433 // We have a variable of another type, so we store the type of the variable. 21434 // 1: Data.Var: type 21435 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 1); 21436 21437 ZigValue *payload = create_const_vals(1); 21438 payload->special = ConstValSpecialStatic; 21439 payload->type = ira->codegen->builtin_types.entry_type; 21440 payload->data.x_type = var->const_value->type; 21441 21442 inner_fields[2]->data.x_union.payload = payload; 21443 } 21444 21445 break; 21446 } 21447 case TldIdFn: 21448 { 21449 // 2: Data.Fn: Data.FnDecl 21450 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 2); 21451 21452 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 21453 assert(!fn_entry->is_test); 21454 21455 if (fn_entry->type_entry == nullptr) { 21456 ir_error_dependency_loop(ira, source_instr); 21457 return ErrorSemanticAnalyzeFail; 21458 } 21459 21460 AstNodeFnProto *fn_node = &fn_entry->proto_node->data.fn_proto; 21461 21462 ZigValue *fn_decl_val = create_const_vals(1); 21463 fn_decl_val->special = ConstValSpecialStatic; 21464 fn_decl_val->type = type_info_fn_decl_type; 21465 fn_decl_val->parent.id = ConstParentIdUnion; 21466 fn_decl_val->parent.data.p_union.union_val = inner_fields[2]; 21467 21468 ZigValue **fn_decl_fields = alloc_const_vals_ptrs(9); 21469 fn_decl_val->data.x_struct.fields = fn_decl_fields; 21470 21471 // fn_type: type 21472 ensure_field_index(fn_decl_val->type, "fn_type", 0); 21473 fn_decl_fields[0]->special = ConstValSpecialStatic; 21474 fn_decl_fields[0]->type = ira->codegen->builtin_types.entry_type; 21475 fn_decl_fields[0]->data.x_type = fn_entry->type_entry; 21476 // inline_type: Data.FnDecl.Inline 21477 ensure_field_index(fn_decl_val->type, "inline_type", 1); 21478 fn_decl_fields[1]->special = ConstValSpecialStatic; 21479 fn_decl_fields[1]->type = type_info_fn_decl_inline_type; 21480 bigint_init_unsigned(&fn_decl_fields[1]->data.x_enum_tag, fn_entry->fn_inline); 21481 // calling_convention: TypeInfo.CallingConvention 21482 ensure_field_index(fn_decl_val->type, "calling_convention", 2); 21483 fn_decl_fields[2]->special = ConstValSpecialStatic; 21484 fn_decl_fields[2]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr); 21485 bigint_init_unsigned(&fn_decl_fields[2]->data.x_enum_tag, fn_node->cc); 21486 // is_var_args: bool 21487 ensure_field_index(fn_decl_val->type, "is_var_args", 3); 21488 bool is_varargs = fn_node->is_var_args; 21489 fn_decl_fields[3]->special = ConstValSpecialStatic; 21490 fn_decl_fields[3]->type = ira->codegen->builtin_types.entry_bool; 21491 fn_decl_fields[3]->data.x_bool = is_varargs; 21492 // is_extern: bool 21493 ensure_field_index(fn_decl_val->type, "is_extern", 4); 21494 fn_decl_fields[4]->special = ConstValSpecialStatic; 21495 fn_decl_fields[4]->type = ira->codegen->builtin_types.entry_bool; 21496 fn_decl_fields[4]->data.x_bool = fn_node->is_extern; 21497 // is_export: bool 21498 ensure_field_index(fn_decl_val->type, "is_export", 5); 21499 fn_decl_fields[5]->special = ConstValSpecialStatic; 21500 fn_decl_fields[5]->type = ira->codegen->builtin_types.entry_bool; 21501 fn_decl_fields[5]->data.x_bool = fn_node->is_export; 21502 // lib_name: ?[]const u8 21503 ensure_field_index(fn_decl_val->type, "lib_name", 6); 21504 fn_decl_fields[6]->special = ConstValSpecialStatic; 21505 ZigType *u8_ptr = get_pointer_to_type_extra( 21506 ira->codegen, ira->codegen->builtin_types.entry_u8, 21507 true, false, PtrLenUnknown, 21508 0, 0, 0, false); 21509 fn_decl_fields[6]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); 21510 if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) { 21511 fn_decl_fields[6]->data.x_optional = create_const_vals(1); 21512 ZigValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee; 21513 init_const_slice(ira->codegen, fn_decl_fields[6]->data.x_optional, lib_name, 0, 21514 buf_len(fn_node->lib_name), true); 21515 } else { 21516 fn_decl_fields[6]->data.x_optional = nullptr; 21517 } 21518 // return_type: type 21519 ensure_field_index(fn_decl_val->type, "return_type", 7); 21520 fn_decl_fields[7]->special = ConstValSpecialStatic; 21521 fn_decl_fields[7]->type = ira->codegen->builtin_types.entry_type; 21522 fn_decl_fields[7]->data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; 21523 // arg_names: [][] const u8 21524 ensure_field_index(fn_decl_val->type, "arg_names", 8); 21525 size_t fn_arg_count = fn_entry->variable_list.length; 21526 ZigValue *fn_arg_name_array = create_const_vals(1); 21527 fn_arg_name_array->special = ConstValSpecialStatic; 21528 fn_arg_name_array->type = get_array_type(ira->codegen, 21529 get_slice_type(ira->codegen, u8_ptr), fn_arg_count, nullptr); 21530 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; 21531 fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); 21532 21533 init_const_slice(ira->codegen, fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false); 21534 21535 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { 21536 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); 21537 ZigValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index]; 21538 ZigValue *arg_name = create_const_str_lit(ira->codegen, 21539 buf_create_from_str(arg_var->name))->data.x_ptr.data.ref.pointee; 21540 init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, strlen(arg_var->name), true); 21541 fn_arg_name_val->parent.id = ConstParentIdArray; 21542 fn_arg_name_val->parent.data.p_array.array_val = fn_arg_name_array; 21543 fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index; 21544 } 21545 21546 inner_fields[2]->data.x_union.payload = fn_decl_val; 21547 break; 21548 } 21549 case TldIdContainer: 21550 { 21551 ZigType *type_entry = ((TldContainer *)curr_entry->value)->type_entry; 21552 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 21553 return ErrorSemanticAnalyzeFail; 21554 21555 // This is a type. 21556 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0); 21557 21558 ZigValue *payload = create_const_vals(1); 21559 payload->special = ConstValSpecialStatic; 21560 payload->type = ira->codegen->builtin_types.entry_type; 21561 payload->data.x_type = type_entry; 21562 21563 inner_fields[2]->data.x_union.payload = payload; 21564 21565 break; 21566 } 21567 default: 21568 zig_unreachable(); 21569 } 21570 21571 declaration_val->data.x_struct.fields = inner_fields; 21572 declaration_index += 1; 21573 } 21574 21575 assert(declaration_index == declaration_count); 21576 return ErrorNone; 21577 } 21578 21579 static BuiltinPtrSize ptr_len_to_size_enum_index(PtrLen ptr_len) { 21580 switch (ptr_len) { 21581 case PtrLenSingle: 21582 return BuiltinPtrSizeOne; 21583 case PtrLenUnknown: 21584 return BuiltinPtrSizeMany; 21585 case PtrLenC: 21586 return BuiltinPtrSizeC; 21587 } 21588 zig_unreachable(); 21589 } 21590 21591 static PtrLen size_enum_index_to_ptr_len(BuiltinPtrSize size_enum_index) { 21592 switch (size_enum_index) { 21593 case BuiltinPtrSizeOne: 21594 return PtrLenSingle; 21595 case BuiltinPtrSizeMany: 21596 case BuiltinPtrSizeSlice: 21597 return PtrLenUnknown; 21598 case BuiltinPtrSizeC: 21599 return PtrLenC; 21600 } 21601 zig_unreachable(); 21602 } 21603 21604 static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) { 21605 Error err; 21606 ZigType *attrs_type; 21607 BuiltinPtrSize size_enum_index; 21608 if (is_slice(ptr_type_entry)) { 21609 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index]->type_entry; 21610 size_enum_index = BuiltinPtrSizeSlice; 21611 } else if (ptr_type_entry->id == ZigTypeIdPointer) { 21612 attrs_type = ptr_type_entry; 21613 size_enum_index = ptr_len_to_size_enum_index(ptr_type_entry->data.pointer.ptr_len); 21614 } else { 21615 zig_unreachable(); 21616 } 21617 21618 if ((err = type_resolve(ira->codegen, attrs_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 21619 return nullptr; 21620 21621 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 21622 assertNoError(type_resolve(ira->codegen, type_info_pointer_type, ResolveStatusSizeKnown)); 21623 21624 ZigValue *result = create_const_vals(1); 21625 result->special = ConstValSpecialStatic; 21626 result->type = type_info_pointer_type; 21627 21628 ZigValue **fields = alloc_const_vals_ptrs(7); 21629 result->data.x_struct.fields = fields; 21630 21631 // size: Size 21632 ensure_field_index(result->type, "size", 0); 21633 ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); 21634 assertNoError(type_resolve(ira->codegen, type_info_pointer_size_type, ResolveStatusSizeKnown)); 21635 fields[0]->special = ConstValSpecialStatic; 21636 fields[0]->type = type_info_pointer_size_type; 21637 bigint_init_unsigned(&fields[0]->data.x_enum_tag, size_enum_index); 21638 21639 // is_const: bool 21640 ensure_field_index(result->type, "is_const", 1); 21641 fields[1]->special = ConstValSpecialStatic; 21642 fields[1]->type = ira->codegen->builtin_types.entry_bool; 21643 fields[1]->data.x_bool = attrs_type->data.pointer.is_const; 21644 // is_volatile: bool 21645 ensure_field_index(result->type, "is_volatile", 2); 21646 fields[2]->special = ConstValSpecialStatic; 21647 fields[2]->type = ira->codegen->builtin_types.entry_bool; 21648 fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile; 21649 // alignment: u32 21650 ensure_field_index(result->type, "alignment", 3); 21651 fields[3]->special = ConstValSpecialStatic; 21652 fields[3]->type = ira->codegen->builtin_types.entry_num_lit_int; 21653 bigint_init_unsigned(&fields[3]->data.x_bigint, get_ptr_align(ira->codegen, attrs_type)); 21654 // child: type 21655 ensure_field_index(result->type, "child", 4); 21656 fields[4]->special = ConstValSpecialStatic; 21657 fields[4]->type = ira->codegen->builtin_types.entry_type; 21658 fields[4]->data.x_type = attrs_type->data.pointer.child_type; 21659 // is_allowzero: bool 21660 ensure_field_index(result->type, "is_allowzero", 5); 21661 fields[5]->special = ConstValSpecialStatic; 21662 fields[5]->type = ira->codegen->builtin_types.entry_bool; 21663 fields[5]->data.x_bool = attrs_type->data.pointer.allow_zero; 21664 // sentinel: var 21665 ensure_field_index(result->type, "sentinel", 6); 21666 fields[6]->special = ConstValSpecialStatic; 21667 if (attrs_type->data.pointer.sentinel != nullptr) { 21668 fields[6]->type = get_optional_type(ira->codegen, attrs_type->data.pointer.child_type); 21669 fields[6]->data.x_optional = attrs_type->data.pointer.sentinel; 21670 } else { 21671 fields[6]->type = ira->codegen->builtin_types.entry_null; 21672 fields[6]->data.x_optional = nullptr; 21673 } 21674 21675 return result; 21676 }; 21677 21678 static void make_enum_field_val(IrAnalyze *ira, ZigValue *enum_field_val, TypeEnumField *enum_field, 21679 ZigType *type_info_enum_field_type) 21680 { 21681 enum_field_val->special = ConstValSpecialStatic; 21682 enum_field_val->type = type_info_enum_field_type; 21683 21684 ZigValue **inner_fields = alloc_const_vals_ptrs(2); 21685 inner_fields[1]->special = ConstValSpecialStatic; 21686 inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 21687 21688 ZigValue *name = create_const_str_lit(ira->codegen, enum_field->name)->data.x_ptr.data.ref.pointee; 21689 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(enum_field->name), true); 21690 21691 bigint_init_bigint(&inner_fields[1]->data.x_bigint, &enum_field->value); 21692 21693 enum_field_val->data.x_struct.fields = inner_fields; 21694 } 21695 21696 static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr, ZigType *type_entry, 21697 ZigValue **out) 21698 { 21699 Error err; 21700 assert(type_entry != nullptr); 21701 assert(!type_is_invalid(type_entry)); 21702 21703 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 21704 return err; 21705 21706 auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); 21707 if (entry != nullptr) { 21708 *out = entry->value; 21709 return ErrorNone; 21710 } 21711 21712 ZigValue *result = nullptr; 21713 switch (type_entry->id) { 21714 case ZigTypeIdInvalid: 21715 zig_unreachable(); 21716 case ZigTypeIdMetaType: 21717 case ZigTypeIdVoid: 21718 case ZigTypeIdBool: 21719 case ZigTypeIdUnreachable: 21720 case ZigTypeIdComptimeFloat: 21721 case ZigTypeIdComptimeInt: 21722 case ZigTypeIdEnumLiteral: 21723 case ZigTypeIdUndefined: 21724 case ZigTypeIdNull: 21725 case ZigTypeIdArgTuple: 21726 case ZigTypeIdOpaque: 21727 result = ira->codegen->intern.for_void(); 21728 break; 21729 case ZigTypeIdInt: 21730 { 21731 result = create_const_vals(1); 21732 result->special = ConstValSpecialStatic; 21733 result->type = ir_type_info_get_type(ira, "Int", nullptr); 21734 21735 ZigValue **fields = alloc_const_vals_ptrs(2); 21736 result->data.x_struct.fields = fields; 21737 21738 // is_signed: bool 21739 ensure_field_index(result->type, "is_signed", 0); 21740 fields[0]->special = ConstValSpecialStatic; 21741 fields[0]->type = ira->codegen->builtin_types.entry_bool; 21742 fields[0]->data.x_bool = type_entry->data.integral.is_signed; 21743 // bits: u8 21744 ensure_field_index(result->type, "bits", 1); 21745 fields[1]->special = ConstValSpecialStatic; 21746 fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 21747 bigint_init_unsigned(&fields[1]->data.x_bigint, type_entry->data.integral.bit_count); 21748 21749 break; 21750 } 21751 case ZigTypeIdFloat: 21752 { 21753 result = create_const_vals(1); 21754 result->special = ConstValSpecialStatic; 21755 result->type = ir_type_info_get_type(ira, "Float", nullptr); 21756 21757 ZigValue **fields = alloc_const_vals_ptrs(1); 21758 result->data.x_struct.fields = fields; 21759 21760 // bits: u8 21761 ensure_field_index(result->type, "bits", 0); 21762 fields[0]->special = ConstValSpecialStatic; 21763 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 21764 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.floating.bit_count); 21765 21766 break; 21767 } 21768 case ZigTypeIdPointer: 21769 { 21770 result = create_ptr_like_type_info(ira, type_entry); 21771 if (result == nullptr) 21772 return ErrorSemanticAnalyzeFail; 21773 break; 21774 } 21775 case ZigTypeIdArray: 21776 { 21777 result = create_const_vals(1); 21778 result->special = ConstValSpecialStatic; 21779 result->type = ir_type_info_get_type(ira, "Array", nullptr); 21780 21781 ZigValue **fields = alloc_const_vals_ptrs(3); 21782 result->data.x_struct.fields = fields; 21783 21784 // len: usize 21785 ensure_field_index(result->type, "len", 0); 21786 fields[0]->special = ConstValSpecialStatic; 21787 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 21788 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.array.len); 21789 // child: type 21790 ensure_field_index(result->type, "child", 1); 21791 fields[1]->special = ConstValSpecialStatic; 21792 fields[1]->type = ira->codegen->builtin_types.entry_type; 21793 fields[1]->data.x_type = type_entry->data.array.child_type; 21794 // sentinel: var 21795 fields[2]->special = ConstValSpecialStatic; 21796 fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type); 21797 fields[2]->data.x_optional = type_entry->data.array.sentinel; 21798 break; 21799 } 21800 case ZigTypeIdVector: { 21801 result = create_const_vals(1); 21802 result->special = ConstValSpecialStatic; 21803 result->type = ir_type_info_get_type(ira, "Vector", nullptr); 21804 21805 ZigValue **fields = alloc_const_vals_ptrs(2); 21806 result->data.x_struct.fields = fields; 21807 21808 // len: usize 21809 ensure_field_index(result->type, "len", 0); 21810 fields[0]->special = ConstValSpecialStatic; 21811 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 21812 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.vector.len); 21813 // child: type 21814 ensure_field_index(result->type, "child", 1); 21815 fields[1]->special = ConstValSpecialStatic; 21816 fields[1]->type = ira->codegen->builtin_types.entry_type; 21817 fields[1]->data.x_type = type_entry->data.vector.elem_type; 21818 21819 break; 21820 } 21821 case ZigTypeIdOptional: 21822 { 21823 result = create_const_vals(1); 21824 result->special = ConstValSpecialStatic; 21825 result->type = ir_type_info_get_type(ira, "Optional", nullptr); 21826 21827 ZigValue **fields = alloc_const_vals_ptrs(1); 21828 result->data.x_struct.fields = fields; 21829 21830 // child: type 21831 ensure_field_index(result->type, "child", 0); 21832 fields[0]->special = ConstValSpecialStatic; 21833 fields[0]->type = ira->codegen->builtin_types.entry_type; 21834 fields[0]->data.x_type = type_entry->data.maybe.child_type; 21835 21836 break; 21837 } 21838 case ZigTypeIdAnyFrame: { 21839 result = create_const_vals(1); 21840 result->special = ConstValSpecialStatic; 21841 result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr); 21842 21843 ZigValue **fields = alloc_const_vals_ptrs(1); 21844 result->data.x_struct.fields = fields; 21845 21846 // child: ?type 21847 ensure_field_index(result->type, "child", 0); 21848 fields[0]->special = ConstValSpecialStatic; 21849 fields[0]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 21850 fields[0]->data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr : 21851 create_const_type(ira->codegen, type_entry->data.any_frame.result_type); 21852 break; 21853 } 21854 case ZigTypeIdEnum: 21855 { 21856 result = create_const_vals(1); 21857 result->special = ConstValSpecialStatic; 21858 result->type = ir_type_info_get_type(ira, "Enum", nullptr); 21859 21860 ZigValue **fields = alloc_const_vals_ptrs(4); 21861 result->data.x_struct.fields = fields; 21862 21863 // layout: ContainerLayout 21864 ensure_field_index(result->type, "layout", 0); 21865 fields[0]->special = ConstValSpecialStatic; 21866 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 21867 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.enumeration.layout); 21868 // tag_type: type 21869 ensure_field_index(result->type, "tag_type", 1); 21870 fields[1]->special = ConstValSpecialStatic; 21871 fields[1]->type = ira->codegen->builtin_types.entry_type; 21872 fields[1]->data.x_type = type_entry->data.enumeration.tag_int_type; 21873 // fields: []TypeInfo.EnumField 21874 ensure_field_index(result->type, "fields", 2); 21875 21876 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 21877 if ((err = type_resolve(ira->codegen, type_info_enum_field_type, ResolveStatusSizeKnown))) { 21878 zig_unreachable(); 21879 } 21880 uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; 21881 21882 ZigValue *enum_field_array = create_const_vals(1); 21883 enum_field_array->special = ConstValSpecialStatic; 21884 enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count, nullptr); 21885 enum_field_array->data.x_array.special = ConstArraySpecialNone; 21886 enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count); 21887 21888 init_const_slice(ira->codegen, fields[2], enum_field_array, 0, enum_field_count, false); 21889 21890 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) 21891 { 21892 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; 21893 ZigValue *enum_field_val = &enum_field_array->data.x_array.data.s_none.elements[enum_field_index]; 21894 make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type); 21895 enum_field_val->parent.id = ConstParentIdArray; 21896 enum_field_val->parent.data.p_array.array_val = enum_field_array; 21897 enum_field_val->parent.data.p_array.elem_index = enum_field_index; 21898 } 21899 // decls: []TypeInfo.Declaration 21900 ensure_field_index(result->type, "decls", 3); 21901 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3], 21902 type_entry->data.enumeration.decls_scope))) 21903 { 21904 return err; 21905 } 21906 21907 break; 21908 } 21909 case ZigTypeIdErrorSet: 21910 { 21911 result = create_const_vals(1); 21912 result->special = ConstValSpecialStatic; 21913 result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr); 21914 21915 ZigType *type_info_error_type = ir_type_info_get_type(ira, "Error", nullptr); 21916 if (!resolve_inferred_error_set(ira->codegen, type_entry, source_instr->source_node)) { 21917 return ErrorSemanticAnalyzeFail; 21918 } 21919 if (type_is_global_error_set(type_entry)) { 21920 result->data.x_optional = nullptr; 21921 break; 21922 } 21923 if ((err = type_resolve(ira->codegen, type_info_error_type, ResolveStatusSizeKnown))) { 21924 zig_unreachable(); 21925 } 21926 ZigValue *slice_val = create_const_vals(1); 21927 result->data.x_optional = slice_val; 21928 21929 uint32_t error_count = type_entry->data.error_set.err_count; 21930 ZigValue *error_array = create_const_vals(1); 21931 error_array->special = ConstValSpecialStatic; 21932 error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count, nullptr); 21933 error_array->data.x_array.special = ConstArraySpecialNone; 21934 error_array->data.x_array.data.s_none.elements = create_const_vals(error_count); 21935 21936 init_const_slice(ira->codegen, slice_val, error_array, 0, error_count, false); 21937 for (uint32_t error_index = 0; error_index < error_count; error_index++) { 21938 ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; 21939 ZigValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index]; 21940 21941 error_val->special = ConstValSpecialStatic; 21942 error_val->type = type_info_error_type; 21943 21944 ZigValue **inner_fields = alloc_const_vals_ptrs(2); 21945 inner_fields[1]->special = ConstValSpecialStatic; 21946 inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 21947 21948 ZigValue *name = nullptr; 21949 if (error->cached_error_name_val != nullptr) 21950 name = error->cached_error_name_val; 21951 if (name == nullptr) 21952 name = create_const_str_lit(ira->codegen, &error->name)->data.x_ptr.data.ref.pointee; 21953 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(&error->name), true); 21954 bigint_init_unsigned(&inner_fields[1]->data.x_bigint, error->value); 21955 21956 error_val->data.x_struct.fields = inner_fields; 21957 error_val->parent.id = ConstParentIdArray; 21958 error_val->parent.data.p_array.array_val = error_array; 21959 error_val->parent.data.p_array.elem_index = error_index; 21960 } 21961 21962 break; 21963 } 21964 case ZigTypeIdErrorUnion: 21965 { 21966 result = create_const_vals(1); 21967 result->special = ConstValSpecialStatic; 21968 result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr); 21969 21970 ZigValue **fields = alloc_const_vals_ptrs(2); 21971 result->data.x_struct.fields = fields; 21972 21973 // error_set: type 21974 ensure_field_index(result->type, "error_set", 0); 21975 fields[0]->special = ConstValSpecialStatic; 21976 fields[0]->type = ira->codegen->builtin_types.entry_type; 21977 fields[0]->data.x_type = type_entry->data.error_union.err_set_type; 21978 21979 // payload: type 21980 ensure_field_index(result->type, "payload", 1); 21981 fields[1]->special = ConstValSpecialStatic; 21982 fields[1]->type = ira->codegen->builtin_types.entry_type; 21983 fields[1]->data.x_type = type_entry->data.error_union.payload_type; 21984 21985 break; 21986 } 21987 case ZigTypeIdUnion: 21988 { 21989 result = create_const_vals(1); 21990 result->special = ConstValSpecialStatic; 21991 result->type = ir_type_info_get_type(ira, "Union", nullptr); 21992 21993 ZigValue **fields = alloc_const_vals_ptrs(4); 21994 result->data.x_struct.fields = fields; 21995 21996 // layout: ContainerLayout 21997 ensure_field_index(result->type, "layout", 0); 21998 fields[0]->special = ConstValSpecialStatic; 21999 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 22000 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.unionation.layout); 22001 // tag_type: ?type 22002 ensure_field_index(result->type, "tag_type", 1); 22003 fields[1]->special = ConstValSpecialStatic; 22004 fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 22005 22006 AstNode *union_decl_node = type_entry->data.unionation.decl_node; 22007 if (union_decl_node->data.container_decl.auto_enum || 22008 union_decl_node->data.container_decl.init_arg_expr != nullptr) 22009 { 22010 ZigValue *tag_type = create_const_vals(1); 22011 tag_type->special = ConstValSpecialStatic; 22012 tag_type->type = ira->codegen->builtin_types.entry_type; 22013 tag_type->data.x_type = type_entry->data.unionation.tag_type; 22014 fields[1]->data.x_optional = tag_type; 22015 } else { 22016 fields[1]->data.x_optional = nullptr; 22017 } 22018 // fields: []TypeInfo.UnionField 22019 ensure_field_index(result->type, "fields", 2); 22020 22021 ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); 22022 if ((err = type_resolve(ira->codegen, type_info_union_field_type, ResolveStatusSizeKnown))) 22023 zig_unreachable(); 22024 uint32_t union_field_count = type_entry->data.unionation.src_field_count; 22025 22026 ZigValue *union_field_array = create_const_vals(1); 22027 union_field_array->special = ConstValSpecialStatic; 22028 union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count, nullptr); 22029 union_field_array->data.x_array.special = ConstArraySpecialNone; 22030 union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count); 22031 22032 init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false); 22033 22034 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 22035 22036 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { 22037 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; 22038 ZigValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index]; 22039 22040 union_field_val->special = ConstValSpecialStatic; 22041 union_field_val->type = type_info_union_field_type; 22042 22043 ZigValue **inner_fields = alloc_const_vals_ptrs(3); 22044 inner_fields[1]->special = ConstValSpecialStatic; 22045 inner_fields[1]->type = get_optional_type(ira->codegen, type_info_enum_field_type); 22046 22047 if (fields[1]->data.x_optional == nullptr) { 22048 inner_fields[1]->data.x_optional = nullptr; 22049 } else { 22050 inner_fields[1]->data.x_optional = create_const_vals(1); 22051 make_enum_field_val(ira, inner_fields[1]->data.x_optional, union_field->enum_field, type_info_enum_field_type); 22052 } 22053 22054 inner_fields[2]->special = ConstValSpecialStatic; 22055 inner_fields[2]->type = ira->codegen->builtin_types.entry_type; 22056 inner_fields[2]->data.x_type = union_field->type_entry; 22057 22058 ZigValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee; 22059 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true); 22060 22061 union_field_val->data.x_struct.fields = inner_fields; 22062 union_field_val->parent.id = ConstParentIdArray; 22063 union_field_val->parent.data.p_array.array_val = union_field_array; 22064 union_field_val->parent.data.p_array.elem_index = union_field_index; 22065 } 22066 // decls: []TypeInfo.Declaration 22067 ensure_field_index(result->type, "decls", 3); 22068 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3], 22069 type_entry->data.unionation.decls_scope))) 22070 { 22071 return err; 22072 } 22073 22074 break; 22075 } 22076 case ZigTypeIdStruct: 22077 { 22078 if (type_entry->data.structure.is_slice) { 22079 result = create_ptr_like_type_info(ira, type_entry); 22080 if (result == nullptr) 22081 return ErrorSemanticAnalyzeFail; 22082 break; 22083 } 22084 22085 result = create_const_vals(1); 22086 result->special = ConstValSpecialStatic; 22087 result->type = ir_type_info_get_type(ira, "Struct", nullptr); 22088 22089 ZigValue **fields = alloc_const_vals_ptrs(3); 22090 result->data.x_struct.fields = fields; 22091 22092 // layout: ContainerLayout 22093 ensure_field_index(result->type, "layout", 0); 22094 fields[0]->special = ConstValSpecialStatic; 22095 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 22096 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.structure.layout); 22097 // fields: []TypeInfo.StructField 22098 ensure_field_index(result->type, "fields", 1); 22099 22100 ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); 22101 if ((err = type_resolve(ira->codegen, type_info_struct_field_type, ResolveStatusSizeKnown))) { 22102 zig_unreachable(); 22103 } 22104 uint32_t struct_field_count = type_entry->data.structure.src_field_count; 22105 22106 ZigValue *struct_field_array = create_const_vals(1); 22107 struct_field_array->special = ConstValSpecialStatic; 22108 struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count, nullptr); 22109 struct_field_array->data.x_array.special = ConstArraySpecialNone; 22110 struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count); 22111 22112 init_const_slice(ira->codegen, fields[1], struct_field_array, 0, struct_field_count, false); 22113 22114 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { 22115 TypeStructField *struct_field = type_entry->data.structure.fields[struct_field_index]; 22116 ZigValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index]; 22117 22118 struct_field_val->special = ConstValSpecialStatic; 22119 struct_field_val->type = type_info_struct_field_type; 22120 22121 ZigValue **inner_fields = alloc_const_vals_ptrs(3); 22122 inner_fields[1]->special = ConstValSpecialStatic; 22123 inner_fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int); 22124 22125 ZigType *field_type = resolve_struct_field_type(ira->codegen, struct_field); 22126 if (field_type == nullptr) 22127 return ErrorSemanticAnalyzeFail; 22128 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) 22129 return err; 22130 if (!type_has_bits(struct_field->type_entry)) { 22131 inner_fields[1]->data.x_optional = nullptr; 22132 } else { 22133 size_t byte_offset = struct_field->offset; 22134 inner_fields[1]->data.x_optional = create_const_vals(1); 22135 inner_fields[1]->data.x_optional->special = ConstValSpecialStatic; 22136 inner_fields[1]->data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int; 22137 bigint_init_unsigned(&inner_fields[1]->data.x_optional->data.x_bigint, byte_offset); 22138 } 22139 22140 inner_fields[2]->special = ConstValSpecialStatic; 22141 inner_fields[2]->type = ira->codegen->builtin_types.entry_type; 22142 inner_fields[2]->data.x_type = struct_field->type_entry; 22143 22144 ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee; 22145 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true); 22146 22147 struct_field_val->data.x_struct.fields = inner_fields; 22148 struct_field_val->parent.id = ConstParentIdArray; 22149 struct_field_val->parent.data.p_array.array_val = struct_field_array; 22150 struct_field_val->parent.data.p_array.elem_index = struct_field_index; 22151 } 22152 // decls: []TypeInfo.Declaration 22153 ensure_field_index(result->type, "decls", 2); 22154 if ((err = ir_make_type_info_decls(ira, source_instr, fields[2], 22155 type_entry->data.structure.decls_scope))) 22156 { 22157 return err; 22158 } 22159 22160 break; 22161 } 22162 case ZigTypeIdFn: 22163 { 22164 result = create_const_vals(1); 22165 result->special = ConstValSpecialStatic; 22166 result->type = ir_type_info_get_type(ira, "Fn", nullptr); 22167 22168 ZigValue **fields = alloc_const_vals_ptrs(5); 22169 result->data.x_struct.fields = fields; 22170 22171 // calling_convention: TypeInfo.CallingConvention 22172 ensure_field_index(result->type, "calling_convention", 0); 22173 fields[0]->special = ConstValSpecialStatic; 22174 fields[0]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr); 22175 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); 22176 // is_generic: bool 22177 ensure_field_index(result->type, "is_generic", 1); 22178 bool is_generic = type_entry->data.fn.is_generic; 22179 fields[1]->special = ConstValSpecialStatic; 22180 fields[1]->type = ira->codegen->builtin_types.entry_bool; 22181 fields[1]->data.x_bool = is_generic; 22182 // is_varargs: bool 22183 ensure_field_index(result->type, "is_var_args", 2); 22184 bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; 22185 fields[2]->special = ConstValSpecialStatic; 22186 fields[2]->type = ira->codegen->builtin_types.entry_bool; 22187 fields[2]->data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; 22188 // return_type: ?type 22189 ensure_field_index(result->type, "return_type", 3); 22190 fields[3]->special = ConstValSpecialStatic; 22191 fields[3]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 22192 if (type_entry->data.fn.fn_type_id.return_type == nullptr) 22193 fields[3]->data.x_optional = nullptr; 22194 else { 22195 ZigValue *return_type = create_const_vals(1); 22196 return_type->special = ConstValSpecialStatic; 22197 return_type->type = ira->codegen->builtin_types.entry_type; 22198 return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; 22199 fields[3]->data.x_optional = return_type; 22200 } 22201 // args: []TypeInfo.FnArg 22202 ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); 22203 if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { 22204 zig_unreachable(); 22205 } 22206 size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - 22207 (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); 22208 22209 ZigValue *fn_arg_array = create_const_vals(1); 22210 fn_arg_array->special = ConstValSpecialStatic; 22211 fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count, nullptr); 22212 fn_arg_array->data.x_array.special = ConstArraySpecialNone; 22213 fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); 22214 22215 init_const_slice(ira->codegen, fields[4], fn_arg_array, 0, fn_arg_count, false); 22216 22217 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { 22218 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; 22219 ZigValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index]; 22220 22221 fn_arg_val->special = ConstValSpecialStatic; 22222 fn_arg_val->type = type_info_fn_arg_type; 22223 22224 bool arg_is_generic = fn_param_info->type == nullptr; 22225 if (arg_is_generic) assert(is_generic); 22226 22227 ZigValue **inner_fields = alloc_const_vals_ptrs(3); 22228 inner_fields[0]->special = ConstValSpecialStatic; 22229 inner_fields[0]->type = ira->codegen->builtin_types.entry_bool; 22230 inner_fields[0]->data.x_bool = arg_is_generic; 22231 inner_fields[1]->special = ConstValSpecialStatic; 22232 inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; 22233 inner_fields[1]->data.x_bool = fn_param_info->is_noalias; 22234 inner_fields[2]->special = ConstValSpecialStatic; 22235 inner_fields[2]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 22236 22237 if (arg_is_generic) 22238 inner_fields[2]->data.x_optional = nullptr; 22239 else { 22240 ZigValue *arg_type = create_const_vals(1); 22241 arg_type->special = ConstValSpecialStatic; 22242 arg_type->type = ira->codegen->builtin_types.entry_type; 22243 arg_type->data.x_type = fn_param_info->type; 22244 inner_fields[2]->data.x_optional = arg_type; 22245 } 22246 22247 fn_arg_val->data.x_struct.fields = inner_fields; 22248 fn_arg_val->parent.id = ConstParentIdArray; 22249 fn_arg_val->parent.data.p_array.array_val = fn_arg_array; 22250 fn_arg_val->parent.data.p_array.elem_index = fn_arg_index; 22251 } 22252 22253 break; 22254 } 22255 case ZigTypeIdBoundFn: 22256 { 22257 ZigType *fn_type = type_entry->data.bound_fn.fn_type; 22258 assert(fn_type->id == ZigTypeIdFn); 22259 if ((err = ir_make_type_info_value(ira, source_instr, fn_type, &result))) 22260 return err; 22261 22262 break; 22263 } 22264 case ZigTypeIdFnFrame: 22265 zig_panic("TODO @typeInfo for async function frames"); 22266 } 22267 22268 assert(result != nullptr); 22269 ira->codegen->type_info_cache.put(type_entry, result); 22270 *out = result; 22271 return ErrorNone; 22272 } 22273 22274 static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira, 22275 IrInstructionTypeInfo *instruction) 22276 { 22277 Error err; 22278 IrInstruction *type_value = instruction->type_value->child; 22279 ZigType *type_entry = ir_resolve_type(ira, type_value); 22280 if (type_is_invalid(type_entry)) 22281 return ira->codegen->invalid_instruction; 22282 22283 ZigType *result_type = ir_type_info_get_type(ira, nullptr, nullptr); 22284 22285 ZigValue *payload; 22286 if ((err = ir_make_type_info_value(ira, &instruction->base, type_entry, &payload))) 22287 return ira->codegen->invalid_instruction; 22288 22289 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 22290 ZigValue *out_val = result->value; 22291 bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry)); 22292 out_val->data.x_union.payload = payload; 22293 22294 if (payload != nullptr) { 22295 payload->parent.id = ConstParentIdUnion; 22296 payload->parent.data.p_union.union_val = out_val; 22297 } 22298 22299 return result; 22300 } 22301 22302 static ZigValue *get_const_field(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, 22303 const char *name, size_t field_index) 22304 { 22305 Error err; 22306 ensure_field_index(struct_value->type, name, field_index); 22307 ZigValue *val = struct_value->data.x_struct.fields[field_index]; 22308 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_node, val, UndefBad))) 22309 return nullptr; 22310 return val; 22311 } 22312 22313 static Error get_const_field_sentinel(IrAnalyze *ira, IrInstruction *source_instr, ZigValue *struct_value, 22314 const char *name, size_t field_index, ZigType *elem_type, ZigValue **result) 22315 { 22316 ZigValue *field_val = get_const_field(ira, source_instr->source_node, struct_value, name, field_index); 22317 if (field_val == nullptr) 22318 return ErrorSemanticAnalyzeFail; 22319 IrInstruction *field_inst = ir_const(ira, source_instr, field_val->type); 22320 IrInstruction *casted_field_inst = ir_implicit_cast(ira, field_inst, 22321 get_optional_type(ira->codegen, elem_type)); 22322 if (type_is_invalid(casted_field_inst->value->type)) 22323 return ErrorSemanticAnalyzeFail; 22324 22325 *result = casted_field_inst->value->data.x_optional; 22326 return ErrorNone; 22327 } 22328 22329 static Error get_const_field_bool(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, 22330 const char *name, size_t field_index, bool *out) 22331 { 22332 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 22333 if (value == nullptr) 22334 return ErrorSemanticAnalyzeFail; 22335 assert(value->type == ira->codegen->builtin_types.entry_bool); 22336 *out = value->data.x_bool; 22337 return ErrorNone; 22338 } 22339 22340 static BigInt *get_const_field_lit_int(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) 22341 { 22342 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 22343 if (value == nullptr) 22344 return nullptr; 22345 assert(value->type == ira->codegen->builtin_types.entry_num_lit_int); 22346 return &value->data.x_bigint; 22347 } 22348 22349 static ZigType *get_const_field_meta_type(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) 22350 { 22351 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 22352 if (value == nullptr) 22353 return ira->codegen->invalid_instruction->value->type; 22354 assert(value->type == ira->codegen->builtin_types.entry_type); 22355 return value->data.x_type; 22356 } 22357 22358 static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, ZigTypeId tagTypeId, ZigValue *payload) { 22359 Error err; 22360 switch (tagTypeId) { 22361 case ZigTypeIdInvalid: 22362 zig_unreachable(); 22363 case ZigTypeIdMetaType: 22364 return ira->codegen->builtin_types.entry_type; 22365 case ZigTypeIdVoid: 22366 return ira->codegen->builtin_types.entry_void; 22367 case ZigTypeIdBool: 22368 return ira->codegen->builtin_types.entry_bool; 22369 case ZigTypeIdUnreachable: 22370 return ira->codegen->builtin_types.entry_unreachable; 22371 case ZigTypeIdInt: { 22372 assert(payload->special == ConstValSpecialStatic); 22373 assert(payload->type == ir_type_info_get_type(ira, "Int", nullptr)); 22374 BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "bits", 1); 22375 if (bi == nullptr) 22376 return ira->codegen->invalid_instruction->value->type; 22377 bool is_signed; 22378 if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_signed", 0, &is_signed))) 22379 return ira->codegen->invalid_instruction->value->type; 22380 return get_int_type(ira->codegen, is_signed, bigint_as_u32(bi)); 22381 } 22382 case ZigTypeIdFloat: 22383 { 22384 assert(payload->special == ConstValSpecialStatic); 22385 assert(payload->type == ir_type_info_get_type(ira, "Float", nullptr)); 22386 BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "bits", 0); 22387 if (bi == nullptr) 22388 return ira->codegen->invalid_instruction->value->type; 22389 uint32_t bits = bigint_as_u32(bi); 22390 switch (bits) { 22391 case 16: return ira->codegen->builtin_types.entry_f16; 22392 case 32: return ira->codegen->builtin_types.entry_f32; 22393 case 64: return ira->codegen->builtin_types.entry_f64; 22394 case 128: return ira->codegen->builtin_types.entry_f128; 22395 } 22396 ir_add_error(ira, instruction, 22397 buf_sprintf("%d-bit float unsupported", bits)); 22398 return nullptr; 22399 } 22400 case ZigTypeIdPointer: 22401 { 22402 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 22403 assert(payload->special == ConstValSpecialStatic); 22404 assert(payload->type == type_info_pointer_type); 22405 ZigValue *size_value = get_const_field(ira, instruction->source_node, payload, "size", 0); 22406 assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type)); 22407 BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag); 22408 PtrLen ptr_len = size_enum_index_to_ptr_len(size_enum_index); 22409 ZigType *elem_type = get_const_field_meta_type(ira, instruction->source_node, payload, "child", 4); 22410 if (type_is_invalid(elem_type)) 22411 return ira->codegen->invalid_instruction->value->type; 22412 ZigValue *sentinel; 22413 if ((err = get_const_field_sentinel(ira, instruction, payload, "sentinel", 6, 22414 elem_type, &sentinel))) 22415 { 22416 return ira->codegen->invalid_instruction->value->type; 22417 } 22418 BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "alignment", 3); 22419 if (bi == nullptr) 22420 return ira->codegen->invalid_instruction->value->type; 22421 22422 bool is_const; 22423 if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_const", 1, &is_const))) 22424 return ira->codegen->invalid_instruction->value->type; 22425 22426 bool is_volatile; 22427 if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_volatile", 2, 22428 &is_volatile))) 22429 { 22430 return ira->codegen->invalid_instruction->value->type; 22431 } 22432 22433 bool is_allowzero; 22434 if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_allowzero", 5, 22435 &is_allowzero))) 22436 { 22437 return ira->codegen->invalid_instruction->value->type; 22438 } 22439 22440 22441 ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, 22442 elem_type, 22443 is_const, 22444 is_volatile, 22445 ptr_len, 22446 bigint_as_u32(bi), 22447 0, // bit_offset_in_host 22448 0, // host_int_bytes 22449 is_allowzero, 22450 VECTOR_INDEX_NONE, nullptr, sentinel); 22451 if (size_enum_index != 2) 22452 return ptr_type; 22453 return get_slice_type(ira->codegen, ptr_type); 22454 } 22455 case ZigTypeIdArray: { 22456 assert(payload->special == ConstValSpecialStatic); 22457 assert(payload->type == ir_type_info_get_type(ira, "Array", nullptr)); 22458 ZigType *elem_type = get_const_field_meta_type(ira, instruction->source_node, payload, "child", 1); 22459 if (type_is_invalid(elem_type)) 22460 return ira->codegen->invalid_instruction->value->type; 22461 ZigValue *sentinel; 22462 if ((err = get_const_field_sentinel(ira, instruction, payload, "sentinel", 2, 22463 elem_type, &sentinel))) 22464 { 22465 return ira->codegen->invalid_instruction->value->type; 22466 } 22467 BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "len", 0); 22468 if (bi == nullptr) 22469 return ira->codegen->invalid_instruction->value->type; 22470 return get_array_type(ira->codegen, elem_type, bigint_as_u64(bi), sentinel); 22471 } 22472 case ZigTypeIdComptimeFloat: 22473 return ira->codegen->builtin_types.entry_num_lit_float; 22474 case ZigTypeIdComptimeInt: 22475 return ira->codegen->builtin_types.entry_num_lit_int; 22476 case ZigTypeIdUndefined: 22477 return ira->codegen->builtin_types.entry_undef; 22478 case ZigTypeIdNull: 22479 return ira->codegen->builtin_types.entry_null; 22480 case ZigTypeIdOptional: 22481 case ZigTypeIdErrorUnion: 22482 case ZigTypeIdErrorSet: 22483 case ZigTypeIdEnum: 22484 case ZigTypeIdOpaque: 22485 case ZigTypeIdFnFrame: 22486 case ZigTypeIdAnyFrame: 22487 case ZigTypeIdVector: 22488 case ZigTypeIdEnumLiteral: 22489 ir_add_error(ira, instruction, buf_sprintf( 22490 "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId))); 22491 return ira->codegen->invalid_instruction->value->type; 22492 case ZigTypeIdUnion: 22493 case ZigTypeIdFn: 22494 case ZigTypeIdBoundFn: 22495 case ZigTypeIdArgTuple: 22496 case ZigTypeIdStruct: 22497 ir_add_error(ira, instruction, buf_sprintf( 22498 "@Type not availble for 'TypeInfo.%s'", type_id_name(tagTypeId))); 22499 return ira->codegen->invalid_instruction->value->type; 22500 } 22501 zig_unreachable(); 22502 } 22503 22504 static IrInstruction *ir_analyze_instruction_type(IrAnalyze *ira, IrInstructionType *instruction) { 22505 IrInstruction *type_info_ir = instruction->type_info->child; 22506 if (type_is_invalid(type_info_ir->value->type)) 22507 return ira->codegen->invalid_instruction; 22508 22509 IrInstruction *casted_ir = ir_implicit_cast(ira, type_info_ir, ir_type_info_get_type(ira, nullptr, nullptr)); 22510 if (type_is_invalid(casted_ir->value->type)) 22511 return ira->codegen->invalid_instruction; 22512 22513 ZigValue *type_info_value = ir_resolve_const(ira, casted_ir, UndefBad); 22514 if (!type_info_value) 22515 return ira->codegen->invalid_instruction; 22516 ZigTypeId typeId = type_id_at_index(bigint_as_usize(&type_info_value->data.x_union.tag)); 22517 ZigType *type = type_info_to_type(ira, type_info_ir, typeId, type_info_value->data.x_union.payload); 22518 if (type_is_invalid(type)) 22519 return ira->codegen->invalid_instruction; 22520 return ir_const_type(ira, &instruction->base, type); 22521 } 22522 22523 static IrInstruction *ir_analyze_instruction_type_id(IrAnalyze *ira, 22524 IrInstructionTypeId *instruction) 22525 { 22526 IrInstruction *type_value = instruction->type_value->child; 22527 ZigType *type_entry = ir_resolve_type(ira, type_value); 22528 if (type_is_invalid(type_entry)) 22529 return ira->codegen->invalid_instruction; 22530 22531 ZigValue *var_value = get_builtin_value(ira->codegen, "TypeId"); 22532 assert(var_value->type->id == ZigTypeIdMetaType); 22533 ZigType *result_type = var_value->data.x_type; 22534 22535 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 22536 bigint_init_unsigned(&result->value->data.x_enum_tag, type_id_index(type_entry)); 22537 return result; 22538 } 22539 22540 static IrInstruction *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira, 22541 IrInstructionSetEvalBranchQuota *instruction) 22542 { 22543 uint64_t new_quota; 22544 if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota)) 22545 return ira->codegen->invalid_instruction; 22546 22547 if (new_quota > *ira->new_irb.exec->backward_branch_quota) { 22548 *ira->new_irb.exec->backward_branch_quota = new_quota; 22549 } 22550 22551 return ir_const_void(ira, &instruction->base); 22552 } 22553 22554 static IrInstruction *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) { 22555 IrInstruction *type_value = instruction->type_value->child; 22556 ZigType *type_entry = ir_resolve_type(ira, type_value); 22557 if (type_is_invalid(type_entry)) 22558 return ira->codegen->invalid_instruction; 22559 22560 if (!type_entry->cached_const_name_val) { 22561 type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, type_bare_name(type_entry)); 22562 } 22563 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 22564 copy_const_val(result->value, type_entry->cached_const_name_val, true); 22565 return result; 22566 } 22567 22568 static void ir_cimport_cache_paths(Buf *cache_dir, Buf *tmp_c_file_digest, Buf *out_zig_dir, Buf *out_zig_path) { 22569 buf_resize(out_zig_dir, 0); 22570 buf_resize(out_zig_path, 0); 22571 buf_appendf(out_zig_dir, "%s" OS_SEP "o" OS_SEP "%s", 22572 buf_ptr(cache_dir), buf_ptr(tmp_c_file_digest)); 22573 buf_appendf(out_zig_path, "%s" OS_SEP "cimport.zig", buf_ptr(out_zig_dir)); 22574 } 22575 static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCImport *instruction) { 22576 Error err; 22577 AstNode *node = instruction->base.source_node; 22578 assert(node->type == NodeTypeFnCallExpr); 22579 AstNode *block_node = node->data.fn_call_expr.params.at(0); 22580 22581 ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.scope); 22582 22583 // Execute the C import block like an inline function 22584 ZigType *void_type = ira->codegen->builtin_types.entry_void; 22585 ZigValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, 22586 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, 22587 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, UndefBad); 22588 if (type_is_invalid(cimport_result->type)) 22589 return ira->codegen->invalid_instruction; 22590 22591 ZigPackage *cur_scope_pkg = scope_package(instruction->base.scope); 22592 Buf *namespace_name = buf_sprintf("%s.cimport:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, 22593 buf_ptr(&cur_scope_pkg->pkg_path), node->line + 1, node->column + 1); 22594 22595 ZigPackage *cimport_pkg = new_anonymous_package(); 22596 cimport_pkg->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package); 22597 cimport_pkg->package_table.put(buf_create_from_str("std"), ira->codegen->std_package); 22598 buf_init_from_buf(&cimport_pkg->pkg_path, namespace_name); 22599 22600 CacheHash *cache_hash; 22601 if ((err = create_c_object_cache(ira->codegen, &cache_hash, false))) { 22602 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to create cache: %s", err_str(err))); 22603 return ira->codegen->invalid_instruction; 22604 } 22605 cache_buf(cache_hash, &cimport_scope->buf); 22606 22607 // Set this because we're not adding any files before checking for a hit. 22608 cache_hash->force_check_manifest = true; 22609 22610 Buf tmp_c_file_digest = BUF_INIT; 22611 buf_resize(&tmp_c_file_digest, 0); 22612 if ((err = cache_hit(cache_hash, &tmp_c_file_digest))) { 22613 if (err != ErrorInvalidFormat) { 22614 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to check cache: %s", err_str(err))); 22615 return ira->codegen->invalid_instruction; 22616 } 22617 } 22618 ira->codegen->caches_to_release.append(cache_hash); 22619 22620 Buf *out_zig_dir = buf_alloc(); 22621 Buf *out_zig_path = buf_alloc(); 22622 if (buf_len(&tmp_c_file_digest) == 0 || cache_hash->files.length == 0) { 22623 // Cache Miss 22624 Buf *tmp_c_file_dir = buf_sprintf("%s" OS_SEP "o" OS_SEP "%s", 22625 buf_ptr(ira->codegen->cache_dir), buf_ptr(&cache_hash->b64_digest)); 22626 Buf *resolve_paths[] = { 22627 tmp_c_file_dir, 22628 buf_create_from_str("cimport.h"), 22629 }; 22630 Buf tmp_c_file_path = os_path_resolve(resolve_paths, 2); 22631 22632 if ((err = os_make_path(tmp_c_file_dir))) { 22633 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); 22634 return ira->codegen->invalid_instruction; 22635 } 22636 22637 if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { 22638 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); 22639 return ira->codegen->invalid_instruction; 22640 } 22641 if (ira->codegen->verbose_cimport) { 22642 fprintf(stderr, "@cImport source: %s\n", buf_ptr(&tmp_c_file_path)); 22643 } 22644 22645 Buf *tmp_dep_file = buf_sprintf("%s.d", buf_ptr(&tmp_c_file_path)); 22646 22647 ZigList<const char *> clang_argv = {0}; 22648 22649 add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true); 22650 22651 clang_argv.append(buf_ptr(&tmp_c_file_path)); 22652 22653 if (ira->codegen->verbose_cc) { 22654 fprintf(stderr, "clang"); 22655 for (size_t i = 0; i < clang_argv.length; i += 1) { 22656 fprintf(stderr, " %s", clang_argv.at(i)); 22657 } 22658 fprintf(stderr, "\n"); 22659 } 22660 22661 clang_argv.append(nullptr); // to make the [start...end] argument work 22662 22663 AstNode *root_node; 22664 Stage2ErrorMsg *errors_ptr; 22665 size_t errors_len; 22666 22667 const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir); 22668 22669 if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len, 22670 &clang_argv.at(0), &clang_argv.last(), Stage2TranslateModeImport, resources_path))) 22671 { 22672 if (err != ErrorCCompileErrors) { 22673 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); 22674 return ira->codegen->invalid_instruction; 22675 } 22676 22677 ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed")); 22678 if (ira->codegen->libc_link_lib == nullptr) { 22679 add_error_note(ira->codegen, parent_err_msg, node, 22680 buf_sprintf("libc headers not available; compilation does not link against libc")); 22681 } 22682 for (size_t i = 0; i < errors_len; i += 1) { 22683 Stage2ErrorMsg *clang_err = &errors_ptr[i]; 22684 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null 22685 if (clang_err->source && clang_err->filename_ptr) { 22686 ErrorMsg *err_msg = err_msg_create_with_offset( 22687 clang_err->filename_ptr ? 22688 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), 22689 clang_err->line, clang_err->column, clang_err->offset, clang_err->source, 22690 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); 22691 err_msg_add_note(parent_err_msg, err_msg); 22692 } 22693 } 22694 22695 return ira->codegen->invalid_instruction; 22696 } 22697 if (ira->codegen->verbose_cimport) { 22698 fprintf(stderr, "@cImport .d file: %s\n", buf_ptr(tmp_dep_file)); 22699 } 22700 22701 if ((err = cache_add_dep_file(cache_hash, tmp_dep_file, false))) { 22702 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to parse .d file: %s", err_str(err))); 22703 return ira->codegen->invalid_instruction; 22704 } 22705 if ((err = cache_final(cache_hash, &tmp_c_file_digest))) { 22706 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to finalize cache: %s", err_str(err))); 22707 return ira->codegen->invalid_instruction; 22708 } 22709 22710 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 22711 if ((err = os_make_path(out_zig_dir))) { 22712 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make output dir: %s", err_str(err))); 22713 return ira->codegen->invalid_instruction; 22714 } 22715 FILE *out_file = fopen(buf_ptr(out_zig_path), "wb"); 22716 if (out_file == nullptr) { 22717 ir_add_error_node(ira, node, 22718 buf_sprintf("C import failed: unable to open output file: %s", strerror(errno))); 22719 return ira->codegen->invalid_instruction; 22720 } 22721 ast_render(out_file, root_node, 4); 22722 if (fclose(out_file) != 0) { 22723 ir_add_error_node(ira, node, 22724 buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno))); 22725 return ira->codegen->invalid_instruction; 22726 } 22727 22728 if (ira->codegen->verbose_cimport) { 22729 fprintf(stderr, "@cImport output: %s\n", buf_ptr(out_zig_path)); 22730 } 22731 22732 } else { 22733 // Cache Hit 22734 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 22735 if (ira->codegen->verbose_cimport) { 22736 fprintf(stderr, "@cImport cache hit: %s\n", buf_ptr(out_zig_path)); 22737 } 22738 } 22739 22740 Buf *import_code = buf_alloc(); 22741 if ((err = file_fetch(ira->codegen, out_zig_path, import_code))) { 22742 ir_add_error_node(ira, node, 22743 buf_sprintf("unable to open '%s': %s", buf_ptr(out_zig_path), err_str(err))); 22744 return ira->codegen->invalid_instruction; 22745 } 22746 ZigType *child_import = add_source_file(ira->codegen, cimport_pkg, out_zig_path, 22747 import_code, SourceKindCImport); 22748 return ir_const_type(ira, &instruction->base, child_import); 22749 } 22750 22751 static IrInstruction *ir_analyze_instruction_c_include(IrAnalyze *ira, IrInstructionCInclude *instruction) { 22752 IrInstruction *name_value = instruction->name->child; 22753 if (type_is_invalid(name_value->value->type)) 22754 return ira->codegen->invalid_instruction; 22755 22756 Buf *include_name = ir_resolve_str(ira, name_value); 22757 if (!include_name) 22758 return ira->codegen->invalid_instruction; 22759 22760 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 22761 // We check for this error in pass1 22762 assert(c_import_buf); 22763 22764 buf_appendf(c_import_buf, "#include <%s>\n", buf_ptr(include_name)); 22765 22766 return ir_const_void(ira, &instruction->base); 22767 } 22768 22769 static IrInstruction *ir_analyze_instruction_c_define(IrAnalyze *ira, IrInstructionCDefine *instruction) { 22770 IrInstruction *name = instruction->name->child; 22771 if (type_is_invalid(name->value->type)) 22772 return ira->codegen->invalid_instruction; 22773 22774 Buf *define_name = ir_resolve_str(ira, name); 22775 if (!define_name) 22776 return ira->codegen->invalid_instruction; 22777 22778 IrInstruction *value = instruction->value->child; 22779 if (type_is_invalid(value->value->type)) 22780 return ira->codegen->invalid_instruction; 22781 22782 Buf *define_value = nullptr; 22783 // The second parameter is either a string or void (equivalent to "") 22784 if (value->value->type->id != ZigTypeIdVoid) { 22785 define_value = ir_resolve_str(ira, value); 22786 if (!define_value) 22787 return ira->codegen->invalid_instruction; 22788 } 22789 22790 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 22791 // We check for this error in pass1 22792 assert(c_import_buf); 22793 22794 buf_appendf(c_import_buf, "#define %s %s\n", buf_ptr(define_name), 22795 define_value ? buf_ptr(define_value) : ""); 22796 22797 return ir_const_void(ira, &instruction->base); 22798 } 22799 22800 static IrInstruction *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstructionCUndef *instruction) { 22801 IrInstruction *name = instruction->name->child; 22802 if (type_is_invalid(name->value->type)) 22803 return ira->codegen->invalid_instruction; 22804 22805 Buf *undef_name = ir_resolve_str(ira, name); 22806 if (!undef_name) 22807 return ira->codegen->invalid_instruction; 22808 22809 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 22810 // We check for this error in pass1 22811 assert(c_import_buf); 22812 22813 buf_appendf(c_import_buf, "#undef %s\n", buf_ptr(undef_name)); 22814 22815 return ir_const_void(ira, &instruction->base); 22816 } 22817 22818 static IrInstruction *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionEmbedFile *instruction) { 22819 IrInstruction *name = instruction->name->child; 22820 if (type_is_invalid(name->value->type)) 22821 return ira->codegen->invalid_instruction; 22822 22823 Buf *rel_file_path = ir_resolve_str(ira, name); 22824 if (!rel_file_path) 22825 return ira->codegen->invalid_instruction; 22826 22827 ZigType *import = get_scope_import(instruction->base.scope); 22828 // figure out absolute path to resource 22829 Buf source_dir_path = BUF_INIT; 22830 os_path_dirname(import->data.structure.root_struct->path, &source_dir_path); 22831 22832 Buf *resolve_paths[] = { 22833 &source_dir_path, 22834 rel_file_path, 22835 }; 22836 Buf *file_path = buf_alloc(); 22837 *file_path = os_path_resolve(resolve_paths, 2); 22838 22839 // load from file system into const expr 22840 Buf *file_contents = buf_alloc(); 22841 Error err; 22842 if ((err = file_fetch(ira->codegen, file_path, file_contents))) { 22843 if (err == ErrorFileNotFound) { 22844 ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(file_path))); 22845 return ira->codegen->invalid_instruction; 22846 } else { 22847 ir_add_error(ira, instruction->name, buf_sprintf("unable to open '%s': %s", buf_ptr(file_path), err_str(err))); 22848 return ira->codegen->invalid_instruction; 22849 } 22850 } 22851 22852 ZigType *result_type = get_array_type(ira->codegen, 22853 ira->codegen->builtin_types.entry_u8, buf_len(file_contents), nullptr); 22854 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 22855 init_const_str_lit(ira->codegen, result->value, file_contents); 22856 return result; 22857 } 22858 22859 static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructionCmpxchgSrc *instruction) { 22860 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child); 22861 if (type_is_invalid(operand_type)) 22862 return ira->codegen->invalid_instruction; 22863 22864 IrInstruction *ptr = instruction->ptr->child; 22865 if (type_is_invalid(ptr->value->type)) 22866 return ira->codegen->invalid_instruction; 22867 22868 // TODO let this be volatile 22869 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 22870 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr, ptr_type); 22871 if (type_is_invalid(casted_ptr->value->type)) 22872 return ira->codegen->invalid_instruction; 22873 22874 IrInstruction *cmp_value = instruction->cmp_value->child; 22875 if (type_is_invalid(cmp_value->value->type)) 22876 return ira->codegen->invalid_instruction; 22877 22878 IrInstruction *new_value = instruction->new_value->child; 22879 if (type_is_invalid(new_value->value->type)) 22880 return ira->codegen->invalid_instruction; 22881 22882 IrInstruction *success_order_value = instruction->success_order_value->child; 22883 if (type_is_invalid(success_order_value->value->type)) 22884 return ira->codegen->invalid_instruction; 22885 22886 AtomicOrder success_order; 22887 if (!ir_resolve_atomic_order(ira, success_order_value, &success_order)) 22888 return ira->codegen->invalid_instruction; 22889 22890 IrInstruction *failure_order_value = instruction->failure_order_value->child; 22891 if (type_is_invalid(failure_order_value->value->type)) 22892 return ira->codegen->invalid_instruction; 22893 22894 AtomicOrder failure_order; 22895 if (!ir_resolve_atomic_order(ira, failure_order_value, &failure_order)) 22896 return ira->codegen->invalid_instruction; 22897 22898 IrInstruction *casted_cmp_value = ir_implicit_cast(ira, cmp_value, operand_type); 22899 if (type_is_invalid(casted_cmp_value->value->type)) 22900 return ira->codegen->invalid_instruction; 22901 22902 IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, operand_type); 22903 if (type_is_invalid(casted_new_value->value->type)) 22904 return ira->codegen->invalid_instruction; 22905 22906 if (success_order < AtomicOrderMonotonic) { 22907 ir_add_error(ira, success_order_value, 22908 buf_sprintf("success atomic ordering must be Monotonic or stricter")); 22909 return ira->codegen->invalid_instruction; 22910 } 22911 if (failure_order < AtomicOrderMonotonic) { 22912 ir_add_error(ira, failure_order_value, 22913 buf_sprintf("failure atomic ordering must be Monotonic or stricter")); 22914 return ira->codegen->invalid_instruction; 22915 } 22916 if (failure_order > success_order) { 22917 ir_add_error(ira, failure_order_value, 22918 buf_sprintf("failure atomic ordering must be no stricter than success")); 22919 return ira->codegen->invalid_instruction; 22920 } 22921 if (failure_order == AtomicOrderRelease || failure_order == AtomicOrderAcqRel) { 22922 ir_add_error(ira, failure_order_value, 22923 buf_sprintf("failure atomic ordering must not be Release or AcqRel")); 22924 return ira->codegen->invalid_instruction; 22925 } 22926 22927 if (instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar && 22928 instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) { 22929 zig_panic("TODO compile-time execution of cmpxchg"); 22930 } 22931 22932 ZigType *result_type = get_optional_type(ira->codegen, operand_type); 22933 IrInstruction *result_loc; 22934 if (handle_is_ptr(result_type)) { 22935 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 22936 result_type, nullptr, true, false, true); 22937 if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { 22938 return result_loc; 22939 } 22940 } else { 22941 result_loc = nullptr; 22942 } 22943 22944 return ir_build_cmpxchg_gen(ira, &instruction->base, result_type, 22945 casted_ptr, casted_cmp_value, casted_new_value, 22946 success_order, failure_order, instruction->is_weak, result_loc); 22947 } 22948 22949 static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { 22950 IrInstruction *order_value = instruction->order_value->child; 22951 if (type_is_invalid(order_value->value->type)) 22952 return ira->codegen->invalid_instruction; 22953 22954 AtomicOrder order; 22955 if (!ir_resolve_atomic_order(ira, order_value, &order)) 22956 return ira->codegen->invalid_instruction; 22957 22958 if (order < AtomicOrderAcquire) { 22959 ir_add_error(ira, order_value, 22960 buf_sprintf("atomic ordering must be Acquire or stricter")); 22961 return ira->codegen->invalid_instruction; 22962 } 22963 22964 IrInstruction *result = ir_build_fence(&ira->new_irb, 22965 instruction->base.scope, instruction->base.source_node, order_value, order); 22966 result->value->type = ira->codegen->builtin_types.entry_void; 22967 return result; 22968 } 22969 22970 static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstructionTruncate *instruction) { 22971 IrInstruction *dest_type_value = instruction->dest_type->child; 22972 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 22973 if (type_is_invalid(dest_type)) 22974 return ira->codegen->invalid_instruction; 22975 22976 if (dest_type->id != ZigTypeIdInt && 22977 dest_type->id != ZigTypeIdComptimeInt) 22978 { 22979 ir_add_error(ira, dest_type_value, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 22980 return ira->codegen->invalid_instruction; 22981 } 22982 22983 IrInstruction *target = instruction->target->child; 22984 ZigType *src_type = target->value->type; 22985 if (type_is_invalid(src_type)) 22986 return ira->codegen->invalid_instruction; 22987 22988 if (src_type->id != ZigTypeIdInt && 22989 src_type->id != ZigTypeIdComptimeInt) 22990 { 22991 ir_add_error(ira, target, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name))); 22992 return ira->codegen->invalid_instruction; 22993 } 22994 22995 if (dest_type->id == ZigTypeIdComptimeInt) { 22996 return ir_implicit_cast(ira, target, dest_type); 22997 } 22998 22999 if (instr_is_comptime(target)) { 23000 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 23001 if (val == nullptr) 23002 return ira->codegen->invalid_instruction; 23003 23004 IrInstruction *result = ir_const(ira, &instruction->base, dest_type); 23005 bigint_truncate(&result->value->data.x_bigint, &val->data.x_bigint, 23006 dest_type->data.integral.bit_count, dest_type->data.integral.is_signed); 23007 return result; 23008 } 23009 23010 if (src_type->data.integral.bit_count == 0 || dest_type->data.integral.bit_count == 0) { 23011 IrInstruction *result = ir_const(ira, &instruction->base, dest_type); 23012 bigint_init_unsigned(&result->value->data.x_bigint, 0); 23013 return result; 23014 } 23015 23016 if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { 23017 const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; 23018 ir_add_error(ira, target, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); 23019 return ira->codegen->invalid_instruction; 23020 } else if (src_type->data.integral.bit_count < dest_type->data.integral.bit_count) { 23021 ir_add_error(ira, target, buf_sprintf("type '%s' has fewer bits than destination type '%s'", 23022 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 23023 return ira->codegen->invalid_instruction; 23024 } 23025 23026 IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope, 23027 instruction->base.source_node, dest_type_value, target); 23028 new_instruction->value->type = dest_type; 23029 return new_instruction; 23030 } 23031 23032 static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstructionIntCast *instruction) { 23033 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 23034 if (type_is_invalid(dest_type)) 23035 return ira->codegen->invalid_instruction; 23036 23037 if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { 23038 ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 23039 return ira->codegen->invalid_instruction; 23040 } 23041 23042 IrInstruction *target = instruction->target->child; 23043 if (type_is_invalid(target->value->type)) 23044 return ira->codegen->invalid_instruction; 23045 23046 if (target->value->type->id != ZigTypeIdInt && target->value->type->id != ZigTypeIdComptimeInt) { 23047 ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", 23048 buf_ptr(&target->value->type->name))); 23049 return ira->codegen->invalid_instruction; 23050 } 23051 23052 if (instr_is_comptime(target)) { 23053 return ir_implicit_cast(ira, target, dest_type); 23054 } 23055 23056 if (dest_type->id == ZigTypeIdComptimeInt) { 23057 ir_add_error(ira, instruction->target, buf_sprintf("attempt to cast runtime value to '%s'", 23058 buf_ptr(&dest_type->name))); 23059 return ira->codegen->invalid_instruction; 23060 } 23061 23062 return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); 23063 } 23064 23065 static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstructionFloatCast *instruction) { 23066 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 23067 if (type_is_invalid(dest_type)) 23068 return ira->codegen->invalid_instruction; 23069 23070 if (dest_type->id != ZigTypeIdFloat) { 23071 ir_add_error(ira, instruction->dest_type, 23072 buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); 23073 return ira->codegen->invalid_instruction; 23074 } 23075 23076 IrInstruction *target = instruction->target->child; 23077 if (type_is_invalid(target->value->type)) 23078 return ira->codegen->invalid_instruction; 23079 23080 if (target->value->type->id == ZigTypeIdComptimeInt || 23081 target->value->type->id == ZigTypeIdComptimeFloat) 23082 { 23083 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { 23084 CastOp op; 23085 if (target->value->type->id == ZigTypeIdComptimeInt) { 23086 op = CastOpIntToFloat; 23087 } else { 23088 op = CastOpNumLitToConcrete; 23089 } 23090 return ir_resolve_cast(ira, &instruction->base, target, dest_type, op); 23091 } else { 23092 return ira->codegen->invalid_instruction; 23093 } 23094 } 23095 23096 if (target->value->type->id != ZigTypeIdFloat) { 23097 ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", 23098 buf_ptr(&target->value->type->name))); 23099 return ira->codegen->invalid_instruction; 23100 } 23101 23102 return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); 23103 } 23104 23105 static IrInstruction *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstructionErrSetCast *instruction) { 23106 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 23107 if (type_is_invalid(dest_type)) 23108 return ira->codegen->invalid_instruction; 23109 23110 if (dest_type->id != ZigTypeIdErrorSet) { 23111 ir_add_error(ira, instruction->dest_type, 23112 buf_sprintf("expected error set type, found '%s'", buf_ptr(&dest_type->name))); 23113 return ira->codegen->invalid_instruction; 23114 } 23115 23116 IrInstruction *target = instruction->target->child; 23117 if (type_is_invalid(target->value->type)) 23118 return ira->codegen->invalid_instruction; 23119 23120 if (target->value->type->id != ZigTypeIdErrorSet) { 23121 ir_add_error(ira, instruction->target, 23122 buf_sprintf("expected error set type, found '%s'", buf_ptr(&target->value->type->name))); 23123 return ira->codegen->invalid_instruction; 23124 } 23125 23126 return ir_analyze_err_set_cast(ira, &instruction->base, target, dest_type); 23127 } 23128 23129 static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstructionFromBytes *instruction) { 23130 Error err; 23131 23132 ZigType *dest_child_type = ir_resolve_type(ira, instruction->dest_child_type->child); 23133 if (type_is_invalid(dest_child_type)) 23134 return ira->codegen->invalid_instruction; 23135 23136 IrInstruction *target = instruction->target->child; 23137 if (type_is_invalid(target->value->type)) 23138 return ira->codegen->invalid_instruction; 23139 23140 bool src_ptr_const; 23141 bool src_ptr_volatile; 23142 uint32_t src_ptr_align; 23143 if (target->value->type->id == ZigTypeIdPointer) { 23144 src_ptr_const = target->value->type->data.pointer.is_const; 23145 src_ptr_volatile = target->value->type->data.pointer.is_volatile; 23146 23147 if ((err = resolve_ptr_align(ira, target->value->type, &src_ptr_align))) 23148 return ira->codegen->invalid_instruction; 23149 } else if (is_slice(target->value->type)) { 23150 ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry; 23151 src_ptr_const = src_ptr_type->data.pointer.is_const; 23152 src_ptr_volatile = src_ptr_type->data.pointer.is_volatile; 23153 23154 if ((err = resolve_ptr_align(ira, src_ptr_type, &src_ptr_align))) 23155 return ira->codegen->invalid_instruction; 23156 } else { 23157 src_ptr_const = true; 23158 src_ptr_volatile = false; 23159 23160 if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusAlignmentKnown))) 23161 return ira->codegen->invalid_instruction; 23162 23163 src_ptr_align = get_abi_alignment(ira->codegen, target->value->type); 23164 } 23165 23166 if (src_ptr_align != 0) { 23167 if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusAlignmentKnown))) 23168 return ira->codegen->invalid_instruction; 23169 } 23170 23171 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_child_type, 23172 src_ptr_const, src_ptr_volatile, PtrLenUnknown, 23173 src_ptr_align, 0, 0, false); 23174 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); 23175 23176 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 23177 src_ptr_const, src_ptr_volatile, PtrLenUnknown, 23178 src_ptr_align, 0, 0, false); 23179 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 23180 23181 IrInstruction *casted_value = ir_implicit_cast(ira, target, u8_slice); 23182 if (type_is_invalid(casted_value->value->type)) 23183 return ira->codegen->invalid_instruction; 23184 23185 bool have_known_len = false; 23186 uint64_t known_len; 23187 23188 if (instr_is_comptime(casted_value)) { 23189 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); 23190 if (!val) 23191 return ira->codegen->invalid_instruction; 23192 23193 ZigValue *len_val = val->data.x_struct.fields[slice_len_index]; 23194 if (value_is_comptime(len_val)) { 23195 known_len = bigint_as_u64(&len_val->data.x_bigint); 23196 have_known_len = true; 23197 } 23198 } 23199 23200 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 23201 dest_slice_type, nullptr, true, false, true); 23202 if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) { 23203 return result_loc; 23204 } 23205 23206 if (casted_value->value->data.rh_slice.id == RuntimeHintSliceIdLen) { 23207 known_len = casted_value->value->data.rh_slice.len; 23208 have_known_len = true; 23209 } 23210 23211 if (have_known_len) { 23212 if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusSizeKnown))) 23213 return ira->codegen->invalid_instruction; 23214 uint64_t child_type_size = type_size(ira->codegen, dest_child_type); 23215 uint64_t remainder = known_len % child_type_size; 23216 if (remainder != 0) { 23217 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 23218 buf_sprintf("unable to convert [%" ZIG_PRI_u64 "]u8 to %s: size mismatch", 23219 known_len, buf_ptr(&dest_slice_type->name))); 23220 add_error_note(ira->codegen, msg, instruction->dest_child_type->source_node, 23221 buf_sprintf("%s has size %" ZIG_PRI_u64 "; remaining bytes: %" ZIG_PRI_u64, 23222 buf_ptr(&dest_child_type->name), child_type_size, remainder)); 23223 return ira->codegen->invalid_instruction; 23224 } 23225 } 23226 23227 return ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type, result_loc); 23228 } 23229 23230 static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { 23231 Error err; 23232 23233 IrInstruction *target = instruction->target->child; 23234 if (type_is_invalid(target->value->type)) 23235 return ira->codegen->invalid_instruction; 23236 23237 if (!is_slice(target->value->type)) { 23238 ir_add_error(ira, instruction->target, 23239 buf_sprintf("expected slice, found '%s'", buf_ptr(&target->value->type->name))); 23240 return ira->codegen->invalid_instruction; 23241 } 23242 23243 ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry; 23244 23245 uint32_t alignment; 23246 if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment))) 23247 return ira->codegen->invalid_instruction; 23248 23249 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 23250 src_ptr_type->data.pointer.is_const, src_ptr_type->data.pointer.is_volatile, PtrLenUnknown, 23251 alignment, 0, 0, false); 23252 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); 23253 23254 if (instr_is_comptime(target)) { 23255 ZigValue *target_val = ir_resolve_const(ira, target, UndefBad); 23256 if (target_val == nullptr) 23257 return ira->codegen->invalid_instruction; 23258 23259 IrInstruction *result = ir_const(ira, &instruction->base, dest_slice_type); 23260 result->value->data.x_struct.fields = alloc_const_vals_ptrs(2); 23261 23262 ZigValue *ptr_val = result->value->data.x_struct.fields[slice_ptr_index]; 23263 ZigValue *target_ptr_val = target_val->data.x_struct.fields[slice_ptr_index]; 23264 copy_const_val(ptr_val, target_ptr_val, false); 23265 ptr_val->type = dest_ptr_type; 23266 23267 ZigValue *len_val = result->value->data.x_struct.fields[slice_len_index]; 23268 len_val->special = ConstValSpecialStatic; 23269 len_val->type = ira->codegen->builtin_types.entry_usize; 23270 ZigValue *target_len_val = target_val->data.x_struct.fields[slice_len_index]; 23271 ZigType *elem_type = src_ptr_type->data.pointer.child_type; 23272 BigInt elem_size_bigint; 23273 bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type)); 23274 bigint_mul(&len_val->data.x_bigint, &target_len_val->data.x_bigint, &elem_size_bigint); 23275 23276 return result; 23277 } 23278 23279 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 23280 dest_slice_type, nullptr, true, false, true); 23281 if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { 23282 return result_loc; 23283 } 23284 23285 return ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type, result_loc); 23286 } 23287 23288 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { 23289 Error err; 23290 23291 ZigType *ptr_type = get_src_ptr_type(ty); 23292 assert(ptr_type != nullptr); 23293 if (ptr_type->id == ZigTypeIdPointer) { 23294 if ((err = type_resolve(ira->codegen, ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 23295 return err; 23296 } 23297 23298 *result_align = get_ptr_align(ira->codegen, ty); 23299 return ErrorNone; 23300 } 23301 23302 static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) { 23303 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 23304 if (type_is_invalid(dest_type)) 23305 return ira->codegen->invalid_instruction; 23306 23307 IrInstruction *target = instruction->target->child; 23308 if (type_is_invalid(target->value->type)) 23309 return ira->codegen->invalid_instruction; 23310 23311 if (target->value->type->id != ZigTypeIdInt && target->value->type->id != ZigTypeIdComptimeInt) { 23312 ir_add_error(ira, instruction->target, buf_sprintf("expected int type, found '%s'", 23313 buf_ptr(&target->value->type->name))); 23314 return ira->codegen->invalid_instruction; 23315 } 23316 23317 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat); 23318 } 23319 23320 static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { 23321 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 23322 if (type_is_invalid(dest_type)) 23323 return ira->codegen->invalid_instruction; 23324 23325 IrInstruction *target = instruction->target->child; 23326 if (type_is_invalid(target->value->type)) 23327 return ira->codegen->invalid_instruction; 23328 23329 if (target->value->type->id == ZigTypeIdComptimeInt) { 23330 return ir_implicit_cast(ira, target, dest_type); 23331 } 23332 23333 if (target->value->type->id != ZigTypeIdFloat && target->value->type->id != ZigTypeIdComptimeFloat) { 23334 ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", 23335 buf_ptr(&target->value->type->name))); 23336 return ira->codegen->invalid_instruction; 23337 } 23338 23339 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt); 23340 } 23341 23342 static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { 23343 IrInstruction *target = instruction->target->child; 23344 if (type_is_invalid(target->value->type)) 23345 return ira->codegen->invalid_instruction; 23346 23347 IrInstruction *casted_target; 23348 if (target->value->type->id == ZigTypeIdErrorSet) { 23349 casted_target = target; 23350 } else { 23351 casted_target = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_global_error_set); 23352 if (type_is_invalid(casted_target->value->type)) 23353 return ira->codegen->invalid_instruction; 23354 } 23355 23356 return ir_analyze_err_to_int(ira, &instruction->base, casted_target, ira->codegen->err_tag_type); 23357 } 23358 23359 static IrInstruction *ir_analyze_instruction_int_to_err(IrAnalyze *ira, IrInstructionIntToErr *instruction) { 23360 IrInstruction *target = instruction->target->child; 23361 if (type_is_invalid(target->value->type)) 23362 return ira->codegen->invalid_instruction; 23363 23364 IrInstruction *casted_target = ir_implicit_cast(ira, target, ira->codegen->err_tag_type); 23365 if (type_is_invalid(casted_target->value->type)) 23366 return ira->codegen->invalid_instruction; 23367 23368 return ir_analyze_int_to_err(ira, &instruction->base, casted_target, ira->codegen->builtin_types.entry_global_error_set); 23369 } 23370 23371 static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstructionBoolToInt *instruction) { 23372 IrInstruction *target = instruction->target->child; 23373 if (type_is_invalid(target->value->type)) 23374 return ira->codegen->invalid_instruction; 23375 23376 if (target->value->type->id != ZigTypeIdBool) { 23377 ir_add_error(ira, instruction->target, buf_sprintf("expected bool, found '%s'", 23378 buf_ptr(&target->value->type->name))); 23379 return ira->codegen->invalid_instruction; 23380 } 23381 23382 if (instr_is_comptime(target)) { 23383 bool is_true; 23384 if (!ir_resolve_bool(ira, target, &is_true)) 23385 return ira->codegen->invalid_instruction; 23386 23387 return ir_const_unsigned(ira, &instruction->base, is_true ? 1 : 0); 23388 } 23389 23390 ZigType *u1_type = get_int_type(ira->codegen, false, 1); 23391 return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt); 23392 } 23393 23394 static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { 23395 IrInstruction *is_signed_value = instruction->is_signed->child; 23396 bool is_signed; 23397 if (!ir_resolve_bool(ira, is_signed_value, &is_signed)) 23398 return ira->codegen->invalid_instruction; 23399 23400 IrInstruction *bit_count_value = instruction->bit_count->child; 23401 uint64_t bit_count; 23402 if (!ir_resolve_unsigned(ira, bit_count_value, ira->codegen->builtin_types.entry_u16, &bit_count)) 23403 return ira->codegen->invalid_instruction; 23404 23405 return ir_const_type(ira, &instruction->base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count)); 23406 } 23407 23408 static IrInstruction *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstructionVectorType *instruction) { 23409 uint64_t len; 23410 if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len)) 23411 return ira->codegen->invalid_instruction; 23412 23413 ZigType *elem_type = ir_resolve_vector_elem_type(ira, instruction->elem_type->child); 23414 if (type_is_invalid(elem_type)) 23415 return ira->codegen->invalid_instruction; 23416 23417 ZigType *vector_type = get_vector_type(ira->codegen, len, elem_type); 23418 23419 return ir_const_type(ira, &instruction->base, vector_type); 23420 } 23421 23422 static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *source_instr, 23423 ZigType *scalar_type, IrInstruction *a, IrInstruction *b, IrInstruction *mask) 23424 { 23425 ir_assert(source_instr && scalar_type && a && b && mask, source_instr); 23426 ir_assert(is_valid_vector_elem_type(scalar_type), source_instr); 23427 23428 uint32_t len_mask; 23429 if (mask->value->type->id == ZigTypeIdVector) { 23430 len_mask = mask->value->type->data.vector.len; 23431 } else if (mask->value->type->id == ZigTypeIdArray) { 23432 len_mask = mask->value->type->data.array.len; 23433 } else { 23434 ir_add_error(ira, mask, 23435 buf_sprintf("expected vector or array, found '%s'", 23436 buf_ptr(&mask->value->type->name))); 23437 return ira->codegen->invalid_instruction; 23438 } 23439 mask = ir_implicit_cast(ira, mask, get_vector_type(ira->codegen, len_mask, 23440 ira->codegen->builtin_types.entry_i32)); 23441 if (type_is_invalid(mask->value->type)) 23442 return ira->codegen->invalid_instruction; 23443 23444 uint32_t len_a; 23445 if (a->value->type->id == ZigTypeIdVector) { 23446 len_a = a->value->type->data.vector.len; 23447 } else if (a->value->type->id == ZigTypeIdArray) { 23448 len_a = a->value->type->data.array.len; 23449 } else if (a->value->type->id == ZigTypeIdUndefined) { 23450 len_a = UINT32_MAX; 23451 } else { 23452 ir_add_error(ira, a, 23453 buf_sprintf("expected vector or array with element type '%s', found '%s'", 23454 buf_ptr(&scalar_type->name), 23455 buf_ptr(&a->value->type->name))); 23456 return ira->codegen->invalid_instruction; 23457 } 23458 23459 uint32_t len_b; 23460 if (b->value->type->id == ZigTypeIdVector) { 23461 len_b = b->value->type->data.vector.len; 23462 } else if (b->value->type->id == ZigTypeIdArray) { 23463 len_b = b->value->type->data.array.len; 23464 } else if (b->value->type->id == ZigTypeIdUndefined) { 23465 len_b = UINT32_MAX; 23466 } else { 23467 ir_add_error(ira, b, 23468 buf_sprintf("expected vector or array with element type '%s', found '%s'", 23469 buf_ptr(&scalar_type->name), 23470 buf_ptr(&b->value->type->name))); 23471 return ira->codegen->invalid_instruction; 23472 } 23473 23474 if (len_a == UINT32_MAX && len_b == UINT32_MAX) { 23475 return ir_const_undef(ira, a, get_vector_type(ira->codegen, len_mask, scalar_type)); 23476 } 23477 23478 if (len_a == UINT32_MAX) { 23479 len_a = len_b; 23480 a = ir_const_undef(ira, a, get_vector_type(ira->codegen, len_a, scalar_type)); 23481 } else { 23482 a = ir_implicit_cast(ira, a, get_vector_type(ira->codegen, len_a, scalar_type)); 23483 if (type_is_invalid(a->value->type)) 23484 return ira->codegen->invalid_instruction; 23485 } 23486 23487 if (len_b == UINT32_MAX) { 23488 len_b = len_a; 23489 b = ir_const_undef(ira, b, get_vector_type(ira->codegen, len_b, scalar_type)); 23490 } else { 23491 b = ir_implicit_cast(ira, b, get_vector_type(ira->codegen, len_b, scalar_type)); 23492 if (type_is_invalid(b->value->type)) 23493 return ira->codegen->invalid_instruction; 23494 } 23495 23496 ZigValue *mask_val = ir_resolve_const(ira, mask, UndefOk); 23497 if (mask_val == nullptr) 23498 return ira->codegen->invalid_instruction; 23499 23500 expand_undef_array(ira->codegen, mask_val); 23501 23502 for (uint32_t i = 0; i < len_mask; i += 1) { 23503 ZigValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i]; 23504 if (mask_elem_val->special == ConstValSpecialUndef) 23505 continue; 23506 int32_t v_i32 = bigint_as_signed(&mask_elem_val->data.x_bigint); 23507 uint32_t v; 23508 IrInstruction *chosen_operand; 23509 if (v_i32 >= 0) { 23510 v = (uint32_t)v_i32; 23511 chosen_operand = a; 23512 } else { 23513 v = (uint32_t)~v_i32; 23514 chosen_operand = b; 23515 } 23516 if (v >= chosen_operand->value->type->data.vector.len) { 23517 ErrorMsg *msg = ir_add_error(ira, mask, 23518 buf_sprintf("mask index '%u' has out-of-bounds selection", i)); 23519 add_error_note(ira->codegen, msg, chosen_operand->source_node, 23520 buf_sprintf("selected index '%u' out of bounds of %s", v, 23521 buf_ptr(&chosen_operand->value->type->name))); 23522 if (chosen_operand == a && v < len_a + len_b) { 23523 add_error_note(ira->codegen, msg, b->source_node, 23524 buf_create_from_str("selections from the second vector are specified with negative numbers")); 23525 } 23526 return ira->codegen->invalid_instruction; 23527 } 23528 } 23529 23530 ZigType *result_type = get_vector_type(ira->codegen, len_mask, scalar_type); 23531 if (instr_is_comptime(a) && instr_is_comptime(b)) { 23532 ZigValue *a_val = ir_resolve_const(ira, a, UndefOk); 23533 if (a_val == nullptr) 23534 return ira->codegen->invalid_instruction; 23535 23536 ZigValue *b_val = ir_resolve_const(ira, b, UndefOk); 23537 if (b_val == nullptr) 23538 return ira->codegen->invalid_instruction; 23539 23540 expand_undef_array(ira->codegen, a_val); 23541 expand_undef_array(ira->codegen, b_val); 23542 23543 IrInstruction *result = ir_const(ira, source_instr, result_type); 23544 result->value->data.x_array.data.s_none.elements = create_const_vals(len_mask); 23545 for (uint32_t i = 0; i < mask_val->type->data.vector.len; i += 1) { 23546 ZigValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i]; 23547 ZigValue *result_elem_val = &result->value->data.x_array.data.s_none.elements[i]; 23548 if (mask_elem_val->special == ConstValSpecialUndef) { 23549 result_elem_val->special = ConstValSpecialUndef; 23550 continue; 23551 } 23552 int32_t v = bigint_as_signed(&mask_elem_val->data.x_bigint); 23553 // We've already checked for and emitted compile errors for index out of bounds here. 23554 ZigValue *src_elem_val = (v >= 0) ? 23555 &a->value->data.x_array.data.s_none.elements[v] : 23556 &b->value->data.x_array.data.s_none.elements[~v]; 23557 copy_const_val(result_elem_val, src_elem_val, false); 23558 23559 ir_assert(result_elem_val->special == ConstValSpecialStatic, source_instr); 23560 } 23561 result->value->special = ConstValSpecialStatic; 23562 return result; 23563 } 23564 23565 // All static analysis passed, and not comptime. 23566 // For runtime codegen, vectors a and b must be the same length. Here we 23567 // recursively @shuffle the smaller vector to append undefined elements 23568 // to it up to the length of the longer vector. This recursion terminates 23569 // in 1 call because these calls to ir_analyze_shuffle_vector guarantee 23570 // len_a == len_b. 23571 if (len_a != len_b) { 23572 uint32_t len_min = min(len_a, len_b); 23573 uint32_t len_max = max(len_a, len_b); 23574 23575 IrInstruction *expand_mask = ir_const(ira, mask, 23576 get_vector_type(ira->codegen, len_max, ira->codegen->builtin_types.entry_i32)); 23577 expand_mask->value->data.x_array.data.s_none.elements = create_const_vals(len_max); 23578 uint32_t i = 0; 23579 for (; i < len_min; i += 1) 23580 bigint_init_unsigned(&expand_mask->value->data.x_array.data.s_none.elements[i].data.x_bigint, i); 23581 for (; i < len_max; i += 1) 23582 bigint_init_signed(&expand_mask->value->data.x_array.data.s_none.elements[i].data.x_bigint, -1); 23583 23584 IrInstruction *undef = ir_const_undef(ira, source_instr, 23585 get_vector_type(ira->codegen, len_min, scalar_type)); 23586 23587 if (len_b < len_a) { 23588 b = ir_analyze_shuffle_vector(ira, source_instr, scalar_type, b, undef, expand_mask); 23589 } else { 23590 a = ir_analyze_shuffle_vector(ira, source_instr, scalar_type, a, undef, expand_mask); 23591 } 23592 } 23593 23594 IrInstruction *result = ir_build_shuffle_vector(&ira->new_irb, 23595 source_instr->scope, source_instr->source_node, 23596 nullptr, a, b, mask); 23597 result->value->type = result_type; 23598 return result; 23599 } 23600 23601 static IrInstruction *ir_analyze_instruction_shuffle_vector(IrAnalyze *ira, IrInstructionShuffleVector *instruction) { 23602 ZigType *scalar_type = ir_resolve_vector_elem_type(ira, instruction->scalar_type); 23603 if (type_is_invalid(scalar_type)) 23604 return ira->codegen->invalid_instruction; 23605 23606 IrInstruction *a = instruction->a->child; 23607 if (type_is_invalid(a->value->type)) 23608 return ira->codegen->invalid_instruction; 23609 23610 IrInstruction *b = instruction->b->child; 23611 if (type_is_invalid(b->value->type)) 23612 return ira->codegen->invalid_instruction; 23613 23614 IrInstruction *mask = instruction->mask->child; 23615 if (type_is_invalid(mask->value->type)) 23616 return ira->codegen->invalid_instruction; 23617 23618 return ir_analyze_shuffle_vector(ira, &instruction->base, scalar_type, a, b, mask); 23619 } 23620 23621 static IrInstruction *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstructionSplatSrc *instruction) { 23622 Error err; 23623 23624 IrInstruction *len = instruction->len->child; 23625 if (type_is_invalid(len->value->type)) 23626 return ira->codegen->invalid_instruction; 23627 23628 IrInstruction *scalar = instruction->scalar->child; 23629 if (type_is_invalid(scalar->value->type)) 23630 return ira->codegen->invalid_instruction; 23631 23632 uint64_t len_u64; 23633 if (!ir_resolve_unsigned(ira, len, ira->codegen->builtin_types.entry_u32, &len_u64)) 23634 return ira->codegen->invalid_instruction; 23635 uint32_t len_int = len_u64; 23636 23637 if ((err = ir_validate_vector_elem_type(ira, scalar, scalar->value->type))) 23638 return ira->codegen->invalid_instruction; 23639 23640 ZigType *return_type = get_vector_type(ira->codegen, len_int, scalar->value->type); 23641 23642 if (instr_is_comptime(scalar)) { 23643 ZigValue *scalar_val = ir_resolve_const(ira, scalar, UndefOk); 23644 if (scalar_val == nullptr) 23645 return ira->codegen->invalid_instruction; 23646 if (scalar_val->special == ConstValSpecialUndef) 23647 return ir_const_undef(ira, &instruction->base, return_type); 23648 23649 IrInstruction *result = ir_const(ira, &instruction->base, return_type); 23650 result->value->data.x_array.data.s_none.elements = create_const_vals(len_int); 23651 for (uint32_t i = 0; i < len_int; i += 1) { 23652 copy_const_val(&result->value->data.x_array.data.s_none.elements[i], scalar_val, false); 23653 } 23654 return result; 23655 } 23656 23657 return ir_build_splat_gen(ira, &instruction->base, return_type, scalar); 23658 } 23659 23660 static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { 23661 IrInstruction *value = instruction->value->child; 23662 if (type_is_invalid(value->value->type)) 23663 return ira->codegen->invalid_instruction; 23664 23665 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 23666 23667 IrInstruction *casted_value = ir_implicit_cast(ira, value, bool_type); 23668 if (type_is_invalid(casted_value->value->type)) 23669 return ira->codegen->invalid_instruction; 23670 23671 if (instr_is_comptime(casted_value)) { 23672 ZigValue *value = ir_resolve_const(ira, casted_value, UndefBad); 23673 if (value == nullptr) 23674 return ira->codegen->invalid_instruction; 23675 23676 return ir_const_bool(ira, &instruction->base, !value->data.x_bool); 23677 } 23678 23679 IrInstruction *result = ir_build_bool_not(&ira->new_irb, instruction->base.scope, 23680 instruction->base.source_node, casted_value); 23681 result->value->type = bool_type; 23682 return result; 23683 } 23684 23685 static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemset *instruction) { 23686 Error err; 23687 23688 IrInstruction *dest_ptr = instruction->dest_ptr->child; 23689 if (type_is_invalid(dest_ptr->value->type)) 23690 return ira->codegen->invalid_instruction; 23691 23692 IrInstruction *byte_value = instruction->byte->child; 23693 if (type_is_invalid(byte_value->value->type)) 23694 return ira->codegen->invalid_instruction; 23695 23696 IrInstruction *count_value = instruction->count->child; 23697 if (type_is_invalid(count_value->value->type)) 23698 return ira->codegen->invalid_instruction; 23699 23700 ZigType *dest_uncasted_type = dest_ptr->value->type; 23701 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 23702 dest_uncasted_type->data.pointer.is_volatile; 23703 23704 ZigType *usize = ira->codegen->builtin_types.entry_usize; 23705 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 23706 uint32_t dest_align; 23707 if (dest_uncasted_type->id == ZigTypeIdPointer) { 23708 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 23709 return ira->codegen->invalid_instruction; 23710 } else { 23711 dest_align = get_abi_alignment(ira->codegen, u8); 23712 } 23713 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 23714 PtrLenUnknown, dest_align, 0, 0, false); 23715 23716 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr); 23717 if (type_is_invalid(casted_dest_ptr->value->type)) 23718 return ira->codegen->invalid_instruction; 23719 23720 IrInstruction *casted_byte = ir_implicit_cast(ira, byte_value, u8); 23721 if (type_is_invalid(casted_byte->value->type)) 23722 return ira->codegen->invalid_instruction; 23723 23724 IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); 23725 if (type_is_invalid(casted_count->value->type)) 23726 return ira->codegen->invalid_instruction; 23727 23728 // TODO test this at comptime with u8 and non-u8 types 23729 if (instr_is_comptime(casted_dest_ptr) && 23730 instr_is_comptime(casted_byte) && 23731 instr_is_comptime(casted_count)) 23732 { 23733 ZigValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); 23734 if (dest_ptr_val == nullptr) 23735 return ira->codegen->invalid_instruction; 23736 23737 ZigValue *byte_val = ir_resolve_const(ira, casted_byte, UndefOk); 23738 if (byte_val == nullptr) 23739 return ira->codegen->invalid_instruction; 23740 23741 ZigValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); 23742 if (count_val == nullptr) 23743 return ira->codegen->invalid_instruction; 23744 23745 if (casted_dest_ptr->value->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 23746 casted_dest_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 23747 { 23748 ZigValue *dest_elements; 23749 size_t start; 23750 size_t bound_end; 23751 switch (dest_ptr_val->data.x_ptr.special) { 23752 case ConstPtrSpecialInvalid: 23753 case ConstPtrSpecialDiscard: 23754 zig_unreachable(); 23755 case ConstPtrSpecialRef: 23756 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 23757 start = 0; 23758 bound_end = 1; 23759 break; 23760 case ConstPtrSpecialBaseArray: 23761 { 23762 ZigValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 23763 expand_undef_array(ira->codegen, array_val); 23764 dest_elements = array_val->data.x_array.data.s_none.elements; 23765 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 23766 bound_end = array_val->type->data.array.len; 23767 break; 23768 } 23769 case ConstPtrSpecialBaseStruct: 23770 zig_panic("TODO memset on const inner struct"); 23771 case ConstPtrSpecialBaseErrorUnionCode: 23772 zig_panic("TODO memset on const inner error union code"); 23773 case ConstPtrSpecialBaseErrorUnionPayload: 23774 zig_panic("TODO memset on const inner error union payload"); 23775 case ConstPtrSpecialBaseOptionalPayload: 23776 zig_panic("TODO memset on const inner optional payload"); 23777 case ConstPtrSpecialHardCodedAddr: 23778 zig_unreachable(); 23779 case ConstPtrSpecialFunction: 23780 zig_panic("TODO memset on ptr cast from function"); 23781 case ConstPtrSpecialNull: 23782 zig_panic("TODO memset on null ptr"); 23783 } 23784 23785 size_t count = bigint_as_usize(&count_val->data.x_bigint); 23786 size_t end = start + count; 23787 if (end > bound_end) { 23788 ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); 23789 return ira->codegen->invalid_instruction; 23790 } 23791 23792 for (size_t i = start; i < end; i += 1) { 23793 copy_const_val(&dest_elements[i], byte_val, true); 23794 } 23795 23796 return ir_const_void(ira, &instruction->base); 23797 } 23798 } 23799 23800 IrInstruction *result = ir_build_memset(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 23801 casted_dest_ptr, casted_byte, casted_count); 23802 result->value->type = ira->codegen->builtin_types.entry_void; 23803 return result; 23804 } 23805 23806 static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcpy *instruction) { 23807 Error err; 23808 23809 IrInstruction *dest_ptr = instruction->dest_ptr->child; 23810 if (type_is_invalid(dest_ptr->value->type)) 23811 return ira->codegen->invalid_instruction; 23812 23813 IrInstruction *src_ptr = instruction->src_ptr->child; 23814 if (type_is_invalid(src_ptr->value->type)) 23815 return ira->codegen->invalid_instruction; 23816 23817 IrInstruction *count_value = instruction->count->child; 23818 if (type_is_invalid(count_value->value->type)) 23819 return ira->codegen->invalid_instruction; 23820 23821 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 23822 ZigType *dest_uncasted_type = dest_ptr->value->type; 23823 ZigType *src_uncasted_type = src_ptr->value->type; 23824 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 23825 dest_uncasted_type->data.pointer.is_volatile; 23826 bool src_is_volatile = (src_uncasted_type->id == ZigTypeIdPointer) && 23827 src_uncasted_type->data.pointer.is_volatile; 23828 23829 uint32_t dest_align; 23830 if (dest_uncasted_type->id == ZigTypeIdPointer) { 23831 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 23832 return ira->codegen->invalid_instruction; 23833 } else { 23834 dest_align = get_abi_alignment(ira->codegen, u8); 23835 } 23836 23837 uint32_t src_align; 23838 if (src_uncasted_type->id == ZigTypeIdPointer) { 23839 if ((err = resolve_ptr_align(ira, src_uncasted_type, &src_align))) 23840 return ira->codegen->invalid_instruction; 23841 } else { 23842 src_align = get_abi_alignment(ira->codegen, u8); 23843 } 23844 23845 ZigType *usize = ira->codegen->builtin_types.entry_usize; 23846 ZigType *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 23847 PtrLenUnknown, dest_align, 0, 0, false); 23848 ZigType *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, 23849 PtrLenUnknown, src_align, 0, 0, false); 23850 23851 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut); 23852 if (type_is_invalid(casted_dest_ptr->value->type)) 23853 return ira->codegen->invalid_instruction; 23854 23855 IrInstruction *casted_src_ptr = ir_implicit_cast(ira, src_ptr, u8_ptr_const); 23856 if (type_is_invalid(casted_src_ptr->value->type)) 23857 return ira->codegen->invalid_instruction; 23858 23859 IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); 23860 if (type_is_invalid(casted_count->value->type)) 23861 return ira->codegen->invalid_instruction; 23862 23863 // TODO test this at comptime with u8 and non-u8 types 23864 // TODO test with dest ptr being a global runtime variable 23865 if (instr_is_comptime(casted_dest_ptr) && 23866 instr_is_comptime(casted_src_ptr) && 23867 instr_is_comptime(casted_count)) 23868 { 23869 ZigValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); 23870 if (dest_ptr_val == nullptr) 23871 return ira->codegen->invalid_instruction; 23872 23873 ZigValue *src_ptr_val = ir_resolve_const(ira, casted_src_ptr, UndefBad); 23874 if (src_ptr_val == nullptr) 23875 return ira->codegen->invalid_instruction; 23876 23877 ZigValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); 23878 if (count_val == nullptr) 23879 return ira->codegen->invalid_instruction; 23880 23881 if (dest_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 23882 size_t count = bigint_as_usize(&count_val->data.x_bigint); 23883 23884 ZigValue *dest_elements; 23885 size_t dest_start; 23886 size_t dest_end; 23887 switch (dest_ptr_val->data.x_ptr.special) { 23888 case ConstPtrSpecialInvalid: 23889 case ConstPtrSpecialDiscard: 23890 zig_unreachable(); 23891 case ConstPtrSpecialRef: 23892 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 23893 dest_start = 0; 23894 dest_end = 1; 23895 break; 23896 case ConstPtrSpecialBaseArray: 23897 { 23898 ZigValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 23899 expand_undef_array(ira->codegen, array_val); 23900 dest_elements = array_val->data.x_array.data.s_none.elements; 23901 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 23902 dest_end = array_val->type->data.array.len; 23903 break; 23904 } 23905 case ConstPtrSpecialBaseStruct: 23906 zig_panic("TODO memcpy on const inner struct"); 23907 case ConstPtrSpecialBaseErrorUnionCode: 23908 zig_panic("TODO memcpy on const inner error union code"); 23909 case ConstPtrSpecialBaseErrorUnionPayload: 23910 zig_panic("TODO memcpy on const inner error union payload"); 23911 case ConstPtrSpecialBaseOptionalPayload: 23912 zig_panic("TODO memcpy on const inner optional payload"); 23913 case ConstPtrSpecialHardCodedAddr: 23914 zig_unreachable(); 23915 case ConstPtrSpecialFunction: 23916 zig_panic("TODO memcpy on ptr cast from function"); 23917 case ConstPtrSpecialNull: 23918 zig_panic("TODO memcpy on null ptr"); 23919 } 23920 23921 if (dest_start + count > dest_end) { 23922 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); 23923 return ira->codegen->invalid_instruction; 23924 } 23925 23926 ZigValue *src_elements; 23927 size_t src_start; 23928 size_t src_end; 23929 23930 switch (src_ptr_val->data.x_ptr.special) { 23931 case ConstPtrSpecialInvalid: 23932 case ConstPtrSpecialDiscard: 23933 zig_unreachable(); 23934 case ConstPtrSpecialRef: 23935 src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; 23936 src_start = 0; 23937 src_end = 1; 23938 break; 23939 case ConstPtrSpecialBaseArray: 23940 { 23941 ZigValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; 23942 expand_undef_array(ira->codegen, array_val); 23943 src_elements = array_val->data.x_array.data.s_none.elements; 23944 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; 23945 src_end = array_val->type->data.array.len; 23946 break; 23947 } 23948 case ConstPtrSpecialBaseStruct: 23949 zig_panic("TODO memcpy on const inner struct"); 23950 case ConstPtrSpecialBaseErrorUnionCode: 23951 zig_panic("TODO memcpy on const inner error union code"); 23952 case ConstPtrSpecialBaseErrorUnionPayload: 23953 zig_panic("TODO memcpy on const inner error union payload"); 23954 case ConstPtrSpecialBaseOptionalPayload: 23955 zig_panic("TODO memcpy on const inner optional payload"); 23956 case ConstPtrSpecialHardCodedAddr: 23957 zig_unreachable(); 23958 case ConstPtrSpecialFunction: 23959 zig_panic("TODO memcpy on ptr cast from function"); 23960 case ConstPtrSpecialNull: 23961 zig_panic("TODO memcpy on null ptr"); 23962 } 23963 23964 if (src_start + count > src_end) { 23965 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); 23966 return ira->codegen->invalid_instruction; 23967 } 23968 23969 // TODO check for noalias violations - this should be generalized to work for any function 23970 23971 for (size_t i = 0; i < count; i += 1) { 23972 copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); 23973 } 23974 23975 return ir_const_void(ira, &instruction->base); 23976 } 23977 } 23978 23979 IrInstruction *result = ir_build_memcpy(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 23980 casted_dest_ptr, casted_src_ptr, casted_count); 23981 result->value->type = ira->codegen->builtin_types.entry_void; 23982 return result; 23983 } 23984 23985 static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) { 23986 IrInstruction *ptr_ptr = instruction->ptr->child; 23987 if (type_is_invalid(ptr_ptr->value->type)) 23988 return ira->codegen->invalid_instruction; 23989 23990 ZigType *ptr_ptr_type = ptr_ptr->value->type; 23991 assert(ptr_ptr_type->id == ZigTypeIdPointer); 23992 ZigType *array_type = ptr_ptr_type->data.pointer.child_type; 23993 23994 IrInstruction *start = instruction->start->child; 23995 if (type_is_invalid(start->value->type)) 23996 return ira->codegen->invalid_instruction; 23997 23998 ZigType *usize = ira->codegen->builtin_types.entry_usize; 23999 IrInstruction *casted_start = ir_implicit_cast(ira, start, usize); 24000 if (type_is_invalid(casted_start->value->type)) 24001 return ira->codegen->invalid_instruction; 24002 24003 IrInstruction *end; 24004 if (instruction->end) { 24005 end = instruction->end->child; 24006 if (type_is_invalid(end->value->type)) 24007 return ira->codegen->invalid_instruction; 24008 end = ir_implicit_cast(ira, end, usize); 24009 if (type_is_invalid(end->value->type)) 24010 return ira->codegen->invalid_instruction; 24011 } else { 24012 end = nullptr; 24013 } 24014 24015 ZigType *return_type; 24016 24017 if (array_type->id == ZigTypeIdArray) { 24018 bool is_comptime_const = ptr_ptr->value->special == ConstValSpecialStatic && 24019 ptr_ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst; 24020 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type, 24021 ptr_ptr_type->data.pointer.is_const || is_comptime_const, 24022 ptr_ptr_type->data.pointer.is_volatile, 24023 PtrLenUnknown, 24024 ptr_ptr_type->data.pointer.explicit_alignment, 0, 0, false); 24025 return_type = get_slice_type(ira->codegen, slice_ptr_type); 24026 } else if (array_type->id == ZigTypeIdPointer) { 24027 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 24028 ZigType *main_type = array_type->data.pointer.child_type; 24029 if (main_type->id == ZigTypeIdArray) { 24030 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, 24031 main_type->data.pointer.child_type, 24032 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile, 24033 PtrLenUnknown, 24034 array_type->data.pointer.explicit_alignment, 0, 0, false); 24035 return_type = get_slice_type(ira->codegen, slice_ptr_type); 24036 } else { 24037 ir_add_error(ira, &instruction->base, buf_sprintf("slice of single-item pointer")); 24038 return ira->codegen->invalid_instruction; 24039 } 24040 } else { 24041 if (array_type->data.pointer.ptr_len == PtrLenC) { 24042 array_type = adjust_ptr_len(ira->codegen, array_type, PtrLenUnknown); 24043 } 24044 return_type = get_slice_type(ira->codegen, array_type); 24045 if (!end) { 24046 ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value")); 24047 return ira->codegen->invalid_instruction; 24048 } 24049 } 24050 } else if (is_slice(array_type)) { 24051 ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; 24052 return_type = get_slice_type(ira->codegen, ptr_type); 24053 } else { 24054 ir_add_error(ira, &instruction->base, 24055 buf_sprintf("slice of non-array type '%s'", buf_ptr(&array_type->name))); 24056 return ira->codegen->invalid_instruction; 24057 } 24058 24059 if (instr_is_comptime(ptr_ptr) && 24060 value_is_comptime(casted_start->value) && 24061 (!end || value_is_comptime(end->value))) 24062 { 24063 ZigValue *array_val; 24064 ZigValue *parent_ptr; 24065 size_t abs_offset; 24066 size_t rel_end; 24067 bool ptr_is_undef = false; 24068 if (array_type->id == ZigTypeIdArray || 24069 (array_type->id == ZigTypeIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) 24070 { 24071 if (array_type->id == ZigTypeIdPointer) { 24072 ZigType *child_array_type = array_type->data.pointer.child_type; 24073 assert(child_array_type->id == ZigTypeIdArray); 24074 parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.source_node); 24075 if (parent_ptr == nullptr) 24076 return ira->codegen->invalid_instruction; 24077 24078 24079 if (parent_ptr->special == ConstValSpecialUndef) { 24080 array_val = nullptr; 24081 abs_offset = 0; 24082 rel_end = SIZE_MAX; 24083 ptr_is_undef = true; 24084 } else { 24085 array_val = const_ptr_pointee(ira, ira->codegen, parent_ptr, instruction->base.source_node); 24086 if (array_val == nullptr) 24087 return ira->codegen->invalid_instruction; 24088 24089 rel_end = child_array_type->data.array.len; 24090 abs_offset = 0; 24091 } 24092 } else { 24093 array_val = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.source_node); 24094 if (array_val == nullptr) 24095 return ira->codegen->invalid_instruction; 24096 rel_end = array_type->data.array.len; 24097 parent_ptr = nullptr; 24098 abs_offset = 0; 24099 } 24100 } else if (array_type->id == ZigTypeIdPointer) { 24101 assert(array_type->data.pointer.ptr_len == PtrLenUnknown); 24102 parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.source_node); 24103 if (parent_ptr == nullptr) 24104 return ira->codegen->invalid_instruction; 24105 24106 if (parent_ptr->special == ConstValSpecialUndef) { 24107 array_val = nullptr; 24108 abs_offset = 0; 24109 rel_end = SIZE_MAX; 24110 ptr_is_undef = true; 24111 } else switch (parent_ptr->data.x_ptr.special) { 24112 case ConstPtrSpecialInvalid: 24113 case ConstPtrSpecialDiscard: 24114 zig_unreachable(); 24115 case ConstPtrSpecialRef: 24116 if (parent_ptr->data.x_ptr.data.ref.pointee->type->id == ZigTypeIdArray) { 24117 array_val = parent_ptr->data.x_ptr.data.ref.pointee; 24118 abs_offset = 0; 24119 rel_end = array_val->type->data.array.len; 24120 } else { 24121 array_val = nullptr; 24122 abs_offset = SIZE_MAX; 24123 rel_end = 1; 24124 } 24125 break; 24126 case ConstPtrSpecialBaseArray: 24127 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 24128 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 24129 rel_end = array_val->type->data.array.len - abs_offset; 24130 break; 24131 case ConstPtrSpecialBaseStruct: 24132 zig_panic("TODO slice const inner struct"); 24133 case ConstPtrSpecialBaseErrorUnionCode: 24134 zig_panic("TODO slice const inner error union code"); 24135 case ConstPtrSpecialBaseErrorUnionPayload: 24136 zig_panic("TODO slice const inner error union payload"); 24137 case ConstPtrSpecialBaseOptionalPayload: 24138 zig_panic("TODO slice const inner optional payload"); 24139 case ConstPtrSpecialHardCodedAddr: 24140 array_val = nullptr; 24141 abs_offset = 0; 24142 rel_end = SIZE_MAX; 24143 break; 24144 case ConstPtrSpecialFunction: 24145 zig_panic("TODO slice of ptr cast from function"); 24146 case ConstPtrSpecialNull: 24147 zig_panic("TODO slice of null ptr"); 24148 } 24149 } else if (is_slice(array_type)) { 24150 ZigValue *slice_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.source_node); 24151 if (slice_ptr == nullptr) 24152 return ira->codegen->invalid_instruction; 24153 24154 if (slice_ptr->special == ConstValSpecialUndef) { 24155 ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); 24156 return ira->codegen->invalid_instruction; 24157 } 24158 24159 parent_ptr = slice_ptr->data.x_struct.fields[slice_ptr_index]; 24160 if (parent_ptr->special == ConstValSpecialUndef) { 24161 ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); 24162 return ira->codegen->invalid_instruction; 24163 } 24164 24165 ZigValue *len_val = slice_ptr->data.x_struct.fields[slice_len_index]; 24166 24167 switch (parent_ptr->data.x_ptr.special) { 24168 case ConstPtrSpecialInvalid: 24169 case ConstPtrSpecialDiscard: 24170 zig_unreachable(); 24171 case ConstPtrSpecialRef: 24172 array_val = nullptr; 24173 abs_offset = SIZE_MAX; 24174 rel_end = 1; 24175 break; 24176 case ConstPtrSpecialBaseArray: 24177 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 24178 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 24179 rel_end = bigint_as_usize(&len_val->data.x_bigint); 24180 break; 24181 case ConstPtrSpecialBaseStruct: 24182 zig_panic("TODO slice const inner struct"); 24183 case ConstPtrSpecialBaseErrorUnionCode: 24184 zig_panic("TODO slice const inner error union code"); 24185 case ConstPtrSpecialBaseErrorUnionPayload: 24186 zig_panic("TODO slice const inner error union payload"); 24187 case ConstPtrSpecialBaseOptionalPayload: 24188 zig_panic("TODO slice const inner optional payload"); 24189 case ConstPtrSpecialHardCodedAddr: 24190 array_val = nullptr; 24191 abs_offset = 0; 24192 rel_end = bigint_as_usize(&len_val->data.x_bigint); 24193 break; 24194 case ConstPtrSpecialFunction: 24195 zig_panic("TODO slice of slice cast from function"); 24196 case ConstPtrSpecialNull: 24197 zig_panic("TODO slice of null"); 24198 } 24199 } else { 24200 zig_unreachable(); 24201 } 24202 24203 ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad); 24204 if (!start_val) 24205 return ira->codegen->invalid_instruction; 24206 24207 uint64_t start_scalar = bigint_as_u64(&start_val->data.x_bigint); 24208 if (!ptr_is_undef && start_scalar > rel_end) { 24209 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); 24210 return ira->codegen->invalid_instruction; 24211 } 24212 24213 uint64_t end_scalar = rel_end; 24214 if (end) { 24215 ZigValue *end_val = ir_resolve_const(ira, end, UndefBad); 24216 if (!end_val) 24217 return ira->codegen->invalid_instruction; 24218 end_scalar = bigint_as_u64(&end_val->data.x_bigint); 24219 } 24220 if (!ptr_is_undef) { 24221 if (end_scalar > rel_end) { 24222 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); 24223 return ira->codegen->invalid_instruction; 24224 } 24225 if (start_scalar > end_scalar) { 24226 ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); 24227 return ira->codegen->invalid_instruction; 24228 } 24229 } 24230 if (ptr_is_undef && start_scalar != end_scalar) { 24231 ir_add_error(ira, &instruction->base, buf_sprintf("non-zero length slice of undefined pointer")); 24232 return ira->codegen->invalid_instruction; 24233 } 24234 24235 IrInstruction *result = ir_const(ira, &instruction->base, return_type); 24236 ZigValue *out_val = result->value; 24237 out_val->data.x_struct.fields = alloc_const_vals_ptrs(2); 24238 24239 ZigValue *ptr_val = out_val->data.x_struct.fields[slice_ptr_index]; 24240 24241 if (array_val) { 24242 size_t index = abs_offset + start_scalar; 24243 bool is_const = slice_is_const(return_type); 24244 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const, PtrLenUnknown); 24245 if (array_type->id == ZigTypeIdArray) { 24246 ptr_val->data.x_ptr.mut = ptr_ptr->value->data.x_ptr.mut; 24247 } else if (is_slice(array_type)) { 24248 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 24249 } else if (array_type->id == ZigTypeIdPointer) { 24250 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 24251 } 24252 } else if (ptr_is_undef) { 24253 ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type, 24254 slice_is_const(return_type)); 24255 ptr_val->special = ConstValSpecialUndef; 24256 } else switch (parent_ptr->data.x_ptr.special) { 24257 case ConstPtrSpecialInvalid: 24258 case ConstPtrSpecialDiscard: 24259 zig_unreachable(); 24260 case ConstPtrSpecialRef: 24261 init_const_ptr_ref(ira->codegen, ptr_val, 24262 parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); 24263 break; 24264 case ConstPtrSpecialBaseArray: 24265 zig_unreachable(); 24266 case ConstPtrSpecialBaseStruct: 24267 zig_panic("TODO"); 24268 case ConstPtrSpecialBaseErrorUnionCode: 24269 zig_panic("TODO"); 24270 case ConstPtrSpecialBaseErrorUnionPayload: 24271 zig_panic("TODO"); 24272 case ConstPtrSpecialBaseOptionalPayload: 24273 zig_panic("TODO"); 24274 case ConstPtrSpecialHardCodedAddr: 24275 init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, 24276 parent_ptr->type->data.pointer.child_type, 24277 parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, 24278 slice_is_const(return_type)); 24279 break; 24280 case ConstPtrSpecialFunction: 24281 zig_panic("TODO"); 24282 case ConstPtrSpecialNull: 24283 zig_panic("TODO"); 24284 } 24285 24286 ZigValue *len_val = out_val->data.x_struct.fields[slice_len_index]; 24287 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); 24288 24289 return result; 24290 } 24291 24292 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 24293 return_type, nullptr, true, false, true); 24294 if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { 24295 return result_loc; 24296 } 24297 return ir_build_slice_gen(ira, &instruction->base, return_type, 24298 ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc); 24299 } 24300 24301 static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { 24302 Error err; 24303 IrInstruction *container = instruction->container->child; 24304 if (type_is_invalid(container->value->type)) 24305 return ira->codegen->invalid_instruction; 24306 ZigType *container_type = ir_resolve_type(ira, container); 24307 24308 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 24309 return ira->codegen->invalid_instruction; 24310 24311 uint64_t result; 24312 if (type_is_invalid(container_type)) { 24313 return ira->codegen->invalid_instruction; 24314 } else if (container_type->id == ZigTypeIdEnum) { 24315 result = container_type->data.enumeration.src_field_count; 24316 } else if (container_type->id == ZigTypeIdStruct) { 24317 result = container_type->data.structure.src_field_count; 24318 } else if (container_type->id == ZigTypeIdUnion) { 24319 result = container_type->data.unionation.src_field_count; 24320 } else if (container_type->id == ZigTypeIdErrorSet) { 24321 if (!resolve_inferred_error_set(ira->codegen, container_type, instruction->base.source_node)) { 24322 return ira->codegen->invalid_instruction; 24323 } 24324 if (type_is_global_error_set(container_type)) { 24325 ir_add_error(ira, &instruction->base, buf_sprintf("global error set member count not available at comptime")); 24326 return ira->codegen->invalid_instruction; 24327 } 24328 result = container_type->data.error_set.err_count; 24329 } else { 24330 ir_add_error(ira, &instruction->base, buf_sprintf("no value count available for type '%s'", buf_ptr(&container_type->name))); 24331 return ira->codegen->invalid_instruction; 24332 } 24333 24334 return ir_const_unsigned(ira, &instruction->base, result); 24335 } 24336 24337 static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstructionMemberType *instruction) { 24338 Error err; 24339 IrInstruction *container_type_value = instruction->container_type->child; 24340 ZigType *container_type = ir_resolve_type(ira, container_type_value); 24341 if (type_is_invalid(container_type)) 24342 return ira->codegen->invalid_instruction; 24343 24344 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 24345 return ira->codegen->invalid_instruction; 24346 24347 24348 uint64_t member_index; 24349 IrInstruction *index_value = instruction->member_index->child; 24350 if (!ir_resolve_usize(ira, index_value, &member_index)) 24351 return ira->codegen->invalid_instruction; 24352 24353 if (container_type->id == ZigTypeIdStruct) { 24354 if (member_index >= container_type->data.structure.src_field_count) { 24355 ir_add_error(ira, index_value, 24356 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 24357 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); 24358 return ira->codegen->invalid_instruction; 24359 } 24360 TypeStructField *field = container_type->data.structure.fields[member_index]; 24361 24362 return ir_const_type(ira, &instruction->base, field->type_entry); 24363 } else if (container_type->id == ZigTypeIdUnion) { 24364 if (member_index >= container_type->data.unionation.src_field_count) { 24365 ir_add_error(ira, index_value, 24366 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 24367 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); 24368 return ira->codegen->invalid_instruction; 24369 } 24370 TypeUnionField *field = &container_type->data.unionation.fields[member_index]; 24371 24372 return ir_const_type(ira, &instruction->base, field->type_entry); 24373 } else { 24374 ir_add_error(ira, container_type_value, 24375 buf_sprintf("type '%s' does not support @memberType", buf_ptr(&container_type->name))); 24376 return ira->codegen->invalid_instruction; 24377 } 24378 } 24379 24380 static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstructionMemberName *instruction) { 24381 Error err; 24382 IrInstruction *container_type_value = instruction->container_type->child; 24383 ZigType *container_type = ir_resolve_type(ira, container_type_value); 24384 if (type_is_invalid(container_type)) 24385 return ira->codegen->invalid_instruction; 24386 24387 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 24388 return ira->codegen->invalid_instruction; 24389 24390 uint64_t member_index; 24391 IrInstruction *index_value = instruction->member_index->child; 24392 if (!ir_resolve_usize(ira, index_value, &member_index)) 24393 return ira->codegen->invalid_instruction; 24394 24395 if (container_type->id == ZigTypeIdStruct) { 24396 if (member_index >= container_type->data.structure.src_field_count) { 24397 ir_add_error(ira, index_value, 24398 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 24399 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); 24400 return ira->codegen->invalid_instruction; 24401 } 24402 TypeStructField *field = container_type->data.structure.fields[member_index]; 24403 24404 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 24405 init_const_str_lit(ira->codegen, result->value, field->name); 24406 return result; 24407 } else if (container_type->id == ZigTypeIdEnum) { 24408 if (member_index >= container_type->data.enumeration.src_field_count) { 24409 ir_add_error(ira, index_value, 24410 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 24411 member_index, buf_ptr(&container_type->name), container_type->data.enumeration.src_field_count)); 24412 return ira->codegen->invalid_instruction; 24413 } 24414 TypeEnumField *field = &container_type->data.enumeration.fields[member_index]; 24415 24416 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 24417 init_const_str_lit(ira->codegen, result->value, field->name); 24418 return result; 24419 } else if (container_type->id == ZigTypeIdUnion) { 24420 if (member_index >= container_type->data.unionation.src_field_count) { 24421 ir_add_error(ira, index_value, 24422 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 24423 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); 24424 return ira->codegen->invalid_instruction; 24425 } 24426 TypeUnionField *field = &container_type->data.unionation.fields[member_index]; 24427 24428 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 24429 init_const_str_lit(ira->codegen, result->value, field->name); 24430 return result; 24431 } else { 24432 ir_add_error(ira, container_type_value, 24433 buf_sprintf("type '%s' does not support @memberName", buf_ptr(&container_type->name))); 24434 return ira->codegen->invalid_instruction; 24435 } 24436 } 24437 24438 static IrInstruction *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstructionHasField *instruction) { 24439 Error err; 24440 ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); 24441 if (type_is_invalid(container_type)) 24442 return ira->codegen->invalid_instruction; 24443 24444 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusZeroBitsKnown))) 24445 return ira->codegen->invalid_instruction; 24446 24447 Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); 24448 if (field_name == nullptr) 24449 return ira->codegen->invalid_instruction; 24450 24451 bool result; 24452 if (container_type->id == ZigTypeIdStruct) { 24453 result = find_struct_type_field(container_type, field_name) != nullptr; 24454 } else if (container_type->id == ZigTypeIdEnum) { 24455 result = find_enum_type_field(container_type, field_name) != nullptr; 24456 } else if (container_type->id == ZigTypeIdUnion) { 24457 result = find_union_type_field(container_type, field_name) != nullptr; 24458 } else { 24459 ir_add_error(ira, instruction->container_type, 24460 buf_sprintf("type '%s' does not support @hasField", buf_ptr(&container_type->name))); 24461 return ira->codegen->invalid_instruction; 24462 } 24463 return ir_const_bool(ira, &instruction->base, result); 24464 } 24465 24466 static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) { 24467 IrInstruction *result = ir_build_breakpoint(&ira->new_irb, 24468 instruction->base.scope, instruction->base.source_node); 24469 result->value->type = ira->codegen->builtin_types.entry_void; 24470 return result; 24471 } 24472 24473 static IrInstruction *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstructionReturnAddress *instruction) { 24474 IrInstruction *result = ir_build_return_address(&ira->new_irb, 24475 instruction->base.scope, instruction->base.source_node); 24476 result->value->type = ira->codegen->builtin_types.entry_usize; 24477 return result; 24478 } 24479 24480 static IrInstruction *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstructionFrameAddress *instruction) { 24481 IrInstruction *result = ir_build_frame_address(&ira->new_irb, 24482 instruction->base.scope, instruction->base.source_node); 24483 result->value->type = ira->codegen->builtin_types.entry_usize; 24484 return result; 24485 } 24486 24487 static IrInstruction *ir_analyze_instruction_frame_handle(IrAnalyze *ira, IrInstructionFrameHandle *instruction) { 24488 ZigFn *fn = exec_fn_entry(ira->new_irb.exec); 24489 ir_assert(fn != nullptr, &instruction->base); 24490 24491 if (fn->inferred_async_node == nullptr) { 24492 fn->inferred_async_node = instruction->base.source_node; 24493 } 24494 24495 ZigType *frame_type = get_fn_frame_type(ira->codegen, fn); 24496 ZigType *ptr_frame_type = get_pointer_to_type(ira->codegen, frame_type, false); 24497 24498 IrInstruction *result = ir_build_handle(&ira->new_irb, instruction->base.scope, instruction->base.source_node); 24499 result->value->type = ptr_frame_type; 24500 return result; 24501 } 24502 24503 static IrInstruction *ir_analyze_instruction_frame_type(IrAnalyze *ira, IrInstructionFrameType *instruction) { 24504 ZigFn *fn = ir_resolve_fn(ira, instruction->fn->child); 24505 if (fn == nullptr) 24506 return ira->codegen->invalid_instruction; 24507 24508 if (fn->type_entry->data.fn.is_generic) { 24509 ir_add_error(ira, &instruction->base, 24510 buf_sprintf("@Frame() of generic function")); 24511 return ira->codegen->invalid_instruction; 24512 } 24513 24514 ZigType *ty = get_fn_frame_type(ira->codegen, fn); 24515 return ir_const_type(ira, &instruction->base, ty); 24516 } 24517 24518 static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstructionFrameSizeSrc *instruction) { 24519 IrInstruction *fn = instruction->fn->child; 24520 if (type_is_invalid(fn->value->type)) 24521 return ira->codegen->invalid_instruction; 24522 24523 if (fn->value->type->id != ZigTypeIdFn) { 24524 ir_add_error(ira, fn, 24525 buf_sprintf("expected function, found '%s'", buf_ptr(&fn->value->type->name))); 24526 return ira->codegen->invalid_instruction; 24527 } 24528 24529 ira->codegen->need_frame_size_prefix_data = true; 24530 24531 IrInstruction *result = ir_build_frame_size_gen(&ira->new_irb, instruction->base.scope, 24532 instruction->base.source_node, fn); 24533 result->value->type = ira->codegen->builtin_types.entry_usize; 24534 return result; 24535 } 24536 24537 static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { 24538 // Here we create a lazy value in order to avoid resolving the alignment of the type 24539 // immediately. This avoids false positive dependency loops such as: 24540 // const Node = struct { 24541 // field: []align(@alignOf(Node)) Node, 24542 // }; 24543 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); 24544 result->value->special = ConstValSpecialLazy; 24545 24546 LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1); 24547 lazy_align_of->ira = ira; 24548 result->value->data.x_lazy = &lazy_align_of->base; 24549 lazy_align_of->base.id = LazyValueIdAlignOf; 24550 24551 lazy_align_of->target_type = instruction->type_value->child; 24552 if (ir_resolve_type_lazy(ira, lazy_align_of->target_type) == nullptr) 24553 return ira->codegen->invalid_instruction; 24554 24555 return result; 24556 } 24557 24558 static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { 24559 Error err; 24560 24561 IrInstruction *type_value = instruction->type_value->child; 24562 if (type_is_invalid(type_value->value->type)) 24563 return ira->codegen->invalid_instruction; 24564 24565 ZigType *dest_type = ir_resolve_type(ira, type_value); 24566 if (type_is_invalid(dest_type)) 24567 return ira->codegen->invalid_instruction; 24568 24569 if (dest_type->id != ZigTypeIdInt) { 24570 ir_add_error(ira, type_value, 24571 buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 24572 return ira->codegen->invalid_instruction; 24573 } 24574 24575 IrInstruction *op1 = instruction->op1->child; 24576 if (type_is_invalid(op1->value->type)) 24577 return ira->codegen->invalid_instruction; 24578 24579 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 24580 if (type_is_invalid(casted_op1->value->type)) 24581 return ira->codegen->invalid_instruction; 24582 24583 IrInstruction *op2 = instruction->op2->child; 24584 if (type_is_invalid(op2->value->type)) 24585 return ira->codegen->invalid_instruction; 24586 24587 IrInstruction *casted_op2; 24588 if (instruction->op == IrOverflowOpShl) { 24589 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 24590 dest_type->data.integral.bit_count - 1); 24591 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 24592 } else { 24593 casted_op2 = ir_implicit_cast(ira, op2, dest_type); 24594 } 24595 if (type_is_invalid(casted_op2->value->type)) 24596 return ira->codegen->invalid_instruction; 24597 24598 IrInstruction *result_ptr = instruction->result_ptr->child; 24599 if (type_is_invalid(result_ptr->value->type)) 24600 return ira->codegen->invalid_instruction; 24601 24602 ZigType *expected_ptr_type; 24603 if (result_ptr->value->type->id == ZigTypeIdPointer) { 24604 uint32_t alignment; 24605 if ((err = resolve_ptr_align(ira, result_ptr->value->type, &alignment))) 24606 return ira->codegen->invalid_instruction; 24607 expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type, 24608 false, result_ptr->value->type->data.pointer.is_volatile, 24609 PtrLenSingle, 24610 alignment, 0, 0, false); 24611 } else { 24612 expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false); 24613 } 24614 24615 IrInstruction *casted_result_ptr = ir_implicit_cast(ira, result_ptr, expected_ptr_type); 24616 if (type_is_invalid(casted_result_ptr->value->type)) 24617 return ira->codegen->invalid_instruction; 24618 24619 if (instr_is_comptime(casted_op1) && 24620 instr_is_comptime(casted_op2) && 24621 instr_is_comptime(casted_result_ptr)) 24622 { 24623 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 24624 if (op1_val == nullptr) 24625 return ira->codegen->invalid_instruction; 24626 24627 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 24628 if (op2_val == nullptr) 24629 return ira->codegen->invalid_instruction; 24630 24631 ZigValue *result_val = ir_resolve_const(ira, casted_result_ptr, UndefBad); 24632 if (result_val == nullptr) 24633 return ira->codegen->invalid_instruction; 24634 24635 BigInt *op1_bigint = &op1_val->data.x_bigint; 24636 BigInt *op2_bigint = &op2_val->data.x_bigint; 24637 ZigValue *pointee_val = const_ptr_pointee(ira, ira->codegen, result_val, 24638 casted_result_ptr->source_node); 24639 if (pointee_val == nullptr) 24640 return ira->codegen->invalid_instruction; 24641 BigInt *dest_bigint = &pointee_val->data.x_bigint; 24642 switch (instruction->op) { 24643 case IrOverflowOpAdd: 24644 bigint_add(dest_bigint, op1_bigint, op2_bigint); 24645 break; 24646 case IrOverflowOpSub: 24647 bigint_sub(dest_bigint, op1_bigint, op2_bigint); 24648 break; 24649 case IrOverflowOpMul: 24650 bigint_mul(dest_bigint, op1_bigint, op2_bigint); 24651 break; 24652 case IrOverflowOpShl: 24653 bigint_shl(dest_bigint, op1_bigint, op2_bigint); 24654 break; 24655 } 24656 bool result_bool = false; 24657 if (!bigint_fits_in_bits(dest_bigint, dest_type->data.integral.bit_count, 24658 dest_type->data.integral.is_signed)) 24659 { 24660 result_bool = true; 24661 BigInt tmp_bigint; 24662 bigint_init_bigint(&tmp_bigint, dest_bigint); 24663 bigint_truncate(dest_bigint, &tmp_bigint, dest_type->data.integral.bit_count, 24664 dest_type->data.integral.is_signed); 24665 } 24666 pointee_val->special = ConstValSpecialStatic; 24667 return ir_const_bool(ira, &instruction->base, result_bool); 24668 } 24669 24670 IrInstruction *result = ir_build_overflow_op(&ira->new_irb, 24671 instruction->base.scope, instruction->base.source_node, 24672 instruction->op, type_value, casted_op1, casted_op2, casted_result_ptr, dest_type); 24673 result->value->type = ira->codegen->builtin_types.entry_bool; 24674 return result; 24675 } 24676 24677 static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, ZigType *float_type, 24678 ZigValue *op1, ZigValue *op2, ZigValue *op3, ZigValue *out_val) { 24679 if (float_type->id == ZigTypeIdComptimeFloat) { 24680 f128M_mulAdd(&out_val->data.x_bigfloat.value, &op1->data.x_bigfloat.value, &op2->data.x_bigfloat.value, 24681 &op3->data.x_bigfloat.value); 24682 } else if (float_type->id == ZigTypeIdFloat) { 24683 switch (float_type->data.floating.bit_count) { 24684 case 16: 24685 out_val->data.x_f16 = f16_mulAdd(op1->data.x_f16, op2->data.x_f16, op3->data.x_f16); 24686 break; 24687 case 32: 24688 out_val->data.x_f32 = fmaf(op1->data.x_f32, op2->data.x_f32, op3->data.x_f32); 24689 break; 24690 case 64: 24691 out_val->data.x_f64 = fma(op1->data.x_f64, op2->data.x_f64, op3->data.x_f64); 24692 break; 24693 case 128: 24694 f128M_mulAdd(&op1->data.x_f128, &op2->data.x_f128, &op3->data.x_f128, &out_val->data.x_f128); 24695 break; 24696 default: 24697 zig_unreachable(); 24698 } 24699 } else { 24700 zig_unreachable(); 24701 } 24702 } 24703 24704 static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructionMulAdd *instruction) { 24705 IrInstruction *type_value = instruction->type_value->child; 24706 if (type_is_invalid(type_value->value->type)) 24707 return ira->codegen->invalid_instruction; 24708 24709 ZigType *expr_type = ir_resolve_type(ira, type_value); 24710 if (type_is_invalid(expr_type)) 24711 return ira->codegen->invalid_instruction; 24712 24713 // Only allow float types, and vectors of floats. 24714 ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 24715 if (float_type->id != ZigTypeIdFloat) { 24716 ir_add_error(ira, type_value, 24717 buf_sprintf("expected float or vector of float type, found '%s'", buf_ptr(&float_type->name))); 24718 return ira->codegen->invalid_instruction; 24719 } 24720 24721 IrInstruction *op1 = instruction->op1->child; 24722 if (type_is_invalid(op1->value->type)) 24723 return ira->codegen->invalid_instruction; 24724 24725 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, expr_type); 24726 if (type_is_invalid(casted_op1->value->type)) 24727 return ira->codegen->invalid_instruction; 24728 24729 IrInstruction *op2 = instruction->op2->child; 24730 if (type_is_invalid(op2->value->type)) 24731 return ira->codegen->invalid_instruction; 24732 24733 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, expr_type); 24734 if (type_is_invalid(casted_op2->value->type)) 24735 return ira->codegen->invalid_instruction; 24736 24737 IrInstruction *op3 = instruction->op3->child; 24738 if (type_is_invalid(op3->value->type)) 24739 return ira->codegen->invalid_instruction; 24740 24741 IrInstruction *casted_op3 = ir_implicit_cast(ira, op3, expr_type); 24742 if (type_is_invalid(casted_op3->value->type)) 24743 return ira->codegen->invalid_instruction; 24744 24745 if (instr_is_comptime(casted_op1) && 24746 instr_is_comptime(casted_op2) && 24747 instr_is_comptime(casted_op3)) { 24748 ZigValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); 24749 if (!op1_const) 24750 return ira->codegen->invalid_instruction; 24751 ZigValue *op2_const = ir_resolve_const(ira, casted_op2, UndefBad); 24752 if (!op2_const) 24753 return ira->codegen->invalid_instruction; 24754 ZigValue *op3_const = ir_resolve_const(ira, casted_op3, UndefBad); 24755 if (!op3_const) 24756 return ira->codegen->invalid_instruction; 24757 24758 IrInstruction *result = ir_const(ira, &instruction->base, expr_type); 24759 ZigValue *out_val = result->value; 24760 24761 if (expr_type->id == ZigTypeIdVector) { 24762 expand_undef_array(ira->codegen, op1_const); 24763 expand_undef_array(ira->codegen, op2_const); 24764 expand_undef_array(ira->codegen, op3_const); 24765 out_val->special = ConstValSpecialUndef; 24766 expand_undef_array(ira->codegen, out_val); 24767 size_t len = expr_type->data.vector.len; 24768 for (size_t i = 0; i < len; i += 1) { 24769 ZigValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i]; 24770 ZigValue *float_operand_op2 = &op2_const->data.x_array.data.s_none.elements[i]; 24771 ZigValue *float_operand_op3 = &op3_const->data.x_array.data.s_none.elements[i]; 24772 ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; 24773 assert(float_operand_op1->type == float_type); 24774 assert(float_operand_op2->type == float_type); 24775 assert(float_operand_op3->type == float_type); 24776 assert(float_out_val->type == float_type); 24777 ir_eval_mul_add(ira, instruction, float_type, 24778 op1_const, op2_const, op3_const, float_out_val); 24779 float_out_val->type = float_type; 24780 } 24781 out_val->type = expr_type; 24782 out_val->special = ConstValSpecialStatic; 24783 } else { 24784 ir_eval_mul_add(ira, instruction, float_type, op1_const, op2_const, op3_const, out_val); 24785 } 24786 return result; 24787 } 24788 24789 IrInstruction *result = ir_build_mul_add(&ira->new_irb, 24790 instruction->base.scope, instruction->base.source_node, 24791 type_value, casted_op1, casted_op2, casted_op3); 24792 result->value->type = expr_type; 24793 return result; 24794 } 24795 24796 static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErrSrc *instruction) { 24797 IrInstruction *base_ptr = instruction->base_ptr->child; 24798 if (type_is_invalid(base_ptr->value->type)) 24799 return ira->codegen->invalid_instruction; 24800 24801 IrInstruction *value; 24802 if (instruction->base_ptr_is_payload) { 24803 value = base_ptr; 24804 } else { 24805 value = ir_get_deref(ira, &instruction->base, base_ptr, nullptr); 24806 } 24807 24808 ZigType *type_entry = value->value->type; 24809 if (type_is_invalid(type_entry)) 24810 return ira->codegen->invalid_instruction; 24811 if (type_entry->id == ZigTypeIdErrorUnion) { 24812 if (instr_is_comptime(value)) { 24813 ZigValue *err_union_val = ir_resolve_const(ira, value, UndefBad); 24814 if (!err_union_val) 24815 return ira->codegen->invalid_instruction; 24816 24817 if (err_union_val->special != ConstValSpecialRuntime) { 24818 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 24819 return ir_const_bool(ira, &instruction->base, (err != nullptr)); 24820 } 24821 } 24822 24823 if (instruction->resolve_err_set) { 24824 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 24825 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { 24826 return ira->codegen->invalid_instruction; 24827 } 24828 if (!type_is_global_error_set(err_set_type) && 24829 err_set_type->data.error_set.err_count == 0) 24830 { 24831 assert(!err_set_type->data.error_set.incomplete); 24832 return ir_const_bool(ira, &instruction->base, false); 24833 } 24834 } 24835 24836 return ir_build_test_err_gen(ira, &instruction->base, value); 24837 } else if (type_entry->id == ZigTypeIdErrorSet) { 24838 return ir_const_bool(ira, &instruction->base, true); 24839 } else { 24840 return ir_const_bool(ira, &instruction->base, false); 24841 } 24842 } 24843 24844 static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, 24845 IrInstruction *base_ptr, bool initializing) 24846 { 24847 ZigType *ptr_type = base_ptr->value->type; 24848 24849 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 24850 assert(ptr_type->id == ZigTypeIdPointer); 24851 24852 ZigType *type_entry = ptr_type->data.pointer.child_type; 24853 if (type_is_invalid(type_entry)) 24854 return ira->codegen->invalid_instruction; 24855 24856 if (type_entry->id != ZigTypeIdErrorUnion) { 24857 ir_add_error(ira, base_ptr, 24858 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 24859 return ira->codegen->invalid_instruction; 24860 } 24861 24862 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 24863 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type, 24864 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 24865 ptr_type->data.pointer.explicit_alignment, 0, 0, false); 24866 24867 if (instr_is_comptime(base_ptr)) { 24868 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 24869 if (!ptr_val) 24870 return ira->codegen->invalid_instruction; 24871 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && 24872 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) 24873 { 24874 ZigValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 24875 if (err_union_val == nullptr) 24876 return ira->codegen->invalid_instruction; 24877 24878 if (initializing && err_union_val->special == ConstValSpecialUndef) { 24879 ZigValue *vals = create_const_vals(2); 24880 ZigValue *err_set_val = &vals[0]; 24881 ZigValue *payload_val = &vals[1]; 24882 24883 err_set_val->special = ConstValSpecialUndef; 24884 err_set_val->type = err_set_type; 24885 err_set_val->parent.id = ConstParentIdErrUnionCode; 24886 err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val; 24887 24888 payload_val->special = ConstValSpecialUndef; 24889 payload_val->type = type_entry->data.error_union.payload_type; 24890 payload_val->parent.id = ConstParentIdErrUnionPayload; 24891 payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val; 24892 24893 err_union_val->special = ConstValSpecialStatic; 24894 err_union_val->data.x_err_union.error_set = err_set_val; 24895 err_union_val->data.x_err_union.payload = payload_val; 24896 } 24897 ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr); 24898 24899 IrInstruction *result; 24900 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 24901 result = ir_build_unwrap_err_code(&ira->new_irb, source_instr->scope, 24902 source_instr->source_node, base_ptr); 24903 result->value->type = result_type; 24904 result->value->special = ConstValSpecialStatic; 24905 } else { 24906 result = ir_const(ira, source_instr, result_type); 24907 } 24908 ZigValue *const_val = result->value; 24909 const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode; 24910 const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val; 24911 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 24912 return result; 24913 } 24914 } 24915 24916 IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, 24917 source_instr->scope, source_instr->source_node, base_ptr); 24918 result->value->type = result_type; 24919 return result; 24920 } 24921 24922 static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, 24923 IrInstructionUnwrapErrCode *instruction) 24924 { 24925 IrInstruction *base_ptr = instruction->err_union_ptr->child; 24926 if (type_is_invalid(base_ptr->value->type)) 24927 return ira->codegen->invalid_instruction; 24928 return ir_analyze_unwrap_err_code(ira, &instruction->base, base_ptr, false); 24929 } 24930 24931 static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, 24932 IrInstruction *base_ptr, bool safety_check_on, bool initializing) 24933 { 24934 ZigType *ptr_type = base_ptr->value->type; 24935 24936 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 24937 assert(ptr_type->id == ZigTypeIdPointer); 24938 24939 ZigType *type_entry = ptr_type->data.pointer.child_type; 24940 if (type_is_invalid(type_entry)) 24941 return ira->codegen->invalid_instruction; 24942 24943 if (type_entry->id != ZigTypeIdErrorUnion) { 24944 ir_add_error(ira, base_ptr, 24945 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 24946 return ira->codegen->invalid_instruction; 24947 } 24948 24949 ZigType *payload_type = type_entry->data.error_union.payload_type; 24950 if (type_is_invalid(payload_type)) 24951 return ira->codegen->invalid_instruction; 24952 24953 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, 24954 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 24955 PtrLenSingle, 0, 0, 0, false); 24956 if (instr_is_comptime(base_ptr)) { 24957 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 24958 if (!ptr_val) 24959 return ira->codegen->invalid_instruction; 24960 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 24961 ZigValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 24962 if (err_union_val == nullptr) 24963 return ira->codegen->invalid_instruction; 24964 if (initializing && err_union_val->special == ConstValSpecialUndef) { 24965 ZigValue *vals = create_const_vals(2); 24966 ZigValue *err_set_val = &vals[0]; 24967 ZigValue *payload_val = &vals[1]; 24968 24969 err_set_val->special = ConstValSpecialStatic; 24970 err_set_val->type = type_entry->data.error_union.err_set_type; 24971 err_set_val->data.x_err_set = nullptr; 24972 24973 payload_val->special = ConstValSpecialUndef; 24974 payload_val->type = payload_type; 24975 24976 err_union_val->special = ConstValSpecialStatic; 24977 err_union_val->data.x_err_union.error_set = err_set_val; 24978 err_union_val->data.x_err_union.payload = payload_val; 24979 } 24980 24981 if (err_union_val->special != ConstValSpecialRuntime) { 24982 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 24983 if (err != nullptr) { 24984 ir_add_error(ira, source_instr, 24985 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); 24986 return ira->codegen->invalid_instruction; 24987 } 24988 24989 IrInstruction *result; 24990 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 24991 result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, 24992 source_instr->source_node, base_ptr, safety_check_on, initializing); 24993 result->value->type = result_type; 24994 result->value->special = ConstValSpecialStatic; 24995 } else { 24996 result = ir_const(ira, source_instr, result_type); 24997 } 24998 result->value->data.x_ptr.special = ConstPtrSpecialRef; 24999 result->value->data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; 25000 result->value->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 25001 return result; 25002 } 25003 } 25004 } 25005 25006 IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, 25007 source_instr->source_node, base_ptr, safety_check_on, initializing); 25008 result->value->type = result_type; 25009 return result; 25010 } 25011 25012 static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, 25013 IrInstructionUnwrapErrPayload *instruction) 25014 { 25015 assert(instruction->value->child); 25016 IrInstruction *value = instruction->value->child; 25017 if (type_is_invalid(value->value->type)) 25018 return ira->codegen->invalid_instruction; 25019 25020 return ir_analyze_unwrap_error_payload(ira, &instruction->base, value, instruction->safety_check_on, false); 25021 } 25022 25023 static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { 25024 AstNode *proto_node = instruction->base.source_node; 25025 assert(proto_node->type == NodeTypeFnProto); 25026 25027 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); 25028 result->value->special = ConstValSpecialLazy; 25029 25030 LazyValueFnType *lazy_fn_type = allocate<LazyValueFnType>(1); 25031 lazy_fn_type->ira = ira; 25032 result->value->data.x_lazy = &lazy_fn_type->base; 25033 lazy_fn_type->base.id = LazyValueIdFnType; 25034 25035 if (proto_node->data.fn_proto.auto_err_set) { 25036 ir_add_error(ira, &instruction->base, 25037 buf_sprintf("inferring error set of return type valid only for function definitions")); 25038 return ira->codegen->invalid_instruction; 25039 } 25040 25041 size_t param_count = proto_node->data.fn_proto.params.length; 25042 lazy_fn_type->proto_node = proto_node; 25043 lazy_fn_type->param_types = allocate<IrInstruction *>(param_count); 25044 25045 for (size_t param_index = 0; param_index < param_count; param_index += 1) { 25046 AstNode *param_node = proto_node->data.fn_proto.params.at(param_index); 25047 assert(param_node->type == NodeTypeParamDecl); 25048 25049 bool param_is_var_args = param_node->data.param_decl.is_var_args; 25050 if (param_is_var_args) { 25051 if (proto_node->data.fn_proto.cc == CallingConventionC) { 25052 break; 25053 } else if (proto_node->data.fn_proto.cc == CallingConventionUnspecified) { 25054 lazy_fn_type->is_generic = true; 25055 return result; 25056 } else { 25057 zig_unreachable(); 25058 } 25059 } 25060 25061 if (instruction->param_types[param_index] == nullptr) { 25062 lazy_fn_type->is_generic = true; 25063 return result; 25064 } 25065 25066 IrInstruction *param_type_value = instruction->param_types[param_index]->child; 25067 if (type_is_invalid(param_type_value->value->type)) 25068 return ira->codegen->invalid_instruction; 25069 if (ir_resolve_const(ira, param_type_value, LazyOk) == nullptr) 25070 return ira->codegen->invalid_instruction; 25071 lazy_fn_type->param_types[param_index] = param_type_value; 25072 } 25073 25074 if (instruction->align_value != nullptr) { 25075 lazy_fn_type->align_inst = instruction->align_value->child; 25076 if (ir_resolve_const(ira, lazy_fn_type->align_inst, LazyOk) == nullptr) 25077 return ira->codegen->invalid_instruction; 25078 } 25079 25080 lazy_fn_type->return_type = instruction->return_type->child; 25081 if (ir_resolve_const(ira, lazy_fn_type->return_type, LazyOk) == nullptr) 25082 return ira->codegen->invalid_instruction; 25083 25084 return result; 25085 } 25086 25087 static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { 25088 IrInstruction *value = instruction->value->child; 25089 if (type_is_invalid(value->value->type)) 25090 return ira->codegen->invalid_instruction; 25091 25092 return ir_const_bool(ira, &instruction->base, instr_is_comptime(value)); 25093 } 25094 25095 static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, 25096 IrInstructionCheckSwitchProngs *instruction) 25097 { 25098 IrInstruction *target_value = instruction->target_value->child; 25099 ZigType *switch_type = target_value->value->type; 25100 if (type_is_invalid(switch_type)) 25101 return ira->codegen->invalid_instruction; 25102 25103 if (switch_type->id == ZigTypeIdEnum) { 25104 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> field_prev_uses = {}; 25105 field_prev_uses.init(switch_type->data.enumeration.src_field_count); 25106 25107 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 25108 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 25109 25110 IrInstruction *start_value_uncasted = range->start->child; 25111 if (type_is_invalid(start_value_uncasted->value->type)) 25112 return ira->codegen->invalid_instruction; 25113 IrInstruction *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 25114 if (type_is_invalid(start_value->value->type)) 25115 return ira->codegen->invalid_instruction; 25116 25117 IrInstruction *end_value_uncasted = range->end->child; 25118 if (type_is_invalid(end_value_uncasted->value->type)) 25119 return ira->codegen->invalid_instruction; 25120 IrInstruction *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 25121 if (type_is_invalid(end_value->value->type)) 25122 return ira->codegen->invalid_instruction; 25123 25124 BigInt start_index; 25125 bigint_init_bigint(&start_index, &start_value->value->data.x_enum_tag); 25126 25127 assert(end_value->value->type->id == ZigTypeIdEnum); 25128 BigInt end_index; 25129 bigint_init_bigint(&end_index, &end_value->value->data.x_enum_tag); 25130 25131 BigInt field_index; 25132 bigint_init_bigint(&field_index, &start_index); 25133 for (;;) { 25134 Cmp cmp = bigint_cmp(&field_index, &end_index); 25135 if (cmp == CmpGT) { 25136 break; 25137 } 25138 auto entry = field_prev_uses.put_unique(field_index, start_value->source_node); 25139 if (entry) { 25140 AstNode *prev_node = entry->value; 25141 TypeEnumField *enum_field = find_enum_field_by_tag(switch_type, &field_index); 25142 assert(enum_field != nullptr); 25143 ErrorMsg *msg = ir_add_error(ira, start_value, 25144 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), 25145 buf_ptr(enum_field->name))); 25146 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 25147 } 25148 bigint_incr(&field_index); 25149 } 25150 } 25151 if (!instruction->have_else_prong) { 25152 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { 25153 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; 25154 25155 auto entry = field_prev_uses.maybe_get(enum_field->value); 25156 if (!entry) { 25157 ir_add_error(ira, &instruction->base, 25158 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), 25159 buf_ptr(enum_field->name))); 25160 } 25161 } 25162 } 25163 } else if (switch_type->id == ZigTypeIdErrorSet) { 25164 if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->source_node)) { 25165 return ira->codegen->invalid_instruction; 25166 } 25167 25168 size_t field_prev_uses_count = ira->codegen->errors_by_index.length; 25169 AstNode **field_prev_uses = allocate<AstNode *>(field_prev_uses_count, "AstNode *"); 25170 25171 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 25172 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 25173 25174 IrInstruction *start_value_uncasted = range->start->child; 25175 if (type_is_invalid(start_value_uncasted->value->type)) 25176 return ira->codegen->invalid_instruction; 25177 IrInstruction *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 25178 if (type_is_invalid(start_value->value->type)) 25179 return ira->codegen->invalid_instruction; 25180 25181 IrInstruction *end_value_uncasted = range->end->child; 25182 if (type_is_invalid(end_value_uncasted->value->type)) 25183 return ira->codegen->invalid_instruction; 25184 IrInstruction *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 25185 if (type_is_invalid(end_value->value->type)) 25186 return ira->codegen->invalid_instruction; 25187 25188 ir_assert(start_value->value->type->id == ZigTypeIdErrorSet, &instruction->base); 25189 uint32_t start_index = start_value->value->data.x_err_set->value; 25190 25191 ir_assert(end_value->value->type->id == ZigTypeIdErrorSet, &instruction->base); 25192 uint32_t end_index = end_value->value->data.x_err_set->value; 25193 25194 if (start_index != end_index) { 25195 ir_add_error(ira, end_value, buf_sprintf("ranges not allowed when switching on errors")); 25196 return ira->codegen->invalid_instruction; 25197 } 25198 25199 AstNode *prev_node = field_prev_uses[start_index]; 25200 if (prev_node != nullptr) { 25201 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name; 25202 ErrorMsg *msg = ir_add_error(ira, start_value, 25203 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name))); 25204 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 25205 } 25206 field_prev_uses[start_index] = start_value->source_node; 25207 } 25208 if (!instruction->have_else_prong) { 25209 if (type_is_global_error_set(switch_type)) { 25210 ir_add_error(ira, &instruction->base, 25211 buf_sprintf("else prong required when switching on type 'anyerror'")); 25212 return ira->codegen->invalid_instruction; 25213 } else { 25214 for (uint32_t i = 0; i < switch_type->data.error_set.err_count; i += 1) { 25215 ErrorTableEntry *err_entry = switch_type->data.error_set.errors[i]; 25216 25217 AstNode *prev_node = field_prev_uses[err_entry->value]; 25218 if (prev_node == nullptr) { 25219 ir_add_error(ira, &instruction->base, 25220 buf_sprintf("error.%s not handled in switch", buf_ptr(&err_entry->name))); 25221 } 25222 } 25223 } 25224 } 25225 25226 deallocate(field_prev_uses, field_prev_uses_count, "AstNode *"); 25227 } else if (switch_type->id == ZigTypeIdInt) { 25228 RangeSet rs = {0}; 25229 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 25230 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 25231 25232 IrInstruction *start_value = range->start->child; 25233 if (type_is_invalid(start_value->value->type)) 25234 return ira->codegen->invalid_instruction; 25235 IrInstruction *casted_start_value = ir_implicit_cast(ira, start_value, switch_type); 25236 if (type_is_invalid(casted_start_value->value->type)) 25237 return ira->codegen->invalid_instruction; 25238 25239 IrInstruction *end_value = range->end->child; 25240 if (type_is_invalid(end_value->value->type)) 25241 return ira->codegen->invalid_instruction; 25242 IrInstruction *casted_end_value = ir_implicit_cast(ira, end_value, switch_type); 25243 if (type_is_invalid(casted_end_value->value->type)) 25244 return ira->codegen->invalid_instruction; 25245 25246 ZigValue *start_val = ir_resolve_const(ira, casted_start_value, UndefBad); 25247 if (!start_val) 25248 return ira->codegen->invalid_instruction; 25249 25250 ZigValue *end_val = ir_resolve_const(ira, casted_end_value, UndefBad); 25251 if (!end_val) 25252 return ira->codegen->invalid_instruction; 25253 25254 assert(start_val->type->id == ZigTypeIdInt || start_val->type->id == ZigTypeIdComptimeInt); 25255 assert(end_val->type->id == ZigTypeIdInt || end_val->type->id == ZigTypeIdComptimeInt); 25256 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint, 25257 start_value->source_node); 25258 if (prev_node != nullptr) { 25259 ErrorMsg *msg = ir_add_error(ira, start_value, buf_sprintf("duplicate switch value")); 25260 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("previous value is here")); 25261 return ira->codegen->invalid_instruction; 25262 } 25263 } 25264 if (!instruction->have_else_prong) { 25265 BigInt min_val; 25266 eval_min_max_value_int(ira->codegen, switch_type, &min_val, false); 25267 BigInt max_val; 25268 eval_min_max_value_int(ira->codegen, switch_type, &max_val, true); 25269 if (!rangeset_spans(&rs, &min_val, &max_val)) { 25270 ir_add_error(ira, &instruction->base, buf_sprintf("switch must handle all possibilities")); 25271 return ira->codegen->invalid_instruction; 25272 } 25273 } 25274 } else if (switch_type->id == ZigTypeIdBool) { 25275 int seenTrue = 0; 25276 int seenFalse = 0; 25277 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 25278 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 25279 25280 IrInstruction *value = range->start->child; 25281 25282 IrInstruction *casted_value = ir_implicit_cast(ira, value, switch_type); 25283 if (type_is_invalid(casted_value->value->type)) 25284 return ira->codegen->invalid_instruction; 25285 25286 ZigValue *const_expr_val = ir_resolve_const(ira, casted_value, UndefBad); 25287 if (!const_expr_val) 25288 return ira->codegen->invalid_instruction; 25289 25290 assert(const_expr_val->type->id == ZigTypeIdBool); 25291 25292 if (const_expr_val->data.x_bool == true) { 25293 seenTrue += 1; 25294 } else { 25295 seenFalse += 1; 25296 } 25297 25298 if ((seenTrue > 1) || (seenFalse > 1)) { 25299 ir_add_error(ira, value, buf_sprintf("duplicate switch value")); 25300 return ira->codegen->invalid_instruction; 25301 } 25302 } 25303 if (((seenTrue < 1) || (seenFalse < 1)) && !instruction->have_else_prong) { 25304 ir_add_error(ira, &instruction->base, buf_sprintf("switch must handle all possibilities")); 25305 return ira->codegen->invalid_instruction; 25306 } 25307 } else if (!instruction->have_else_prong) { 25308 ir_add_error(ira, &instruction->base, 25309 buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); 25310 return ira->codegen->invalid_instruction; 25311 } 25312 return ir_const_void(ira, &instruction->base); 25313 } 25314 25315 static IrInstruction *ir_analyze_instruction_check_statement_is_void(IrAnalyze *ira, 25316 IrInstructionCheckStatementIsVoid *instruction) 25317 { 25318 IrInstruction *statement_value = instruction->statement_value->child; 25319 ZigType *statement_type = statement_value->value->type; 25320 if (type_is_invalid(statement_type)) 25321 return ira->codegen->invalid_instruction; 25322 25323 if (statement_type->id != ZigTypeIdVoid && statement_type->id != ZigTypeIdUnreachable) { 25324 ir_add_error(ira, &instruction->base, buf_sprintf("expression value is ignored")); 25325 } 25326 25327 return ir_const_void(ira, &instruction->base); 25328 } 25329 25330 static IrInstruction *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructionPanic *instruction) { 25331 IrInstruction *msg = instruction->msg->child; 25332 if (type_is_invalid(msg->value->type)) 25333 return ir_unreach_error(ira); 25334 25335 if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) { 25336 ir_add_error(ira, &instruction->base, buf_sprintf("encountered @panic at compile-time")); 25337 return ir_unreach_error(ira); 25338 } 25339 25340 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 25341 true, false, PtrLenUnknown, 0, 0, 0, false); 25342 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 25343 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type); 25344 if (type_is_invalid(casted_msg->value->type)) 25345 return ir_unreach_error(ira); 25346 25347 IrInstruction *new_instruction = ir_build_panic(&ira->new_irb, instruction->base.scope, 25348 instruction->base.source_node, casted_msg); 25349 return ir_finish_anal(ira, new_instruction); 25350 } 25351 25352 static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint32_t align_bytes, bool safety_check_on) { 25353 Error err; 25354 25355 ZigType *target_type = target->value->type; 25356 assert(!type_is_invalid(target_type)); 25357 25358 ZigType *result_type; 25359 uint32_t old_align_bytes; 25360 25361 if (target_type->id == ZigTypeIdPointer) { 25362 result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes); 25363 if ((err = resolve_ptr_align(ira, target_type, &old_align_bytes))) 25364 return ira->codegen->invalid_instruction; 25365 } else if (target_type->id == ZigTypeIdFn) { 25366 FnTypeId fn_type_id = target_type->data.fn.fn_type_id; 25367 old_align_bytes = fn_type_id.alignment; 25368 fn_type_id.alignment = align_bytes; 25369 result_type = get_fn_type(ira->codegen, &fn_type_id); 25370 } else if (target_type->id == ZigTypeIdOptional && 25371 target_type->data.maybe.child_type->id == ZigTypeIdPointer) 25372 { 25373 ZigType *ptr_type = target_type->data.maybe.child_type; 25374 if ((err = resolve_ptr_align(ira, ptr_type, &old_align_bytes))) 25375 return ira->codegen->invalid_instruction; 25376 ZigType *better_ptr_type = adjust_ptr_align(ira->codegen, ptr_type, align_bytes); 25377 25378 result_type = get_optional_type(ira->codegen, better_ptr_type); 25379 } else if (target_type->id == ZigTypeIdOptional && 25380 target_type->data.maybe.child_type->id == ZigTypeIdFn) 25381 { 25382 FnTypeId fn_type_id = target_type->data.maybe.child_type->data.fn.fn_type_id; 25383 old_align_bytes = fn_type_id.alignment; 25384 fn_type_id.alignment = align_bytes; 25385 ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id); 25386 result_type = get_optional_type(ira->codegen, fn_type); 25387 } else if (is_slice(target_type)) { 25388 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry; 25389 if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes))) 25390 return ira->codegen->invalid_instruction; 25391 ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes); 25392 result_type = get_slice_type(ira->codegen, result_ptr_type); 25393 } else { 25394 ir_add_error(ira, target, 25395 buf_sprintf("expected pointer or slice, found '%s'", buf_ptr(&target_type->name))); 25396 return ira->codegen->invalid_instruction; 25397 } 25398 25399 if (instr_is_comptime(target)) { 25400 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 25401 if (!val) 25402 return ira->codegen->invalid_instruction; 25403 25404 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 25405 val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0) 25406 { 25407 ir_add_error(ira, target, 25408 buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes", 25409 val->data.x_ptr.data.hard_coded_addr.addr, align_bytes)); 25410 return ira->codegen->invalid_instruction; 25411 } 25412 25413 IrInstruction *result = ir_const(ira, target, result_type); 25414 copy_const_val(result->value, val, true); 25415 result->value->type = result_type; 25416 return result; 25417 } 25418 25419 IrInstruction *result; 25420 if (safety_check_on && align_bytes > old_align_bytes && align_bytes != 1) { 25421 result = ir_build_align_cast(&ira->new_irb, target->scope, target->source_node, nullptr, target); 25422 } else { 25423 result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, result_type, target, CastOpNoop); 25424 } 25425 result->value->type = result_type; 25426 return result; 25427 } 25428 25429 static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, 25430 ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on) 25431 { 25432 Error err; 25433 25434 ZigType *src_type = ptr->value->type; 25435 assert(!type_is_invalid(src_type)); 25436 25437 if (src_type == dest_type) { 25438 return ptr; 25439 } 25440 25441 // We have a check for zero bits later so we use get_src_ptr_type to 25442 // validate src_type and dest_type. 25443 25444 ZigType *src_ptr_type = get_src_ptr_type(src_type); 25445 if (src_ptr_type == nullptr) { 25446 ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); 25447 return ira->codegen->invalid_instruction; 25448 } 25449 25450 ZigType *dest_ptr_type = get_src_ptr_type(dest_type); 25451 if (dest_ptr_type == nullptr) { 25452 ir_add_error(ira, dest_type_src, 25453 buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 25454 return ira->codegen->invalid_instruction; 25455 } 25456 25457 if (get_ptr_const(src_type) && !get_ptr_const(dest_type)) { 25458 ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); 25459 return ira->codegen->invalid_instruction; 25460 } 25461 uint32_t src_align_bytes; 25462 if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) 25463 return ira->codegen->invalid_instruction; 25464 25465 uint32_t dest_align_bytes; 25466 if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) 25467 return ira->codegen->invalid_instruction; 25468 25469 if (instr_is_comptime(ptr)) { 25470 bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); 25471 UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad; 25472 ZigValue *val = ir_resolve_const(ira, ptr, is_undef_allowed); 25473 if (!val) 25474 return ira->codegen->invalid_instruction; 25475 25476 if (value_is_comptime(val) && val->special != ConstValSpecialUndef) { 25477 bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || 25478 (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 25479 val->data.x_ptr.data.hard_coded_addr.addr == 0); 25480 if (is_addr_zero && !dest_allows_addr_zero) { 25481 ir_add_error(ira, source_instr, 25482 buf_sprintf("null pointer casted to type '%s'", buf_ptr(&dest_type->name))); 25483 return ira->codegen->invalid_instruction; 25484 } 25485 } 25486 25487 IrInstruction *result; 25488 if (ptr->value->data.x_ptr.mut == ConstPtrMutInfer) { 25489 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); 25490 25491 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 25492 return ira->codegen->invalid_instruction; 25493 } else { 25494 result = ir_const(ira, source_instr, dest_type); 25495 } 25496 copy_const_val(result->value, val, true); 25497 result->value->type = dest_type; 25498 25499 // Keep the bigger alignment, it can only help- 25500 // unless the target is zero bits. 25501 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { 25502 result = ir_align_cast(ira, result, src_align_bytes, false); 25503 } 25504 25505 return result; 25506 } 25507 25508 if (dest_align_bytes > src_align_bytes) { 25509 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 25510 add_error_note(ira->codegen, msg, ptr->source_node, 25511 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); 25512 add_error_note(ira->codegen, msg, dest_type_src->source_node, 25513 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_type->name), dest_align_bytes)); 25514 return ira->codegen->invalid_instruction; 25515 } 25516 25517 IrInstruction *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); 25518 25519 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 25520 return ira->codegen->invalid_instruction; 25521 25522 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) 25523 return ira->codegen->invalid_instruction; 25524 25525 if (type_has_bits(dest_type) && !type_has_bits(src_type)) { 25526 ErrorMsg *msg = ir_add_error(ira, source_instr, 25527 buf_sprintf("'%s' and '%s' do not have the same in-memory representation", 25528 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 25529 add_error_note(ira->codegen, msg, ptr->source_node, 25530 buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name))); 25531 add_error_note(ira->codegen, msg, dest_type_src->source_node, 25532 buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name))); 25533 return ira->codegen->invalid_instruction; 25534 } 25535 25536 // Keep the bigger alignment, it can only help- 25537 // unless the target is zero bits. 25538 IrInstruction *result; 25539 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { 25540 result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); 25541 if (type_is_invalid(result->value->type)) 25542 return ira->codegen->invalid_instruction; 25543 } else { 25544 result = casted_ptr; 25545 } 25546 return result; 25547 } 25548 25549 static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtrCastSrc *instruction) { 25550 IrInstruction *dest_type_value = instruction->dest_type->child; 25551 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 25552 if (type_is_invalid(dest_type)) 25553 return ira->codegen->invalid_instruction; 25554 25555 IrInstruction *ptr = instruction->ptr->child; 25556 ZigType *src_type = ptr->value->type; 25557 if (type_is_invalid(src_type)) 25558 return ira->codegen->invalid_instruction; 25559 25560 return ir_analyze_ptr_cast(ira, &instruction->base, ptr, dest_type, dest_type_value, 25561 instruction->safety_check_on); 25562 } 25563 25564 static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ZigValue *val, size_t len) { 25565 size_t buf_i = 0; 25566 // TODO optimize the buf case 25567 expand_undef_array(codegen, val); 25568 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) { 25569 ZigValue *elem = &val->data.x_array.data.s_none.elements[elem_i]; 25570 buf_write_value_bytes(codegen, &buf[buf_i], elem); 25571 buf_i += type_size(codegen, elem->type); 25572 } 25573 } 25574 25575 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val) { 25576 if (val->special == ConstValSpecialUndef) { 25577 expand_undef_struct(codegen, val); 25578 val->special = ConstValSpecialStatic; 25579 } 25580 assert(val->special == ConstValSpecialStatic); 25581 switch (val->type->id) { 25582 case ZigTypeIdInvalid: 25583 case ZigTypeIdMetaType: 25584 case ZigTypeIdOpaque: 25585 case ZigTypeIdBoundFn: 25586 case ZigTypeIdArgTuple: 25587 case ZigTypeIdUnreachable: 25588 case ZigTypeIdComptimeFloat: 25589 case ZigTypeIdComptimeInt: 25590 case ZigTypeIdEnumLiteral: 25591 case ZigTypeIdUndefined: 25592 case ZigTypeIdNull: 25593 case ZigTypeIdErrorUnion: 25594 case ZigTypeIdErrorSet: 25595 zig_unreachable(); 25596 case ZigTypeIdVoid: 25597 return; 25598 case ZigTypeIdBool: 25599 buf[0] = val->data.x_bool ? 1 : 0; 25600 return; 25601 case ZigTypeIdInt: 25602 bigint_write_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 25603 codegen->is_big_endian); 25604 return; 25605 case ZigTypeIdEnum: 25606 bigint_write_twos_complement(&val->data.x_enum_tag, buf, 25607 val->type->data.enumeration.tag_int_type->data.integral.bit_count, 25608 codegen->is_big_endian); 25609 return; 25610 case ZigTypeIdFloat: 25611 float_write_ieee597(val, buf, codegen->is_big_endian); 25612 return; 25613 case ZigTypeIdPointer: 25614 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 25615 BigInt bn; 25616 bigint_init_unsigned(&bn, val->data.x_ptr.data.hard_coded_addr.addr); 25617 bigint_write_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, codegen->is_big_endian); 25618 return; 25619 } else { 25620 zig_unreachable(); 25621 } 25622 case ZigTypeIdArray: 25623 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.array.len); 25624 case ZigTypeIdVector: 25625 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.vector.len); 25626 case ZigTypeIdStruct: 25627 switch (val->type->data.structure.layout) { 25628 case ContainerLayoutAuto: 25629 zig_unreachable(); 25630 case ContainerLayoutExtern: { 25631 size_t src_field_count = val->type->data.structure.src_field_count; 25632 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 25633 TypeStructField *struct_field = val->type->data.structure.fields[field_i]; 25634 if (struct_field->gen_index == SIZE_MAX) 25635 continue; 25636 ZigValue *field_val = val->data.x_struct.fields[field_i]; 25637 size_t offset = struct_field->offset; 25638 buf_write_value_bytes(codegen, buf + offset, field_val); 25639 } 25640 return; 25641 } 25642 case ContainerLayoutPacked: { 25643 size_t src_field_count = val->type->data.structure.src_field_count; 25644 size_t gen_field_count = val->type->data.structure.gen_field_count; 25645 size_t gen_i = 0; 25646 size_t src_i = 0; 25647 size_t offset = 0; 25648 bool is_big_endian = codegen->is_big_endian; 25649 uint8_t child_buf_prealloc[16]; 25650 size_t child_buf_len = 16; 25651 uint8_t *child_buf = child_buf_prealloc; 25652 while (gen_i < gen_field_count) { 25653 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 25654 if (big_int_byte_count > child_buf_len) { 25655 child_buf = allocate_nonzero<uint8_t>(big_int_byte_count); 25656 child_buf_len = big_int_byte_count; 25657 } 25658 BigInt big_int; 25659 bigint_init_unsigned(&big_int, 0); 25660 size_t used_bits = 0; 25661 while (src_i < src_field_count) { 25662 TypeStructField *field = val->type->data.structure.fields[src_i]; 25663 assert(field->gen_index != SIZE_MAX); 25664 if (field->gen_index != gen_i) 25665 break; 25666 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 25667 buf_write_value_bytes(codegen, child_buf, val->data.x_struct.fields[src_i]); 25668 BigInt child_val; 25669 bigint_read_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian, 25670 false); 25671 if (is_big_endian) { 25672 BigInt shift_amt; 25673 bigint_init_unsigned(&shift_amt, packed_bits_size); 25674 BigInt shifted; 25675 bigint_shl(&shifted, &big_int, &shift_amt); 25676 bigint_or(&big_int, &shifted, &child_val); 25677 } else { 25678 BigInt shift_amt; 25679 bigint_init_unsigned(&shift_amt, used_bits); 25680 BigInt child_val_shifted; 25681 bigint_shl(&child_val_shifted, &child_val, &shift_amt); 25682 BigInt tmp; 25683 bigint_or(&tmp, &big_int, &child_val_shifted); 25684 big_int = tmp; 25685 used_bits += packed_bits_size; 25686 } 25687 src_i += 1; 25688 } 25689 bigint_write_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian); 25690 offset += big_int_byte_count; 25691 gen_i += 1; 25692 } 25693 return; 25694 } 25695 } 25696 case ZigTypeIdOptional: 25697 zig_panic("TODO buf_write_value_bytes maybe type"); 25698 case ZigTypeIdFn: 25699 zig_panic("TODO buf_write_value_bytes fn type"); 25700 case ZigTypeIdUnion: 25701 zig_panic("TODO buf_write_value_bytes union type"); 25702 case ZigTypeIdFnFrame: 25703 zig_panic("TODO buf_write_value_bytes async fn frame type"); 25704 case ZigTypeIdAnyFrame: 25705 zig_panic("TODO buf_write_value_bytes anyframe type"); 25706 } 25707 zig_unreachable(); 25708 } 25709 25710 static Error buf_read_value_bytes_array(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, 25711 ZigValue *val, ZigType *elem_type, size_t len) 25712 { 25713 Error err; 25714 uint64_t elem_size = type_size(codegen, elem_type); 25715 25716 switch (val->data.x_array.special) { 25717 case ConstArraySpecialNone: 25718 val->data.x_array.data.s_none.elements = create_const_vals(len); 25719 for (size_t i = 0; i < len; i++) { 25720 ZigValue *elem = &val->data.x_array.data.s_none.elements[i]; 25721 elem->special = ConstValSpecialStatic; 25722 elem->type = elem_type; 25723 if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem))) 25724 return err; 25725 } 25726 return ErrorNone; 25727 case ConstArraySpecialUndef: 25728 zig_panic("TODO buf_read_value_bytes ConstArraySpecialUndef array type"); 25729 case ConstArraySpecialBuf: 25730 zig_panic("TODO buf_read_value_bytes ConstArraySpecialBuf array type"); 25731 } 25732 zig_unreachable(); 25733 } 25734 25735 static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ZigValue *val) { 25736 Error err; 25737 src_assert(val->special == ConstValSpecialStatic, source_node); 25738 switch (val->type->id) { 25739 case ZigTypeIdInvalid: 25740 case ZigTypeIdMetaType: 25741 case ZigTypeIdOpaque: 25742 case ZigTypeIdBoundFn: 25743 case ZigTypeIdArgTuple: 25744 case ZigTypeIdUnreachable: 25745 case ZigTypeIdComptimeFloat: 25746 case ZigTypeIdComptimeInt: 25747 case ZigTypeIdEnumLiteral: 25748 case ZigTypeIdUndefined: 25749 case ZigTypeIdNull: 25750 zig_unreachable(); 25751 case ZigTypeIdVoid: 25752 return ErrorNone; 25753 case ZigTypeIdBool: 25754 val->data.x_bool = (buf[0] != 0); 25755 return ErrorNone; 25756 case ZigTypeIdInt: 25757 bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 25758 codegen->is_big_endian, val->type->data.integral.is_signed); 25759 return ErrorNone; 25760 case ZigTypeIdFloat: 25761 float_read_ieee597(val, buf, codegen->is_big_endian); 25762 return ErrorNone; 25763 case ZigTypeIdPointer: 25764 { 25765 val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 25766 BigInt bn; 25767 bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, 25768 codegen->is_big_endian, false); 25769 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_usize(&bn); 25770 return ErrorNone; 25771 } 25772 case ZigTypeIdArray: 25773 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.array.child_type, 25774 val->type->data.array.len); 25775 case ZigTypeIdVector: 25776 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.vector.elem_type, 25777 val->type->data.vector.len); 25778 case ZigTypeIdEnum: 25779 switch (val->type->data.enumeration.layout) { 25780 case ContainerLayoutAuto: 25781 zig_panic("TODO buf_read_value_bytes enum auto"); 25782 case ContainerLayoutPacked: 25783 zig_panic("TODO buf_read_value_bytes enum packed"); 25784 case ContainerLayoutExtern: { 25785 ZigType *tag_int_type = val->type->data.enumeration.tag_int_type; 25786 src_assert(tag_int_type->id == ZigTypeIdInt, source_node); 25787 bigint_read_twos_complement(&val->data.x_enum_tag, buf, tag_int_type->data.integral.bit_count, 25788 codegen->is_big_endian, tag_int_type->data.integral.is_signed); 25789 return ErrorNone; 25790 } 25791 } 25792 zig_unreachable(); 25793 case ZigTypeIdStruct: 25794 switch (val->type->data.structure.layout) { 25795 case ContainerLayoutAuto: { 25796 ErrorMsg *msg = opt_ir_add_error_node(ira, codegen, source_node, 25797 buf_sprintf("non-extern, non-packed struct '%s' cannot have its bytes reinterpreted", 25798 buf_ptr(&val->type->name))); 25799 add_error_note(codegen, msg, val->type->data.structure.decl_node, 25800 buf_sprintf("declared here")); 25801 return ErrorSemanticAnalyzeFail; 25802 } 25803 case ContainerLayoutExtern: { 25804 size_t src_field_count = val->type->data.structure.src_field_count; 25805 val->data.x_struct.fields = alloc_const_vals_ptrs(src_field_count); 25806 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 25807 ZigValue *field_val = val->data.x_struct.fields[field_i]; 25808 field_val->special = ConstValSpecialStatic; 25809 TypeStructField *struct_field = val->type->data.structure.fields[field_i]; 25810 field_val->type = struct_field->type_entry; 25811 if (struct_field->gen_index == SIZE_MAX) 25812 continue; 25813 size_t offset = struct_field->offset; 25814 uint8_t *new_buf = buf + offset; 25815 if ((err = buf_read_value_bytes(ira, codegen, source_node, new_buf, field_val))) 25816 return err; 25817 } 25818 return ErrorNone; 25819 } 25820 case ContainerLayoutPacked: { 25821 size_t src_field_count = val->type->data.structure.src_field_count; 25822 val->data.x_struct.fields = alloc_const_vals_ptrs(src_field_count); 25823 size_t gen_field_count = val->type->data.structure.gen_field_count; 25824 size_t gen_i = 0; 25825 size_t src_i = 0; 25826 size_t offset = 0; 25827 bool is_big_endian = codegen->is_big_endian; 25828 uint8_t child_buf_prealloc[16]; 25829 size_t child_buf_len = 16; 25830 uint8_t *child_buf = child_buf_prealloc; 25831 while (gen_i < gen_field_count) { 25832 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 25833 if (big_int_byte_count > child_buf_len) { 25834 child_buf = allocate_nonzero<uint8_t>(big_int_byte_count); 25835 child_buf_len = big_int_byte_count; 25836 } 25837 BigInt big_int; 25838 bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false); 25839 while (src_i < src_field_count) { 25840 TypeStructField *field = val->type->data.structure.fields[src_i]; 25841 src_assert(field->gen_index != SIZE_MAX, source_node); 25842 if (field->gen_index != gen_i) 25843 break; 25844 ZigValue *field_val = val->data.x_struct.fields[src_i]; 25845 field_val->special = ConstValSpecialStatic; 25846 field_val->type = field->type_entry; 25847 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 25848 25849 BigInt child_val; 25850 if (is_big_endian) { 25851 zig_panic("TODO buf_read_value_bytes packed struct big endian"); 25852 } else { 25853 BigInt packed_bits_size_bi; 25854 bigint_init_unsigned(&packed_bits_size_bi, packed_bits_size); 25855 bigint_truncate(&child_val, &big_int, packed_bits_size, false); 25856 BigInt tmp; 25857 bigint_shr(&tmp, &big_int, &packed_bits_size_bi); 25858 big_int = tmp; 25859 } 25860 25861 bigint_write_twos_complement(&child_val, child_buf, big_int_byte_count * 8, is_big_endian); 25862 if ((err = buf_read_value_bytes(ira, codegen, source_node, child_buf, field_val))) { 25863 return err; 25864 } 25865 25866 src_i += 1; 25867 } 25868 offset += big_int_byte_count; 25869 gen_i += 1; 25870 } 25871 return ErrorNone; 25872 } 25873 } 25874 zig_unreachable(); 25875 case ZigTypeIdOptional: 25876 zig_panic("TODO buf_read_value_bytes maybe type"); 25877 case ZigTypeIdErrorUnion: 25878 zig_panic("TODO buf_read_value_bytes error union"); 25879 case ZigTypeIdErrorSet: 25880 zig_panic("TODO buf_read_value_bytes pure error type"); 25881 case ZigTypeIdFn: 25882 zig_panic("TODO buf_read_value_bytes fn type"); 25883 case ZigTypeIdUnion: 25884 zig_panic("TODO buf_read_value_bytes union type"); 25885 case ZigTypeIdFnFrame: 25886 zig_panic("TODO buf_read_value_bytes async fn frame type"); 25887 case ZigTypeIdAnyFrame: 25888 zig_panic("TODO buf_read_value_bytes anyframe type"); 25889 } 25890 zig_unreachable(); 25891 } 25892 25893 static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 25894 ZigType *dest_type) 25895 { 25896 Error err; 25897 25898 ZigType *src_type = value->value->type; 25899 ir_assert(get_codegen_ptr_type(src_type) == nullptr, source_instr); 25900 ir_assert(type_can_bit_cast(src_type), source_instr); 25901 ir_assert(get_codegen_ptr_type(dest_type) == nullptr, source_instr); 25902 ir_assert(type_can_bit_cast(dest_type), source_instr); 25903 25904 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown))) 25905 return ira->codegen->invalid_instruction; 25906 25907 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown))) 25908 return ira->codegen->invalid_instruction; 25909 25910 25911 uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); 25912 uint64_t src_size_bytes = type_size(ira->codegen, src_type); 25913 if (dest_size_bytes != src_size_bytes) { 25914 ir_add_error(ira, source_instr, 25915 buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64, 25916 buf_ptr(&dest_type->name), dest_size_bytes, 25917 buf_ptr(&src_type->name), src_size_bytes)); 25918 return ira->codegen->invalid_instruction; 25919 } 25920 25921 uint64_t dest_size_bits = type_size_bits(ira->codegen, dest_type); 25922 uint64_t src_size_bits = type_size_bits(ira->codegen, src_type); 25923 if (dest_size_bits != src_size_bits) { 25924 ir_add_error(ira, source_instr, 25925 buf_sprintf("destination type '%s' has %" ZIG_PRI_u64 " bits but source type '%s' has %" ZIG_PRI_u64 " bits", 25926 buf_ptr(&dest_type->name), dest_size_bits, 25927 buf_ptr(&src_type->name), src_size_bits)); 25928 return ira->codegen->invalid_instruction; 25929 } 25930 25931 if (instr_is_comptime(value)) { 25932 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 25933 if (!val) 25934 return ira->codegen->invalid_instruction; 25935 25936 IrInstruction *result = ir_const(ira, source_instr, dest_type); 25937 uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes); 25938 buf_write_value_bytes(ira->codegen, buf, val); 25939 if ((err = buf_read_value_bytes(ira, ira->codegen, source_instr->source_node, buf, result->value))) 25940 return ira->codegen->invalid_instruction; 25941 return result; 25942 } 25943 25944 return ir_build_bit_cast_gen(ira, source_instr, value, dest_type); 25945 } 25946 25947 static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 25948 ZigType *ptr_type) 25949 { 25950 ir_assert(get_src_ptr_type(ptr_type) != nullptr, source_instr); 25951 ir_assert(type_has_bits(ptr_type), source_instr); 25952 25953 IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); 25954 if (type_is_invalid(casted_int->value->type)) 25955 return ira->codegen->invalid_instruction; 25956 25957 if (instr_is_comptime(casted_int)) { 25958 ZigValue *val = ir_resolve_const(ira, casted_int, UndefBad); 25959 if (!val) 25960 return ira->codegen->invalid_instruction; 25961 25962 uint64_t addr = bigint_as_u64(&val->data.x_bigint); 25963 if (!ptr_allows_addr_zero(ptr_type) && addr == 0) { 25964 ir_add_error(ira, source_instr, 25965 buf_sprintf("pointer type '%s' does not allow address zero", buf_ptr(&ptr_type->name))); 25966 return ira->codegen->invalid_instruction; 25967 } 25968 25969 IrInstruction *result = ir_const(ira, source_instr, ptr_type); 25970 result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 25971 result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; 25972 result->value->data.x_ptr.data.hard_coded_addr.addr = addr; 25973 return result; 25974 } 25975 25976 IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, source_instr->scope, 25977 source_instr->source_node, nullptr, casted_int); 25978 result->value->type = ptr_type; 25979 return result; 25980 } 25981 25982 static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) { 25983 Error err; 25984 IrInstruction *dest_type_value = instruction->dest_type->child; 25985 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 25986 if (type_is_invalid(dest_type)) 25987 return ira->codegen->invalid_instruction; 25988 25989 // We explicitly check for the size, so we can use get_src_ptr_type 25990 if (get_src_ptr_type(dest_type) == nullptr) { 25991 ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 25992 return ira->codegen->invalid_instruction; 25993 } 25994 25995 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 25996 return ira->codegen->invalid_instruction; 25997 if (!type_has_bits(dest_type)) { 25998 ir_add_error(ira, dest_type_value, 25999 buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name))); 26000 return ira->codegen->invalid_instruction; 26001 } 26002 26003 26004 IrInstruction *target = instruction->target->child; 26005 if (type_is_invalid(target->value->type)) 26006 return ira->codegen->invalid_instruction; 26007 26008 return ir_analyze_int_to_ptr(ira, &instruction->base, target, dest_type); 26009 } 26010 26011 static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, 26012 IrInstructionDeclRef *instruction) 26013 { 26014 IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld); 26015 if (type_is_invalid(ref_instruction->value->type)) { 26016 return ira->codegen->invalid_instruction; 26017 } 26018 26019 if (instruction->lval == LValPtr) { 26020 return ref_instruction; 26021 } else { 26022 return ir_get_deref(ira, &instruction->base, ref_instruction, nullptr); 26023 } 26024 } 26025 26026 static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { 26027 Error err; 26028 IrInstruction *target = instruction->target->child; 26029 if (type_is_invalid(target->value->type)) 26030 return ira->codegen->invalid_instruction; 26031 26032 ZigType *usize = ira->codegen->builtin_types.entry_usize; 26033 26034 // We check size explicitly so we can use get_src_ptr_type here. 26035 if (get_src_ptr_type(target->value->type) == nullptr) { 26036 ir_add_error(ira, target, 26037 buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value->type->name))); 26038 return ira->codegen->invalid_instruction; 26039 } 26040 26041 if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusZeroBitsKnown))) 26042 return ira->codegen->invalid_instruction; 26043 if (!type_has_bits(target->value->type)) { 26044 ir_add_error(ira, target, 26045 buf_sprintf("pointer to size 0 type has no address")); 26046 return ira->codegen->invalid_instruction; 26047 } 26048 26049 if (instr_is_comptime(target)) { 26050 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 26051 if (!val) 26052 return ira->codegen->invalid_instruction; 26053 if (val->type->id == ZigTypeIdPointer && val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 26054 IrInstruction *result = ir_const(ira, &instruction->base, usize); 26055 bigint_init_unsigned(&result->value->data.x_bigint, val->data.x_ptr.data.hard_coded_addr.addr); 26056 result->value->type = usize; 26057 return result; 26058 } 26059 } 26060 26061 IrInstruction *result = ir_build_ptr_to_int(&ira->new_irb, instruction->base.scope, 26062 instruction->base.source_node, target); 26063 result->value->type = usize; 26064 return result; 26065 } 26066 26067 static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) { 26068 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); 26069 result->value->special = ConstValSpecialLazy; 26070 26071 LazyValuePtrType *lazy_ptr_type = allocate<LazyValuePtrType>(1); 26072 lazy_ptr_type->ira = ira; 26073 result->value->data.x_lazy = &lazy_ptr_type->base; 26074 lazy_ptr_type->base.id = LazyValueIdPtrType; 26075 26076 if (instruction->sentinel != nullptr) { 26077 lazy_ptr_type->sentinel = instruction->sentinel->child; 26078 if (ir_resolve_const(ira, lazy_ptr_type->sentinel, LazyOk) == nullptr) 26079 return ira->codegen->invalid_instruction; 26080 } 26081 26082 lazy_ptr_type->elem_type = instruction->child_type->child; 26083 if (ir_resolve_type_lazy(ira, lazy_ptr_type->elem_type) == nullptr) 26084 return ira->codegen->invalid_instruction; 26085 26086 if (instruction->align_value != nullptr) { 26087 lazy_ptr_type->align_inst = instruction->align_value->child; 26088 if (ir_resolve_const(ira, lazy_ptr_type->align_inst, LazyOk) == nullptr) 26089 return ira->codegen->invalid_instruction; 26090 } 26091 26092 lazy_ptr_type->ptr_len = instruction->ptr_len; 26093 lazy_ptr_type->is_const = instruction->is_const; 26094 lazy_ptr_type->is_volatile = instruction->is_volatile; 26095 lazy_ptr_type->is_allowzero = instruction->is_allow_zero; 26096 lazy_ptr_type->bit_offset_in_host = instruction->bit_offset_start; 26097 lazy_ptr_type->host_int_bytes = instruction->host_int_bytes; 26098 26099 return result; 26100 } 26101 26102 static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstructionAlignCast *instruction) { 26103 IrInstruction *target = instruction->target->child; 26104 if (type_is_invalid(target->value->type)) 26105 return ira->codegen->invalid_instruction; 26106 26107 ZigType *elem_type = nullptr; 26108 if (is_slice(target->value->type)) { 26109 ZigType *slice_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry; 26110 elem_type = slice_ptr_type->data.pointer.child_type; 26111 } else if (target->value->type->id == ZigTypeIdPointer) { 26112 elem_type = target->value->type->data.pointer.child_type; 26113 } 26114 26115 uint32_t align_bytes; 26116 IrInstruction *align_bytes_inst = instruction->align_bytes->child; 26117 if (!ir_resolve_align(ira, align_bytes_inst, elem_type, &align_bytes)) 26118 return ira->codegen->invalid_instruction; 26119 26120 IrInstruction *result = ir_align_cast(ira, target, align_bytes, true); 26121 if (type_is_invalid(result->value->type)) 26122 return ira->codegen->invalid_instruction; 26123 26124 return result; 26125 } 26126 26127 static IrInstruction *ir_analyze_instruction_opaque_type(IrAnalyze *ira, IrInstructionOpaqueType *instruction) { 26128 Buf *bare_name = buf_alloc(); 26129 Buf *full_name = get_anon_type_name(ira->codegen, ira->new_irb.exec, "opaque", 26130 instruction->base.scope, instruction->base.source_node, bare_name); 26131 ZigType *result_type = get_opaque_type(ira->codegen, instruction->base.scope, instruction->base.source_node, 26132 buf_ptr(full_name), bare_name); 26133 return ir_const_type(ira, &instruction->base, result_type); 26134 } 26135 26136 static IrInstruction *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstructionSetAlignStack *instruction) { 26137 uint32_t align_bytes; 26138 IrInstruction *align_bytes_inst = instruction->align_bytes->child; 26139 if (!ir_resolve_align(ira, align_bytes_inst, nullptr, &align_bytes)) 26140 return ira->codegen->invalid_instruction; 26141 26142 if (align_bytes > 256) { 26143 ir_add_error(ira, &instruction->base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes)); 26144 return ira->codegen->invalid_instruction; 26145 } 26146 26147 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 26148 if (fn_entry == nullptr) { 26149 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack outside function")); 26150 return ira->codegen->invalid_instruction; 26151 } 26152 if (fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionNaked) { 26153 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in naked function")); 26154 return ira->codegen->invalid_instruction; 26155 } 26156 26157 if (fn_entry->fn_inline == FnInlineAlways) { 26158 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in inline function")); 26159 return ira->codegen->invalid_instruction; 26160 } 26161 26162 if (fn_entry->set_alignstack_node != nullptr) { 26163 ErrorMsg *msg = ir_add_error_node(ira, instruction->base.source_node, 26164 buf_sprintf("alignstack set twice")); 26165 add_error_note(ira->codegen, msg, fn_entry->set_alignstack_node, buf_sprintf("first set here")); 26166 return ira->codegen->invalid_instruction; 26167 } 26168 26169 fn_entry->set_alignstack_node = instruction->base.source_node; 26170 fn_entry->alignstack_value = align_bytes; 26171 26172 return ir_const_void(ira, &instruction->base); 26173 } 26174 26175 static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstructionArgType *instruction) { 26176 IrInstruction *fn_type_inst = instruction->fn_type->child; 26177 ZigType *fn_type = ir_resolve_type(ira, fn_type_inst); 26178 if (type_is_invalid(fn_type)) 26179 return ira->codegen->invalid_instruction; 26180 26181 IrInstruction *arg_index_inst = instruction->arg_index->child; 26182 uint64_t arg_index; 26183 if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) 26184 return ira->codegen->invalid_instruction; 26185 26186 if (fn_type->id == ZigTypeIdBoundFn) { 26187 fn_type = fn_type->data.bound_fn.fn_type; 26188 arg_index += 1; 26189 } 26190 if (fn_type->id != ZigTypeIdFn) { 26191 ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); 26192 return ira->codegen->invalid_instruction; 26193 } 26194 26195 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 26196 if (arg_index >= fn_type_id->param_count) { 26197 if (instruction->allow_var) { 26198 // TODO remove this with var args 26199 return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var); 26200 } 26201 ir_add_error(ira, arg_index_inst, 26202 buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", 26203 arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); 26204 return ira->codegen->invalid_instruction; 26205 } 26206 26207 ZigType *result_type = fn_type_id->param_info[arg_index].type; 26208 if (result_type == nullptr) { 26209 // Args are only unresolved if our function is generic. 26210 ir_assert(fn_type->data.fn.is_generic, &instruction->base); 26211 26212 if (instruction->allow_var) { 26213 return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var); 26214 } else { 26215 ir_add_error(ira, arg_index_inst, 26216 buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", 26217 arg_index, buf_ptr(&fn_type->name))); 26218 return ira->codegen->invalid_instruction; 26219 } 26220 } 26221 return ir_const_type(ira, &instruction->base, result_type); 26222 } 26223 26224 static IrInstruction *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstructionTagType *instruction) { 26225 Error err; 26226 IrInstruction *target_inst = instruction->target->child; 26227 ZigType *enum_type = ir_resolve_type(ira, target_inst); 26228 if (type_is_invalid(enum_type)) 26229 return ira->codegen->invalid_instruction; 26230 26231 if (enum_type->id == ZigTypeIdEnum) { 26232 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) 26233 return ira->codegen->invalid_instruction; 26234 26235 return ir_const_type(ira, &instruction->base, enum_type->data.enumeration.tag_int_type); 26236 } else if (enum_type->id == ZigTypeIdUnion) { 26237 ZigType *tag_type = ir_resolve_union_tag_type(ira, instruction->target, enum_type); 26238 if (type_is_invalid(tag_type)) 26239 return ira->codegen->invalid_instruction; 26240 return ir_const_type(ira, &instruction->base, tag_type); 26241 } else { 26242 ir_add_error(ira, target_inst, buf_sprintf("expected enum or union, found '%s'", 26243 buf_ptr(&enum_type->name))); 26244 return ira->codegen->invalid_instruction; 26245 } 26246 } 26247 26248 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op) { 26249 ZigType *operand_type = ir_resolve_type(ira, op); 26250 if (type_is_invalid(operand_type)) 26251 return ira->codegen->builtin_types.entry_invalid; 26252 26253 if (operand_type->id == ZigTypeIdInt) { 26254 if (operand_type->data.integral.bit_count < 8) { 26255 ir_add_error(ira, op, 26256 buf_sprintf("expected integer type 8 bits or larger, found %" PRIu32 "-bit integer type", 26257 operand_type->data.integral.bit_count)); 26258 return ira->codegen->builtin_types.entry_invalid; 26259 } 26260 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); 26261 if (operand_type->data.integral.bit_count > max_atomic_bits) { 26262 ir_add_error(ira, op, 26263 buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type", 26264 max_atomic_bits, operand_type->data.integral.bit_count)); 26265 return ira->codegen->builtin_types.entry_invalid; 26266 } 26267 if (!is_power_of_2(operand_type->data.integral.bit_count)) { 26268 ir_add_error(ira, op, 26269 buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count)); 26270 return ira->codegen->builtin_types.entry_invalid; 26271 } 26272 } else if (operand_type->id == ZigTypeIdEnum) { 26273 ZigType *int_type = operand_type->data.enumeration.tag_int_type; 26274 if (int_type->data.integral.bit_count < 8) { 26275 ir_add_error(ira, op, 26276 buf_sprintf("expected enum tag type 8 bits or larger, found %" PRIu32 "-bit tag type", 26277 int_type->data.integral.bit_count)); 26278 return ira->codegen->builtin_types.entry_invalid; 26279 } 26280 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); 26281 if (int_type->data.integral.bit_count > max_atomic_bits) { 26282 ir_add_error(ira, op, 26283 buf_sprintf("expected %" PRIu32 "-bit enum tag type or smaller, found %" PRIu32 "-bit tag type", 26284 max_atomic_bits, int_type->data.integral.bit_count)); 26285 return ira->codegen->builtin_types.entry_invalid; 26286 } 26287 if (!is_power_of_2(int_type->data.integral.bit_count)) { 26288 ir_add_error(ira, op, 26289 buf_sprintf("%" PRIu32 "-bit enum tag type is not a power of 2", int_type->data.integral.bit_count)); 26290 return ira->codegen->builtin_types.entry_invalid; 26291 } 26292 } else if (get_codegen_ptr_type(operand_type) == nullptr) { 26293 ir_add_error(ira, op, 26294 buf_sprintf("expected integer, enum or pointer type, found '%s'", buf_ptr(&operand_type->name))); 26295 return ira->codegen->builtin_types.entry_invalid; 26296 } 26297 26298 return operand_type; 26299 } 26300 26301 static IrInstruction *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstructionAtomicRmw *instruction) { 26302 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 26303 if (type_is_invalid(operand_type)) 26304 return ira->codegen->invalid_instruction; 26305 26306 IrInstruction *ptr_inst = instruction->ptr->child; 26307 if (type_is_invalid(ptr_inst->value->type)) 26308 return ira->codegen->invalid_instruction; 26309 26310 // TODO let this be volatile 26311 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 26312 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 26313 if (type_is_invalid(casted_ptr->value->type)) 26314 return ira->codegen->invalid_instruction; 26315 26316 AtomicRmwOp op; 26317 if (instruction->op == nullptr) { 26318 op = instruction->resolved_op; 26319 } else { 26320 if (!ir_resolve_atomic_rmw_op(ira, instruction->op->child, &op)) { 26321 return ira->codegen->invalid_instruction; 26322 } 26323 } 26324 26325 if (operand_type->id == ZigTypeIdEnum && op != AtomicRmwOp_xchg) { 26326 ir_add_error(ira, instruction->op, 26327 buf_sprintf("@atomicRmw on enum only works with .Xchg")); 26328 return ira->codegen->invalid_instruction; 26329 } 26330 26331 IrInstruction *operand = instruction->operand->child; 26332 if (type_is_invalid(operand->value->type)) 26333 return ira->codegen->invalid_instruction; 26334 26335 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, operand_type); 26336 if (type_is_invalid(casted_operand->value->type)) 26337 return ira->codegen->invalid_instruction; 26338 26339 AtomicOrder ordering; 26340 if (instruction->ordering == nullptr) { 26341 ordering = instruction->resolved_ordering; 26342 } else { 26343 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 26344 return ira->codegen->invalid_instruction; 26345 if (ordering == AtomicOrderUnordered) { 26346 ir_add_error(ira, instruction->ordering, 26347 buf_sprintf("@atomicRmw atomic ordering must not be Unordered")); 26348 return ira->codegen->invalid_instruction; 26349 } 26350 } 26351 26352 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar) 26353 { 26354 zig_panic("TODO compile-time execution of atomicRmw"); 26355 } 26356 26357 IrInstruction *result = ir_build_atomic_rmw(&ira->new_irb, instruction->base.scope, 26358 instruction->base.source_node, nullptr, casted_ptr, nullptr, casted_operand, nullptr, 26359 op, ordering); 26360 result->value->type = operand_type; 26361 return result; 26362 } 26363 26364 static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstructionAtomicLoad *instruction) { 26365 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 26366 if (type_is_invalid(operand_type)) 26367 return ira->codegen->invalid_instruction; 26368 26369 IrInstruction *ptr_inst = instruction->ptr->child; 26370 if (type_is_invalid(ptr_inst->value->type)) 26371 return ira->codegen->invalid_instruction; 26372 26373 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true); 26374 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 26375 if (type_is_invalid(casted_ptr->value->type)) 26376 return ira->codegen->invalid_instruction; 26377 26378 AtomicOrder ordering; 26379 if (instruction->ordering == nullptr) { 26380 ordering = instruction->resolved_ordering; 26381 } else { 26382 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 26383 return ira->codegen->invalid_instruction; 26384 } 26385 26386 if (ordering == AtomicOrderRelease || ordering == AtomicOrderAcqRel) { 26387 ir_assert(instruction->ordering != nullptr, &instruction->base); 26388 ir_add_error(ira, instruction->ordering, 26389 buf_sprintf("@atomicLoad atomic ordering must not be Release or AcqRel")); 26390 return ira->codegen->invalid_instruction; 26391 } 26392 26393 if (instr_is_comptime(casted_ptr)) { 26394 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr); 26395 ir_assert(result->value->type != nullptr, &instruction->base); 26396 return result; 26397 } 26398 26399 IrInstruction *result = ir_build_atomic_load(&ira->new_irb, instruction->base.scope, 26400 instruction->base.source_node, nullptr, casted_ptr, nullptr, ordering); 26401 result->value->type = operand_type; 26402 return result; 26403 } 26404 26405 static IrInstruction *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstructionAtomicStore *instruction) { 26406 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 26407 if (type_is_invalid(operand_type)) 26408 return ira->codegen->invalid_instruction; 26409 26410 IrInstruction *ptr_inst = instruction->ptr->child; 26411 if (type_is_invalid(ptr_inst->value->type)) 26412 return ira->codegen->invalid_instruction; 26413 26414 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 26415 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 26416 if (type_is_invalid(casted_ptr->value->type)) 26417 return ira->codegen->invalid_instruction; 26418 26419 IrInstruction *value = instruction->value->child; 26420 if (type_is_invalid(value->value->type)) 26421 return ira->codegen->invalid_instruction; 26422 26423 IrInstruction *casted_value = ir_implicit_cast(ira, value, operand_type); 26424 if (type_is_invalid(casted_value->value->type)) 26425 return ira->codegen->invalid_instruction; 26426 26427 26428 AtomicOrder ordering; 26429 if (instruction->ordering == nullptr) { 26430 ordering = instruction->resolved_ordering; 26431 } else { 26432 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 26433 return ira->codegen->invalid_instruction; 26434 } 26435 26436 if (ordering == AtomicOrderAcquire || ordering == AtomicOrderAcqRel) { 26437 ir_assert(instruction->ordering != nullptr, &instruction->base); 26438 ir_add_error(ira, instruction->ordering, 26439 buf_sprintf("@atomicStore atomic ordering must not be Acquire or AcqRel")); 26440 return ira->codegen->invalid_instruction; 26441 } 26442 26443 if (instr_is_comptime(casted_value) && instr_is_comptime(casted_ptr)) { 26444 IrInstruction *result = ir_analyze_store_ptr(ira, &instruction->base, casted_ptr, value, false); 26445 result->value->type = ira->codegen->builtin_types.entry_void; 26446 return result; 26447 } 26448 26449 IrInstruction *result = ir_build_atomic_store(&ira->new_irb, instruction->base.scope, 26450 instruction->base.source_node, nullptr, casted_ptr, casted_value, nullptr, ordering); 26451 result->value->type = ira->codegen->builtin_types.entry_void; 26452 return result; 26453 } 26454 26455 static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) { 26456 IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope, 26457 instruction->base.source_node); 26458 result->value->type = ira->codegen->builtin_types.entry_void; 26459 return result; 26460 } 26461 26462 static void ir_eval_float_op(IrAnalyze *ira, IrInstructionFloatOp *source_instr, ZigType *float_type, 26463 ZigValue *op, ZigValue *out_val) { 26464 assert(ira && source_instr && float_type && out_val && op); 26465 assert(float_type->id == ZigTypeIdFloat || 26466 float_type->id == ZigTypeIdComptimeFloat); 26467 26468 BuiltinFnId fop = source_instr->op; 26469 unsigned bits; 26470 26471 switch (float_type->id) { 26472 case ZigTypeIdComptimeFloat: 26473 bits = 128; 26474 break; 26475 case ZigTypeIdFloat: 26476 bits = float_type->data.floating.bit_count; 26477 break; 26478 default: 26479 zig_unreachable(); 26480 } 26481 26482 switch (bits) { 26483 case 16: { 26484 switch (fop) { 26485 case BuiltinFnIdSqrt: 26486 out_val->data.x_f16 = f16_sqrt(op->data.x_f16); 26487 break; 26488 case BuiltinFnIdSin: 26489 case BuiltinFnIdCos: 26490 case BuiltinFnIdExp: 26491 case BuiltinFnIdExp2: 26492 case BuiltinFnIdLn: 26493 case BuiltinFnIdLog10: 26494 case BuiltinFnIdLog2: 26495 case BuiltinFnIdFabs: 26496 case BuiltinFnIdFloor: 26497 case BuiltinFnIdCeil: 26498 case BuiltinFnIdTrunc: 26499 case BuiltinFnIdNearbyInt: 26500 case BuiltinFnIdRound: 26501 zig_panic("unimplemented f16 builtin"); 26502 default: 26503 zig_unreachable(); 26504 }; 26505 break; 26506 }; 26507 case 32: { 26508 switch (fop) { 26509 case BuiltinFnIdSqrt: 26510 out_val->data.x_f32 = sqrtf(op->data.x_f32); 26511 break; 26512 case BuiltinFnIdSin: 26513 out_val->data.x_f32 = sinf(op->data.x_f32); 26514 break; 26515 case BuiltinFnIdCos: 26516 out_val->data.x_f32 = cosf(op->data.x_f32); 26517 break; 26518 case BuiltinFnIdExp: 26519 out_val->data.x_f32 = expf(op->data.x_f32); 26520 break; 26521 case BuiltinFnIdExp2: 26522 out_val->data.x_f32 = exp2f(op->data.x_f32); 26523 break; 26524 case BuiltinFnIdLn: 26525 out_val->data.x_f32 = logf(op->data.x_f32); 26526 break; 26527 case BuiltinFnIdLog10: 26528 out_val->data.x_f32 = log10f(op->data.x_f32); 26529 break; 26530 case BuiltinFnIdLog2: 26531 out_val->data.x_f32 = log2f(op->data.x_f32); 26532 break; 26533 case BuiltinFnIdFabs: 26534 out_val->data.x_f32 = fabsf(op->data.x_f32); 26535 break; 26536 case BuiltinFnIdFloor: 26537 out_val->data.x_f32 = floorf(op->data.x_f32); 26538 break; 26539 case BuiltinFnIdCeil: 26540 out_val->data.x_f32 = ceilf(op->data.x_f32); 26541 break; 26542 case BuiltinFnIdTrunc: 26543 out_val->data.x_f32 = truncf(op->data.x_f32); 26544 break; 26545 case BuiltinFnIdNearbyInt: 26546 out_val->data.x_f32 = nearbyintf(op->data.x_f32); 26547 break; 26548 case BuiltinFnIdRound: 26549 out_val->data.x_f32 = roundf(op->data.x_f32); 26550 break; 26551 default: 26552 zig_unreachable(); 26553 }; 26554 break; 26555 }; 26556 case 64: { 26557 switch (fop) { 26558 case BuiltinFnIdSqrt: 26559 out_val->data.x_f64 = sqrt(op->data.x_f64); 26560 break; 26561 case BuiltinFnIdSin: 26562 out_val->data.x_f64 = sin(op->data.x_f64); 26563 break; 26564 case BuiltinFnIdCos: 26565 out_val->data.x_f64 = cos(op->data.x_f64); 26566 break; 26567 case BuiltinFnIdExp: 26568 out_val->data.x_f64 = exp(op->data.x_f64); 26569 break; 26570 case BuiltinFnIdExp2: 26571 out_val->data.x_f64 = exp2(op->data.x_f64); 26572 break; 26573 case BuiltinFnIdLn: 26574 out_val->data.x_f64 = log(op->data.x_f64); 26575 break; 26576 case BuiltinFnIdLog10: 26577 out_val->data.x_f64 = log10(op->data.x_f64); 26578 break; 26579 case BuiltinFnIdLog2: 26580 out_val->data.x_f64 = log2(op->data.x_f64); 26581 break; 26582 case BuiltinFnIdFabs: 26583 out_val->data.x_f64 = fabs(op->data.x_f64); 26584 break; 26585 case BuiltinFnIdFloor: 26586 out_val->data.x_f64 = floor(op->data.x_f64); 26587 break; 26588 case BuiltinFnIdCeil: 26589 out_val->data.x_f64 = ceil(op->data.x_f64); 26590 break; 26591 case BuiltinFnIdTrunc: 26592 out_val->data.x_f64 = trunc(op->data.x_f64); 26593 break; 26594 case BuiltinFnIdNearbyInt: 26595 out_val->data.x_f64 = nearbyint(op->data.x_f64); 26596 break; 26597 case BuiltinFnIdRound: 26598 out_val->data.x_f64 = round(op->data.x_f64); 26599 break; 26600 default: 26601 zig_unreachable(); 26602 } 26603 break; 26604 }; 26605 case 128: { 26606 float128_t *out, *in; 26607 if (float_type->id == ZigTypeIdComptimeFloat) { 26608 out = &out_val->data.x_bigfloat.value; 26609 in = &op->data.x_bigfloat.value; 26610 } else { 26611 out = &out_val->data.x_f128; 26612 in = &op->data.x_f128; 26613 } 26614 switch (fop) { 26615 case BuiltinFnIdSqrt: 26616 f128M_sqrt(in, out); 26617 break; 26618 case BuiltinFnIdNearbyInt: 26619 case BuiltinFnIdSin: 26620 case BuiltinFnIdCos: 26621 case BuiltinFnIdExp: 26622 case BuiltinFnIdExp2: 26623 case BuiltinFnIdLn: 26624 case BuiltinFnIdLog10: 26625 case BuiltinFnIdLog2: 26626 case BuiltinFnIdFabs: 26627 case BuiltinFnIdFloor: 26628 case BuiltinFnIdCeil: 26629 case BuiltinFnIdTrunc: 26630 case BuiltinFnIdRound: 26631 zig_panic("unimplemented f128 builtin"); 26632 default: 26633 zig_unreachable(); 26634 } 26635 break; 26636 }; 26637 default: 26638 zig_unreachable(); 26639 } 26640 } 26641 26642 static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) { 26643 IrInstruction *type = instruction->type->child; 26644 if (type_is_invalid(type->value->type)) 26645 return ira->codegen->invalid_instruction; 26646 26647 ZigType *expr_type = ir_resolve_type(ira, type); 26648 if (type_is_invalid(expr_type)) 26649 return ira->codegen->invalid_instruction; 26650 26651 // Only allow float types, and vectors of floats. 26652 ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 26653 if (float_type->id != ZigTypeIdFloat && float_type->id != ZigTypeIdComptimeFloat) { 26654 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))); 26655 return ira->codegen->invalid_instruction; 26656 } 26657 26658 IrInstruction *op1 = instruction->op1->child; 26659 if (type_is_invalid(op1->value->type)) 26660 return ira->codegen->invalid_instruction; 26661 26662 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, float_type); 26663 if (type_is_invalid(casted_op1->value->type)) 26664 return ira->codegen->invalid_instruction; 26665 26666 if (instr_is_comptime(casted_op1)) { 26667 // Our comptime 16-bit and 128-bit support is quite limited. 26668 if ((float_type->id == ZigTypeIdComptimeFloat || 26669 float_type->data.floating.bit_count == 16 || 26670 float_type->data.floating.bit_count == 128) && 26671 instruction->op != BuiltinFnIdSqrt) { 26672 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))); 26673 return ira->codegen->invalid_instruction; 26674 } 26675 26676 ZigValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); 26677 if (!op1_const) 26678 return ira->codegen->invalid_instruction; 26679 26680 IrInstruction *result = ir_const(ira, &instruction->base, expr_type); 26681 ZigValue *out_val = result->value; 26682 26683 if (expr_type->id == ZigTypeIdVector) { 26684 expand_undef_array(ira->codegen, op1_const); 26685 out_val->special = ConstValSpecialUndef; 26686 expand_undef_array(ira->codegen, out_val); 26687 size_t len = expr_type->data.vector.len; 26688 for (size_t i = 0; i < len; i += 1) { 26689 ZigValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i]; 26690 ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; 26691 assert(float_operand_op1->type == float_type); 26692 assert(float_out_val->type == float_type); 26693 ir_eval_float_op(ira, instruction, float_type, 26694 op1_const, float_out_val); 26695 float_out_val->type = float_type; 26696 } 26697 out_val->type = expr_type; 26698 out_val->special = ConstValSpecialStatic; 26699 } else { 26700 ir_eval_float_op(ira, instruction, float_type, op1_const, out_val); 26701 } 26702 return result; 26703 } 26704 26705 ir_assert(float_type->id == ZigTypeIdFloat, &instruction->base); 26706 26707 IrInstruction *result = ir_build_float_op(&ira->new_irb, instruction->base.scope, 26708 instruction->base.source_node, nullptr, casted_op1, instruction->op); 26709 result->value->type = expr_type; 26710 return result; 26711 } 26712 26713 static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstructionBswap *instruction) { 26714 Error err; 26715 26716 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 26717 if (type_is_invalid(int_type)) 26718 return ira->codegen->invalid_instruction; 26719 26720 IrInstruction *uncasted_op = instruction->op->child; 26721 if (type_is_invalid(uncasted_op->value->type)) 26722 return ira->codegen->invalid_instruction; 26723 26724 uint32_t vector_len; // UINT32_MAX means not a vector 26725 if (uncasted_op->value->type->id == ZigTypeIdArray && 26726 is_valid_vector_elem_type(uncasted_op->value->type->data.array.child_type)) 26727 { 26728 vector_len = uncasted_op->value->type->data.array.len; 26729 } else if (uncasted_op->value->type->id == ZigTypeIdVector) { 26730 vector_len = uncasted_op->value->type->data.vector.len; 26731 } else { 26732 vector_len = UINT32_MAX; 26733 } 26734 26735 bool is_vector = (vector_len != UINT32_MAX); 26736 ZigType *op_type = is_vector ? get_vector_type(ira->codegen, vector_len, int_type) : int_type; 26737 26738 IrInstruction *op = ir_implicit_cast(ira, uncasted_op, op_type); 26739 if (type_is_invalid(op->value->type)) 26740 return ira->codegen->invalid_instruction; 26741 26742 if (int_type->data.integral.bit_count == 8 || int_type->data.integral.bit_count == 0) 26743 return op; 26744 26745 if (int_type->data.integral.bit_count % 8 != 0) { 26746 ir_add_error(ira, instruction->op, 26747 buf_sprintf("@byteSwap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", 26748 buf_ptr(&int_type->name), int_type->data.integral.bit_count)); 26749 return ira->codegen->invalid_instruction; 26750 } 26751 26752 if (instr_is_comptime(op)) { 26753 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 26754 if (val == nullptr) 26755 return ira->codegen->invalid_instruction; 26756 if (val->special == ConstValSpecialUndef) 26757 return ir_const_undef(ira, &instruction->base, op_type); 26758 26759 IrInstruction *result = ir_const(ira, &instruction->base, op_type); 26760 size_t buf_size = int_type->data.integral.bit_count / 8; 26761 uint8_t *buf = allocate_nonzero<uint8_t>(buf_size); 26762 if (is_vector) { 26763 expand_undef_array(ira->codegen, val); 26764 result->value->data.x_array.data.s_none.elements = create_const_vals(op_type->data.vector.len); 26765 for (unsigned i = 0; i < op_type->data.vector.len; i += 1) { 26766 ZigValue *op_elem_val = &val->data.x_array.data.s_none.elements[i]; 26767 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, instruction->base.source_node, 26768 op_elem_val, UndefOk))) 26769 { 26770 return ira->codegen->invalid_instruction; 26771 } 26772 ZigValue *result_elem_val = &result->value->data.x_array.data.s_none.elements[i]; 26773 result_elem_val->type = int_type; 26774 result_elem_val->special = op_elem_val->special; 26775 if (op_elem_val->special == ConstValSpecialUndef) 26776 continue; 26777 26778 bigint_write_twos_complement(&op_elem_val->data.x_bigint, buf, int_type->data.integral.bit_count, true); 26779 bigint_read_twos_complement(&result->value->data.x_array.data.s_none.elements[i].data.x_bigint, 26780 buf, int_type->data.integral.bit_count, false, 26781 int_type->data.integral.is_signed); 26782 } 26783 } else { 26784 bigint_write_twos_complement(&val->data.x_bigint, buf, int_type->data.integral.bit_count, true); 26785 bigint_read_twos_complement(&result->value->data.x_bigint, buf, int_type->data.integral.bit_count, false, 26786 int_type->data.integral.is_signed); 26787 } 26788 free(buf); 26789 return result; 26790 } 26791 26792 IrInstruction *result = ir_build_bswap(&ira->new_irb, instruction->base.scope, 26793 instruction->base.source_node, nullptr, op); 26794 result->value->type = op_type; 26795 return result; 26796 } 26797 26798 static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstructionBitReverse *instruction) { 26799 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 26800 if (type_is_invalid(int_type)) 26801 return ira->codegen->invalid_instruction; 26802 26803 IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); 26804 if (type_is_invalid(op->value->type)) 26805 return ira->codegen->invalid_instruction; 26806 26807 if (int_type->data.integral.bit_count == 0) { 26808 IrInstruction *result = ir_const(ira, &instruction->base, int_type); 26809 bigint_init_unsigned(&result->value->data.x_bigint, 0); 26810 return result; 26811 } 26812 26813 if (instr_is_comptime(op)) { 26814 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 26815 if (val == nullptr) 26816 return ira->codegen->invalid_instruction; 26817 if (val->special == ConstValSpecialUndef) 26818 return ir_const_undef(ira, &instruction->base, int_type); 26819 26820 IrInstruction *result = ir_const(ira, &instruction->base, int_type); 26821 size_t num_bits = int_type->data.integral.bit_count; 26822 size_t buf_size = (num_bits + 7) / 8; 26823 uint8_t *comptime_buf = allocate_nonzero<uint8_t>(buf_size); 26824 uint8_t *result_buf = allocate_nonzero<uint8_t>(buf_size); 26825 memset(comptime_buf,0,buf_size); 26826 memset(result_buf,0,buf_size); 26827 26828 bigint_write_twos_complement(&val->data.x_bigint,comptime_buf,num_bits,ira->codegen->is_big_endian); 26829 26830 size_t bit_i = 0; 26831 size_t bit_rev_i = num_bits - 1; 26832 for (; bit_i < num_bits; bit_i++, bit_rev_i--) { 26833 if (comptime_buf[bit_i / 8] & (1 << (bit_i % 8))) { 26834 result_buf[bit_rev_i / 8] |= (1 << (bit_rev_i % 8)); 26835 } 26836 } 26837 26838 bigint_read_twos_complement(&result->value->data.x_bigint, 26839 result_buf, 26840 int_type->data.integral.bit_count, 26841 ira->codegen->is_big_endian, 26842 int_type->data.integral.is_signed); 26843 26844 return result; 26845 } 26846 26847 IrInstruction *result = ir_build_bit_reverse(&ira->new_irb, instruction->base.scope, 26848 instruction->base.source_node, nullptr, op); 26849 result->value->type = int_type; 26850 return result; 26851 } 26852 26853 26854 static IrInstruction *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstructionEnumToInt *instruction) { 26855 IrInstruction *target = instruction->target->child; 26856 if (type_is_invalid(target->value->type)) 26857 return ira->codegen->invalid_instruction; 26858 26859 return ir_analyze_enum_to_int(ira, &instruction->base, target); 26860 } 26861 26862 static IrInstruction *ir_analyze_instruction_int_to_enum(IrAnalyze *ira, IrInstructionIntToEnum *instruction) { 26863 Error err; 26864 IrInstruction *dest_type_value = instruction->dest_type->child; 26865 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 26866 if (type_is_invalid(dest_type)) 26867 return ira->codegen->invalid_instruction; 26868 26869 if (dest_type->id != ZigTypeIdEnum) { 26870 ir_add_error(ira, instruction->dest_type, 26871 buf_sprintf("expected enum, found type '%s'", buf_ptr(&dest_type->name))); 26872 return ira->codegen->invalid_instruction; 26873 } 26874 26875 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 26876 return ira->codegen->invalid_instruction; 26877 26878 ZigType *tag_type = dest_type->data.enumeration.tag_int_type; 26879 26880 IrInstruction *target = instruction->target->child; 26881 if (type_is_invalid(target->value->type)) 26882 return ira->codegen->invalid_instruction; 26883 26884 IrInstruction *casted_target = ir_implicit_cast(ira, target, tag_type); 26885 if (type_is_invalid(casted_target->value->type)) 26886 return ira->codegen->invalid_instruction; 26887 26888 return ir_analyze_int_to_enum(ira, &instruction->base, casted_target, dest_type); 26889 } 26890 26891 static IrInstruction *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, IrInstructionCheckRuntimeScope *instruction) { 26892 IrInstruction *block_comptime_inst = instruction->scope_is_comptime->child; 26893 bool scope_is_comptime; 26894 if (!ir_resolve_bool(ira, block_comptime_inst, &scope_is_comptime)) 26895 return ira->codegen->invalid_instruction; 26896 26897 IrInstruction *is_comptime_inst = instruction->is_comptime->child; 26898 bool is_comptime; 26899 if (!ir_resolve_bool(ira, is_comptime_inst, &is_comptime)) 26900 return ira->codegen->invalid_instruction; 26901 26902 if (!scope_is_comptime && is_comptime) { 26903 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 26904 buf_sprintf("comptime control flow inside runtime block")); 26905 add_error_note(ira->codegen, msg, block_comptime_inst->source_node, 26906 buf_sprintf("runtime block created here")); 26907 return ira->codegen->invalid_instruction; 26908 } 26909 26910 return ir_const_void(ira, &instruction->base); 26911 } 26912 26913 static IrInstruction *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstructionHasDecl *instruction) { 26914 ZigType *container_type = ir_resolve_type(ira, instruction->container->child); 26915 if (type_is_invalid(container_type)) 26916 return ira->codegen->invalid_instruction; 26917 26918 Buf *name = ir_resolve_str(ira, instruction->name->child); 26919 if (name == nullptr) 26920 return ira->codegen->invalid_instruction; 26921 26922 if (!is_container(container_type)) { 26923 ir_add_error(ira, instruction->container, 26924 buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&container_type->name))); 26925 return ira->codegen->invalid_instruction; 26926 } 26927 26928 ScopeDecls *container_scope = get_container_scope(container_type); 26929 Tld *tld = find_container_decl(ira->codegen, container_scope, name); 26930 if (tld == nullptr) 26931 return ir_const_bool(ira, &instruction->base, false); 26932 26933 if (tld->visib_mod == VisibModPrivate && tld->import != get_scope_import(instruction->base.scope)) { 26934 return ir_const_bool(ira, &instruction->base, false); 26935 } 26936 26937 return ir_const_bool(ira, &instruction->base, true); 26938 } 26939 26940 static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstructionUndeclaredIdent *instruction) { 26941 // put a variable of same name with invalid type in global scope 26942 // so that future references to this same name will find a variable with an invalid type 26943 populate_invalid_variable_in_scope(ira->codegen, instruction->base.scope, instruction->base.source_node, 26944 instruction->name); 26945 ir_add_error(ira, &instruction->base, 26946 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(instruction->name))); 26947 return ira->codegen->invalid_instruction; 26948 } 26949 26950 static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstructionEndExpr *instruction) { 26951 IrInstruction *value = instruction->value->child; 26952 if (type_is_invalid(value->value->type)) 26953 return ira->codegen->invalid_instruction; 26954 26955 bool was_written = instruction->result_loc->written; 26956 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 26957 value->value->type, value, false, false, true); 26958 if (result_loc != nullptr) { 26959 if (type_is_invalid(result_loc->value->type)) 26960 return ira->codegen->invalid_instruction; 26961 if (result_loc->value->type->id == ZigTypeIdUnreachable) 26962 return result_loc; 26963 26964 if (!was_written || instruction->result_loc->id == ResultLocIdPeer) { 26965 IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value, 26966 instruction->result_loc->allow_write_through_const); 26967 if (type_is_invalid(store_ptr->value->type)) { 26968 return ira->codegen->invalid_instruction; 26969 } 26970 } 26971 26972 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer && 26973 instruction->result_loc->id != ResultLocIdPeer) 26974 { 26975 if (instr_is_comptime(value)) { 26976 result_loc->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 26977 } else { 26978 result_loc->value->special = ConstValSpecialRuntime; 26979 } 26980 } 26981 } 26982 26983 return ir_const_void(ira, &instruction->base); 26984 } 26985 26986 static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) { 26987 IrInstruction *operand = instruction->operand->child; 26988 if (type_is_invalid(operand->value->type)) 26989 return operand; 26990 26991 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, 26992 &instruction->result_loc_cast->base, operand->value->type, operand, false, false, true); 26993 if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) 26994 return result_loc; 26995 26996 if (instruction->result_loc_cast->parent->gen_instruction != nullptr) { 26997 return instruction->result_loc_cast->parent->gen_instruction; 26998 } 26999 27000 ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child); 27001 if (type_is_invalid(dest_type)) 27002 return ira->codegen->invalid_instruction; 27003 return ir_implicit_cast2(ira, &instruction->base, operand, dest_type); 27004 } 27005 27006 static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) { 27007 IrInstruction *operand = instruction->operand->child; 27008 if (type_is_invalid(operand->value->type)) 27009 return operand; 27010 27011 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, 27012 &instruction->result_loc_bit_cast->base, operand->value->type, operand, false, false, true); 27013 if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) 27014 return result_loc; 27015 27016 if (instruction->result_loc_bit_cast->parent->gen_instruction != nullptr) { 27017 return instruction->result_loc_bit_cast->parent->gen_instruction; 27018 } 27019 27020 return result_loc; 27021 } 27022 27023 static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *ira, 27024 IrInstructionUnionInitNamedField *instruction) 27025 { 27026 ZigType *union_type = ir_resolve_type(ira, instruction->union_type->child); 27027 if (type_is_invalid(union_type)) 27028 return ira->codegen->invalid_instruction; 27029 27030 if (union_type->id != ZigTypeIdUnion) { 27031 ir_add_error(ira, instruction->union_type, 27032 buf_sprintf("non-union type '%s' passed to @unionInit", buf_ptr(&union_type->name))); 27033 return ira->codegen->invalid_instruction; 27034 } 27035 27036 Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); 27037 if (field_name == nullptr) 27038 return ira->codegen->invalid_instruction; 27039 27040 IrInstruction *field_result_loc = instruction->field_result_loc->child; 27041 if (type_is_invalid(field_result_loc->value->type)) 27042 return ira->codegen->invalid_instruction; 27043 27044 IrInstruction *result_loc = instruction->result_loc->child; 27045 if (type_is_invalid(result_loc->value->type)) 27046 return ira->codegen->invalid_instruction; 27047 27048 return ir_analyze_union_init(ira, &instruction->base, instruction->base.source_node, 27049 union_type, field_name, field_result_loc, result_loc); 27050 } 27051 27052 static IrInstruction *ir_analyze_instruction_suspend_begin(IrAnalyze *ira, IrInstructionSuspendBegin *instruction) { 27053 IrInstructionSuspendBegin *result = ir_build_suspend_begin(&ira->new_irb, instruction->base.scope, 27054 instruction->base.source_node); 27055 return &result->base; 27056 } 27057 27058 static IrInstruction *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, 27059 IrInstructionSuspendFinish *instruction) 27060 { 27061 IrInstruction *begin_base = instruction->begin->base.child; 27062 if (type_is_invalid(begin_base->value->type)) 27063 return ira->codegen->invalid_instruction; 27064 ir_assert(begin_base->id == IrInstructionIdSuspendBegin, &instruction->base); 27065 IrInstructionSuspendBegin *begin = reinterpret_cast<IrInstructionSuspendBegin *>(begin_base); 27066 27067 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 27068 ir_assert(fn_entry != nullptr, &instruction->base); 27069 27070 if (fn_entry->inferred_async_node == nullptr) { 27071 fn_entry->inferred_async_node = instruction->base.source_node; 27072 } 27073 27074 return ir_build_suspend_finish(&ira->new_irb, instruction->base.scope, instruction->base.source_node, begin); 27075 } 27076 27077 static IrInstruction *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInstruction *source_instr, 27078 IrInstruction *frame_ptr, ZigFn **target_fn) 27079 { 27080 if (type_is_invalid(frame_ptr->value->type)) 27081 return ira->codegen->invalid_instruction; 27082 27083 *target_fn = nullptr; 27084 27085 ZigType *result_type; 27086 IrInstruction *frame; 27087 if (frame_ptr->value->type->id == ZigTypeIdPointer && 27088 frame_ptr->value->type->data.pointer.ptr_len == PtrLenSingle && 27089 frame_ptr->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 27090 { 27091 ZigFn *func = frame_ptr->value->type->data.pointer.child_type->data.frame.fn; 27092 result_type = func->type_entry->data.fn.fn_type_id.return_type; 27093 *target_fn = func; 27094 frame = frame_ptr; 27095 } else { 27096 frame = ir_get_deref(ira, source_instr, frame_ptr, nullptr); 27097 if (frame->value->type->id == ZigTypeIdPointer && 27098 frame->value->type->data.pointer.ptr_len == PtrLenSingle && 27099 frame->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 27100 { 27101 ZigFn *func = frame->value->type->data.pointer.child_type->data.frame.fn; 27102 result_type = func->type_entry->data.fn.fn_type_id.return_type; 27103 *target_fn = func; 27104 } else if (frame->value->type->id != ZigTypeIdAnyFrame || 27105 frame->value->type->data.any_frame.result_type == nullptr) 27106 { 27107 ir_add_error(ira, source_instr, 27108 buf_sprintf("expected anyframe->T, found '%s'", buf_ptr(&frame->value->type->name))); 27109 return ira->codegen->invalid_instruction; 27110 } else { 27111 result_type = frame->value->type->data.any_frame.result_type; 27112 } 27113 } 27114 27115 ZigType *any_frame_type = get_any_frame_type(ira->codegen, result_type); 27116 IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); 27117 if (type_is_invalid(casted_frame->value->type)) 27118 return ira->codegen->invalid_instruction; 27119 27120 return casted_frame; 27121 } 27122 27123 static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstructionAwaitSrc *instruction) { 27124 IrInstruction *operand = instruction->frame->child; 27125 if (type_is_invalid(operand->value->type)) 27126 return ira->codegen->invalid_instruction; 27127 ZigFn *target_fn; 27128 IrInstruction *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base, operand, &target_fn); 27129 if (type_is_invalid(frame->value->type)) 27130 return ira->codegen->invalid_instruction; 27131 27132 ZigType *result_type = frame->value->type->data.any_frame.result_type; 27133 27134 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 27135 ir_assert(fn_entry != nullptr, &instruction->base); 27136 27137 // If it's not @Frame(func) then it's definitely a suspend point 27138 if (target_fn == nullptr) { 27139 if (fn_entry->inferred_async_node == nullptr) { 27140 fn_entry->inferred_async_node = instruction->base.source_node; 27141 } 27142 } 27143 27144 if (type_can_fail(result_type)) { 27145 fn_entry->calls_or_awaits_errorable_fn = true; 27146 } 27147 27148 IrInstruction *result_loc; 27149 if (type_has_bits(result_type)) { 27150 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, 27151 result_type, nullptr, true, true, true); 27152 if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) 27153 return result_loc; 27154 } else { 27155 result_loc = nullptr; 27156 } 27157 27158 IrInstructionAwaitGen *result = ir_build_await_gen(ira, &instruction->base, frame, result_type, result_loc); 27159 result->target_fn = target_fn; 27160 fn_entry->await_list.append(result); 27161 return ir_finish_anal(ira, &result->base); 27162 } 27163 27164 static IrInstruction *ir_analyze_instruction_resume(IrAnalyze *ira, IrInstructionResume *instruction) { 27165 IrInstruction *frame_ptr = instruction->frame->child; 27166 if (type_is_invalid(frame_ptr->value->type)) 27167 return ira->codegen->invalid_instruction; 27168 27169 IrInstruction *frame; 27170 if (frame_ptr->value->type->id == ZigTypeIdPointer && 27171 frame_ptr->value->type->data.pointer.ptr_len == PtrLenSingle && 27172 frame_ptr->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 27173 { 27174 frame = frame_ptr; 27175 } else { 27176 frame = ir_get_deref(ira, &instruction->base, frame_ptr, nullptr); 27177 } 27178 27179 ZigType *any_frame_type = get_any_frame_type(ira->codegen, nullptr); 27180 IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); 27181 if (type_is_invalid(casted_frame->value->type)) 27182 return ira->codegen->invalid_instruction; 27183 27184 return ir_build_resume(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_frame); 27185 } 27186 27187 static IrInstruction *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstructionSpillBegin *instruction) { 27188 if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) 27189 return ir_const_void(ira, &instruction->base); 27190 27191 IrInstruction *operand = instruction->operand->child; 27192 if (type_is_invalid(operand->value->type)) 27193 return ira->codegen->invalid_instruction; 27194 27195 if (!type_has_bits(operand->value->type)) 27196 return ir_const_void(ira, &instruction->base); 27197 27198 ir_assert(instruction->spill_id == SpillIdRetErrCode, &instruction->base); 27199 ira->new_irb.exec->need_err_code_spill = true; 27200 27201 IrInstructionSpillBegin *result = ir_build_spill_begin(&ira->new_irb, instruction->base.scope, 27202 instruction->base.source_node, operand, instruction->spill_id); 27203 return &result->base; 27204 } 27205 27206 static IrInstruction *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstructionSpillEnd *instruction) { 27207 IrInstruction *operand = instruction->begin->operand->child; 27208 if (type_is_invalid(operand->value->type)) 27209 return ira->codegen->invalid_instruction; 27210 27211 if (ir_should_inline(ira->new_irb.exec, instruction->base.scope) || !type_has_bits(operand->value->type)) 27212 return operand; 27213 27214 ir_assert(instruction->begin->base.child->id == IrInstructionIdSpillBegin, &instruction->base); 27215 IrInstructionSpillBegin *begin = reinterpret_cast<IrInstructionSpillBegin *>(instruction->begin->base.child); 27216 27217 IrInstruction *result = ir_build_spill_end(&ira->new_irb, instruction->base.scope, 27218 instruction->base.source_node, begin); 27219 result->value->type = operand->value->type; 27220 return result; 27221 } 27222 27223 static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { 27224 switch (instruction->id) { 27225 case IrInstructionIdInvalid: 27226 case IrInstructionIdWidenOrShorten: 27227 case IrInstructionIdStructFieldPtr: 27228 case IrInstructionIdUnionFieldPtr: 27229 case IrInstructionIdOptionalWrap: 27230 case IrInstructionIdErrWrapCode: 27231 case IrInstructionIdErrWrapPayload: 27232 case IrInstructionIdCast: 27233 case IrInstructionIdDeclVarGen: 27234 case IrInstructionIdPtrCastGen: 27235 case IrInstructionIdCmpxchgGen: 27236 case IrInstructionIdArrayToVector: 27237 case IrInstructionIdVectorToArray: 27238 case IrInstructionIdPtrOfArrayToSlice: 27239 case IrInstructionIdAssertZero: 27240 case IrInstructionIdAssertNonNull: 27241 case IrInstructionIdResizeSlice: 27242 case IrInstructionIdLoadPtrGen: 27243 case IrInstructionIdBitCastGen: 27244 case IrInstructionIdCallGen: 27245 case IrInstructionIdReturnPtr: 27246 case IrInstructionIdAllocaGen: 27247 case IrInstructionIdSliceGen: 27248 case IrInstructionIdRefGen: 27249 case IrInstructionIdTestErrGen: 27250 case IrInstructionIdFrameSizeGen: 27251 case IrInstructionIdAwaitGen: 27252 case IrInstructionIdSplatGen: 27253 case IrInstructionIdVectorExtractElem: 27254 case IrInstructionIdVectorStoreElem: 27255 zig_unreachable(); 27256 27257 case IrInstructionIdReturn: 27258 return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction); 27259 case IrInstructionIdConst: 27260 return ir_analyze_instruction_const(ira, (IrInstructionConst *)instruction); 27261 case IrInstructionIdUnOp: 27262 return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction); 27263 case IrInstructionIdBinOp: 27264 return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction); 27265 case IrInstructionIdMergeErrSets: 27266 return ir_analyze_instruction_merge_err_sets(ira, (IrInstructionMergeErrSets *)instruction); 27267 case IrInstructionIdDeclVarSrc: 27268 return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVarSrc *)instruction); 27269 case IrInstructionIdLoadPtr: 27270 return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction); 27271 case IrInstructionIdStorePtr: 27272 return ir_analyze_instruction_store_ptr(ira, (IrInstructionStorePtr *)instruction); 27273 case IrInstructionIdElemPtr: 27274 return ir_analyze_instruction_elem_ptr(ira, (IrInstructionElemPtr *)instruction); 27275 case IrInstructionIdVarPtr: 27276 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); 27277 case IrInstructionIdFieldPtr: 27278 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); 27279 case IrInstructionIdCallSrc: 27280 return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction); 27281 case IrInstructionIdBr: 27282 return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); 27283 case IrInstructionIdCondBr: 27284 return ir_analyze_instruction_cond_br(ira, (IrInstructionCondBr *)instruction); 27285 case IrInstructionIdUnreachable: 27286 return ir_analyze_instruction_unreachable(ira, (IrInstructionUnreachable *)instruction); 27287 case IrInstructionIdPhi: 27288 return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); 27289 case IrInstructionIdTypeOf: 27290 return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); 27291 case IrInstructionIdSetCold: 27292 return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); 27293 case IrInstructionIdSetRuntimeSafety: 27294 return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction); 27295 case IrInstructionIdSetFloatMode: 27296 return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction); 27297 case IrInstructionIdAnyFrameType: 27298 return ir_analyze_instruction_any_frame_type(ira, (IrInstructionAnyFrameType *)instruction); 27299 case IrInstructionIdSliceType: 27300 return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction); 27301 case IrInstructionIdGlobalAsm: 27302 return ir_analyze_instruction_global_asm(ira, (IrInstructionGlobalAsm *)instruction); 27303 case IrInstructionIdAsm: 27304 return ir_analyze_instruction_asm(ira, (IrInstructionAsm *)instruction); 27305 case IrInstructionIdArrayType: 27306 return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction); 27307 case IrInstructionIdSizeOf: 27308 return ir_analyze_instruction_size_of(ira, (IrInstructionSizeOf *)instruction); 27309 case IrInstructionIdTestNonNull: 27310 return ir_analyze_instruction_test_non_null(ira, (IrInstructionTestNonNull *)instruction); 27311 case IrInstructionIdOptionalUnwrapPtr: 27312 return ir_analyze_instruction_optional_unwrap_ptr(ira, (IrInstructionOptionalUnwrapPtr *)instruction); 27313 case IrInstructionIdClz: 27314 return ir_analyze_instruction_clz(ira, (IrInstructionClz *)instruction); 27315 case IrInstructionIdCtz: 27316 return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction); 27317 case IrInstructionIdPopCount: 27318 return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction); 27319 case IrInstructionIdBswap: 27320 return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction); 27321 case IrInstructionIdBitReverse: 27322 return ir_analyze_instruction_bit_reverse(ira, (IrInstructionBitReverse *)instruction); 27323 case IrInstructionIdSwitchBr: 27324 return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction); 27325 case IrInstructionIdSwitchTarget: 27326 return ir_analyze_instruction_switch_target(ira, (IrInstructionSwitchTarget *)instruction); 27327 case IrInstructionIdSwitchVar: 27328 return ir_analyze_instruction_switch_var(ira, (IrInstructionSwitchVar *)instruction); 27329 case IrInstructionIdSwitchElseVar: 27330 return ir_analyze_instruction_switch_else_var(ira, (IrInstructionSwitchElseVar *)instruction); 27331 case IrInstructionIdUnionTag: 27332 return ir_analyze_instruction_union_tag(ira, (IrInstructionUnionTag *)instruction); 27333 case IrInstructionIdImport: 27334 return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction); 27335 case IrInstructionIdRef: 27336 return ir_analyze_instruction_ref(ira, (IrInstructionRef *)instruction); 27337 case IrInstructionIdContainerInitList: 27338 return ir_analyze_instruction_container_init_list(ira, (IrInstructionContainerInitList *)instruction); 27339 case IrInstructionIdContainerInitFields: 27340 return ir_analyze_instruction_container_init_fields(ira, (IrInstructionContainerInitFields *)instruction); 27341 case IrInstructionIdCompileErr: 27342 return ir_analyze_instruction_compile_err(ira, (IrInstructionCompileErr *)instruction); 27343 case IrInstructionIdCompileLog: 27344 return ir_analyze_instruction_compile_log(ira, (IrInstructionCompileLog *)instruction); 27345 case IrInstructionIdErrName: 27346 return ir_analyze_instruction_err_name(ira, (IrInstructionErrName *)instruction); 27347 case IrInstructionIdTypeName: 27348 return ir_analyze_instruction_type_name(ira, (IrInstructionTypeName *)instruction); 27349 case IrInstructionIdCImport: 27350 return ir_analyze_instruction_c_import(ira, (IrInstructionCImport *)instruction); 27351 case IrInstructionIdCInclude: 27352 return ir_analyze_instruction_c_include(ira, (IrInstructionCInclude *)instruction); 27353 case IrInstructionIdCDefine: 27354 return ir_analyze_instruction_c_define(ira, (IrInstructionCDefine *)instruction); 27355 case IrInstructionIdCUndef: 27356 return ir_analyze_instruction_c_undef(ira, (IrInstructionCUndef *)instruction); 27357 case IrInstructionIdEmbedFile: 27358 return ir_analyze_instruction_embed_file(ira, (IrInstructionEmbedFile *)instruction); 27359 case IrInstructionIdCmpxchgSrc: 27360 return ir_analyze_instruction_cmpxchg(ira, (IrInstructionCmpxchgSrc *)instruction); 27361 case IrInstructionIdFence: 27362 return ir_analyze_instruction_fence(ira, (IrInstructionFence *)instruction); 27363 case IrInstructionIdTruncate: 27364 return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction); 27365 case IrInstructionIdIntCast: 27366 return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction); 27367 case IrInstructionIdFloatCast: 27368 return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction); 27369 case IrInstructionIdErrSetCast: 27370 return ir_analyze_instruction_err_set_cast(ira, (IrInstructionErrSetCast *)instruction); 27371 case IrInstructionIdFromBytes: 27372 return ir_analyze_instruction_from_bytes(ira, (IrInstructionFromBytes *)instruction); 27373 case IrInstructionIdToBytes: 27374 return ir_analyze_instruction_to_bytes(ira, (IrInstructionToBytes *)instruction); 27375 case IrInstructionIdIntToFloat: 27376 return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); 27377 case IrInstructionIdFloatToInt: 27378 return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction); 27379 case IrInstructionIdBoolToInt: 27380 return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction); 27381 case IrInstructionIdIntType: 27382 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); 27383 case IrInstructionIdVectorType: 27384 return ir_analyze_instruction_vector_type(ira, (IrInstructionVectorType *)instruction); 27385 case IrInstructionIdShuffleVector: 27386 return ir_analyze_instruction_shuffle_vector(ira, (IrInstructionShuffleVector *)instruction); 27387 case IrInstructionIdSplatSrc: 27388 return ir_analyze_instruction_splat(ira, (IrInstructionSplatSrc *)instruction); 27389 case IrInstructionIdBoolNot: 27390 return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); 27391 case IrInstructionIdMemset: 27392 return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); 27393 case IrInstructionIdMemcpy: 27394 return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); 27395 case IrInstructionIdSliceSrc: 27396 return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction); 27397 case IrInstructionIdMemberCount: 27398 return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); 27399 case IrInstructionIdMemberType: 27400 return ir_analyze_instruction_member_type(ira, (IrInstructionMemberType *)instruction); 27401 case IrInstructionIdMemberName: 27402 return ir_analyze_instruction_member_name(ira, (IrInstructionMemberName *)instruction); 27403 case IrInstructionIdBreakpoint: 27404 return ir_analyze_instruction_breakpoint(ira, (IrInstructionBreakpoint *)instruction); 27405 case IrInstructionIdReturnAddress: 27406 return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction); 27407 case IrInstructionIdFrameAddress: 27408 return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction); 27409 case IrInstructionIdFrameHandle: 27410 return ir_analyze_instruction_frame_handle(ira, (IrInstructionFrameHandle *)instruction); 27411 case IrInstructionIdFrameType: 27412 return ir_analyze_instruction_frame_type(ira, (IrInstructionFrameType *)instruction); 27413 case IrInstructionIdFrameSizeSrc: 27414 return ir_analyze_instruction_frame_size(ira, (IrInstructionFrameSizeSrc *)instruction); 27415 case IrInstructionIdAlignOf: 27416 return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); 27417 case IrInstructionIdOverflowOp: 27418 return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); 27419 case IrInstructionIdTestErrSrc: 27420 return ir_analyze_instruction_test_err(ira, (IrInstructionTestErrSrc *)instruction); 27421 case IrInstructionIdUnwrapErrCode: 27422 return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); 27423 case IrInstructionIdUnwrapErrPayload: 27424 return ir_analyze_instruction_unwrap_err_payload(ira, (IrInstructionUnwrapErrPayload *)instruction); 27425 case IrInstructionIdFnProto: 27426 return ir_analyze_instruction_fn_proto(ira, (IrInstructionFnProto *)instruction); 27427 case IrInstructionIdTestComptime: 27428 return ir_analyze_instruction_test_comptime(ira, (IrInstructionTestComptime *)instruction); 27429 case IrInstructionIdCheckSwitchProngs: 27430 return ir_analyze_instruction_check_switch_prongs(ira, (IrInstructionCheckSwitchProngs *)instruction); 27431 case IrInstructionIdCheckStatementIsVoid: 27432 return ir_analyze_instruction_check_statement_is_void(ira, (IrInstructionCheckStatementIsVoid *)instruction); 27433 case IrInstructionIdDeclRef: 27434 return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction); 27435 case IrInstructionIdPanic: 27436 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); 27437 case IrInstructionIdPtrCastSrc: 27438 return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction); 27439 case IrInstructionIdIntToPtr: 27440 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); 27441 case IrInstructionIdPtrToInt: 27442 return ir_analyze_instruction_ptr_to_int(ira, (IrInstructionPtrToInt *)instruction); 27443 case IrInstructionIdTagName: 27444 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionTagName *)instruction); 27445 case IrInstructionIdFieldParentPtr: 27446 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); 27447 case IrInstructionIdByteOffsetOf: 27448 return ir_analyze_instruction_byte_offset_of(ira, (IrInstructionByteOffsetOf *)instruction); 27449 case IrInstructionIdBitOffsetOf: 27450 return ir_analyze_instruction_bit_offset_of(ira, (IrInstructionBitOffsetOf *)instruction); 27451 case IrInstructionIdTypeInfo: 27452 return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); 27453 case IrInstructionIdType: 27454 return ir_analyze_instruction_type(ira, (IrInstructionType *)instruction); 27455 case IrInstructionIdHasField: 27456 return ir_analyze_instruction_has_field(ira, (IrInstructionHasField *) instruction); 27457 case IrInstructionIdTypeId: 27458 return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); 27459 case IrInstructionIdSetEvalBranchQuota: 27460 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstructionSetEvalBranchQuota *)instruction); 27461 case IrInstructionIdPtrType: 27462 return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); 27463 case IrInstructionIdAlignCast: 27464 return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); 27465 case IrInstructionIdImplicitCast: 27466 return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction); 27467 case IrInstructionIdResolveResult: 27468 return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction); 27469 case IrInstructionIdResetResult: 27470 return ir_analyze_instruction_reset_result(ira, (IrInstructionResetResult *)instruction); 27471 case IrInstructionIdOpaqueType: 27472 return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); 27473 case IrInstructionIdSetAlignStack: 27474 return ir_analyze_instruction_set_align_stack(ira, (IrInstructionSetAlignStack *)instruction); 27475 case IrInstructionIdArgType: 27476 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction); 27477 case IrInstructionIdTagType: 27478 return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction); 27479 case IrInstructionIdExport: 27480 return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction); 27481 case IrInstructionIdErrorReturnTrace: 27482 return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction); 27483 case IrInstructionIdErrorUnion: 27484 return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction); 27485 case IrInstructionIdAtomicRmw: 27486 return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction); 27487 case IrInstructionIdAtomicLoad: 27488 return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction); 27489 case IrInstructionIdAtomicStore: 27490 return ir_analyze_instruction_atomic_store(ira, (IrInstructionAtomicStore *)instruction); 27491 case IrInstructionIdSaveErrRetAddr: 27492 return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction); 27493 case IrInstructionIdAddImplicitReturnType: 27494 return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction); 27495 case IrInstructionIdFloatOp: 27496 return ir_analyze_instruction_float_op(ira, (IrInstructionFloatOp *)instruction); 27497 case IrInstructionIdMulAdd: 27498 return ir_analyze_instruction_mul_add(ira, (IrInstructionMulAdd *)instruction); 27499 case IrInstructionIdIntToErr: 27500 return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); 27501 case IrInstructionIdErrToInt: 27502 return ir_analyze_instruction_err_to_int(ira, (IrInstructionErrToInt *)instruction); 27503 case IrInstructionIdIntToEnum: 27504 return ir_analyze_instruction_int_to_enum(ira, (IrInstructionIntToEnum *)instruction); 27505 case IrInstructionIdEnumToInt: 27506 return ir_analyze_instruction_enum_to_int(ira, (IrInstructionEnumToInt *)instruction); 27507 case IrInstructionIdCheckRuntimeScope: 27508 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction); 27509 case IrInstructionIdHasDecl: 27510 return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction); 27511 case IrInstructionIdUndeclaredIdent: 27512 return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction); 27513 case IrInstructionIdAllocaSrc: 27514 return nullptr; 27515 case IrInstructionIdEndExpr: 27516 return ir_analyze_instruction_end_expr(ira, (IrInstructionEndExpr *)instruction); 27517 case IrInstructionIdBitCastSrc: 27518 return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction); 27519 case IrInstructionIdUnionInitNamedField: 27520 return ir_analyze_instruction_union_init_named_field(ira, (IrInstructionUnionInitNamedField *)instruction); 27521 case IrInstructionIdSuspendBegin: 27522 return ir_analyze_instruction_suspend_begin(ira, (IrInstructionSuspendBegin *)instruction); 27523 case IrInstructionIdSuspendFinish: 27524 return ir_analyze_instruction_suspend_finish(ira, (IrInstructionSuspendFinish *)instruction); 27525 case IrInstructionIdResume: 27526 return ir_analyze_instruction_resume(ira, (IrInstructionResume *)instruction); 27527 case IrInstructionIdAwaitSrc: 27528 return ir_analyze_instruction_await(ira, (IrInstructionAwaitSrc *)instruction); 27529 case IrInstructionIdSpillBegin: 27530 return ir_analyze_instruction_spill_begin(ira, (IrInstructionSpillBegin *)instruction); 27531 case IrInstructionIdSpillEnd: 27532 return ir_analyze_instruction_spill_end(ira, (IrInstructionSpillEnd *)instruction); 27533 } 27534 zig_unreachable(); 27535 } 27536 27537 // This function attempts to evaluate IR code while doing type checking and other analysis. 27538 // It emits a new IrExecutable which is partially evaluated IR code. 27539 ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, 27540 ZigType *expected_type, AstNode *expected_type_source_node) 27541 { 27542 assert(old_exec->first_err_trace_msg == nullptr); 27543 assert(expected_type == nullptr || !type_is_invalid(expected_type)); 27544 27545 IrAnalyze *ira = allocate<IrAnalyze>(1); 27546 old_exec->analysis = ira; 27547 ira->codegen = codegen; 27548 27549 ira->explicit_return_type = expected_type; 27550 ira->explicit_return_type_source_node = expected_type_source_node; 27551 27552 ira->old_irb.codegen = codegen; 27553 ira->old_irb.exec = old_exec; 27554 27555 ira->new_irb.codegen = codegen; 27556 ira->new_irb.exec = new_exec; 27557 27558 ZigValue *vals = create_const_vals(ira->old_irb.exec->mem_slot_count); 27559 ira->exec_context.mem_slot_list.resize(ira->old_irb.exec->mem_slot_count); 27560 for (size_t i = 0; i < ira->exec_context.mem_slot_list.length; i += 1) { 27561 ira->exec_context.mem_slot_list.items[i] = &vals[i]; 27562 } 27563 27564 IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); 27565 IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); 27566 ir_ref_bb(new_entry_bb); 27567 ira->new_irb.current_basic_block = new_entry_bb; 27568 ira->old_bb_index = 0; 27569 27570 ir_start_bb(ira, old_entry_bb, nullptr); 27571 27572 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 27573 IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 27574 27575 if (old_instruction->ref_count == 0 && !ir_has_side_effects(old_instruction)) { 27576 ira->instruction_index += 1; 27577 continue; 27578 } 27579 27580 if (ira->codegen->verbose_ir) { 27581 fprintf(stderr, "analyze #%" PRIu32 "\n", old_instruction->debug_id); 27582 } 27583 IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); 27584 if (new_instruction != nullptr) { 27585 ir_assert(new_instruction->value->type != nullptr || new_instruction->value->type != nullptr, old_instruction); 27586 old_instruction->child = new_instruction; 27587 27588 if (type_is_invalid(new_instruction->value->type)) { 27589 if (new_exec->first_err_trace_msg != nullptr) { 27590 ira->codegen->trace_err = new_exec->first_err_trace_msg; 27591 } else { 27592 new_exec->first_err_trace_msg = ira->codegen->trace_err; 27593 } 27594 if (new_exec->first_err_trace_msg != nullptr && 27595 !old_instruction->source_node->already_traced_this_node) 27596 { 27597 old_instruction->source_node->already_traced_this_node = true; 27598 new_exec->first_err_trace_msg = add_error_note(ira->codegen, new_exec->first_err_trace_msg, 27599 old_instruction->source_node, buf_create_from_str("referenced here")); 27600 } 27601 return ira->codegen->builtin_types.entry_invalid; 27602 } 27603 27604 // unreachable instructions do their own control flow. 27605 if (new_instruction->value->type->id == ZigTypeIdUnreachable) 27606 continue; 27607 } 27608 27609 ira->instruction_index += 1; 27610 } 27611 27612 if (new_exec->first_err_trace_msg != nullptr) { 27613 codegen->trace_err = new_exec->first_err_trace_msg; 27614 if (codegen->trace_err != nullptr && new_exec->source_node != nullptr && 27615 !new_exec->source_node->already_traced_this_node) 27616 { 27617 new_exec->source_node->already_traced_this_node = true; 27618 codegen->trace_err = add_error_note(codegen, codegen->trace_err, 27619 new_exec->source_node, buf_create_from_str("referenced here")); 27620 } 27621 return ira->codegen->builtin_types.entry_invalid; 27622 } else if (ira->src_implicit_return_type_list.length == 0) { 27623 return codegen->builtin_types.entry_unreachable; 27624 } else { 27625 return ir_resolve_peer_types(ira, expected_type_source_node, expected_type, ira->src_implicit_return_type_list.items, 27626 ira->src_implicit_return_type_list.length); 27627 } 27628 } 27629 27630 bool ir_has_side_effects(IrInstruction *instruction) { 27631 switch (instruction->id) { 27632 case IrInstructionIdInvalid: 27633 zig_unreachable(); 27634 case IrInstructionIdBr: 27635 case IrInstructionIdCondBr: 27636 case IrInstructionIdSwitchBr: 27637 case IrInstructionIdDeclVarSrc: 27638 case IrInstructionIdDeclVarGen: 27639 case IrInstructionIdStorePtr: 27640 case IrInstructionIdVectorStoreElem: 27641 case IrInstructionIdCallSrc: 27642 case IrInstructionIdCallGen: 27643 case IrInstructionIdReturn: 27644 case IrInstructionIdUnreachable: 27645 case IrInstructionIdSetCold: 27646 case IrInstructionIdSetRuntimeSafety: 27647 case IrInstructionIdSetFloatMode: 27648 case IrInstructionIdImport: 27649 case IrInstructionIdCompileErr: 27650 case IrInstructionIdCompileLog: 27651 case IrInstructionIdCImport: 27652 case IrInstructionIdCInclude: 27653 case IrInstructionIdCDefine: 27654 case IrInstructionIdCUndef: 27655 case IrInstructionIdFence: 27656 case IrInstructionIdMemset: 27657 case IrInstructionIdMemcpy: 27658 case IrInstructionIdBreakpoint: 27659 case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free 27660 case IrInstructionIdCheckSwitchProngs: 27661 case IrInstructionIdCheckStatementIsVoid: 27662 case IrInstructionIdCheckRuntimeScope: 27663 case IrInstructionIdPanic: 27664 case IrInstructionIdSetEvalBranchQuota: 27665 case IrInstructionIdPtrType: 27666 case IrInstructionIdSetAlignStack: 27667 case IrInstructionIdExport: 27668 case IrInstructionIdSaveErrRetAddr: 27669 case IrInstructionIdAddImplicitReturnType: 27670 case IrInstructionIdAtomicRmw: 27671 case IrInstructionIdAtomicStore: 27672 case IrInstructionIdCmpxchgGen: 27673 case IrInstructionIdCmpxchgSrc: 27674 case IrInstructionIdAssertZero: 27675 case IrInstructionIdAssertNonNull: 27676 case IrInstructionIdResizeSlice: 27677 case IrInstructionIdGlobalAsm: 27678 case IrInstructionIdUndeclaredIdent: 27679 case IrInstructionIdEndExpr: 27680 case IrInstructionIdPtrOfArrayToSlice: 27681 case IrInstructionIdSliceGen: 27682 case IrInstructionIdOptionalWrap: 27683 case IrInstructionIdVectorToArray: 27684 case IrInstructionIdResetResult: 27685 case IrInstructionIdSuspendBegin: 27686 case IrInstructionIdSuspendFinish: 27687 case IrInstructionIdResume: 27688 case IrInstructionIdAwaitSrc: 27689 case IrInstructionIdAwaitGen: 27690 case IrInstructionIdSpillBegin: 27691 return true; 27692 27693 case IrInstructionIdPhi: 27694 case IrInstructionIdUnOp: 27695 case IrInstructionIdBinOp: 27696 case IrInstructionIdMergeErrSets: 27697 case IrInstructionIdLoadPtr: 27698 case IrInstructionIdConst: 27699 case IrInstructionIdCast: 27700 case IrInstructionIdContainerInitList: 27701 case IrInstructionIdContainerInitFields: 27702 case IrInstructionIdUnionInitNamedField: 27703 case IrInstructionIdFieldPtr: 27704 case IrInstructionIdElemPtr: 27705 case IrInstructionIdVarPtr: 27706 case IrInstructionIdReturnPtr: 27707 case IrInstructionIdTypeOf: 27708 case IrInstructionIdStructFieldPtr: 27709 case IrInstructionIdArrayType: 27710 case IrInstructionIdSliceType: 27711 case IrInstructionIdAnyFrameType: 27712 case IrInstructionIdSizeOf: 27713 case IrInstructionIdTestNonNull: 27714 case IrInstructionIdOptionalUnwrapPtr: 27715 case IrInstructionIdClz: 27716 case IrInstructionIdCtz: 27717 case IrInstructionIdPopCount: 27718 case IrInstructionIdBswap: 27719 case IrInstructionIdBitReverse: 27720 case IrInstructionIdSwitchVar: 27721 case IrInstructionIdSwitchElseVar: 27722 case IrInstructionIdSwitchTarget: 27723 case IrInstructionIdUnionTag: 27724 case IrInstructionIdRef: 27725 case IrInstructionIdEmbedFile: 27726 case IrInstructionIdTruncate: 27727 case IrInstructionIdIntType: 27728 case IrInstructionIdVectorType: 27729 case IrInstructionIdShuffleVector: 27730 case IrInstructionIdSplatSrc: 27731 case IrInstructionIdSplatGen: 27732 case IrInstructionIdBoolNot: 27733 case IrInstructionIdSliceSrc: 27734 case IrInstructionIdMemberCount: 27735 case IrInstructionIdMemberType: 27736 case IrInstructionIdMemberName: 27737 case IrInstructionIdAlignOf: 27738 case IrInstructionIdReturnAddress: 27739 case IrInstructionIdFrameAddress: 27740 case IrInstructionIdFrameHandle: 27741 case IrInstructionIdFrameType: 27742 case IrInstructionIdFrameSizeSrc: 27743 case IrInstructionIdFrameSizeGen: 27744 case IrInstructionIdTestErrSrc: 27745 case IrInstructionIdTestErrGen: 27746 case IrInstructionIdFnProto: 27747 case IrInstructionIdTestComptime: 27748 case IrInstructionIdPtrCastSrc: 27749 case IrInstructionIdPtrCastGen: 27750 case IrInstructionIdBitCastSrc: 27751 case IrInstructionIdBitCastGen: 27752 case IrInstructionIdWidenOrShorten: 27753 case IrInstructionIdPtrToInt: 27754 case IrInstructionIdIntToPtr: 27755 case IrInstructionIdIntToEnum: 27756 case IrInstructionIdIntToErr: 27757 case IrInstructionIdErrToInt: 27758 case IrInstructionIdDeclRef: 27759 case IrInstructionIdErrName: 27760 case IrInstructionIdTypeName: 27761 case IrInstructionIdTagName: 27762 case IrInstructionIdFieldParentPtr: 27763 case IrInstructionIdByteOffsetOf: 27764 case IrInstructionIdBitOffsetOf: 27765 case IrInstructionIdTypeInfo: 27766 case IrInstructionIdType: 27767 case IrInstructionIdHasField: 27768 case IrInstructionIdTypeId: 27769 case IrInstructionIdAlignCast: 27770 case IrInstructionIdImplicitCast: 27771 case IrInstructionIdResolveResult: 27772 case IrInstructionIdOpaqueType: 27773 case IrInstructionIdArgType: 27774 case IrInstructionIdTagType: 27775 case IrInstructionIdErrorReturnTrace: 27776 case IrInstructionIdErrorUnion: 27777 case IrInstructionIdFloatOp: 27778 case IrInstructionIdMulAdd: 27779 case IrInstructionIdAtomicLoad: 27780 case IrInstructionIdIntCast: 27781 case IrInstructionIdFloatCast: 27782 case IrInstructionIdErrSetCast: 27783 case IrInstructionIdIntToFloat: 27784 case IrInstructionIdFloatToInt: 27785 case IrInstructionIdBoolToInt: 27786 case IrInstructionIdFromBytes: 27787 case IrInstructionIdToBytes: 27788 case IrInstructionIdEnumToInt: 27789 case IrInstructionIdArrayToVector: 27790 case IrInstructionIdHasDecl: 27791 case IrInstructionIdAllocaSrc: 27792 case IrInstructionIdAllocaGen: 27793 case IrInstructionIdSpillEnd: 27794 case IrInstructionIdVectorExtractElem: 27795 return false; 27796 27797 case IrInstructionIdAsm: 27798 { 27799 IrInstructionAsm *asm_instruction = (IrInstructionAsm *)instruction; 27800 return asm_instruction->has_side_effects; 27801 } 27802 case IrInstructionIdUnwrapErrPayload: 27803 { 27804 IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = 27805 (IrInstructionUnwrapErrPayload *)instruction; 27806 return unwrap_err_payload_instruction->safety_check_on || 27807 unwrap_err_payload_instruction->initializing; 27808 } 27809 case IrInstructionIdUnwrapErrCode: 27810 return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing; 27811 case IrInstructionIdUnionFieldPtr: 27812 return reinterpret_cast<IrInstructionUnionFieldPtr *>(instruction)->initializing; 27813 case IrInstructionIdErrWrapPayload: 27814 return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr; 27815 case IrInstructionIdErrWrapCode: 27816 return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr; 27817 case IrInstructionIdLoadPtrGen: 27818 return reinterpret_cast<IrInstructionLoadPtrGen *>(instruction)->result_loc != nullptr; 27819 case IrInstructionIdRefGen: 27820 return reinterpret_cast<IrInstructionRefGen *>(instruction)->result_loc != nullptr; 27821 } 27822 zig_unreachable(); 27823 } 27824 27825 static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, LazyValueFnType *lazy_fn_type) { 27826 Error err; 27827 AstNode *proto_node = lazy_fn_type->proto_node; 27828 27829 FnTypeId fn_type_id = {0}; 27830 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); 27831 27832 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { 27833 AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); 27834 assert(param_node->type == NodeTypeParamDecl); 27835 27836 bool param_is_var_args = param_node->data.param_decl.is_var_args; 27837 if (param_is_var_args) { 27838 if (fn_type_id.cc == CallingConventionC) { 27839 fn_type_id.param_count = fn_type_id.next_param_index; 27840 continue; 27841 } else if (fn_type_id.cc == CallingConventionUnspecified) { 27842 return get_generic_fn_type(ira->codegen, &fn_type_id); 27843 } else { 27844 zig_unreachable(); 27845 } 27846 } 27847 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; 27848 param_info->is_noalias = param_node->data.param_decl.is_noalias; 27849 27850 if (lazy_fn_type->param_types[fn_type_id.next_param_index] == nullptr) { 27851 param_info->type = nullptr; 27852 return get_generic_fn_type(ira->codegen, &fn_type_id); 27853 } else { 27854 IrInstruction *param_type_inst = lazy_fn_type->param_types[fn_type_id.next_param_index]; 27855 ZigType *param_type = ir_resolve_type(ira, param_type_inst); 27856 if (type_is_invalid(param_type)) 27857 return nullptr; 27858 switch (type_requires_comptime(ira->codegen, param_type)) { 27859 case ReqCompTimeYes: 27860 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 27861 ir_add_error(ira, param_type_inst, 27862 buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", 27863 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 27864 return nullptr; 27865 } 27866 param_info->type = param_type; 27867 fn_type_id.next_param_index += 1; 27868 return get_generic_fn_type(ira->codegen, &fn_type_id); 27869 case ReqCompTimeInvalid: 27870 return nullptr; 27871 case ReqCompTimeNo: 27872 break; 27873 } 27874 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 27875 if ((err = type_resolve(ira->codegen, param_type, ResolveStatusZeroBitsKnown))) 27876 return nullptr; 27877 if (!type_has_bits(param_type)) { 27878 ir_add_error(ira, param_type_inst, 27879 buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", 27880 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 27881 return nullptr; 27882 } 27883 } 27884 param_info->type = param_type; 27885 } 27886 } 27887 27888 if (lazy_fn_type->align_inst != nullptr) { 27889 if (!ir_resolve_align(ira, lazy_fn_type->align_inst, nullptr, &fn_type_id.alignment)) 27890 return nullptr; 27891 } 27892 27893 fn_type_id.return_type = ir_resolve_type(ira, lazy_fn_type->return_type); 27894 if (type_is_invalid(fn_type_id.return_type)) 27895 return nullptr; 27896 if (fn_type_id.return_type->id == ZigTypeIdOpaque) { 27897 ir_add_error(ira, lazy_fn_type->return_type, buf_create_from_str("return type cannot be opaque")); 27898 return nullptr; 27899 } 27900 27901 return get_fn_type(ira->codegen, &fn_type_id); 27902 } 27903 27904 static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { 27905 Error err; 27906 if (val->special != ConstValSpecialLazy) 27907 return ErrorNone; 27908 switch (val->data.x_lazy->id) { 27909 case LazyValueIdInvalid: 27910 zig_unreachable(); 27911 case LazyValueIdAlignOf: { 27912 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); 27913 IrAnalyze *ira = lazy_align_of->ira; 27914 27915 if (lazy_align_of->target_type->value->special == ConstValSpecialStatic) { 27916 switch (lazy_align_of->target_type->value->data.x_type->id) { 27917 case ZigTypeIdInvalid: 27918 zig_unreachable(); 27919 case ZigTypeIdMetaType: 27920 case ZigTypeIdUnreachable: 27921 case ZigTypeIdComptimeFloat: 27922 case ZigTypeIdComptimeInt: 27923 case ZigTypeIdEnumLiteral: 27924 case ZigTypeIdUndefined: 27925 case ZigTypeIdNull: 27926 case ZigTypeIdBoundFn: 27927 case ZigTypeIdArgTuple: 27928 case ZigTypeIdVoid: 27929 case ZigTypeIdOpaque: 27930 ir_add_error(ira, lazy_align_of->target_type, 27931 buf_sprintf("no align available for type '%s'", 27932 buf_ptr(&lazy_align_of->target_type->value->data.x_type->name))); 27933 return ErrorSemanticAnalyzeFail; 27934 case ZigTypeIdBool: 27935 case ZigTypeIdInt: 27936 case ZigTypeIdFloat: 27937 case ZigTypeIdPointer: 27938 case ZigTypeIdArray: 27939 case ZigTypeIdStruct: 27940 case ZigTypeIdOptional: 27941 case ZigTypeIdErrorUnion: 27942 case ZigTypeIdErrorSet: 27943 case ZigTypeIdEnum: 27944 case ZigTypeIdUnion: 27945 case ZigTypeIdFn: 27946 case ZigTypeIdVector: 27947 case ZigTypeIdFnFrame: 27948 case ZigTypeIdAnyFrame: 27949 break; 27950 } 27951 } 27952 27953 uint32_t align_in_bytes; 27954 if ((err = type_val_resolve_abi_align(ira->codegen, lazy_align_of->target_type->value, 27955 &align_in_bytes))) 27956 { 27957 return err; 27958 } 27959 27960 val->special = ConstValSpecialStatic; 27961 assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt); 27962 bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); 27963 return ErrorNone; 27964 } 27965 case LazyValueIdSizeOf: { 27966 LazyValueSizeOf *lazy_size_of = reinterpret_cast<LazyValueSizeOf *>(val->data.x_lazy); 27967 IrAnalyze *ira = lazy_size_of->ira; 27968 27969 if (lazy_size_of->target_type->value->special == ConstValSpecialStatic) { 27970 switch (lazy_size_of->target_type->value->data.x_type->id) { 27971 case ZigTypeIdInvalid: // handled above 27972 zig_unreachable(); 27973 case ZigTypeIdUnreachable: 27974 case ZigTypeIdUndefined: 27975 case ZigTypeIdNull: 27976 case ZigTypeIdBoundFn: 27977 case ZigTypeIdArgTuple: 27978 case ZigTypeIdOpaque: 27979 ir_add_error(ira, lazy_size_of->target_type, 27980 buf_sprintf("no size available for type '%s'", 27981 buf_ptr(&lazy_size_of->target_type->value->data.x_type->name))); 27982 return ErrorSemanticAnalyzeFail; 27983 case ZigTypeIdMetaType: 27984 case ZigTypeIdEnumLiteral: 27985 case ZigTypeIdComptimeFloat: 27986 case ZigTypeIdComptimeInt: 27987 case ZigTypeIdVoid: 27988 case ZigTypeIdBool: 27989 case ZigTypeIdInt: 27990 case ZigTypeIdFloat: 27991 case ZigTypeIdPointer: 27992 case ZigTypeIdArray: 27993 case ZigTypeIdStruct: 27994 case ZigTypeIdOptional: 27995 case ZigTypeIdErrorUnion: 27996 case ZigTypeIdErrorSet: 27997 case ZigTypeIdEnum: 27998 case ZigTypeIdUnion: 27999 case ZigTypeIdFn: 28000 case ZigTypeIdVector: 28001 case ZigTypeIdFnFrame: 28002 case ZigTypeIdAnyFrame: 28003 break; 28004 } 28005 } 28006 28007 size_t abi_size; 28008 size_t size_in_bits; 28009 if ((err = type_val_resolve_abi_size(ira->codegen, source_node, lazy_size_of->target_type->value, 28010 &abi_size, &size_in_bits))) 28011 { 28012 return err; 28013 } 28014 28015 val->special = ConstValSpecialStatic; 28016 assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt); 28017 bigint_init_unsigned(&val->data.x_bigint, abi_size); 28018 return ErrorNone; 28019 } 28020 case LazyValueIdSliceType: { 28021 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy); 28022 IrAnalyze *ira = lazy_slice_type->ira; 28023 28024 ZigType *elem_type = ir_resolve_type(ira, lazy_slice_type->elem_type); 28025 if (type_is_invalid(elem_type)) 28026 return ErrorSemanticAnalyzeFail; 28027 28028 ZigValue *sentinel_val; 28029 if (lazy_slice_type->sentinel != nullptr) { 28030 if (type_is_invalid(lazy_slice_type->sentinel->value->type)) 28031 return ErrorSemanticAnalyzeFail; 28032 IrInstruction *sentinel = ir_implicit_cast(ira, lazy_slice_type->sentinel, elem_type); 28033 if (type_is_invalid(sentinel->value->type)) 28034 return ErrorSemanticAnalyzeFail; 28035 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 28036 if (sentinel_val == nullptr) 28037 return ErrorSemanticAnalyzeFail; 28038 } else { 28039 sentinel_val = nullptr; 28040 } 28041 28042 uint32_t align_bytes = 0; 28043 if (lazy_slice_type->align_inst != nullptr) { 28044 if (!ir_resolve_align(ira, lazy_slice_type->align_inst, elem_type, &align_bytes)) 28045 return ErrorSemanticAnalyzeFail; 28046 } 28047 28048 switch (elem_type->id) { 28049 case ZigTypeIdInvalid: // handled above 28050 zig_unreachable(); 28051 case ZigTypeIdUnreachable: 28052 case ZigTypeIdUndefined: 28053 case ZigTypeIdNull: 28054 case ZigTypeIdArgTuple: 28055 case ZigTypeIdOpaque: 28056 ir_add_error(ira, lazy_slice_type->elem_type, 28057 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&elem_type->name))); 28058 return ErrorSemanticAnalyzeFail; 28059 case ZigTypeIdMetaType: 28060 case ZigTypeIdVoid: 28061 case ZigTypeIdBool: 28062 case ZigTypeIdInt: 28063 case ZigTypeIdFloat: 28064 case ZigTypeIdPointer: 28065 case ZigTypeIdArray: 28066 case ZigTypeIdStruct: 28067 case ZigTypeIdComptimeFloat: 28068 case ZigTypeIdComptimeInt: 28069 case ZigTypeIdEnumLiteral: 28070 case ZigTypeIdOptional: 28071 case ZigTypeIdErrorUnion: 28072 case ZigTypeIdErrorSet: 28073 case ZigTypeIdEnum: 28074 case ZigTypeIdUnion: 28075 case ZigTypeIdFn: 28076 case ZigTypeIdBoundFn: 28077 case ZigTypeIdVector: 28078 case ZigTypeIdFnFrame: 28079 case ZigTypeIdAnyFrame: 28080 break; 28081 } 28082 28083 ResolveStatus needed_status = (align_bytes == 0) ? 28084 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; 28085 if ((err = type_resolve(ira->codegen, elem_type, needed_status))) 28086 return err; 28087 ZigType *slice_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 28088 lazy_slice_type->is_const, lazy_slice_type->is_volatile, 28089 PtrLenUnknown, 28090 align_bytes, 28091 0, 0, lazy_slice_type->is_allowzero, 28092 VECTOR_INDEX_NONE, nullptr, sentinel_val); 28093 val->special = ConstValSpecialStatic; 28094 assert(val->type->id == ZigTypeIdMetaType); 28095 val->data.x_type = get_slice_type(ira->codegen, slice_ptr_type); 28096 return ErrorNone; 28097 } 28098 case LazyValueIdPtrType: { 28099 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(val->data.x_lazy); 28100 IrAnalyze *ira = lazy_ptr_type->ira; 28101 28102 ZigType *elem_type = ir_resolve_type(ira, lazy_ptr_type->elem_type); 28103 if (type_is_invalid(elem_type)) 28104 return ErrorSemanticAnalyzeFail; 28105 28106 ZigValue *sentinel_val; 28107 if (lazy_ptr_type->sentinel != nullptr) { 28108 if (type_is_invalid(lazy_ptr_type->sentinel->value->type)) 28109 return ErrorSemanticAnalyzeFail; 28110 IrInstruction *sentinel = ir_implicit_cast(ira, lazy_ptr_type->sentinel, elem_type); 28111 if (type_is_invalid(sentinel->value->type)) 28112 return ErrorSemanticAnalyzeFail; 28113 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 28114 if (sentinel_val == nullptr) 28115 return ErrorSemanticAnalyzeFail; 28116 } else { 28117 sentinel_val = nullptr; 28118 } 28119 28120 uint32_t align_bytes = 0; 28121 if (lazy_ptr_type->align_inst != nullptr) { 28122 if (!ir_resolve_align(ira, lazy_ptr_type->align_inst, elem_type, &align_bytes)) 28123 return ErrorSemanticAnalyzeFail; 28124 } 28125 28126 if (elem_type->id == ZigTypeIdUnreachable) { 28127 ir_add_error(ira, lazy_ptr_type->elem_type, 28128 buf_create_from_str("pointer to noreturn not allowed")); 28129 return ErrorSemanticAnalyzeFail; 28130 } else if (elem_type->id == ZigTypeIdOpaque && lazy_ptr_type->ptr_len == PtrLenUnknown) { 28131 ir_add_error(ira, lazy_ptr_type->elem_type, 28132 buf_create_from_str("unknown-length pointer to opaque")); 28133 return ErrorSemanticAnalyzeFail; 28134 } else if (lazy_ptr_type->ptr_len == PtrLenC) { 28135 bool ok_type; 28136 if ((err = type_allowed_in_extern(ira->codegen, elem_type, &ok_type))) 28137 return err; 28138 if (!ok_type) { 28139 ir_add_error(ira, lazy_ptr_type->elem_type, 28140 buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", 28141 buf_ptr(&elem_type->name))); 28142 return ErrorSemanticAnalyzeFail; 28143 } else if (elem_type->id == ZigTypeIdOpaque) { 28144 ir_add_error(ira, lazy_ptr_type->elem_type, 28145 buf_sprintf("C pointers cannot point opaque types")); 28146 return ErrorSemanticAnalyzeFail; 28147 } else if (lazy_ptr_type->is_allowzero) { 28148 ir_add_error(ira, lazy_ptr_type->elem_type, 28149 buf_sprintf("C pointers always allow address zero")); 28150 return ErrorSemanticAnalyzeFail; 28151 } 28152 } 28153 28154 if (align_bytes != 0) { 28155 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) 28156 return err; 28157 if (!type_has_bits(elem_type)) 28158 align_bytes = 0; 28159 } 28160 bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC; 28161 assert(val->type->id == ZigTypeIdMetaType); 28162 val->data.x_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 28163 lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes, 28164 lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes, 28165 allow_zero, VECTOR_INDEX_NONE, nullptr, sentinel_val); 28166 val->special = ConstValSpecialStatic; 28167 return ErrorNone; 28168 } 28169 case LazyValueIdOptType: { 28170 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(val->data.x_lazy); 28171 IrAnalyze *ira = lazy_opt_type->ira; 28172 28173 ZigType *payload_type = ir_resolve_type(ira, lazy_opt_type->payload_type); 28174 if (type_is_invalid(payload_type)) 28175 return ErrorSemanticAnalyzeFail; 28176 28177 if (payload_type->id == ZigTypeIdOpaque || payload_type->id == ZigTypeIdUnreachable) { 28178 ir_add_error(ira, lazy_opt_type->payload_type, 28179 buf_sprintf("type '%s' cannot be optional", buf_ptr(&payload_type->name))); 28180 return ErrorSemanticAnalyzeFail; 28181 } 28182 28183 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 28184 return err; 28185 28186 assert(val->type->id == ZigTypeIdMetaType); 28187 val->data.x_type = get_optional_type(ira->codegen, payload_type); 28188 val->special = ConstValSpecialStatic; 28189 return ErrorNone; 28190 } 28191 case LazyValueIdFnType: { 28192 LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(val->data.x_lazy); 28193 ZigType *fn_type = ir_resolve_lazy_fn_type(lazy_fn_type->ira, source_node, lazy_fn_type); 28194 if (fn_type == nullptr) 28195 return ErrorSemanticAnalyzeFail; 28196 val->special = ConstValSpecialStatic; 28197 assert(val->type->id == ZigTypeIdMetaType); 28198 val->data.x_type = fn_type; 28199 return ErrorNone; 28200 } 28201 case LazyValueIdErrUnionType: { 28202 LazyValueErrUnionType *lazy_err_union_type = 28203 reinterpret_cast<LazyValueErrUnionType *>(val->data.x_lazy); 28204 IrAnalyze *ira = lazy_err_union_type->ira; 28205 28206 ZigType *err_set_type = ir_resolve_type(ira, lazy_err_union_type->err_set_type); 28207 if (type_is_invalid(err_set_type)) 28208 return ErrorSemanticAnalyzeFail; 28209 28210 ZigType *payload_type = ir_resolve_type(ira, lazy_err_union_type->payload_type); 28211 if (type_is_invalid(payload_type)) 28212 return ErrorSemanticAnalyzeFail; 28213 28214 if (err_set_type->id != ZigTypeIdErrorSet) { 28215 ir_add_error(ira, lazy_err_union_type->err_set_type, 28216 buf_sprintf("expected error set type, found type '%s'", 28217 buf_ptr(&err_set_type->name))); 28218 return ErrorSemanticAnalyzeFail; 28219 } 28220 28221 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 28222 return ErrorSemanticAnalyzeFail; 28223 28224 assert(val->type->id == ZigTypeIdMetaType); 28225 val->data.x_type = get_error_union_type(ira->codegen, err_set_type, payload_type); 28226 val->special = ConstValSpecialStatic; 28227 return ErrorNone; 28228 } 28229 } 28230 zig_unreachable(); 28231 } 28232 28233 Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) { 28234 Error err; 28235 if ((err = ir_resolve_lazy_raw(source_node, val))) { 28236 if (codegen->trace_err != nullptr && source_node != nullptr && !source_node->already_traced_this_node) { 28237 source_node->already_traced_this_node = true; 28238 codegen->trace_err = add_error_note(codegen, codegen->trace_err, source_node, 28239 buf_create_from_str("referenced here")); 28240 } 28241 return err; 28242 } 28243 if (type_is_invalid(val->type)) { 28244 return ErrorSemanticAnalyzeFail; 28245 } 28246 return ErrorNone; 28247 } 28248 28249 void IrInstruction::dump() { 28250 IrInstruction *inst = this; 28251 if (inst->source_node != nullptr) { 28252 inst->source_node->src(); 28253 } else { 28254 fprintf(stderr, "(null source node)\n"); 28255 } 28256 IrPass pass = (inst->child == nullptr) ? IrPassGen : IrPassSrc; 28257 ir_print_instruction(inst->scope->codegen, stderr, inst, 0, pass); 28258 if (pass == IrPassSrc) { 28259 fprintf(stderr, "-> "); 28260 ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen); 28261 } 28262 } 28263 28264 void IrAnalyze::dump() { 28265 ir_print(this->codegen, stderr, this->new_irb.exec, 0, IrPassGen); 28266 if (this->new_irb.current_basic_block != nullptr) { 28267 fprintf(stderr, "Current basic block:\n"); 28268 ir_print_basic_block(this->codegen, stderr, this->new_irb.current_basic_block, 1, IrPassGen); 28269 } 28270 }